summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog37
-rw-r--r--ChangeLog.pre-2-037
-rw-r--r--ChangeLog.pre-2-1037
-rw-r--r--ChangeLog.pre-2-237
-rw-r--r--ChangeLog.pre-2-437
-rw-r--r--ChangeLog.pre-2-637
-rw-r--r--ChangeLog.pre-2-837
-rw-r--r--docs/reference/gdk-pixbuf/gdk-pixbuf.hierarchy2
-rw-r--r--docs/reference/gtk/gtk.hierarchy1
-rw-r--r--docs/reference/gtk/tmpl/gtk-unused.sgml80
-rw-r--r--docs/reference/gtk/tmpl/gtksignal.sgml219
-rw-r--r--docs/reference/gtk/tmpl/gtkspinbutton.sgml14
-rw-r--r--docs/reference/gtk/tmpl/gtktextview.sgml10
-rw-r--r--docs/reference/gtk/tmpl/gtktreeviewcolumn.sgml7
-rw-r--r--docs/reference/gtk/tmpl/gtktypeutils.sgml20
-rw-r--r--gtk/Makefile.am3
-rw-r--r--gtk/gtk.h1
-rw-r--r--gtk/gtkcombo.c2
-rw-r--r--gtk/gtkfixed.c16
-rw-r--r--gtk/gtkrc.c497
-rw-r--r--gtk/gtkrc.h37
-rw-r--r--gtk/gtksettings.c682
-rw-r--r--gtk/gtksettings.h111
-rw-r--r--gtk/gtkspinbutton.c54
-rw-r--r--gtk/gtkspinbutton.h4
-rw-r--r--gtk/gtkstyle.c279
-rw-r--r--gtk/gtkstyle.h68
-rw-r--r--gtk/gtktypeutils.c2
-rw-r--r--gtk/gtkwidget.c349
-rw-r--r--gtk/gtkwidget.h40
-rw-r--r--gtk/gtkwindow.c2
-rw-r--r--gtk/testgtkrc17
-rw-r--r--tests/testgtkrc17
33 files changed, 2257 insertions, 536 deletions
diff --git a/ChangeLog b/ChangeLog
index 0bd006cca8..45b07c3347 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,40 @@
+Sun Mar 18 01:15:30 2001 Tim Janik <timj@gtk.org>
+
+ * gtk/gtkspinbutton.[hc]: added rc-style argument
+ GtkSpinButton::shadow_type.
+ removed spin_button->shadow_type, gtk_spin_button_set_shadow_type()
+ and ARG_SHADOW_TYPE as it doesn' make much sense to try to override
+ rc-style settings.
+
+ * gtk/gtkfixed.c: removed gtk_fixed_paint() (was unused).
+
+ * gtk/gtkwidget.c: quark cleanups.
+
+ * gtk/gtkrc.[hc]: added gtk_rc_scanner_new() to create an rc-file
+ scanner with appropriate configuration, renamed GtkRcStyleClass.clone
+ to create_rc_style() (we don't do cloning in standard OO sense).
+ added per rc style properties.
+
+ * gtk/gtkstyle.[hc]: added code to retrive pspec conformant rc-style
+ property values and for caching those. some cleanups.
+
+ * gtk/Makefile.am: -DG_DISABLE_CONST_RETURNS.
+
+ * gtk/gtksettings.[hc]: new file for global rc-file properties
+ (at least currently, should get extended to support X properties
+ and other communication mechanisms).
+
+ * gtk/gtkwidget.[hc]: added style property support:
+ (gtk_widget_class_install_style_property_parser): install style
+ property pspec with parser function for rc-file values other
+ than LONG, DOUBLE or STRING.
+ (gtk_widget_class_install_style_property): same as above without
+ parser (parsers are going to be needed quite infrequently).
+ (gtk_widget_style_get_property): retrive style property value.
+ (gtk_widget_style_get_valist): same as above with varargs support,
+ has NOCOPY semantics.
+ (gtk_widget_style_get): wrapper around gtk_widget_style_get_valist().
+
Fri Mar 16 18:24:53 2001 Jonathan Blandford <jrb@redhat.com>
* demos/gtk-demo/main.c (row_activated_cb): modified to use
diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0
index 0bd006cca8..45b07c3347 100644
--- a/ChangeLog.pre-2-0
+++ b/ChangeLog.pre-2-0
@@ -1,3 +1,40 @@
+Sun Mar 18 01:15:30 2001 Tim Janik <timj@gtk.org>
+
+ * gtk/gtkspinbutton.[hc]: added rc-style argument
+ GtkSpinButton::shadow_type.
+ removed spin_button->shadow_type, gtk_spin_button_set_shadow_type()
+ and ARG_SHADOW_TYPE as it doesn' make much sense to try to override
+ rc-style settings.
+
+ * gtk/gtkfixed.c: removed gtk_fixed_paint() (was unused).
+
+ * gtk/gtkwidget.c: quark cleanups.
+
+ * gtk/gtkrc.[hc]: added gtk_rc_scanner_new() to create an rc-file
+ scanner with appropriate configuration, renamed GtkRcStyleClass.clone
+ to create_rc_style() (we don't do cloning in standard OO sense).
+ added per rc style properties.
+
+ * gtk/gtkstyle.[hc]: added code to retrive pspec conformant rc-style
+ property values and for caching those. some cleanups.
+
+ * gtk/Makefile.am: -DG_DISABLE_CONST_RETURNS.
+
+ * gtk/gtksettings.[hc]: new file for global rc-file properties
+ (at least currently, should get extended to support X properties
+ and other communication mechanisms).
+
+ * gtk/gtkwidget.[hc]: added style property support:
+ (gtk_widget_class_install_style_property_parser): install style
+ property pspec with parser function for rc-file values other
+ than LONG, DOUBLE or STRING.
+ (gtk_widget_class_install_style_property): same as above without
+ parser (parsers are going to be needed quite infrequently).
+ (gtk_widget_style_get_property): retrive style property value.
+ (gtk_widget_style_get_valist): same as above with varargs support,
+ has NOCOPY semantics.
+ (gtk_widget_style_get): wrapper around gtk_widget_style_get_valist().
+
Fri Mar 16 18:24:53 2001 Jonathan Blandford <jrb@redhat.com>
* demos/gtk-demo/main.c (row_activated_cb): modified to use
diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10
index 0bd006cca8..45b07c3347 100644
--- a/ChangeLog.pre-2-10
+++ b/ChangeLog.pre-2-10
@@ -1,3 +1,40 @@
+Sun Mar 18 01:15:30 2001 Tim Janik <timj@gtk.org>
+
+ * gtk/gtkspinbutton.[hc]: added rc-style argument
+ GtkSpinButton::shadow_type.
+ removed spin_button->shadow_type, gtk_spin_button_set_shadow_type()
+ and ARG_SHADOW_TYPE as it doesn' make much sense to try to override
+ rc-style settings.
+
+ * gtk/gtkfixed.c: removed gtk_fixed_paint() (was unused).
+
+ * gtk/gtkwidget.c: quark cleanups.
+
+ * gtk/gtkrc.[hc]: added gtk_rc_scanner_new() to create an rc-file
+ scanner with appropriate configuration, renamed GtkRcStyleClass.clone
+ to create_rc_style() (we don't do cloning in standard OO sense).
+ added per rc style properties.
+
+ * gtk/gtkstyle.[hc]: added code to retrive pspec conformant rc-style
+ property values and for caching those. some cleanups.
+
+ * gtk/Makefile.am: -DG_DISABLE_CONST_RETURNS.
+
+ * gtk/gtksettings.[hc]: new file for global rc-file properties
+ (at least currently, should get extended to support X properties
+ and other communication mechanisms).
+
+ * gtk/gtkwidget.[hc]: added style property support:
+ (gtk_widget_class_install_style_property_parser): install style
+ property pspec with parser function for rc-file values other
+ than LONG, DOUBLE or STRING.
+ (gtk_widget_class_install_style_property): same as above without
+ parser (parsers are going to be needed quite infrequently).
+ (gtk_widget_style_get_property): retrive style property value.
+ (gtk_widget_style_get_valist): same as above with varargs support,
+ has NOCOPY semantics.
+ (gtk_widget_style_get): wrapper around gtk_widget_style_get_valist().
+
Fri Mar 16 18:24:53 2001 Jonathan Blandford <jrb@redhat.com>
* demos/gtk-demo/main.c (row_activated_cb): modified to use
diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2
index 0bd006cca8..45b07c3347 100644
--- a/ChangeLog.pre-2-2
+++ b/ChangeLog.pre-2-2
@@ -1,3 +1,40 @@
+Sun Mar 18 01:15:30 2001 Tim Janik <timj@gtk.org>
+
+ * gtk/gtkspinbutton.[hc]: added rc-style argument
+ GtkSpinButton::shadow_type.
+ removed spin_button->shadow_type, gtk_spin_button_set_shadow_type()
+ and ARG_SHADOW_TYPE as it doesn' make much sense to try to override
+ rc-style settings.
+
+ * gtk/gtkfixed.c: removed gtk_fixed_paint() (was unused).
+
+ * gtk/gtkwidget.c: quark cleanups.
+
+ * gtk/gtkrc.[hc]: added gtk_rc_scanner_new() to create an rc-file
+ scanner with appropriate configuration, renamed GtkRcStyleClass.clone
+ to create_rc_style() (we don't do cloning in standard OO sense).
+ added per rc style properties.
+
+ * gtk/gtkstyle.[hc]: added code to retrive pspec conformant rc-style
+ property values and for caching those. some cleanups.
+
+ * gtk/Makefile.am: -DG_DISABLE_CONST_RETURNS.
+
+ * gtk/gtksettings.[hc]: new file for global rc-file properties
+ (at least currently, should get extended to support X properties
+ and other communication mechanisms).
+
+ * gtk/gtkwidget.[hc]: added style property support:
+ (gtk_widget_class_install_style_property_parser): install style
+ property pspec with parser function for rc-file values other
+ than LONG, DOUBLE or STRING.
+ (gtk_widget_class_install_style_property): same as above without
+ parser (parsers are going to be needed quite infrequently).
+ (gtk_widget_style_get_property): retrive style property value.
+ (gtk_widget_style_get_valist): same as above with varargs support,
+ has NOCOPY semantics.
+ (gtk_widget_style_get): wrapper around gtk_widget_style_get_valist().
+
Fri Mar 16 18:24:53 2001 Jonathan Blandford <jrb@redhat.com>
* demos/gtk-demo/main.c (row_activated_cb): modified to use
diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4
index 0bd006cca8..45b07c3347 100644
--- a/ChangeLog.pre-2-4
+++ b/ChangeLog.pre-2-4
@@ -1,3 +1,40 @@
+Sun Mar 18 01:15:30 2001 Tim Janik <timj@gtk.org>
+
+ * gtk/gtkspinbutton.[hc]: added rc-style argument
+ GtkSpinButton::shadow_type.
+ removed spin_button->shadow_type, gtk_spin_button_set_shadow_type()
+ and ARG_SHADOW_TYPE as it doesn' make much sense to try to override
+ rc-style settings.
+
+ * gtk/gtkfixed.c: removed gtk_fixed_paint() (was unused).
+
+ * gtk/gtkwidget.c: quark cleanups.
+
+ * gtk/gtkrc.[hc]: added gtk_rc_scanner_new() to create an rc-file
+ scanner with appropriate configuration, renamed GtkRcStyleClass.clone
+ to create_rc_style() (we don't do cloning in standard OO sense).
+ added per rc style properties.
+
+ * gtk/gtkstyle.[hc]: added code to retrive pspec conformant rc-style
+ property values and for caching those. some cleanups.
+
+ * gtk/Makefile.am: -DG_DISABLE_CONST_RETURNS.
+
+ * gtk/gtksettings.[hc]: new file for global rc-file properties
+ (at least currently, should get extended to support X properties
+ and other communication mechanisms).
+
+ * gtk/gtkwidget.[hc]: added style property support:
+ (gtk_widget_class_install_style_property_parser): install style
+ property pspec with parser function for rc-file values other
+ than LONG, DOUBLE or STRING.
+ (gtk_widget_class_install_style_property): same as above without
+ parser (parsers are going to be needed quite infrequently).
+ (gtk_widget_style_get_property): retrive style property value.
+ (gtk_widget_style_get_valist): same as above with varargs support,
+ has NOCOPY semantics.
+ (gtk_widget_style_get): wrapper around gtk_widget_style_get_valist().
+
Fri Mar 16 18:24:53 2001 Jonathan Blandford <jrb@redhat.com>
* demos/gtk-demo/main.c (row_activated_cb): modified to use
diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6
index 0bd006cca8..45b07c3347 100644
--- a/ChangeLog.pre-2-6
+++ b/ChangeLog.pre-2-6
@@ -1,3 +1,40 @@
+Sun Mar 18 01:15:30 2001 Tim Janik <timj@gtk.org>
+
+ * gtk/gtkspinbutton.[hc]: added rc-style argument
+ GtkSpinButton::shadow_type.
+ removed spin_button->shadow_type, gtk_spin_button_set_shadow_type()
+ and ARG_SHADOW_TYPE as it doesn' make much sense to try to override
+ rc-style settings.
+
+ * gtk/gtkfixed.c: removed gtk_fixed_paint() (was unused).
+
+ * gtk/gtkwidget.c: quark cleanups.
+
+ * gtk/gtkrc.[hc]: added gtk_rc_scanner_new() to create an rc-file
+ scanner with appropriate configuration, renamed GtkRcStyleClass.clone
+ to create_rc_style() (we don't do cloning in standard OO sense).
+ added per rc style properties.
+
+ * gtk/gtkstyle.[hc]: added code to retrive pspec conformant rc-style
+ property values and for caching those. some cleanups.
+
+ * gtk/Makefile.am: -DG_DISABLE_CONST_RETURNS.
+
+ * gtk/gtksettings.[hc]: new file for global rc-file properties
+ (at least currently, should get extended to support X properties
+ and other communication mechanisms).
+
+ * gtk/gtkwidget.[hc]: added style property support:
+ (gtk_widget_class_install_style_property_parser): install style
+ property pspec with parser function for rc-file values other
+ than LONG, DOUBLE or STRING.
+ (gtk_widget_class_install_style_property): same as above without
+ parser (parsers are going to be needed quite infrequently).
+ (gtk_widget_style_get_property): retrive style property value.
+ (gtk_widget_style_get_valist): same as above with varargs support,
+ has NOCOPY semantics.
+ (gtk_widget_style_get): wrapper around gtk_widget_style_get_valist().
+
Fri Mar 16 18:24:53 2001 Jonathan Blandford <jrb@redhat.com>
* demos/gtk-demo/main.c (row_activated_cb): modified to use
diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8
index 0bd006cca8..45b07c3347 100644
--- a/ChangeLog.pre-2-8
+++ b/ChangeLog.pre-2-8
@@ -1,3 +1,40 @@
+Sun Mar 18 01:15:30 2001 Tim Janik <timj@gtk.org>
+
+ * gtk/gtkspinbutton.[hc]: added rc-style argument
+ GtkSpinButton::shadow_type.
+ removed spin_button->shadow_type, gtk_spin_button_set_shadow_type()
+ and ARG_SHADOW_TYPE as it doesn' make much sense to try to override
+ rc-style settings.
+
+ * gtk/gtkfixed.c: removed gtk_fixed_paint() (was unused).
+
+ * gtk/gtkwidget.c: quark cleanups.
+
+ * gtk/gtkrc.[hc]: added gtk_rc_scanner_new() to create an rc-file
+ scanner with appropriate configuration, renamed GtkRcStyleClass.clone
+ to create_rc_style() (we don't do cloning in standard OO sense).
+ added per rc style properties.
+
+ * gtk/gtkstyle.[hc]: added code to retrive pspec conformant rc-style
+ property values and for caching those. some cleanups.
+
+ * gtk/Makefile.am: -DG_DISABLE_CONST_RETURNS.
+
+ * gtk/gtksettings.[hc]: new file for global rc-file properties
+ (at least currently, should get extended to support X properties
+ and other communication mechanisms).
+
+ * gtk/gtkwidget.[hc]: added style property support:
+ (gtk_widget_class_install_style_property_parser): install style
+ property pspec with parser function for rc-file values other
+ than LONG, DOUBLE or STRING.
+ (gtk_widget_class_install_style_property): same as above without
+ parser (parsers are going to be needed quite infrequently).
+ (gtk_widget_style_get_property): retrive style property value.
+ (gtk_widget_style_get_valist): same as above with varargs support,
+ has NOCOPY semantics.
+ (gtk_widget_style_get): wrapper around gtk_widget_style_get_valist().
+
Fri Mar 16 18:24:53 2001 Jonathan Blandford <jrb@redhat.com>
* demos/gtk-demo/main.c (row_activated_cb): modified to use
diff --git a/docs/reference/gdk-pixbuf/gdk-pixbuf.hierarchy b/docs/reference/gdk-pixbuf/gdk-pixbuf.hierarchy
index 3b8038b7dd..65da5aa3ab 100644
--- a/docs/reference/gdk-pixbuf/gdk-pixbuf.hierarchy
+++ b/docs/reference/gdk-pixbuf/gdk-pixbuf.hierarchy
@@ -4,5 +4,5 @@ GObject
GdkDrawableImplX11
GdkWindowImplX11
GdkColormap
- GtkRcStyle
+ GtkSettings
GdkPixbufLoader
diff --git a/docs/reference/gtk/gtk.hierarchy b/docs/reference/gtk/gtk.hierarchy
index 0919709543..4655ff729f 100644
--- a/docs/reference/gtk/gtk.hierarchy
+++ b/docs/reference/gtk/gtk.hierarchy
@@ -5,6 +5,7 @@ GObject
GdkWindowImplX11
GdkPixmap
GdkColormap
+ GtkSettings
GtkObject
GtkWidget
GtkMisc
diff --git a/docs/reference/gtk/tmpl/gtk-unused.sgml b/docs/reference/gtk/tmpl/gtk-unused.sgml
index ed4abe8fb9..ef1a5fa0cb 100644
--- a/docs/reference/gtk/tmpl/gtk-unused.sgml
+++ b/docs/reference/gtk/tmpl/gtk-unused.sgml
@@ -219,6 +219,12 @@ The last structured enumerated type value.
</para>
+<!-- ##### MACRO GTK_TYPE_TREE_COLUMN ##### -->
+<para>
+
+</para>
+
+
<!-- ##### MACRO GTK_VALUE_ARGS ##### -->
<para>
Use to get the value of a GtkArg whose GtkType is GTK_TYPE_ARGS
@@ -439,24 +445,6 @@ The position of the cursor.
</para>
-<!-- ##### USER_FUNCTION GtkEmissionHook ##### -->
-<para>
-A simple function pointer to get invoked when the
-signal is emitted. This allows you tie a hook to the signal type,
-so that it will trap all emissions of that signal, from any object.
-</para>
-<para>
-You may not attach these to signals created with the
-#GTK_RUN_NO_HOOKS flag.
-</para>
-
-@object:
-@signal_id:
-@n_params:
-@params:
-@data:
-@Returns:
-
<!-- ##### ENUM GtkFontFilterType ##### -->
<para>
A set of bit flags used to specify the filter being set
@@ -597,6 +585,12 @@ and its unique identifying integer.
@nparams:
@params:
+<!-- ##### ARG GtkSpinButton:shadow-type ##### -->
+<para>
+the type of border that surrounds the arrows of a spin button.
+</para>
+
+
<!-- ##### STRUCT GtkStatusbarMsg ##### -->
<para>
Holds the data for a statusbar message. <structfield>text</structfield> holds the actual text string. <structfield>context_id</structfield> is the context that this message is associated with, and <structfield>message_id</structfield> is this particular message's identifier. However, these fields should not be modified directly.
@@ -633,6 +627,18 @@ produce superscript and subscript.
</para>
+<!-- ##### ARG GtkTextView:justify ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG GtkTextView:wrap-mode ##### -->
+<para>
+
+</para>
+
+
<!-- ##### SIGNAL GtkWidget::debug-msg ##### -->
<para>
@@ -1032,20 +1038,6 @@ Internal function.
@ruler: the gtkruler
-<!-- ##### FUNCTION gtk_signal_add_emission_hook ##### -->
-<para>
-Add an emission hook for a type of signal, for any object.
-</para>
-
-@signal_id: the type of signal to hook for.
-@hook_func: the function to invoke to handle the emission hook.
-@data: the user data passed in to hook_func.
-@Returns: the id (that you may pass as a parameter
-to gtk_signal_remove_emission_hook()).
-@i:
-@h:
-@d:
-
<!-- ##### FUNCTION gtk_signal_add_emission_hook_full ##### -->
<para>
Add an emission hook for a type of signal, for any object.
@@ -1085,12 +1077,6 @@ This function is labeled private.
@object: the object whose signal handlers should be destroyed.
-<!-- ##### FUNCTION gtk_signal_init ##### -->
-<para>
-
-</para>
-
-
<!-- ##### FUNCTION gtk_signal_n_emissions ##### -->
<para>
Find out the recursion depth of emissions for a particular type
@@ -1132,16 +1118,6 @@ Obtain information about a signal.
which contains all the information, or NULL.
The pointer is allocated just for you: you must g_free() it.
-<!-- ##### FUNCTION gtk_signal_remove_emission_hook ##### -->
-<para>
-Delete an emission hook. (see gtk_signal_add_emission_hook())
-</para>
-
-@signal_id: the id of the signal type.
-@hook_id: the id of the emission handler, returned by add_emission_hook().
-@i:
-@h:
-
<!-- ##### FUNCTION gtk_signal_set_funcs ##### -->
<para>
These set default functions to call when the user didn't
@@ -1157,6 +1133,14 @@ isn't a function pointer. May be NULL.
@destroy_func: the function to invoke when each hook is destroyed.
May be NULL.
+<!-- ##### FUNCTION gtk_spin_button_set_shadow_type ##### -->
+<para>
+Creates a border around the arrows of a #GtkSpinButton. The type of border is determined by @shadow_type.
+</para>
+
+@spin_button: a #GtkSpinButton
+@shadow_type: the new border type.
+
<!-- ##### FUNCTION gtk_trace_referencing ##### -->
<para>
Private: print debugging information while doing a gtk_object_ref() or
diff --git a/docs/reference/gtk/tmpl/gtksignal.sgml b/docs/reference/gtk/tmpl/gtksignal.sgml
index 1bb805c8ba..11705206fd 100644
--- a/docs/reference/gtk/tmpl/gtksignal.sgml
+++ b/docs/reference/gtk/tmpl/gtksignal.sgml
@@ -157,6 +157,25 @@ you might have to write a marshaller.
@field:
+<!-- ##### USER_FUNCTION GtkEmissionHook ##### -->
+<para>
+A simple function pointer to get invoked when the
+signal is emitted. This allows you tie a hook to the signal type,
+so that it will trap all emissions of that signal, from any object.
+</para>
+<para>
+You may not attach these to signals created with the
+#GTK_RUN_NO_HOOKS flag.
+</para>
+
+@object:
+@signal_id:
+@n_params:
+@params:
+@data:
+@Returns:
+
+
<!-- ##### ENUM GtkSignalRunType ##### -->
<para>
These configure the signal's emission. They control
@@ -232,6 +251,13 @@ to the signal.
@GTK_RUN_ACTION:
@GTK_RUN_NO_HOOKS:
+<!-- ##### FUNCTION gtk_signal_init ##### -->
+<para>
+
+</para>
+
+
+
<!-- ##### FUNCTION gtk_signal_new ##### -->
<para>
Create a new signal type. (This is usually done in the
@@ -289,7 +315,7 @@ you don't want a return value.
the callbacks.
-<!-- ##### MACRO gtk_signal_lookup ##### -->
+<!-- ##### FUNCTION gtk_signal_lookup ##### -->
<para>
Given the name of the signal and the type of object it connects
to, get the signal's identifying integer. Emitting the signal
@@ -299,13 +325,12 @@ by number is somewhat faster than using the name each time.
It also tries the ancestors of the given type.
</para>
-@Returns: the signal's identifying number, or 0 if no signal was found.
-<!-- # Unused Parameters # -->
@name: the signal's name, e.g. clicked.
@object_type: the type that the signal operates on, e.g. #GTK_TYPE_BUTTON.
+@Returns: the signal's identifying number, or 0 if no signal was found.
-<!-- ##### MACRO gtk_signal_name ##### -->
+<!-- ##### FUNCTION gtk_signal_name ##### -->
<para>
Given the signal's identifier, find its name.
</para>
@@ -313,9 +338,8 @@ Given the signal's identifier, find its name.
Two different signals may have the same name, if they have differing types.
</para>
-@Returns: the signal name, or NULL if the signal number was invalid.
-<!-- # Unused Parameters # -->
@signal_id: the signal's identifying number.
+@Returns: the signal name, or NULL if the signal number was invalid.
<!-- ##### FUNCTION gtk_signal_emit ##### -->
@@ -383,7 +407,7 @@ an array of GtkArgs instead of using C's varargs mechanism.
followed by one which is a pointer to the return type.
-<!-- ##### MACRO gtk_signal_emit_stop ##### -->
+<!-- ##### FUNCTION gtk_signal_emit_stop ##### -->
<para>
This function aborts a signal's current emission.
</para>
@@ -397,11 +421,11 @@ It will print a warning if used on a signal which
isn't being emitted.
</para>
-@i:
-@s:
-<!-- # Unused Parameters # -->
@object: the object whose signal handlers you wish to stop.
@signal_id: the signal identifier, as returned by gtk_signal_lookup().
+<!-- # Unused Parameters # -->
+@i:
+@s:
<!-- ##### FUNCTION gtk_signal_emit_stop_by_name ##### -->
@@ -417,7 +441,7 @@ except it will lookup the signal id for you.
@name: the name of the signal you wish to stop.
-<!-- ##### MACRO gtk_signal_connect ##### -->
+<!-- ##### FUNCTION gtk_signal_connect ##### -->
<para>
Attach a function pointer and user data to a signal for
a particular object.
@@ -456,38 +480,38 @@ static void attach_print_signal(GtkButton* button, gint to_print)
</programlisting>
</informalexample>
-@o:
-@s:
-@f:
-@d:
-@Returns: the connection id.
-<!-- # Unused Parameters # -->
@object: the object associated with the signal, e.g. if a button
is getting pressed, this is that button.
@name: name of the signal.
@func: function pointer to attach to the signal.
@func_data: value to pass as to your function (through the marshaller).
+@Returns: the connection id.
+<!-- # Unused Parameters # -->
+@o:
+@s:
+@f:
+@d:
-<!-- ##### MACRO gtk_signal_connect_after ##### -->
+<!-- ##### FUNCTION gtk_signal_connect_after ##### -->
<para>
Attach a function pointer and user data to a signal
so that this handler will be called after the other handlers.
</para>
-@o:
-@s:
-@f:
-@d:
-@Returns: the unique identifier for this attachment: the connection id.
-<!-- # Unused Parameters # -->
@object: the object associated with the signal.
@name: name of the signal.
@func: function pointer to attach to the signal.
@func_data: value to pass as to your function (through the marshaller).
+@Returns: the unique identifier for this attachment: the connection id.
+<!-- # Unused Parameters # -->
+@o:
+@s:
+@f:
+@d:
-<!-- ##### MACRO gtk_signal_connect_object ##### -->
+<!-- ##### FUNCTION gtk_signal_connect_object ##### -->
<para>
This function is for registering a callback that will
call another object's callback. That is,
@@ -508,21 +532,21 @@ gtk_signal_connect_object(button, "clicked", gtk_widget_show, window);
</programlisting>
</informalexample>
-@o:
-@s:
-@f:
-@d:
-@Returns: the connection id.
-<!-- # Unused Parameters # -->
@object: the object which emits the signal.
@name: the name of the signal.
@func: the function to callback.
@slot_object: the object to pass as the first parameter to func.
(Though it pretends to take an object, you can
really pass any gpointer as the #slot_object .)
+@Returns: the connection id.
+<!-- # Unused Parameters # -->
+@o:
+@s:
+@f:
+@d:
-<!-- ##### MACRO gtk_signal_connect_object_after ##### -->
+<!-- ##### FUNCTION gtk_signal_connect_object_after ##### -->
<para>
Attach a signal hook to a signal, passing in an alternate
object as the first parameter, and guaranteeing
@@ -530,16 +554,16 @@ that the default handler and all normal
handlers are called first.
</para>
-@o:
-@s:
-@f:
-@d:
-@Returns: the connection id.
-<!-- # Unused Parameters # -->
@object: the object associated with the signal.
@name: name of the signal.
@func: function pointer to attach to the signal.
@slot_object: the object to pass as the first parameter to #func.
+@Returns: the connection id.
+<!-- # Unused Parameters # -->
+@o:
+@s:
+@f:
+@d:
<!-- ##### FUNCTION gtk_signal_connect_full ##### -->
@@ -628,98 +652,95 @@ should signal the removal of this signal.
@name: name of the signal.
-<!-- ##### MACRO gtk_signal_disconnect ##### -->
+<!-- ##### FUNCTION gtk_signal_disconnect ##### -->
<para>
Destroy a user-defined handler connection.
</para>
-<!-- # Unused Parameters # -->
@object: the object which the handler pertains to.
@handler_id: the connection id.
-<!-- ##### MACRO gtk_signal_disconnect_by_func ##### -->
+<!-- ##### FUNCTION gtk_signal_disconnect_by_func ##### -->
<para>
Destroy all connections for a particular object, with
the given function-pointer and user-data.
</para>
-@o:
-@f:
-@d:
-<!-- # Unused Parameters # -->
@object: the object which emits the signal.
@func: the function pointer to search for.
@data: the user data to search for.
+<!-- # Unused Parameters # -->
+@o:
+@f:
+@d:
-<!-- ##### MACRO gtk_signal_disconnect_by_data ##### -->
+<!-- ##### FUNCTION gtk_signal_disconnect_by_data ##### -->
<para>
Destroy all connections for a particular object, with
the given user-data.
</para>
-@o:
-@d:
-<!-- # Unused Parameters # -->
@object: the object which emits the signal.
@data: the user data to search for.
+<!-- # Unused Parameters # -->
+@o:
+@d:
-<!-- ##### MACRO gtk_signal_handler_block ##### -->
+<!-- ##### FUNCTION gtk_signal_handler_block ##### -->
<para>
Prevent an user-defined handler from being invoked. All other
signal processing will go on as normal, but this particular
handler will ignore it.
</para>
-<!-- # Unused Parameters # -->
@object: the object which emits the signal to block.
@handler_id: the connection id.
-<!-- ##### MACRO gtk_signal_handler_block_by_func ##### -->
+<!-- ##### FUNCTION gtk_signal_handler_block_by_func ##### -->
<para>
Prevent a user-defined handler from being invoked, by reference to
the user-defined handler's function pointer and user data. (It may result in
multiple hooks being blocked, if you've called connect multiple times.)
</para>
-@o:
-@f:
-@d:
-<!-- # Unused Parameters # -->
@object: the object which emits the signal to block.
@func: the function pointer of the handler to block.
@data: the user data of the handler to block.
+<!-- # Unused Parameters # -->
+@o:
+@f:
+@d:
-<!-- ##### MACRO gtk_signal_handler_block_by_data ##### -->
+<!-- ##### FUNCTION gtk_signal_handler_block_by_data ##### -->
<para>
Prevent all user-defined handlers with a certain user data from being invoked.
</para>
-@o:
-@d:
-<!-- # Unused Parameters # -->
@object: the object which emits the signal we want to block.
@data: the user data of the handlers to block.
+<!-- # Unused Parameters # -->
+@o:
+@d:
-<!-- ##### MACRO gtk_signal_handler_unblock ##### -->
+<!-- ##### FUNCTION gtk_signal_handler_unblock ##### -->
<para>
Undo a block, by connection id. Note that undoing a block doesn't
necessarily make the hook callable, because if you block a
hook twice, you must unblock it twice.
</para>
-<!-- # Unused Parameters # -->
@object: the object which emits the signal we want to unblock.
@handler_id: the emission handler identifier, as returned by
gtk_signal_connect(), etc.
-<!-- ##### MACRO gtk_signal_handler_unblock_by_func ##### -->
+<!-- ##### FUNCTION gtk_signal_handler_unblock_by_func ##### -->
<para>
Undo a block, by function pointer and data.
Note that undoing a block doesn't
@@ -727,29 +748,29 @@ necessarily make the hook callable, because if you block a
hook twice, you must unblock it twice.
</para>
-@o:
-@f:
-@d:
-<!-- # Unused Parameters # -->
@object: the object which emits the signal we want to unblock.
@func: the function pointer to search for.
@data: the user data to search for.
+<!-- # Unused Parameters # -->
+@o:
+@f:
+@d:
-<!-- ##### MACRO gtk_signal_handler_unblock_by_data ##### -->
+<!-- ##### FUNCTION gtk_signal_handler_unblock_by_data ##### -->
<para>
Undo block(s), to all signals for a particular object
with a particular user-data pointer
</para>
-@o:
-@d:
-<!-- # Unused Parameters # -->
@object: the object which emits the signal we want to unblock.
@data: the user data to search for.
+<!-- # Unused Parameters # -->
+@o:
+@d:
-<!-- ##### MACRO gtk_signal_handler_pending ##### -->
+<!-- ##### FUNCTION gtk_signal_handler_pending ##### -->
<para>
Returns a connection id corresponding to a given signal id and object.
</para>
@@ -760,36 +781,64 @@ may opt to not emit the signal if no one is attached anyway,
thus saving the cost of building the arguments.
</para>
-@i:
-@s:
-@b:
-@Returns: the connection id, if a connection was found. 0 otherwise.
-<!-- # Unused Parameters # -->
@object: the object to search for the desired user-defined handler.
@signal_id: the number of the signal to search for.
@may_be_blocked: whether it is acceptable to return a blocked
handler.
+@Returns: the connection id, if a connection was found. 0 otherwise.
+<!-- # Unused Parameters # -->
+@i:
+@s:
+@b:
-<!-- ##### MACRO gtk_signal_handler_pending_by_func ##### -->
+<!-- ##### FUNCTION gtk_signal_handler_pending_by_func ##### -->
<para>
Returns a connection id corresponding to a given signal id, object, function
pointer and user data.
</para>
-@o:
-@s:
-@b:
-@f:
-@d:
-@Returns: the connection id, if a handler was found. 0 otherwise.
-<!-- # Unused Parameters # -->
@object: the object to search for the desired handler.
@signal_id: the number of the signal to search for.
@may_be_blocked: whether it is acceptable to return a blocked
handler.
@func: the function pointer to search for.
@data: the user data to search for.
+@Returns: the connection id, if a handler was found. 0 otherwise.
+<!-- # Unused Parameters # -->
+@o:
+@s:
+@b:
+@f:
+@d:
+
+
+<!-- ##### FUNCTION gtk_signal_add_emission_hook ##### -->
+<para>
+Add an emission hook for a type of signal, for any object.
+</para>
+
+@signal_id: the type of signal to hook for.
+@hook_func: the function to invoke to handle the emission hook.
+@data: the user data passed in to hook_func.
+@Returns: the id (that you may pass as a parameter
+to gtk_signal_remove_emission_hook()).
+<!-- # Unused Parameters # -->
+@i:
+@h:
+@d:
+
+
+<!-- ##### FUNCTION gtk_signal_remove_emission_hook ##### -->
+<para>
+Delete an emission hook. (see gtk_signal_add_emission_hook())
+</para>
+
+@signal_id: the id of the signal type.
+@hook_id: the id of the emission handler, returned by add_emission_hook().
+<!-- # Unused Parameters # -->
+@i:
+@h:
<!-- ##### MACRO gtk_signal_default_marshaller ##### -->
diff --git a/docs/reference/gtk/tmpl/gtkspinbutton.sgml b/docs/reference/gtk/tmpl/gtkspinbutton.sgml
index 7b28651e4a..8e82038d75 100644
--- a/docs/reference/gtk/tmpl/gtkspinbutton.sgml
+++ b/docs/reference/gtk/tmpl/gtkspinbutton.sgml
@@ -294,15 +294,6 @@ Sets a spin button's value to the lower limit when it's upper limit is reached,
@wrap: defaults to FALSE, set to TRUE to make the spin button wrap.
-<!-- ##### FUNCTION gtk_spin_button_set_shadow_type ##### -->
-<para>
-Creates a border around the arrows of a #GtkSpinButton. The type of border is determined by @shadow_type.
-</para>
-
-@spin_button: a #GtkSpinButton
-@shadow_type: the new border type.
-
-
<!-- ##### FUNCTION gtk_spin_button_set_snap_to_ticks ##### -->
<para>
Sets whether a number typed into a spin button should be snapped to the nearest step increment.
@@ -379,11 +370,6 @@ whether a spin button should wrap upon reaching its limits.
how a spin button should be updated.
</para>
-<!-- ##### ARG GtkSpinButton:shadow-type ##### -->
-<para>
-the type of border that surrounds the arrows of a spin button.
-</para>
-
<!-- ##### ARG GtkSpinButton:value ##### -->
<para>
reads the current value, or sets a new value.
diff --git a/docs/reference/gtk/tmpl/gtktextview.sgml b/docs/reference/gtk/tmpl/gtktextview.sgml
index 0f5962ed0c..5d07a0e65c 100644
--- a/docs/reference/gtk/tmpl/gtktextview.sgml
+++ b/docs/reference/gtk/tmpl/gtktextview.sgml
@@ -631,16 +631,6 @@ types related to the text widget and how they work together.
</para>
-<!-- ##### ARG GtkTextView:wrap-mode ##### -->
-<para>
-
-</para>
-
-<!-- ##### ARG GtkTextView:justify ##### -->
-<para>
-
-</para>
-
<!-- ##### ARG GtkTextView:left-margin ##### -->
<para>
diff --git a/docs/reference/gtk/tmpl/gtktreeviewcolumn.sgml b/docs/reference/gtk/tmpl/gtktreeviewcolumn.sgml
index d813c35ada..23d8a43878 100644
--- a/docs/reference/gtk/tmpl/gtktreeviewcolumn.sgml
+++ b/docs/reference/gtk/tmpl/gtktreeviewcolumn.sgml
@@ -14,13 +14,6 @@ GtkTreeViewColumn
</para>
-<!-- ##### MACRO GTK_TYPE_TREE_COLUMN ##### -->
-<para>
-
-</para>
-
-
-
<!-- ##### STRUCT GtkTreeViewColumn ##### -->
<para>
diff --git a/docs/reference/gtk/tmpl/gtktypeutils.sgml b/docs/reference/gtk/tmpl/gtktypeutils.sgml
index 16a7e543fe..6295e2dfa1 100644
--- a/docs/reference/gtk/tmpl/gtktypeutils.sgml
+++ b/docs/reference/gtk/tmpl/gtktypeutils.sgml
@@ -560,33 +560,30 @@ Create a new, unique type.
@type_info: must not be null, and @type_info->type_name must also not be null.
-<!-- ##### MACRO gtk_type_name ##### -->
+<!-- ##### FUNCTION gtk_type_name ##### -->
<para>
</para>
-@Returns: a pointer to the name of a type, or NULL if it has none.
-<!-- # Unused Parameters # -->
@type: a GtkType
+@Returns: a pointer to the name of a type, or NULL if it has none.
-<!-- ##### MACRO gtk_type_from_name ##### -->
+<!-- ##### FUNCTION gtk_type_from_name ##### -->
<para>
Get the internal representation of a type given its name.
</para>
-@Returns: a GtkType
-<!-- # Unused Parameters # -->
@name: the name of a gtk type
+@Returns: a GtkType
-<!-- ##### MACRO gtk_type_parent ##### -->
+<!-- ##### FUNCTION gtk_type_parent ##### -->
<para>
</para>
-@Returns: the GtkType of the parent
-<!-- # Unused Parameters # -->
@type: a GtkType
+@Returns: the GtkType of the parent
<!-- ##### FUNCTION gtk_type_class ##### -->
@@ -611,16 +608,15 @@ has all the proper initializers called.
@Returns: gpointer to a GtkTypeObject
-<!-- ##### MACRO gtk_type_is_a ##### -->
+<!-- ##### FUNCTION gtk_type_is_a ##### -->
<para>
Look in the type hierarchy to see if @type has @is_a_type among its
ancestors. Do so with a simple lookup, not a loop.
</para>
-@Returns:
-<!-- # Unused Parameters # -->
@type: GtkType
@is_a_type: GtkType
+@Returns:
<!-- ##### FUNCTION gtk_type_enum_get_values ##### -->
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 623759da91..a33192e884 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -11,6 +11,7 @@ INCLUDES = @STRIP_BEGIN@ \
-DGTK_LOCALEDIR=\"$(gtklocaledir)\" \
-DGTK_VERSION=\"@GTK_VERSION@\" \
-DTESTGTK_RCFILE=\"`pwd`/$(srcdir)/testgtkrc\" \
+ -DG_DISABLE_CONST_RETURNS \
-I$(top_builddir)/gtk \
-I$(top_srcdir) -I../gdk \
-I$(top_srcdir)/gdk \
@@ -147,6 +148,7 @@ gtk_public_h_sources = @STRIP_BEGIN@ \
gtkscrolledwindow.h \
gtkselection.h \
gtkseparator.h \
+ gtksettings.h \
gtksignal.h \
gtksocket.h \
gtkspinbutton.h \
@@ -306,6 +308,7 @@ gtk_c_sources = @STRIP_BEGIN@ \
gtkscrolledwindow.c \
gtkselection.c \
gtkseparator.c \
+ gtksettings.c \
gtksignal.c \
gtksocket.c \
gtkspinbutton.c \
diff --git a/gtk/gtk.h b/gtk/gtk.h
index c1df20b2ad..e762c68df9 100644
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
@@ -123,6 +123,7 @@
#include <gtk/gtkselection.h>
#include <gtk/gtkseparator.h>
#include <gtk/gtkseparatormenuitem.h>
+#include <gtk/gtksettings.h>
#include <gtk/gtksignal.h>
#include <gtk/gtksocket.h>
#include <gtk/gtkspinbutton.h>
diff --git a/gtk/gtkcombo.c b/gtk/gtkcombo.c
index 706692e767..be607894ce 100644
--- a/gtk/gtkcombo.c
+++ b/gtk/gtkcombo.c
@@ -259,8 +259,6 @@ gtk_combo_window_key_press (GtkWidget *window,
GdkEventKey *event,
GtkCombo *combo)
{
- GList *li;
-
if (event->keyval == GDK_Return || event->keyval == GDK_KP_Enter)
{
if (GTK_WIDGET_VISIBLE (combo->popwin))
diff --git a/gtk/gtkfixed.c b/gtk/gtkfixed.c
index 9380399439..ab1bffceae 100644
--- a/gtk/gtkfixed.c
+++ b/gtk/gtkfixed.c
@@ -35,8 +35,6 @@ static void gtk_fixed_size_request (GtkWidget *widget,
GtkRequisition *requisition);
static void gtk_fixed_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
-static void gtk_fixed_paint (GtkWidget *widget,
- GdkRectangle *area);
static void gtk_fixed_add (GtkContainer *container,
GtkWidget *widget);
static void gtk_fixed_remove (GtkContainer *container,
@@ -333,20 +331,6 @@ gtk_fixed_size_allocate (GtkWidget *widget,
}
static void
-gtk_fixed_paint (GtkWidget *widget,
- GdkRectangle *area)
-{
- g_return_if_fail (widget != NULL);
- g_return_if_fail (GTK_IS_FIXED (widget));
- g_return_if_fail (area != NULL);
-
- if (GTK_WIDGET_DRAWABLE (widget))
- gdk_window_clear_area (widget->window,
- area->x, area->y,
- area->width, area->height);
-}
-
-static void
gtk_fixed_add (GtkContainer *container,
GtkWidget *widget)
{
diff --git a/gtk/gtkrc.c b/gtk/gtkrc.c
index 069cc4e222..de18328b6e 100644
--- a/gtk/gtkrc.c
+++ b/gtk/gtkrc.c
@@ -57,6 +57,7 @@
#include "gtkthemes.h"
#include "gtkintl.h"
#include "gtkiconfactory.h"
+#include "gtksettings.h"
#ifdef G_OS_WIN32
#include <io.h>
@@ -101,6 +102,8 @@ static void gtk_rc_parse_any (const gchar *input_nam
const gchar *input_string);
static guint gtk_rc_parse_statement (GScanner *scanner);
static guint gtk_rc_parse_style (GScanner *scanner);
+static guint gtk_rc_parse_assignment (GScanner *scanner,
+ GtkRcProperty *prop);
static guint gtk_rc_parse_bg (GScanner *scanner,
GtkRcStyle *style);
static guint gtk_rc_parse_fg (GScanner *scanner,
@@ -145,12 +148,14 @@ static void gtk_rc_style_class_init (GtkRcStyleClass *klass);
static void gtk_rc_style_finalize (GObject *object);
static void gtk_rc_style_real_merge (GtkRcStyle *dest,
GtkRcStyle *src);
-static GtkRcStyle *gtk_rc_style_real_clone (GtkRcStyle *rc_style);
-static GtkStyle * gtk_rc_style_real_create_style (GtkRcStyle *rc_style);
+static GtkRcStyle* gtk_rc_style_real_create_rc_style (GtkRcStyle *rc_style);
+static GtkStyle* gtk_rc_style_real_create_style (GtkRcStyle *rc_style);
+static gint gtk_rc_properties_cmp (gconstpointer bsearch_node1,
+ gconstpointer bsearch_node2);
static gpointer parent_class = NULL;
-static const GScannerConfig gtk_rc_scanner_config =
+static const GScannerConfig gtk_rc_scanner_config =
{
(
" \t\r\n"
@@ -267,7 +272,6 @@ static GtkImageLoader image_loader = NULL;
#ifdef G_OS_WIN32
-
static gchar *
get_gtk_dll_name (void)
{
@@ -286,8 +290,7 @@ get_themes_directory (void)
get_gtk_dll_name (),
"themes");
}
-
-#endif
+#endif /* G_OS_WIN32 */
static gchar *
gtk_rc_make_default_dir (const gchar *type)
@@ -563,12 +566,11 @@ gtk_rc_get_default_files (void)
void
gtk_rc_init (void)
{
+ static gboolean initialized = FALSE;
static gchar *locale_suffixes[3];
static gint n_locale_suffixes = 0;
-
gint i, j;
- static gboolean initialized = FALSE;
if (!initialized)
{
@@ -631,13 +633,13 @@ gtk_rc_init (void)
}
}
- i = 0;
- while (gtk_rc_default_files[i] != NULL)
+ g_object_freeze_notify (G_OBJECT (gtk_settings_get_global ()));
+ for (i = 0; gtk_rc_default_files[i] != NULL; i++)
{
- /* Try to find a locale specific RC file corresponding to
- * to parse before the default file.
+ /* Try to find a locale specific RC file corresponding to the
+ * current locale to parse before the default file.
*/
- for (j=n_locale_suffixes-1; j>=0; j--)
+ for (j = n_locale_suffixes - 1; j >= 0; j--)
{
gchar *name = g_strconcat (gtk_rc_default_files[i],
".",
@@ -646,10 +648,9 @@ gtk_rc_init (void)
gtk_rc_parse (name);
g_free (name);
}
-
gtk_rc_parse (gtk_rc_default_files[i]);
- i++;
}
+ g_object_thaw_notify (G_OBJECT (gtk_settings_get_global ()));
}
void
@@ -801,6 +802,7 @@ gtk_rc_style_init (GtkRcStyle *style)
}
style->xthickness = -1;
style->ythickness = -1;
+ style->rc_properties = NULL;
style->rc_style_lists = NULL;
style->icon_factories = NULL;
@@ -816,55 +818,17 @@ gtk_rc_style_class_init (GtkRcStyleClass *klass)
object_class->finalize = gtk_rc_style_finalize;
klass->parse = NULL;
- klass->clone = gtk_rc_style_real_clone;
+ klass->create_rc_style = gtk_rc_style_real_create_rc_style;
klass->merge = gtk_rc_style_real_merge;
klass->create_style = gtk_rc_style_real_create_style;
}
-/* Like g_slist_remove, but remove all copies of data */
-static GSList *
-gtk_rc_slist_remove_all (GSList *list,
- gpointer data)
-{
- GSList *tmp;
- GSList *prev;
-
- prev = NULL;
- tmp = list;
-
- while (tmp)
- {
- if (tmp->data == data)
- {
- if (list == tmp)
- list = list->next;
-
- if (prev)
- prev->next = tmp->next;
-
- g_slist_free_1 (tmp);
-
- if (prev)
- tmp = prev->next;
- else
- tmp = list;
- }
- else
- {
- prev = tmp;
- tmp = tmp->next;
- }
- }
-
- return list;
-}
-
static void
gtk_rc_style_finalize (GObject *object)
{
- gint i;
GSList *tmp_list1, *tmp_list2;
GtkRcStyle *rc_style;
+ gint i;
rc_style = GTK_RC_STYLE (object);
@@ -873,7 +837,7 @@ gtk_rc_style_finalize (GObject *object)
if (rc_style->font_desc)
pango_font_description_free (rc_style->font_desc);
- for (i=0 ; i < 5 ; i++)
+ for (i = 0; i < 5; i++)
if (rc_style->bg_pixmap_name[i])
g_free (rc_style->bg_pixmap_name[i]);
@@ -896,9 +860,8 @@ gtk_rc_style_finalize (GObject *object)
GtkRcStyle *other_style = tmp_list2->data;
if (other_style != rc_style)
- other_style->rc_style_lists =
- gtk_rc_slist_remove_all (other_style->rc_style_lists, rc_styles);
-
+ other_style->rc_style_lists = g_slist_remove_all (other_style->rc_style_lists,
+ rc_styles);
tmp_list2 = tmp_list2->next;
}
@@ -909,9 +872,23 @@ gtk_rc_style_finalize (GObject *object)
tmp_list1 = tmp_list1->next;
}
-
g_slist_free (rc_style->rc_style_lists);
+ if (rc_style->rc_properties)
+ {
+ guint i;
+
+ for (i = 0; i < rc_style->rc_properties->n_nodes; i++)
+ {
+ GtkRcProperty *node = g_bsearch_array_get_nth (rc_style->rc_properties, i);
+
+ g_free (node->origin);
+ g_value_unset (&node->value);
+ }
+ g_bsearch_array_destroy (rc_style->rc_properties);
+ rc_style->rc_properties = NULL;
+ }
+
tmp_list1 = rc_style->icon_factories;
while (tmp_list1)
{
@@ -919,7 +896,6 @@ gtk_rc_style_finalize (GObject *object)
tmp_list1 = tmp_list1->next;
}
-
g_slist_free (rc_style->icon_factories);
G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -952,7 +928,7 @@ gtk_rc_style_copy (GtkRcStyle *orig)
g_return_val_if_fail (GTK_IS_RC_STYLE (orig), NULL);
- style = GTK_RC_STYLE_GET_CLASS (orig)->clone (orig);
+ style = GTK_RC_STYLE_GET_CLASS (orig)->create_rc_style (orig);
GTK_RC_STYLE_GET_CLASS (style)->merge (style, orig);
return style;
@@ -975,11 +951,26 @@ gtk_rc_style_unref (GtkRcStyle *rc_style)
}
static GtkRcStyle *
-gtk_rc_style_real_clone (GtkRcStyle *style)
+gtk_rc_style_real_create_rc_style (GtkRcStyle *style)
{
return GTK_RC_STYLE (g_object_new (G_OBJECT_TYPE (style), NULL));
}
+static gint
+gtk_rc_properties_cmp (gconstpointer bsearch_node1,
+ gconstpointer bsearch_node2)
+{
+ const GtkRcProperty *prop1 = bsearch_node1;
+ const GtkRcProperty *prop2 = bsearch_node2;
+ gint cmp;
+
+ cmp = G_BSEARCH_ARRAY_CMP (prop1->type_name, prop2->type_name);
+ if (cmp == 0)
+ cmp = G_BSEARCH_ARRAY_CMP (prop1->property_name, prop2->property_name);
+
+ return cmp;
+}
+
static void
gtk_rc_style_real_merge (GtkRcStyle *dest,
GtkRcStyle *src)
@@ -1024,6 +1015,31 @@ gtk_rc_style_real_merge (GtkRcStyle *dest,
if (!dest->font_desc && src->font_desc)
dest->font_desc = pango_font_description_copy (src->font_desc);
+
+ if (src->rc_properties)
+ {
+ guint i;
+
+ if (!dest->rc_properties)
+ dest->rc_properties = g_bsearch_array_new (sizeof (GtkRcProperty),
+ gtk_rc_properties_cmp,
+ 0);
+ for (i = 0; i < src->rc_properties->n_nodes; i++)
+ {
+ GtkRcProperty *node = g_bsearch_array_get_nth (src->rc_properties, i);
+ GtkRcProperty *prop, key = { 0, 0, NULL, { 0, }, };
+
+ key.type_name = node->type_name;
+ key.property_name = node->property_name;
+ prop = g_bsearch_array_insert (dest->rc_properties, &key, FALSE);
+ if (!prop->origin)
+ {
+ prop->origin = g_strdup (node->origin);
+ g_value_init (&prop->value, G_VALUE_TYPE (&node->value));
+ g_value_copy (&node->value, &prop->value);
+ }
+ }
+ }
}
static GtkStyle *
@@ -1274,6 +1290,12 @@ gtk_rc_add_class_style (GtkRcStyle *rc_style,
gtk_rc_sets_class = gtk_rc_add_rc_sets (gtk_rc_sets_class, rc_style, pattern);
}
+GScanner*
+gtk_rc_scanner_new (void)
+{
+ return g_scanner_new (&gtk_rc_scanner_config);
+}
+
static void
gtk_rc_parse_any (const gchar *input_name,
gint input_fd,
@@ -1282,8 +1304,8 @@ gtk_rc_parse_any (const gchar *input_name,
GScanner *scanner;
guint i;
gboolean done;
-
- scanner = g_scanner_new ((GScannerConfig *) &gtk_rc_scanner_config);
+
+ scanner = gtk_rc_scanner_new ();
if (input_fd >= 0)
{
@@ -1478,7 +1500,7 @@ gtk_rc_init_style (GSList *rc_styles)
}
proto_style_class = GTK_RC_STYLE_GET_CLASS (base_style);
- proto_style = proto_style_class->clone (base_style);
+ proto_style = proto_style_class->create_rc_style (base_style);
tmp_styles = rc_styles;
while (tmp_styles)
@@ -1536,23 +1558,204 @@ gtk_rc_init_style (GSList *rc_styles)
*********************/
static guint
+rc_parse_token_or_compound (GScanner *scanner,
+ GString *gstring,
+ GTokenType delimiter)
+{
+ guint token = g_scanner_get_next_token (scanner);
+
+ /* we either scan a single token (skipping comments)
+ * or a compund statement.
+ * compunds are enclosed in (), [] or {} braces, we read
+ * them in via deep recursion.
+ */
+
+ switch (token)
+ {
+ gchar *string;
+ case G_TOKEN_INT:
+ g_string_printfa (gstring, " 0x%lx", scanner->value.v_int);
+ break;
+ case G_TOKEN_FLOAT:
+ g_string_printfa (gstring, " %f", scanner->value.v_float);
+ break;
+ case G_TOKEN_STRING:
+ string = g_strescape (scanner->value.v_string, NULL);
+ g_string_append (gstring, " \"");
+ g_string_append (gstring, string);
+ g_string_append_c (gstring, '"');
+ g_free (string);
+ break;
+ case G_TOKEN_IDENTIFIER:
+ g_string_append_c (gstring, ' ');
+ g_string_append (gstring, scanner->value.v_identifier);
+ break;
+ case G_TOKEN_COMMENT_SINGLE:
+ case G_TOKEN_COMMENT_MULTI:
+ return rc_parse_token_or_compound (scanner, gstring, delimiter);
+ case G_TOKEN_LEFT_PAREN:
+ g_string_append_c (gstring, ' ');
+ g_string_append_c (gstring, token);
+ token = rc_parse_token_or_compound (scanner, gstring, G_TOKEN_RIGHT_PAREN);
+ if (token != G_TOKEN_NONE)
+ return token;
+ break;
+ case G_TOKEN_LEFT_CURLY:
+ g_string_append_c (gstring, ' ');
+ g_string_append_c (gstring, token);
+ token = rc_parse_token_or_compound (scanner, gstring, G_TOKEN_RIGHT_CURLY);
+ if (token != G_TOKEN_NONE)
+ return token;
+ break;
+ case G_TOKEN_LEFT_BRACE:
+ g_string_append_c (gstring, ' ');
+ g_string_append_c (gstring, token);
+ token = rc_parse_token_or_compound (scanner, gstring, G_TOKEN_RIGHT_BRACE);
+ if (token != G_TOKEN_NONE)
+ return token;
+ break;
+ default:
+ if (token >= 256 || token < 1)
+ return delimiter ? delimiter : G_TOKEN_STRING;
+ g_string_append_c (gstring, ' ');
+ g_string_append_c (gstring, token);
+ if (token == delimiter)
+ return G_TOKEN_NONE;
+ break;
+ }
+ if (!delimiter)
+ return G_TOKEN_NONE;
+ else
+ return rc_parse_token_or_compound (scanner, gstring, delimiter);
+}
+
+static guint
+gtk_rc_parse_assignment (GScanner *scanner,
+ GtkRcProperty *prop)
+{
+ gboolean scan_identifier = scanner->config->scan_identifier;
+ gboolean scan_symbols = scanner->config->scan_symbols;
+ gboolean identifier_2_string = scanner->config->identifier_2_string;
+ gboolean char_2_token = scanner->config->char_2_token;
+ gboolean scan_identifier_NULL = scanner->config->scan_identifier_NULL;
+ gboolean numbers_2_int = scanner->config->numbers_2_int;
+ gboolean negate = FALSE;
+ guint token;
+
+ /* check that this is an assignment */
+ if (g_scanner_get_next_token (scanner) != '=')
+ return '=';
+
+ /* adjust scanner mode */
+ scanner->config->scan_identifier = TRUE;
+ scanner->config->scan_symbols = FALSE;
+ scanner->config->identifier_2_string = FALSE;
+ scanner->config->char_2_token = TRUE;
+ scanner->config->scan_identifier_NULL = FALSE;
+ scanner->config->numbers_2_int = TRUE;
+
+ /* record location */
+ prop->origin = g_strdup_printf ("%s:%u", scanner->input_name, scanner->line);
+
+ /* parse optional sign */
+ if (g_scanner_peek_next_token (scanner) == '-')
+ {
+ g_scanner_get_next_token (scanner); /* eat sign */
+ negate = TRUE;
+ }
+
+ /* parse one of LONG, DOUBLE and STRING or, if that fails, create an unparsed compund */
+ token = g_scanner_peek_next_token (scanner);
+ switch (token)
+ {
+ case G_TOKEN_INT:
+ g_scanner_get_next_token (scanner);
+ g_value_init (&prop->value, G_TYPE_LONG);
+ g_value_set_long (&prop->value, negate ? -scanner->value.v_int : scanner->value.v_int);
+ token = G_TOKEN_NONE;
+ break;
+ case G_TOKEN_FLOAT:
+ g_scanner_get_next_token (scanner);
+ g_value_init (&prop->value, G_TYPE_DOUBLE);
+ g_value_set_double (&prop->value, negate ? -scanner->value.v_float : scanner->value.v_float);
+ token = G_TOKEN_NONE;
+ break;
+ case G_TOKEN_STRING:
+ g_scanner_get_next_token (scanner);
+ if (negate)
+ token = G_TOKEN_INT;
+ else
+ {
+ g_value_init (&prop->value, G_TYPE_STRING);
+ g_value_set_string (&prop->value, scanner->value.v_string);
+ token = G_TOKEN_NONE;
+ }
+ break;
+ case G_TOKEN_IDENTIFIER:
+ case G_TOKEN_LEFT_PAREN:
+ case G_TOKEN_LEFT_CURLY:
+ case G_TOKEN_LEFT_BRACE:
+ if (!negate)
+ {
+ GString *gstring = g_string_new ("");
+
+ token = rc_parse_token_or_compound (scanner, gstring, 0);
+ if (token == G_TOKEN_NONE)
+ {
+ g_string_append_c (gstring, ' ');
+ g_value_init (&prop->value, G_TYPE_GSTRING);
+ g_value_set_static_boxed (&prop->value, gstring);
+ }
+ else
+ g_string_free (gstring, TRUE);
+ break;
+ }
+ /* fall through */
+ default:
+ g_scanner_get_next_token (scanner);
+ token = G_TOKEN_INT;
+ break;
+ }
+
+ /* restore scanner mode */
+ scanner->config->scan_identifier = scan_identifier;
+ scanner->config->scan_symbols = scan_symbols;
+ scanner->config->identifier_2_string = identifier_2_string;
+ scanner->config->char_2_token = char_2_token;
+ scanner->config->scan_identifier_NULL = scan_identifier_NULL;
+ scanner->config->numbers_2_int = numbers_2_int;
+
+ return token;
+}
+
+static gboolean
+is_c_identifier (const gchar *string)
+{
+ const gchar *p;
+ gboolean is_varname;
+
+ is_varname = strchr (G_CSET_a_2_z G_CSET_A_2_Z "_", string[0]) != NULL;
+ for (p = string + 1; *p && is_varname; p++)
+ is_varname &= strchr (G_CSET_a_2_z G_CSET_A_2_Z G_CSET_DIGITS "_-", *p) != NULL;
+
+ return is_varname;
+}
+
+static guint
gtk_rc_parse_statement (GScanner *scanner)
{
guint token;
token = g_scanner_peek_next_token (scanner);
-
switch (token)
{
case GTK_RC_TOKEN_INCLUDE:
token = g_scanner_get_next_token (scanner);
if (token != GTK_RC_TOKEN_INCLUDE)
return GTK_RC_TOKEN_INCLUDE;
-
token = g_scanner_get_next_token (scanner);
if (token != G_TOKEN_STRING)
return G_TOKEN_STRING;
-
gtk_rc_parse_file (scanner->value.v_string, FALSE);
return G_TOKEN_NONE;
@@ -1583,6 +1786,39 @@ gtk_rc_parse_statement (GScanner *scanner)
case GTK_RC_TOKEN_IM_MODULE_FILE:
return gtk_rc_parse_im_module_file (scanner);
+ case G_TOKEN_IDENTIFIER:
+ if (is_c_identifier (scanner->next_value.v_identifier))
+ {
+ GtkRcProperty prop = { 0, 0, NULL, { 0, }, };
+ gchar *name;
+
+ g_scanner_get_next_token (scanner); /* eat identifier */
+ name = g_strdup (scanner->value.v_identifier);
+
+ token = gtk_rc_parse_assignment (scanner, &prop);
+ if (token == G_TOKEN_NONE)
+ {
+ GtkSettingsValue svalue;
+
+ svalue.origin = prop.origin;
+ memcpy (&svalue.value, &prop.value, sizeof (prop.value));
+ g_strcanon (name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-", '-');
+ gtk_settings_set_property_value (gtk_settings_get_global (),
+ name,
+ &svalue);
+ }
+ g_free (prop.origin);
+ if (G_VALUE_TYPE (&prop.value))
+ g_value_unset (&prop.value);
+ g_free (name);
+
+ return token;
+ }
+ else
+ {
+ g_scanner_get_next_token (scanner);
+ return G_TOKEN_IDENTIFIER;
+ }
default:
g_scanner_get_next_token (scanner);
return /* G_TOKEN_SYMBOL */ GTK_RC_TOKEN_STYLE;
@@ -1666,6 +1902,33 @@ gtk_rc_parse_style (GScanner *scanner)
pango_font_description_free (rc_style->font_desc);
rc_style->font_desc = pango_font_description_copy (parent_style->font_desc);
}
+
+ if (parent_style->rc_properties)
+ {
+ guint i;
+
+ if (!rc_style->rc_properties)
+ rc_style->rc_properties = g_bsearch_array_new (sizeof (GtkRcProperty),
+ gtk_rc_properties_cmp,
+ 0);
+ for (i = 0; i < parent_style->rc_properties->n_nodes; i++)
+ {
+ GtkRcProperty *node = g_bsearch_array_get_nth (parent_style->rc_properties, i);
+ GtkRcProperty *prop, key = { 0, 0, NULL, { 0, }, };
+
+ key.type_name = node->type_name;
+ key.property_name = node->property_name;
+ prop = g_bsearch_array_insert (rc_style->rc_properties, &key, FALSE);
+ if (prop->origin)
+ {
+ g_free (prop->origin);
+ g_value_unset (&prop->value);
+ }
+ prop->origin = g_strdup (node->origin);
+ g_value_init (&prop->value, G_VALUE_TYPE (&node->value));
+ g_value_copy (&node->value, &prop->value);
+ }
+ }
for (i = 0; i < 5; i++)
{
@@ -1761,6 +2024,65 @@ gtk_rc_parse_style (GScanner *scanner)
}
token = gtk_rc_parse_stock (scanner, rc_style, our_factory);
break;
+ case G_TOKEN_IDENTIFIER:
+ if (is_c_identifier (scanner->next_value.v_identifier) &&
+ scanner->next_value.v_identifier[0] >= 'A' &&
+ scanner->next_value.v_identifier[0] <= 'Z') /* match namespaced type names */
+ {
+ GtkRcProperty prop = { 0, 0, NULL, { 0, }, };
+
+ g_scanner_get_next_token (scanner); /* eat type name */
+ prop.type_name = g_quark_from_string (scanner->value.v_identifier);
+ if (g_scanner_get_next_token (scanner) != ':' ||
+ g_scanner_get_next_token (scanner) != ':')
+ {
+ token = ':';
+ break;
+ }
+ if (g_scanner_get_next_token (scanner) != G_TOKEN_IDENTIFIER ||
+ !is_c_identifier (scanner->value.v_identifier))
+ {
+ token = G_TOKEN_IDENTIFIER;
+ break;
+ }
+
+ /* it's important that we do the same canonification as GParamSpecPool here */
+ g_strcanon (scanner->value.v_identifier, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-", '-');
+ prop.property_name = g_quark_from_string (scanner->value.v_identifier);
+
+ token = gtk_rc_parse_assignment (scanner, &prop);
+ if (token == G_TOKEN_NONE)
+ {
+ GtkRcProperty *tmp;
+
+ g_return_val_if_fail (prop.origin != NULL && G_VALUE_TYPE (&prop.value) != 0, G_TOKEN_ERROR);
+
+ if (!rc_style->rc_properties)
+ rc_style->rc_properties = g_bsearch_array_new (sizeof (GtkRcProperty),
+ gtk_rc_properties_cmp,
+ 0);
+ tmp = g_bsearch_array_insert (rc_style->rc_properties, &prop, FALSE);
+ if (prop.origin != tmp->origin)
+ {
+ g_free (tmp->origin);
+ g_value_unset (&tmp->value);
+ tmp->origin = prop.origin;
+ memcpy (&tmp->value, &prop.value, sizeof (prop.value));
+ }
+ }
+ else
+ {
+ g_free (prop.origin);
+ if (G_VALUE_TYPE (&prop.value))
+ g_value_unset (&prop.value);
+ }
+ }
+ else
+ {
+ g_scanner_get_next_token (scanner);
+ token = G_TOKEN_IDENTIFIER;
+ }
+ break;
default:
g_scanner_get_next_token (scanner);
token = G_TOKEN_RIGHT_CURLY;
@@ -1770,19 +2092,12 @@ gtk_rc_parse_style (GScanner *scanner)
if (token != G_TOKEN_NONE)
{
if (insert)
- {
- if (rc_style->font_desc)
- pango_font_description_free (rc_style->font_desc);
-
- for (i = 0; i < 5; i++)
- if (rc_style->bg_pixmap_name[i])
- g_free (rc_style->bg_pixmap_name[i]);
- g_free (rc_style);
- }
+ gtk_rc_style_unref (rc_style);
+
return token;
}
token = g_scanner_peek_next_token (scanner);
- }
+ } /* while (token != G_TOKEN_RIGHT_CURLY) */
token = g_scanner_get_next_token (scanner);
if (token != G_TOKEN_RIGHT_CURLY)
@@ -1813,6 +2128,28 @@ gtk_rc_parse_style (GScanner *scanner)
return G_TOKEN_NONE;
}
+const GtkRcProperty*
+_gtk_rc_style_lookup_rc_property (GtkRcStyle *rc_style,
+ GQuark type_name,
+ GQuark property_name)
+{
+ GtkRcProperty *node = NULL;
+
+ g_return_val_if_fail (GTK_IS_RC_STYLE (rc_style), NULL);
+
+ if (rc_style->rc_properties)
+ {
+ GtkRcProperty key;
+
+ key.type_name = type_name;
+ key.property_name = property_name;
+
+ node = g_bsearch_array_lookup (rc_style->rc_properties, &key);
+ }
+
+ return node;
+}
+
static guint
gtk_rc_parse_bg (GScanner *scanner,
GtkRcStyle *style)
@@ -2317,7 +2654,7 @@ gtk_rc_parse_color (GScanner *scanner,
g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
- /* we don't need to set our own scop here, because
+ /* we don't need to set our own scope here, because
* we don't need own symbols
*/
diff --git a/gtk/gtkrc.h b/gtk/gtkrc.h
index 29f8b61a02..c68a13d209 100644
--- a/gtk/gtkrc.h
+++ b/gtk/gtkrc.h
@@ -75,6 +75,7 @@ struct _GtkRcStyle
gint ythickness;
/*< private >*/
+ GBSearchArray *rc_properties;
/* list of RC style lists including this RC style */
GSList *rc_style_lists;
@@ -91,7 +92,7 @@ struct _GtkRcStyleClass
* g_object_new (G_OBJECT_TYPE (style), NULL);
* should work in most cases.
*/
- GtkRcStyle * (*clone) (GtkRcStyle *rc_style);
+ GtkRcStyle * (*create_rc_style) (GtkRcStyle *rc_style);
/* Fill in engine specific parts of GtkRcStyle by parsing contents
* of brackets. Returns G_TOKEN_NONE if succesful, otherwise returns
@@ -112,7 +113,7 @@ struct _GtkRcStyleClass
};
void gtk_rc_init (void);
-void gtk_rc_add_default_file (const gchar *filename);
+void gtk_rc_add_default_file (const gchar *filename);
void gtk_rc_set_default_files (gchar **filenames);
gchar** gtk_rc_get_default_files (void);
void gtk_rc_parse (const gchar *filename);
@@ -128,7 +129,7 @@ void gtk_rc_add_class_style (GtkRcStyle *rc_style,
GType gtk_rc_style_get_type (void) G_GNUC_CONST;
GtkRcStyle* gtk_rc_style_new (void);
-GtkRcStyle *gtk_rc_style_copy (GtkRcStyle *orig);
+GtkRcStyle* gtk_rc_style_copy (GtkRcStyle *orig);
void gtk_rc_style_ref (GtkRcStyle *rc_style);
void gtk_rc_style_unref (GtkRcStyle *rc_style);
@@ -194,17 +195,35 @@ typedef enum {
GTK_RC_TOKEN_LAST
} GtkRcTokenType;
-guint gtk_rc_parse_color (GScanner *scanner,
+GScanner* gtk_rc_scanner_new (void);
+guint gtk_rc_parse_color (GScanner *scanner,
GdkColor *color);
-guint gtk_rc_parse_state (GScanner *scanner,
+guint gtk_rc_parse_state (GScanner *scanner,
GtkStateType *state);
-guint gtk_rc_parse_priority (GScanner *scanner,
+guint gtk_rc_parse_priority (GScanner *scanner,
GtkPathPriorityType *priority);
-
-#ifdef G_OS_WIN32
-gchar *gtk_win32_get_installation_directory (void);
+/* rc properties
+ * (structure forward declared in gtkstyle.h)
+ */
+struct _GtkRcProperty
+{
+ /* quark-ified property identifier like "GtkScrollbar::spacing" */
+ GQuark type_name;
+ GQuark property_name;
+
+ /* fields similar to GtkSettingsValue */
+ gchar *origin;
+ GValue value;
+};
+const GtkRcProperty* _gtk_rc_style_lookup_rc_property (GtkRcStyle *rc_style,
+ GQuark type_name,
+ GQuark property_name);
+
+
+#ifdef G_OS_WIN32
+gchar* gtk_win32_get_installation_directory (void);
#endif
diff --git a/gtk/gtksettings.c b/gtk/gtksettings.c
new file mode 100644
index 0000000000..6fa5feab79
--- /dev/null
+++ b/gtk/gtksettings.c
@@ -0,0 +1,682 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2000 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtksettings.h"
+
+
+
+enum {
+ PROP_0,
+ PROP_DOUBLE_CLICK_TIMEOUT,
+ PROP_BELL_PITCH,
+ PROP_BELL_DURATION,
+ PROP_BELL_PERCENT
+};
+
+
+/* --- prototypes --- */
+static void gtk_settings_init (GtkSettings *settings);
+static void gtk_settings_class_init (GtkSettingsClass *class);
+static void gtk_settings_finalize (GObject *object);
+static GObject* gtk_settings_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_properties);
+static void gtk_settings_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void gtk_settings_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gtk_settings_notify (GObject *object,
+ GParamSpec *pspec);
+static guint settings_install_property_parser (GtkSettingsClass *class,
+ GParamSpec *pspec,
+ GtkRcPropertyParser parser);
+
+
+/* --- variables --- */
+static gpointer parent_class = NULL;
+static GtkSettings *the_singleton = NULL;
+static GQuark quark_property_parser = 0;
+static GQuark quark_property_id = 0;
+static GSList *object_list = NULL;
+static guint class_n_properties = 0;
+
+
+/* --- functions --- */
+GType
+gtk_settings_get_type (void)
+{
+ static GType settings_type = 0;
+
+ if (!settings_type)
+ {
+ static const GTypeInfo settings_info =
+ {
+ sizeof (GtkSettingsClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) gtk_settings_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GtkSettings),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) gtk_settings_init,
+ };
+
+ settings_type = g_type_register_static (G_TYPE_OBJECT, "GtkSettings", &settings_info, 0);
+ }
+
+ return settings_type;
+}
+
+static void
+gtk_settings_init (GtkSettings *settings)
+{
+ GObjectClass *gobject_class = G_OBJECT_GET_CLASS (settings);
+ guint i;
+
+ g_datalist_init (&settings->queued_settings);
+ settings->property_values = NULL;
+ object_list = g_slist_prepend (object_list, settings);
+
+ /* build up property array for all yet existing properties and queue
+ * notification for them (at least notification for internal properties
+ * will instantly be caught)
+ */
+ settings->property_values = g_renew (GValue, settings->property_values, class_n_properties);
+ settings->property_values[class_n_properties - 1].g_type = 0;
+ for (i = 0; i < class_n_properties; i++)
+ {
+ GParamSpec *pspec = gobject_class->property_specs[i]; // FIXME: g_object_list_properties(this_class_type)
+
+ g_value_init (settings->property_values + i, G_PARAM_SPEC_VALUE_TYPE (pspec));
+ g_param_value_set_default (pspec, settings->property_values + i);
+ g_object_notify (G_OBJECT (settings), pspec->name);
+ }
+}
+
+static void
+gtk_settings_class_init (GtkSettingsClass *class)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+
+ parent_class = g_type_class_peek_parent (class);
+
+ gobject_class->constructor = gtk_settings_constructor;
+ gobject_class->finalize = gtk_settings_finalize;
+ gobject_class->get_property = gtk_settings_get_property;
+ gobject_class->set_property = gtk_settings_set_property;
+ gobject_class->notify = gtk_settings_notify;
+
+ quark_property_parser = g_quark_from_static_string ("gtk-rc-property-parser");
+ quark_property_id = g_quark_try_string ("GObject-property-id");
+ g_assert (quark_property_id != 0); /* special quarks from GObjectClass */
+
+ g_assert (PROP_DOUBLE_CLICK_TIMEOUT ==
+ settings_install_property_parser (class,
+ g_param_spec_int ("double-click-timeout", "Double Click Timeout", NULL,
+ 1, G_MAXINT, 1,
+ G_PARAM_READWRITE),
+ NULL));
+ g_assert (PROP_BELL_PITCH ==
+ settings_install_property_parser (class,
+ g_param_spec_int ("bell-pitch", "Bell Pitch", NULL,
+ 0, G_MAXINT, 440,
+ G_PARAM_READWRITE),
+ NULL));
+ g_assert (PROP_BELL_DURATION ==
+ settings_install_property_parser (class,
+ g_param_spec_int ("bell_duration", "Bell Duration", NULL,
+ 1, G_MAXINT, 250,
+ G_PARAM_READWRITE),
+ NULL));
+ g_assert (PROP_BELL_PERCENT ==
+ settings_install_property_parser (class,
+ g_param_spec_float ("bell_percent", "Bell Percent", NULL,
+ 0, 100, 80,
+ G_PARAM_READWRITE),
+ NULL));
+}
+
+static void
+gtk_settings_finalize (GObject *object)
+{
+ GtkSettings *settings = GTK_SETTINGS (object);
+ guint i;
+
+ object_list = g_slist_remove (object_list, settings);
+
+ for (i = 0; i < class_n_properties; i++)
+ g_value_unset (settings->property_values + i);
+ g_free (settings->property_values);
+
+ g_datalist_clear (&settings->queued_settings);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static GObject*
+gtk_settings_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_properties)
+{
+ GObject *object;
+
+ /* currently we're a singleton, that might change with multiple display support though */
+ if (!the_singleton)
+ {
+ object = G_OBJECT_CLASS (parent_class)->constructor (type,
+ n_construct_properties,
+ construct_properties);
+ the_singleton = GTK_SETTINGS (g_object_ref (object));
+ }
+ else
+ object = g_object_ref (G_OBJECT (the_singleton));
+
+ return object;
+}
+
+GtkSettings*
+gtk_settings_get_global (void)
+{
+ if (!the_singleton)
+ g_object_new (GTK_TYPE_SETTINGS, NULL);
+
+ return the_singleton; /* we don't add a reference count here, we'd be settings_ref_global() if we did */
+}
+
+static void
+gtk_settings_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GtkSettings *settings = GTK_SETTINGS (object);
+
+ g_value_copy (value, settings->property_values + property_id - 1);
+}
+
+static void
+gtk_settings_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkSettings *settings = GTK_SETTINGS (object);
+
+ g_value_copy (settings->property_values + property_id - 1, value);
+}
+
+static void
+gtk_settings_notify (GObject *object,
+ GParamSpec *pspec)
+{
+ guint property_id = GPOINTER_TO_UINT (g_param_spec_get_qdata ((pspec), quark_property_id));
+
+#if 1
+ GValue tmp_value = { 0, };
+ gchar *contents;
+ g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+ g_object_get_property (object, pspec->name, &tmp_value);
+ contents = g_strdup_value_contents (&tmp_value);
+#endif
+
+ switch (property_id)
+ {
+ case PROP_DOUBLE_CLICK_TIMEOUT:
+ g_print ("settings-notify: %s = \"%s\"\n", pspec->name, contents);
+ break;
+ case PROP_BELL_PITCH:
+ g_print ("settings-notify: %s = \"%s\"\n", pspec->name, contents);
+ break;
+ case PROP_BELL_DURATION:
+ g_print ("settings-notify: %s = \"%s\"\n", pspec->name, contents);
+ break;
+ case PROP_BELL_PERCENT:
+ g_print ("settings-notify: %s = \"%s\"\n", pspec->name, contents);
+ break;
+ }
+
+#if 1
+ g_free (contents);
+ g_value_unset (&tmp_value);
+#endif
+}
+
+static void
+apply_queued_setting (GtkSettings *data,
+ GParamSpec *pspec,
+ GtkSettingsValue *qvalue)
+{
+ gboolean warn_convert = TRUE;
+
+ if (g_value_type_transformable (G_VALUE_TYPE (&qvalue->value), G_PARAM_SPEC_VALUE_TYPE (pspec)))
+ {
+ GValue tmp_value = { 0, };
+
+ warn_convert = FALSE;
+ g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+ if (g_param_value_convert (pspec, &qvalue->value, &tmp_value, TRUE))
+ g_object_set_property (G_OBJECT (data), pspec->name, &tmp_value);
+ else
+ {
+ gchar *debug = g_strdup_value_contents (&tmp_value);
+
+ g_message ("%s: rc-value `%s' for rc-property \"%s\" of type `%s' has invalid contents \"%s\"",
+ qvalue->origin,
+ G_VALUE_TYPE_NAME (&qvalue->value),
+ pspec->name,
+ g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
+ debug);
+ g_free (debug);
+ }
+ g_value_unset (&tmp_value);
+ }
+ else
+ {
+ GtkRcPropertyParser parser = g_param_spec_get_qdata (pspec, quark_property_parser);
+
+ if (parser)
+ {
+ GValue tmp_value = { 0, };
+
+ g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+ if (parser (pspec, g_value_get_boxed (&qvalue->value), &tmp_value))
+ {
+ warn_convert = FALSE;
+ g_object_set_property (G_OBJECT (data), pspec->name, &tmp_value);
+ }
+ g_value_unset (&tmp_value);
+ }
+ }
+
+ if (warn_convert)
+ g_message ("%s: unable to convert rc-value of type `%s' to rc-property \"%s\" of type `%s'",
+ qvalue->origin,
+ G_VALUE_TYPE_NAME (&qvalue->value),
+ pspec->name,
+ g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
+}
+
+static guint
+settings_install_property_parser (GtkSettingsClass *class,
+ GParamSpec *pspec,
+ GtkRcPropertyParser parser)
+{
+ GSList *node, *next;
+
+ switch (G_TYPE_FUNDAMENTAL (G_PARAM_SPEC_VALUE_TYPE (pspec)))
+ {
+ case G_TYPE_BOOLEAN:
+ case G_TYPE_UCHAR:
+ case G_TYPE_CHAR:
+ case G_TYPE_UINT:
+ case G_TYPE_INT:
+ case G_TYPE_ULONG:
+ case G_TYPE_LONG:
+ case G_TYPE_FLOAT:
+ case G_TYPE_DOUBLE:
+ case G_TYPE_STRING:
+ break;
+ default:
+ if (!parser)
+ g_warning (G_STRLOC ": parser needs to be specified for property \"%s\" of type `%s'",
+ pspec->name, g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)));
+ return 0;
+ }
+ if (g_object_class_find_property (G_OBJECT_CLASS (class), pspec->name))
+ {
+ g_warning (G_STRLOC ": an rc-data property \"%s\" already exists",
+ pspec->name);
+ return 0;
+ }
+
+ for (node = object_list; node; node = node->next)
+ g_object_freeze_notify (node->data);
+
+ g_object_class_install_property (G_OBJECT_CLASS (class), ++class_n_properties, pspec);
+ g_param_spec_set_qdata (pspec, quark_property_parser, parser);
+
+ for (node = object_list; node; node = node->next)
+ {
+ GtkSettings *settings = node->data;
+ GtkSettingsValue *qvalue;
+
+ settings->property_values = g_renew (GValue, settings->property_values, class_n_properties);
+ settings->property_values[class_n_properties - 1].g_type = 0;
+ g_value_init (settings->property_values + class_n_properties - 1, G_PARAM_SPEC_VALUE_TYPE (pspec));
+ g_param_value_set_default (pspec, settings->property_values + class_n_properties - 1);
+ g_object_notify (G_OBJECT (settings), pspec->name);
+
+ qvalue = g_datalist_get_data (&settings->queued_settings, pspec->name);
+ if (qvalue)
+ apply_queued_setting (settings, pspec, qvalue);
+ }
+
+ for (node = object_list; node; node = next)
+ {
+ next = node->next;
+ g_object_thaw_notify (node->data);
+ }
+
+ return class_n_properties;
+}
+
+void
+gtk_settings_install_property (GtkSettings *settings,
+ GParamSpec *pspec)
+{
+ g_return_if_fail (GTK_IS_SETTINGS (settings));
+ g_return_if_fail (G_IS_PARAM_SPEC (pspec));
+
+ settings_install_property_parser (GTK_SETTINGS_GET_CLASS (settings), pspec, NULL);
+}
+
+void
+gtk_settings_install_property_parser (GtkSettings *settings,
+ GParamSpec *pspec,
+ GtkRcPropertyParser parser)
+{
+ g_return_if_fail (GTK_IS_SETTINGS (settings));
+ g_return_if_fail (G_IS_PARAM_SPEC (pspec));
+ g_return_if_fail (parser != NULL);
+
+ settings_install_property_parser (GTK_SETTINGS_GET_CLASS (settings), pspec, parser);
+}
+
+static void
+free_value (gpointer data)
+{
+ GtkSettingsValue *qvalue = data;
+
+ g_value_unset (&qvalue->value);
+ g_free (qvalue->origin);
+ g_free (qvalue);
+}
+
+void
+gtk_settings_set_property_value (GtkSettings *settings,
+ const gchar *prop_name,
+ const GtkSettingsValue *new_value)
+{
+ GtkSettingsValue *qvalue;
+ GParamSpec *pspec;
+ gchar *name;
+ GQuark name_quark;
+
+ g_return_if_fail (GTK_SETTINGS (settings));
+ g_return_if_fail (prop_name != NULL);
+ g_return_if_fail (new_value != NULL);
+ g_return_if_fail (new_value->origin != NULL);
+
+ if (!G_VALUE_HOLDS_LONG (&new_value->value) &&
+ !G_VALUE_HOLDS_DOUBLE (&new_value->value) &&
+ !G_VALUE_HOLDS_STRING (&new_value->value) &&
+ !G_VALUE_HOLDS (&new_value->value, G_TYPE_GSTRING))
+ {
+ g_warning (G_STRLOC ": value type invalid");
+ return;
+ }
+
+ name = g_strdup (prop_name);
+ g_strcanon (name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-", '-');
+ name_quark = g_quark_try_string (name);
+ if (name_quark)
+ g_free (name);
+ else
+ name_quark = g_quark_from_string (name);
+
+ qvalue = g_datalist_id_get_data (&settings->queued_settings, name_quark);
+ if (!qvalue)
+ {
+ qvalue = g_new0 (GtkSettingsValue, 1);
+ g_datalist_id_set_data_full (&settings->queued_settings, name_quark, qvalue, free_value);
+ }
+ else
+ {
+ g_free (qvalue->origin);
+ g_value_unset (&qvalue->value);
+ }
+ qvalue->origin = g_strdup (new_value->origin);
+ g_value_init (&qvalue->value, G_VALUE_TYPE (&new_value->value));
+ g_value_copy (&new_value->value, &qvalue->value);
+ pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (settings), g_quark_to_string (name_quark));
+ if (pspec)
+ apply_queued_setting (settings, pspec, qvalue);
+}
+
+void
+gtk_settings_set_string_property (GtkSettings *settings,
+ const gchar *name,
+ const gchar *v_string,
+ const gchar *origin)
+{
+ GtkSettingsValue svalue = { NULL, { 0, }, };
+
+ g_return_if_fail (GTK_SETTINGS (settings));
+ g_return_if_fail (name != NULL);
+ g_return_if_fail (v_string != NULL);
+ g_return_if_fail (origin != NULL);
+
+ svalue.origin = (gchar*) origin;
+ g_value_init (&svalue.value, G_TYPE_STRING);
+ g_value_set_static_string (&svalue.value, v_string);
+ gtk_settings_set_property_value (settings, name, &svalue);
+ g_value_unset (&svalue.value);
+}
+
+void
+gtk_settings_set_long_property (GtkSettings *settings,
+ const gchar *name,
+ glong v_long,
+ const gchar *origin)
+{
+ GtkSettingsValue svalue = { NULL, { 0, }, };
+
+ g_return_if_fail (GTK_SETTINGS (settings));
+ g_return_if_fail (name != NULL);
+ g_return_if_fail (origin != NULL);
+
+ svalue.origin = (gchar*) origin;
+ g_value_init (&svalue.value, G_TYPE_LONG);
+ g_value_set_long (&svalue.value, v_long);
+ gtk_settings_set_property_value (settings, name, &svalue);
+ g_value_unset (&svalue.value);
+}
+
+void
+gtk_settings_set_double_property (GtkSettings *settings,
+ const gchar *name,
+ gdouble v_double,
+ const gchar *origin)
+{
+ GtkSettingsValue svalue = { NULL, { 0, }, };
+
+ g_return_if_fail (GTK_SETTINGS (settings));
+ g_return_if_fail (name != NULL);
+ g_return_if_fail (origin != NULL);
+
+ svalue.origin = (gchar*) origin;
+ g_value_init (&svalue.value, G_TYPE_DOUBLE);
+ g_value_set_double (&svalue.value, v_double);
+ gtk_settings_set_property_value (settings, name, &svalue);
+ g_value_unset (&svalue.value);
+}
+
+gboolean
+gtk_rc_property_parse_color (const GParamSpec *pspec,
+ const GString *gstring,
+ GValue *property_value)
+{
+ GdkColor color = { 0, 0, 0, 0, };
+ GScanner *scanner;
+ gboolean success;
+
+ g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE);
+ g_return_val_if_fail (G_VALUE_HOLDS (property_value, GTK_TYPE_GDK_COLOR), FALSE);
+
+ scanner = gtk_rc_scanner_new ();
+ g_scanner_input_text (scanner, gstring->str, gstring->len);
+ if (gtk_rc_parse_color (scanner, &color) == G_TOKEN_NONE &&
+ g_scanner_get_next_token (scanner) == G_TOKEN_EOF)
+ {
+ g_value_set_boxed (property_value, &color);
+ success = TRUE;
+ }
+ else
+ success = FALSE;
+ g_scanner_destroy (scanner);
+
+ return success;
+}
+
+gboolean
+gtk_rc_property_parse_enum (const GParamSpec *pspec,
+ const GString *gstring,
+ GValue *property_value)
+{
+ gboolean need_closing_brace = FALSE, success = FALSE;
+ GScanner *scanner;
+ GEnumValue *enum_value = NULL;
+
+ g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE);
+ g_return_val_if_fail (G_VALUE_HOLDS_ENUM (property_value), FALSE);
+
+ scanner = gtk_rc_scanner_new ();
+ g_scanner_input_text (scanner, gstring->str, gstring->len);
+
+ /* we just want to parse _one_ value, but for consistency with flags parsing
+ * we support optional paranthesis
+ */
+ g_scanner_get_next_token (scanner);
+ if (scanner->token == '(')
+ {
+ need_closing_brace = TRUE;
+ g_scanner_get_next_token (scanner);
+ }
+ if (scanner->token == G_TOKEN_IDENTIFIER)
+ {
+ GEnumClass *class = G_PARAM_SPEC_ENUM (pspec)->enum_class;
+
+ enum_value = g_enum_get_value_by_name (class, scanner->value.v_identifier);
+ if (!enum_value)
+ enum_value = g_enum_get_value_by_nick (class, scanner->value.v_identifier);
+ if (enum_value)
+ {
+ g_value_set_enum (property_value, enum_value->value);
+ success = TRUE;
+ }
+ }
+ else if (scanner->token == G_TOKEN_INT)
+ {
+ g_value_set_enum (property_value, scanner->value.v_int);
+ success = TRUE;
+ }
+ if (need_closing_brace && g_scanner_get_next_token (scanner) != ')')
+ success = FALSE;
+ if (g_scanner_get_next_token (scanner) != G_TOKEN_EOF)
+ success = FALSE;
+
+ g_scanner_destroy (scanner);
+
+ return success;
+}
+
+static guint
+parse_flags_value (GScanner *scanner,
+ GFlagsClass *class,
+ guint *number)
+{
+ g_scanner_get_next_token (scanner);
+ if (scanner->token == G_TOKEN_IDENTIFIER)
+ {
+ GFlagsValue *flags_value;
+
+ flags_value = g_flags_get_value_by_name (class, scanner->value.v_identifier);
+ if (!flags_value)
+ flags_value = g_flags_get_value_by_nick (class, scanner->value.v_identifier);
+ if (flags_value)
+ {
+ *number |= flags_value->value;
+ return G_TOKEN_NONE;
+ }
+ }
+ else if (scanner->token == G_TOKEN_INT)
+ {
+ *number |= scanner->value.v_int;
+ return G_TOKEN_NONE;
+ }
+ return G_TOKEN_IDENTIFIER;
+}
+
+gboolean
+gtk_rc_property_parse_flags (const GParamSpec *pspec,
+ const GString *gstring,
+ GValue *property_value)
+{
+ GFlagsClass *class;
+ gboolean success = FALSE;
+ GScanner *scanner;
+
+ g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE);
+ g_return_val_if_fail (G_VALUE_HOLDS_FLAGS (property_value), FALSE);
+
+ class = G_PARAM_SPEC_FLAGS (pspec)->flags_class;
+ scanner = gtk_rc_scanner_new ();
+ g_scanner_input_text (scanner, gstring->str, gstring->len);
+
+ /* parse either a single flags value or a "\( ... [ \| ... ] \)" compound */
+ if (g_scanner_peek_next_token (scanner) == G_TOKEN_IDENTIFIER ||
+ scanner->next_token == G_TOKEN_INT)
+ {
+ guint token, flags_value = 0;
+
+ token = parse_flags_value (scanner, class, &flags_value);
+
+ if (token == G_TOKEN_NONE && g_scanner_peek_next_token (scanner) == G_TOKEN_EOF)
+ {
+ success = TRUE;
+ g_value_set_flags (property_value, flags_value);
+ }
+
+ }
+ else if (g_scanner_get_next_token (scanner) == '(')
+ {
+ guint token, flags_value = 0;
+
+ /* parse first value */
+ token = parse_flags_value (scanner, class, &flags_value);
+
+ /* parse nth values, preceeded by '|' */
+ while (token == G_TOKEN_NONE && g_scanner_get_next_token (scanner) == '|')
+ token = parse_flags_value (scanner, class, &flags_value);
+
+ /* done, last token must have closed expression */
+ if (token == G_TOKEN_NONE && scanner->token == ')' &&
+ g_scanner_peek_next_token (scanner) == G_TOKEN_EOF)
+ {
+ g_value_set_flags (property_value, flags_value);
+ success = TRUE;
+ }
+ }
+ g_scanner_destroy (scanner);
+
+ return success;
+}
diff --git a/gtk/gtksettings.h b/gtk/gtksettings.h
new file mode 100644
index 0000000000..43cd683937
--- /dev/null
+++ b/gtk/gtksettings.h
@@ -0,0 +1,111 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2000 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_SETTINGS_H__
+#define __GTK_SETTINGS_H__
+
+#include <gtk/gtkrc.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* -- type macros --- */
+#define GTK_TYPE_SETTINGS (gtk_settings_get_type ())
+#define GTK_SETTINGS(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_SETTINGS, GtkSettings))
+#define GTK_SETTINGS_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_SETTINGS, GtkSettingsClass))
+#define GTK_IS_SETTINGS(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_SETTINGS))
+#define GTK_IS_SETTINGS_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_SETTINGS))
+#define GTK_SETTINGS_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), GTK_TYPE_SETTINGS, GtkSettingsClass))
+
+
+/* --- typedefs --- */
+typedef struct _GtkSettings GtkSettings;
+typedef struct _GtkSettingsClass GtkSettingsClass;
+typedef struct _GtkSettingsValue GtkSettingsValue;
+
+
+/* --- structures --- */
+struct _GtkSettings
+{
+ GObject parent_instance;
+
+ GData *queued_settings; /* of type GtkSettingsValue* */
+ GValue *property_values;
+};
+struct _GtkSettingsClass
+{
+ GObjectClass parent_class;
+
+};
+struct _GtkSettingsValue
+{
+ /* origin should be something like "filename:linenumber" for rc files,
+ * or e.g. "XProperty" for other sources
+ */
+ gchar *origin;
+
+ /* valid types are LONG, DOUBLE and STRING corresponding to the token parsed,
+ * or a GSTRING holding an unparsed statement
+ */
+ GValue value;
+};
+
+
+/* --- functions --- */
+GType gtk_settings_get_type (void);
+GtkSettings* gtk_settings_get_global (void); /* singleton */
+void gtk_settings_install_property (GtkSettings *settings,
+ GParamSpec *pspec);
+void gtk_settings_install_property_parser (GtkSettings *settings,
+ GParamSpec *pspec,
+ GtkRcPropertyParser parser);
+
+/* --- precoded parsing functions --- */
+gboolean gtk_rc_property_parse_color (const GParamSpec *pspec,
+ const GString *gstring,
+ GValue *property_value);
+gboolean gtk_rc_property_parse_enum (const GParamSpec *pspec,
+ const GString *gstring,
+ GValue *property_value);
+gboolean gtk_rc_property_parse_flags (const GParamSpec *pspec,
+ const GString *gstring,
+ GValue *property_value);
+
+/*< private >*/
+void gtk_settings_set_property_value (GtkSettings *settings,
+ const gchar *name,
+ const GtkSettingsValue *svalue);
+void gtk_settings_set_string_property (GtkSettings *settings,
+ const gchar *name,
+ const gchar *v_string,
+ const gchar *origin);
+void gtk_settings_set_long_property (GtkSettings *settings,
+ const gchar *name,
+ glong v_long,
+ const gchar *origin);
+void gtk_settings_set_double_property (GtkSettings *settings,
+ const gchar *name,
+ gdouble v_double,
+ const gchar *origin);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GTK_SETTINGS_H__ */
diff --git a/gtk/gtkspinbutton.c b/gtk/gtkspinbutton.c
index f33a3d59e2..cc6a0acab6 100644
--- a/gtk/gtkspinbutton.c
+++ b/gtk/gtkspinbutton.c
@@ -36,6 +36,7 @@
#include "gtkspinbutton.h"
#include "gtkmain.h"
#include "gtksignal.h"
+#include "gtksettings.h"
#define MIN_SPIN_BUTTON_WIDTH 30
@@ -55,7 +56,6 @@ enum {
ARG_NUMERIC,
ARG_WRAP,
ARG_UPDATE_POLICY,
- ARG_SHADOW_TYPE,
ARG_VALUE
};
@@ -121,6 +121,7 @@ static void gtk_spin_button_real_spin (GtkSpinButton *spin_button,
static gint gtk_spin_button_default_input (GtkSpinButton *spin_button,
gfloat *new_val);
static gint gtk_spin_button_default_output (GtkSpinButton *spin_button);
+static gint spin_button_get_shadow_type (GtkSpinButton *spin_button);
static GtkEntryClass *parent_class = NULL;
@@ -221,15 +222,17 @@ gtk_spin_button_class_init (GtkSpinButtonClass *class)
GTK_TYPE_SPIN_BUTTON_UPDATE_POLICY,
GTK_ARG_READWRITE,
ARG_UPDATE_POLICY);
- gtk_object_add_arg_type ("GtkSpinButton::shadow_type",
- GTK_TYPE_SHADOW_TYPE,
- GTK_ARG_READWRITE,
- ARG_SHADOW_TYPE);
gtk_object_add_arg_type ("GtkSpinButton::value",
GTK_TYPE_FLOAT,
GTK_ARG_READWRITE,
ARG_VALUE);
-
+
+ gtk_widget_class_install_style_property_parser (widget_class,
+ g_param_spec_enum ("shadow_type", "Shadow Type", NULL,
+ GTK_TYPE_SHADOW_TYPE,
+ GTK_SHADOW_NONE,
+ G_PARAM_READABLE),
+ gtk_rc_property_parse_enum);
spinbutton_signals[INPUT] =
gtk_signal_new ("input",
GTK_RUN_LAST,
@@ -290,9 +293,6 @@ gtk_spin_button_set_arg (GtkObject *object,
case ARG_UPDATE_POLICY:
gtk_spin_button_set_update_policy (spin_button, GTK_VALUE_ENUM (*arg));
break;
- case ARG_SHADOW_TYPE:
- gtk_spin_button_set_shadow_type (spin_button, GTK_VALUE_ENUM (*arg));
- break;
case ARG_VALUE:
gtk_spin_button_set_value (spin_button, GTK_VALUE_FLOAT (*arg));
break;
@@ -333,9 +333,6 @@ gtk_spin_button_get_arg (GtkObject *object,
case ARG_UPDATE_POLICY:
GTK_VALUE_ENUM (*arg) = spin_button->update_policy;
break;
- case ARG_SHADOW_TYPE:
- GTK_VALUE_ENUM (*arg) = spin_button->shadow_type;
- break;
case ARG_VALUE:
GTK_VALUE_FLOAT (*arg) = spin_button->adjustment->value;
break;
@@ -350,7 +347,6 @@ gtk_spin_button_init (GtkSpinButton *spin_button)
{
spin_button->adjustment = NULL;
spin_button->panel = NULL;
- spin_button->shadow_type = GTK_SHADOW_NONE;
spin_button->timer = 0;
spin_button->ev_time = 0;
spin_button->climb_rate = 0.0;
@@ -584,14 +580,17 @@ gtk_spin_button_expose (GtkWidget *widget,
if (GTK_WIDGET_DRAWABLE (widget))
{
+ GtkShadowType shadow_type;
+
/* FIXME this seems like really broken code -
* why aren't we looking at event->window
* and acting accordingly?
*/
-
- if (spin->shadow_type != GTK_SHADOW_NONE)
+
+ shadow_type = spin_button_get_shadow_type (spin);
+ if (shadow_type != GTK_SHADOW_NONE)
gtk_paint_box (widget->style, spin->panel,
- GTK_STATE_NORMAL, spin->shadow_type,
+ GTK_STATE_NORMAL, shadow_type,
&event->area, widget, "spinbutton",
0, 0,
ARROW_SIZE + 2 * widget->style->xthickness,
@@ -616,6 +615,7 @@ static void
gtk_spin_button_draw_arrow (GtkSpinButton *spin_button,
guint arrow)
{
+ GtkShadowType spin_shadow_type;
GtkStateType state_type;
GtkShadowType shadow_type;
GtkWidget *widget;
@@ -626,6 +626,7 @@ gtk_spin_button_draw_arrow (GtkSpinButton *spin_button,
g_return_if_fail (GTK_IS_SPIN_BUTTON (spin_button));
widget = GTK_WIDGET (spin_button);
+ spin_shadow_type = spin_button_get_shadow_type (spin_button);
if (GTK_WIDGET_DRAWABLE (spin_button))
{
@@ -659,7 +660,7 @@ gtk_spin_button_draw_arrow (GtkSpinButton *spin_button,
}
if (arrow == GTK_ARROW_UP)
{
- if (spin_button->shadow_type != GTK_SHADOW_NONE)
+ if (spin_shadow_type != GTK_SHADOW_NONE)
{
x = widget->style->xthickness;
y = widget->style->ythickness;
@@ -678,7 +679,7 @@ gtk_spin_button_draw_arrow (GtkSpinButton *spin_button,
}
else
{
- if (spin_button->shadow_type != GTK_SHADOW_NONE)
+ if (spin_shadow_type != GTK_SHADOW_NONE)
{
x = widget->style->xthickness;
y = widget->requisition.height / 2;
@@ -1563,19 +1564,14 @@ gtk_spin_button_set_wrap (GtkSpinButton *spin_button,
spin_button->wrap = (wrap != 0);
}
-void
-gtk_spin_button_set_shadow_type (GtkSpinButton *spin_button,
- GtkShadowType shadow_type)
+static gint
+spin_button_get_shadow_type (GtkSpinButton *spin_button)
{
- g_return_if_fail (spin_button != NULL);
- g_return_if_fail (GTK_IS_SPIN_BUTTON (spin_button));
+ GtkShadowType rc_shadow_type;
- if (shadow_type != spin_button->shadow_type)
- {
- spin_button->shadow_type = shadow_type;
- if (GTK_WIDGET_DRAWABLE (spin_button))
- gtk_widget_queue_draw (GTK_WIDGET (spin_button));
- }
+ gtk_widget_style_get (GTK_WIDGET (spin_button), "shadow_type", &rc_shadow_type, NULL);
+
+ return rc_shadow_type;
}
void
diff --git a/gtk/gtkspinbutton.h b/gtk/gtkspinbutton.h
index 2f46ebdcb4..04a4c7906d 100644
--- a/gtk/gtkspinbutton.h
+++ b/gtk/gtkspinbutton.h
@@ -79,7 +79,6 @@ struct _GtkSpinButton
GtkAdjustment *adjustment;
GdkWindow *panel;
- GtkShadowType shadow_type;
guint32 timer;
guint32 ev_time;
@@ -149,9 +148,6 @@ void gtk_spin_button_spin (GtkSpinButton *spin_button,
void gtk_spin_button_set_wrap (GtkSpinButton *spin_button,
gboolean wrap);
-void gtk_spin_button_set_shadow_type (GtkSpinButton *spin_button,
- GtkShadowType shadow_type);
-
void gtk_spin_button_set_snap_to_ticks (GtkSpinButton *spin_button,
gboolean snap_to_ticks);
void gtk_spin_button_update (GtkSpinButton *spin_button);
diff --git a/gtk/gtkstyle.c b/gtk/gtkstyle.c
index 4f4922d7b9..ebd5d0de61 100644
--- a/gtk/gtkstyle.c
+++ b/gtk/gtkstyle.c
@@ -36,29 +36,31 @@
#define LIGHTNESS_MULT 1.3
#define DARKNESS_MULT 0.7
-/* actually glib should do that for us */
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif /* M_PI */
-#ifndef M_PI_4
-#define M_PI_4 0.78539816339744830962
-#endif /* M_PI_4 */
-
-static void gtk_style_realize (GtkStyle *style,
- GdkColormap *colormap);
-
-static void gtk_style_real_realize (GtkStyle *style);
-static void gtk_style_real_unrealize (GtkStyle *style);
-static void gtk_style_real_copy (GtkStyle *style,
- GtkStyle *src);
-static void gtk_style_real_set_background (GtkStyle *style,
- GdkWindow *window,
- GtkStateType state_type);
-static GtkStyle *gtk_style_real_clone (GtkStyle *style);
-static void gtk_style_real_init_from_rc (GtkStyle *style,
- GtkRcStyle *rc_style);
-
+/* --- typedefs & structures --- */
+typedef struct {
+ GType widget_type;
+ GParamSpec *pspec;
+ GValue value;
+} PropertyValue;
+
+
+/* --- prototypes --- */
+static void gtk_style_init (GtkStyle *style);
+static void gtk_style_class_init (GtkStyleClass *klass);
+static void gtk_style_finalize (GObject *object);
+static void gtk_style_realize (GtkStyle *style,
+ GdkColormap *colormap);
+static void gtk_style_real_realize (GtkStyle *style);
+static void gtk_style_real_unrealize (GtkStyle *style);
+static void gtk_style_real_copy (GtkStyle *style,
+ GtkStyle *src);
+static void gtk_style_real_set_background (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type);
+static GtkStyle *gtk_style_real_clone (GtkStyle *style);
+static void gtk_style_real_init_from_rc (GtkStyle *style,
+ GtkRcStyle *rc_style);
static GdkPixbuf *gtk_default_render_icon (GtkStyle *style,
const GtkIconSource *source,
GtkTextDirection direction,
@@ -66,7 +68,6 @@ static GdkPixbuf *gtk_default_render_icon (GtkStyle *style,
GtkIconSize size,
GtkWidget *widget,
const gchar *detail);
-
static void gtk_default_draw_hline (GtkStyle *style,
GdkWindow *window,
GtkStateType state_type,
@@ -285,13 +286,18 @@ static void gtk_default_draw_layout (GtkStyle *style,
gint x,
gint y,
PangoLayout *layout);
-
-static void gtk_style_shade (GdkColor *a, GdkColor *b, gdouble k);
-static void rgb_to_hls (gdouble *r, gdouble *g, gdouble *b);
-static void hls_to_rgb (gdouble *h, gdouble *l, gdouble *s);
-
-GdkFont *default_font = NULL;
-
+static void gtk_style_shade (GdkColor *a,
+ GdkColor *b,
+ gdouble k);
+static void rgb_to_hls (gdouble *r,
+ gdouble *g,
+ gdouble *b);
+static void hls_to_rgb (gdouble *h,
+ gdouble *l,
+ gdouble *s);
+
+
+/* --- variables --- */
static GdkColor gtk_default_normal_fg = { 0, 0, 0, 0 };
static GdkColor gtk_default_active_fg = { 0, 0, 0, 0 };
static GdkColor gtk_default_prelight_fg = { 0, 0, 0, 0 };
@@ -305,19 +311,18 @@ static GdkColor gtk_default_selected_bg = { 0, 0, 0, 0x9c40 };
static GdkColor gtk_default_insensitive_bg = { 0, 0xd6d6, 0xd6d6, 0xd6d6 };
static gpointer parent_class = NULL;
+static GdkFont *static_default_font = NULL;
-static void gtk_style_init (GtkStyle *style);
-static void gtk_style_class_init (GtkStyleClass *klass);
-static void gtk_style_finalize (GObject *object);
+/* --- functions --- */
GType
gtk_style_get_type (void)
{
- static GType object_type = 0;
-
- if (!object_type)
+ static GType style_type = 0;
+
+ if (!style_type)
{
- static const GTypeInfo object_info =
+ static const GTypeInfo style_info =
{
sizeof (GtkStyleClass),
(GBaseInitFunc) NULL,
@@ -330,12 +335,12 @@ gtk_style_get_type (void)
(GInstanceInitFunc) gtk_style_init,
};
- object_type = g_type_register_static (G_TYPE_OBJECT,
- "GtkStyle",
- &object_info, 0);
+ style_type = g_type_register_static (G_TYPE_OBJECT,
+ "GtkStyle",
+ &style_info, 0);
}
- return object_type;
+ return style_type;
}
static void
@@ -345,18 +350,18 @@ gtk_style_init (GtkStyle *style)
style->font_desc = pango_font_description_from_string ("Sans 10");
- if (!default_font)
+ if (!static_default_font)
{
- default_font = gdk_font_from_description (style->font_desc);
+ static_default_font = gdk_font_from_description (style->font_desc);
- if (!default_font)
- default_font = gdk_font_load ("fixed");
+ if (!static_default_font)
+ static_default_font = gdk_font_load ("fixed");
- if (!default_font)
- g_error ("Unable to load \"fixed\" font!");
+ if (!static_default_font)
+ g_error ("Unable to load \"fixed\" font");
}
- style->font = default_font;
+ style->font = static_default_font;
gdk_font_ref (style->font);
style->attach_count = 0;
@@ -413,6 +418,8 @@ gtk_style_init (GtkStyle *style)
style->xthickness = 2;
style->ythickness = 2;
+
+ style->property_cache = NULL;
}
static void
@@ -460,6 +467,21 @@ gtk_style_finalize (GObject *object)
GtkStyle *style = GTK_STYLE (object);
g_return_if_fail (style->attach_count == 0);
+
+ if (style->property_cache)
+ {
+ guint i;
+
+ for (i = 0; i < style->property_cache->n_nodes; i++)
+ {
+ PropertyValue *node = g_bsearch_array_get_nth (style->property_cache, i);
+
+ g_param_spec_unref (node->pspec);
+ g_value_unset (&node->value);
+ }
+ g_bsearch_array_destroy (style->property_cache);
+ style->property_cache = NULL;
+ }
if (style->styles)
{
@@ -471,7 +493,7 @@ gtk_style_finalize (GObject *object)
while (tmp_list)
{
- ((GtkStyle*) tmp_list->data)->styles = style->styles->next;
+ GTK_STYLE (tmp_list->data)->styles = style->styles->next;
tmp_list = tmp_list->next;
}
g_slist_free_1 (style->styles);
@@ -668,10 +690,8 @@ gtk_style_lookup_icon_set (GtkStyle *style,
iter = style->icon_factories;
while (iter != NULL)
{
- GtkIconSet *icon_set =
- gtk_icon_factory_lookup (GTK_ICON_FACTORY (iter->data),
- stock_id);
-
+ GtkIconSet *icon_set = gtk_icon_factory_lookup (GTK_ICON_FACTORY (iter->data),
+ stock_id);
if (icon_set)
return icon_set;
@@ -1062,6 +1082,22 @@ gtk_style_real_copy (GtkStyle *style,
style->rc_style = src->rc_style;
if (src->rc_style)
gtk_rc_style_ref (src->rc_style);
+
+ /* don't copy, just clear cache */
+ if (style->property_cache)
+ {
+ guint i;
+
+ for (i = 0; i < style->property_cache->n_nodes; i++)
+ {
+ PropertyValue *node = g_bsearch_array_get_nth (style->property_cache, i);
+
+ g_param_spec_unref (node->pspec);
+ g_value_unset (&node->value);
+ }
+ g_bsearch_array_destroy (style->property_cache);
+ style->property_cache = NULL;
+ }
}
static void
@@ -1071,6 +1107,22 @@ gtk_style_real_init_from_rc (GtkStyle *style,
GdkFont *old_font;
gint i;
+ /* cache _should_ be still empty */
+ if (style->property_cache)
+ {
+ guint i;
+
+ for (i = 0; i < style->property_cache->n_nodes; i++)
+ {
+ PropertyValue *node = g_bsearch_array_get_nth (style->property_cache, i);
+
+ g_param_spec_unref (node->pspec);
+ g_value_unset (&node->value);
+ }
+ g_bsearch_array_destroy (style->property_cache);
+ style->property_cache = NULL;
+ }
+
if (rc_style->font_desc)
{
pango_font_description_free (style->font_desc);
@@ -1101,7 +1153,6 @@ gtk_style_real_init_from_rc (GtkStyle *style,
if (rc_style->ythickness >= 0)
style->ythickness = rc_style->ythickness;
-
if (rc_style->icon_factories)
{
GSList *iter;
@@ -1118,6 +1169,118 @@ gtk_style_real_init_from_rc (GtkStyle *style,
}
}
+static gint
+style_property_values_cmp (gconstpointer bsearch_node1,
+ gconstpointer bsearch_node2)
+{
+ const PropertyValue *val1 = bsearch_node1;
+ const PropertyValue *val2 = bsearch_node2;
+ gint cmp;
+
+ cmp = G_BSEARCH_ARRAY_CMP (val1->widget_type, val2->widget_type);
+ if (cmp == 0)
+ cmp = G_BSEARCH_ARRAY_CMP (val1->pspec, val2->pspec);
+
+ return cmp;
+}
+
+const GValue*
+_gtk_style_peek_property_value (GtkStyle *style,
+ GType widget_type,
+ GParamSpec *pspec,
+ GtkRcPropertyParser parser)
+{
+ PropertyValue *pcache, key = { 0, NULL, { 0, } };
+ const GtkRcProperty *rcprop = NULL;
+
+ g_return_val_if_fail (GTK_IS_STYLE (style), NULL);
+ g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), NULL);
+ g_return_val_if_fail (g_type_is_a (pspec->owner_type, GTK_TYPE_WIDGET), NULL);
+ g_return_val_if_fail (g_type_is_a (widget_type, pspec->owner_type), NULL);
+
+ /* need value cache array */
+ if (!style->property_cache)
+ style->property_cache = g_bsearch_array_new (sizeof (PropertyValue),
+ style_property_values_cmp,
+ 0);
+ /* lookup, or insert value if not yet present */
+ key.widget_type = widget_type;
+ key.pspec = pspec;
+ pcache = g_bsearch_array_insert (style->property_cache, &key, FALSE);
+ if (G_VALUE_TYPE (&pcache->value))
+ return &pcache->value;
+
+ /* cache miss, initialize value type, then set contents */
+ g_value_init (&pcache->value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+
+ /* value provided by rc style? */
+ if (style->rc_style)
+ {
+ GQuark prop_quark = g_quark_from_string (pspec->name);
+
+ do
+ {
+ rcprop = _gtk_rc_style_lookup_rc_property (style->rc_style,
+ g_type_qname (widget_type),
+ prop_quark);
+ if (rcprop)
+ break;
+ widget_type = g_type_parent (widget_type);
+ }
+ while (g_type_is_a (widget_type, pspec->owner_type));
+ }
+
+ /* when supplied by rc style, we need to convert */
+ if (rcprop)
+ {
+ if (G_VALUE_TYPE (&rcprop->value) == G_TYPE_GSTRING)
+ {
+ GString *gstring;
+
+ /* value still unparsed, need to revert to user supplied parser function */
+
+ gstring = g_value_get_boxed (&rcprop->value);
+
+ if (!parser || !parser (pspec, gstring, &pcache->value) ||
+ g_param_value_validate (pspec, &pcache->value))
+ {
+ gchar *contents = g_strescape (gstring->str, NULL);
+
+ g_message ("%s: failed to parse property `%s::%s' of type `%s' from rc file value \"%s\"",
+ rcprop->origin,
+ g_type_name (pspec->owner_type), pspec->name,
+ g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
+ gstring->str);
+ g_free (contents);
+ rcprop = NULL;
+ }
+ }
+ else
+ {
+ /* we use the normal conversion functionality of param specs */
+ if (!g_param_value_convert (pspec, &rcprop->value, &pcache->value, TRUE))
+ {
+ gchar *contents = g_strdup_value_contents (&rcprop->value);
+
+ g_message ("%s: failed to retrive property `%s::%s' of type `%s' from rc file value \"%s\" of type `%s'",
+ rcprop->origin,
+ g_type_name (pspec->owner_type), pspec->name,
+ g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
+ contents,
+ G_VALUE_TYPE_NAME (&rcprop->value));
+ g_free (contents);
+ rcprop = NULL;
+ }
+ }
+ }
+
+ /* not supplied by rc style (or conversion failed), revert to default */
+ if (!rcprop)
+ g_param_value_set_default (pspec, &pcache->value);
+
+ return &pcache->value;
+}
+
static void
gtk_style_real_realize (GtkStyle *style)
{
@@ -1146,7 +1309,7 @@ gtk_style_real_realize (GtkStyle *style)
}
else if (style->font->type == GDK_FONT_FONTSET)
{
- gc_values.font = default_font;
+ gc_values.font = static_default_font;
}
gc_values.foreground = style->black;
@@ -1394,7 +1557,7 @@ gtk_default_render_icon (GtkStyle *style,
if (!gtk_icon_size_lookup (size, &width, &height))
{
- g_warning ("Bad icon size '%s' passed to render_icon", size);
+ g_warning (G_STRLOC ": invalid icon size `%d'", size);
return NULL;
}
@@ -1728,8 +1891,8 @@ gtk_default_draw_polygon (GtkStyle *style,
gint npoints,
gboolean fill)
{
- static const gdouble pi_over_4 = M_PI_4;
- static const gdouble pi_3_over_4 = M_PI_4 * 3;
+ static const gdouble pi_over_4 = G_PI_4;
+ static const gdouble pi_3_over_4 = G_PI_4 * 3;
GdkGC *gc1;
GdkGC *gc2;
GdkGC *gc3;
diff --git a/gtk/gtkstyle.h b/gtk/gtkstyle.h
index bcb02be505..407f9ae77c 100644
--- a/gtk/gtkstyle.h
+++ b/gtk/gtkstyle.h
@@ -36,9 +36,6 @@
extern "C" {
#endif /* __cplusplus */
-typedef struct _GtkStyle GtkStyle;
-typedef struct _GtkStyleClass GtkStyleClass;
-
#define GTK_TYPE_STYLE (gtk_style_get_type ())
#define GTK_STYLE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GTK_TYPE_STYLE, GtkStyle))
#define GTK_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_STYLE, GtkStyleClass))
@@ -49,10 +46,16 @@ typedef struct _GtkStyleClass GtkStyleClass;
/* Some forward declarations needed to rationalize the header
* files.
*/
+typedef struct _GtkStyle GtkStyle;
+typedef struct _GtkStyleClass GtkStyleClass;
typedef struct _GtkThemeEngine GtkThemeEngine;
typedef struct _GtkRcStyle GtkRcStyle;
typedef struct _GtkIconSet GtkIconSet;
typedef struct _GtkIconSource GtkIconSource;
+typedef struct _GtkRcProperty GtkRcProperty;
+typedef gboolean (*GtkRcPropertyParser) (const GParamSpec *pspec,
+ const GString *rc_string,
+ GValue *property_value);
/* We make this forward declaration here, since we pass
* GtkWidgt's to the draw functions.
@@ -64,7 +67,7 @@ typedef struct _GtkWidget GtkWidget;
*/
#define GTK_STYLE_NUM_STYLECOLORS() (7 * 5)
-#define GTK_STYLE_ATTACHED(style) (((GtkStyle*) (style))->attach_count > 0)
+#define GTK_STYLE_ATTACHED(style) (GTK_STYLE (style)->attach_count > 0)
struct _GtkStyle
{
@@ -107,12 +110,12 @@ struct _GtkStyle
gint depth;
GdkColormap *colormap;
- GtkRcStyle *rc_style; /* the Rc style from which this style
- * was created
- */
- GSList *styles;
+ /* the RcStyle from which this style was created */
+ GtkRcStyle *rc_style;
- GSList *icon_factories;
+ GSList *styles; /* of type GtkStyle* */
+ GBSearchArray *property_cache;
+ GSList *icon_factories; /* of type GtkIconFactory* */
};
struct _GtkStyleClass
@@ -409,7 +412,7 @@ void gtk_style_apply_default_background (GtkStyle *style,
GtkIconSet* gtk_style_lookup_icon_set (GtkStyle *style,
const gchar *stock_id);
-GdkPixbuf * gtk_style_render_icon (GtkStyle *style,
+GdkPixbuf* gtk_style_render_icon (GtkStyle *style,
const GtkIconSource *source,
GtkTextDirection direction,
GtkStateType state,
@@ -461,14 +464,6 @@ void gtk_draw_diamond (GtkStyle *style,
gint y,
gint width,
gint height);
-#ifndef GTK_DISABLE_DEPRECATED
-void gtk_draw_string (GtkStyle *style,
- GdkWindow *window,
- GtkStateType state_type,
- gint x,
- gint y,
- const gchar *string);
-#endif /* GTK_DISABLE_DEPRECATED */
void gtk_draw_box (GtkStyle *style,
GdkWindow *window,
GtkStateType state_type,
@@ -640,17 +635,6 @@ void gtk_paint_diamond (GtkStyle *style,
gint y,
gint width,
gint height);
-#ifndef GTK_DISABLE_DEPRECATED
-void gtk_paint_string (GtkStyle *style,
- GdkWindow *window,
- GtkStateType state_type,
- GdkRectangle *area,
- GtkWidget *widget,
- const gchar *detail,
- gint x,
- gint y,
- const gchar *string);
-#endif /* GTK_DISABLE_DEPRECATED */
void gtk_paint_box (GtkStyle *style,
GdkWindow *window,
GtkStateType state_type,
@@ -799,6 +783,32 @@ void gtk_paint_layout (GtkStyle *style,
PangoLayout *layout);
+/* --- private API --- */
+const GValue* _gtk_style_peek_property_value (GtkStyle *style,
+ GType widget_type,
+ GParamSpec *pspec,
+ GtkRcPropertyParser parser);
+
+
+/* depprecated */
+#ifndef GTK_DISABLE_DEPRECATED
+void gtk_draw_string (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ gint x,
+ gint y,
+ const gchar *string);
+void gtk_paint_string (GtkStyle *style,
+ GdkWindow *window,
+ GtkStateType state_type,
+ GdkRectangle *area,
+ GtkWidget *widget,
+ const gchar *detail,
+ gint x,
+ gint y,
+ const gchar *string);
+#endif /* GTK_DISABLE_DEPRECATED */
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/gtk/gtktypeutils.c b/gtk/gtktypeutils.c
index 0b54cdfecc..97e10fd458 100644
--- a/gtk/gtktypeutils.c
+++ b/gtk/gtktypeutils.c
@@ -140,9 +140,7 @@ gtk_type_init (GTypeDebugFlags debug_flags)
#include "gtktypebuiltins_ids.c" /* type entries */
{ NULL }
};
- GTypeFundamentalInfo finfo = { 0, };
GTypeInfo tinfo = { 0, };
- GtkType type_id;
guint i;
initialized = TRUE;
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 2500432ec9..7492e8cf82 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -39,6 +39,7 @@
#include "gtkprivate.h"
#include "gdk/gdk.h"
#include "gdk/gdkprivate.h" /* Used in gtk_reset_shapes_recurse to avoid copy */
+#include "gobject/gvaluecollector.h"
#define WIDGET_CLASS(w) GTK_WIDGET_GET_CLASS (w)
@@ -191,37 +192,29 @@ static void gtk_widget_propagate_hierarchy_changed (GtkWidget *widget,
static GtkWidgetAuxInfo* gtk_widget_aux_info_new (void);
static void gtk_widget_aux_info_destroy (GtkWidgetAuxInfo *aux_info);
-static gpointer parent_class = NULL;
-static guint widget_signals[LAST_SIGNAL] = { 0 };
+static gpointer parent_class = NULL;
+static guint widget_signals[LAST_SIGNAL] = { 0 };
-static GMemChunk *aux_info_mem_chunk = NULL;
-
-static GdkColormap *default_colormap = NULL;
-static GtkStyle *gtk_default_style = NULL;
-
-static GSList *colormap_stack = NULL;
-static GSList *style_stack = NULL;
-static guint composite_child_stack = 0;
-
-static const gchar *aux_info_key = "gtk-aux-info";
-static guint aux_info_key_id = 0;
-static const gchar *event_key = "gtk-event-mask";
-static guint event_key_id = 0;
-static const gchar *extension_event_key = "gtk-extension-event-mode";
-static guint extension_event_key_id = 0;
-static const gchar *parent_window_key = "gtk-parent-window";
-static guint parent_window_key_id = 0;
-static const gchar *saved_default_style_key = "gtk-saved-default-style";
-static guint saved_default_style_key_id = 0;
-static const gchar *shape_info_key = "gtk-shape-info";
-static const gchar *colormap_key = "gtk-colormap";
-static const gchar *pango_context_key = "gtk-pango-context";
-static guint pango_context_key_id = 0;
+static GMemChunk *aux_info_mem_chunk = NULL;
+static GdkColormap *default_colormap = NULL;
+static GtkStyle *gtk_default_style = NULL;
+static GSList *colormap_stack = NULL;
+static GSList *style_stack = NULL;
+static guint composite_child_stack = 0;
+static GtkTextDirection gtk_default_direction = GTK_TEXT_DIR_LTR;
+static GParamSpecPool *style_property_spec_pool = NULL;
-static const gchar *rc_style_key = "gtk-rc-style";
-static guint rc_style_key_id = 0;
+static GQuark quark_property_parser = 0;
+static GQuark quark_aux_info = 0;
+static GQuark quark_event_mask = 0;
+static GQuark quark_extension_event_mode = 0;
+static GQuark quark_parent_window = 0;
+static GQuark quark_saved_default_style = 0;
+static GQuark quark_shape_info = 0;
+static GQuark quark_colormap = 0;
+static GQuark quark_pango_context = 0;
+static GQuark quark_rc_style = 0;
-static GtkTextDirection gtk_default_direction = GTK_TEXT_DIR_LTR;
/*****************************************
* gtk_widget_get_type:
@@ -332,6 +325,19 @@ gtk_widget_class_init (GtkWidgetClass *klass)
klass->no_expose_event = NULL;
+ quark_property_parser = g_quark_from_static_string ("gtk-rc-property-parser");
+ quark_aux_info = g_quark_from_static_string ("gtk-aux-info");
+ quark_event_mask = g_quark_from_static_string ("gtk-event-mask");
+ quark_extension_event_mode = g_quark_from_static_string ("gtk-extension-event-mode");
+ quark_parent_window = g_quark_from_static_string ("gtk-parent-window");
+ quark_saved_default_style = g_quark_from_static_string ("gtk-saved-default-style");
+ quark_shape_info = g_quark_from_static_string ("gtk-shape-info");
+ quark_colormap = g_quark_from_static_string ("gtk-colormap");
+ quark_pango_context = g_quark_from_static_string ("gtk-pango-context");
+ quark_rc_style = g_quark_from_static_string ("gtk-rc-style");
+
+ style_property_spec_pool = g_param_spec_pool_new (FALSE);
+
gtk_object_add_arg_type ("GtkWidget::name", GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_NAME);
gtk_object_add_arg_type ("GtkWidget::parent", GTK_TYPE_CONTAINER, GTK_ARG_READWRITE, ARG_PARENT);
gtk_object_add_arg_type ("GtkWidget::x", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_X);
@@ -906,28 +912,28 @@ gtk_widget_get_arg (GtkObject *object,
GTK_VALUE_OBJECT (*arg) = (GtkObject*) widget->parent;
break;
case ARG_X:
- aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
+ aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
if (!aux_info)
GTK_VALUE_INT (*arg) = -1;
else
GTK_VALUE_INT (*arg) = aux_info->x;
break;
case ARG_Y:
- aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
+ aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
if (!aux_info)
GTK_VALUE_INT (*arg) = -1;
else
GTK_VALUE_INT (*arg) = aux_info->y;
break;
case ARG_WIDTH:
- aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
+ aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
if (!aux_info)
GTK_VALUE_INT (*arg) = -1;
else
GTK_VALUE_INT (*arg) = aux_info->width;
break;
case ARG_HEIGHT:
- aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
+ aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
if (!aux_info)
GTK_VALUE_INT (*arg) = -1;
else
@@ -964,14 +970,14 @@ gtk_widget_get_arg (GtkObject *object,
GTK_VALUE_BOXED (*arg) = (gpointer) gtk_widget_get_style (widget);
break;
case ARG_EVENTS:
- eventp = gtk_object_get_data_by_id (GTK_OBJECT (widget), event_key_id);
+ eventp = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_event_mask);
if (!eventp)
GTK_VALUE_FLAGS (*arg) = 0;
else
GTK_VALUE_FLAGS (*arg) = *eventp;
break;
case ARG_EXTENSION_EVENTS:
- modep = gtk_object_get_data_by_id (GTK_OBJECT (widget), extension_event_key_id);
+ modep = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_extension_event_mode);
if (!modep)
GTK_VALUE_FLAGS (*arg) = 0;
else
@@ -1584,8 +1590,7 @@ gtk_widget_realize (GtkWidget *widget)
if (GTK_WIDGET_HAS_SHAPE_MASK (widget))
{
- shape_info = gtk_object_get_data (GTK_OBJECT (widget),
- shape_info_key);
+ shape_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_shape_info);
gdk_window_shape_combine_mask (widget->window,
shape_info->shape_mask,
shape_info->offset_x,
@@ -1917,7 +1922,7 @@ gtk_widget_get_child_requisition (GtkWidget *widget,
*requisition = widget->requisition;
- aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
+ aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
if (aux_info)
{
if (aux_info->width > 0)
@@ -1948,7 +1953,7 @@ gtk_widget_size_allocate (GtkWidget *widget,
g_return_if_fail (GTK_IS_WIDGET (widget));
real_allocation = *allocation;
- aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
+ aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
if (aux_info)
{
@@ -3094,13 +3099,11 @@ gtk_widget_set_style (GtkWidget *widget,
GTK_WIDGET_UNSET_FLAGS (widget, GTK_RC_STYLE);
GTK_PRIVATE_SET_FLAG (widget, GTK_USER_STYLE);
- default_style = gtk_object_get_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id);
+ default_style = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_saved_default_style);
if (!default_style)
{
gtk_style_ref (widget->style);
- if (!saved_default_style_key_id)
- saved_default_style_key_id = g_quark_from_static_string (saved_default_style_key);
- gtk_object_set_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id, widget->style);
+ gtk_object_set_data_by_id (GTK_OBJECT (widget), quark_saved_default_style, widget->style);
}
gtk_widget_set_style_internal (widget, style, initial_emission);
@@ -3148,16 +3151,14 @@ gtk_widget_set_rc_style (GtkWidget *widget)
GTK_PRIVATE_UNSET_FLAG (widget, GTK_USER_STYLE);
GTK_WIDGET_SET_FLAGS (widget, GTK_RC_STYLE);
- saved_style = gtk_object_get_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id);
+ saved_style = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_saved_default_style);
new_style = gtk_rc_get_style (widget);
if (new_style)
{
if (!saved_style)
{
gtk_style_ref (widget->style);
- if (!saved_default_style_key_id)
- saved_default_style_key_id = g_quark_from_static_string (saved_default_style_key);
- gtk_object_set_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id, widget->style);
+ gtk_object_set_data_by_id (GTK_OBJECT (widget), quark_saved_default_style, widget->style);
}
gtk_widget_set_style_internal (widget, new_style, initial_emission);
}
@@ -3167,7 +3168,7 @@ gtk_widget_set_rc_style (GtkWidget *widget)
{
g_assert (initial_emission == FALSE); /* FIXME: remove this line */
- gtk_object_remove_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id);
+ gtk_object_remove_data_by_id (GTK_OBJECT (widget), quark_saved_default_style);
gtk_widget_set_style_internal (widget, saved_style, initial_emission);
gtk_style_unref (saved_style);
}
@@ -3189,10 +3190,10 @@ gtk_widget_restore_default_style (GtkWidget *widget)
GTK_PRIVATE_UNSET_FLAG (widget, GTK_USER_STYLE);
- default_style = gtk_object_get_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id);
+ default_style = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_saved_default_style);
if (default_style)
{
- gtk_object_remove_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id);
+ gtk_object_remove_data_by_id (GTK_OBJECT (widget), quark_saved_default_style);
gtk_widget_set_style_internal (widget, default_style, FALSE);
gtk_style_unref (default_style);
}
@@ -3246,15 +3247,12 @@ gtk_widget_modify_style (GtkWidget *widget,
g_return_if_fail (GTK_IS_RC_STYLE (style));
- if (!rc_style_key_id)
- rc_style_key_id = g_quark_from_static_string (rc_style_key);
-
old_style = gtk_object_get_data_by_id (GTK_OBJECT (widget),
- rc_style_key_id);
+ quark_rc_style);
if (style != old_style)
gtk_object_set_data_by_id_full (GTK_OBJECT (widget),
- rc_style_key_id,
+ quark_rc_style,
gtk_rc_style_copy (style),
(GtkDestroyNotify)gtk_rc_style_unref);
@@ -3282,17 +3280,14 @@ gtk_widget_get_modifier_style (GtkWidget *widget)
{
GtkRcStyle *rc_style;
- if (!rc_style_key_id)
- rc_style_key_id = g_quark_from_static_string (rc_style_key);
-
rc_style = gtk_object_get_data_by_id (GTK_OBJECT (widget),
- rc_style_key_id);
+ quark_rc_style);
if (!rc_style)
{
rc_style = gtk_rc_style_new();
gtk_object_set_data_by_id_full (GTK_OBJECT (widget),
- rc_style_key_id,
+ quark_rc_style,
rc_style,
(GtkDestroyNotify)gtk_rc_style_unref);
}
@@ -3638,10 +3633,7 @@ gtk_widget_pop_style (void)
static PangoContext *
gtk_widget_peek_pango_context (GtkWidget *widget)
{
- if (!pango_context_key_id)
- pango_context_key_id = g_quark_from_static_string (pango_context_key);
-
- return gtk_object_get_data_by_id (GTK_OBJECT (widget), pango_context_key_id);
+ return gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_pango_context);
}
/**
@@ -3668,15 +3660,12 @@ gtk_widget_get_pango_context (GtkWidget *widget)
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
- if (!pango_context_key_id)
- pango_context_key_id = g_quark_from_static_string (pango_context_key);
-
- context = gtk_object_get_data_by_id (GTK_OBJECT (widget), pango_context_key_id);
+ context = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_pango_context);
if (!context)
{
context = gtk_widget_create_pango_context (GTK_WIDGET (widget));
- gtk_object_set_data_by_id_full (GTK_OBJECT (widget), pango_context_key_id, context,
- (GDestroyNotify)g_object_unref);
+ gtk_object_set_data_by_id_full (GTK_OBJECT (widget), quark_pango_context, context,
+ (GDestroyNotify) g_object_unref);
}
return context;
@@ -3777,7 +3766,7 @@ gtk_widget_render_icon (GtkWidget *widget,
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
g_return_val_if_fail (stock_id != NULL, NULL);
- g_return_val_if_fail (size != NULL, NULL);
+ g_return_val_if_fail (size > GTK_ICON_SIZE_INVALID, NULL);
gtk_widget_ensure_style (widget);
@@ -3818,13 +3807,11 @@ gtk_widget_set_parent_window (GtkWidget *widget,
g_return_if_fail (GTK_IS_WIDGET (widget));
old_parent_window = gtk_object_get_data_by_id (GTK_OBJECT (widget),
- parent_window_key_id);
+ quark_parent_window);
if (parent_window != old_parent_window)
{
- if (!parent_window_key_id)
- parent_window_key_id = g_quark_from_static_string (parent_window_key);
- gtk_object_set_data_by_id (GTK_OBJECT (widget), parent_window_key_id,
+ gtk_object_set_data_by_id (GTK_OBJECT (widget), quark_parent_window,
parent_window);
if (old_parent_window)
gdk_window_unref (old_parent_window);
@@ -3854,7 +3841,7 @@ gtk_widget_get_parent_window (GtkWidget *widget)
g_return_val_if_fail (widget->parent != NULL, NULL);
parent_window = gtk_object_get_data_by_id (GTK_OBJECT (widget),
- parent_window_key_id);
+ quark_parent_window);
return (parent_window != NULL) ? parent_window : widget->parent->window;
}
@@ -3887,13 +3874,11 @@ gtk_widget_set_uposition (GtkWidget *widget,
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_WIDGET (widget));
- aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
+ aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
if (!aux_info)
{
- if (!aux_info_key_id)
- aux_info_key_id = g_quark_from_static_string (aux_info_key);
aux_info = gtk_widget_aux_info_new ();
- gtk_object_set_data_by_id (GTK_OBJECT (widget), aux_info_key_id, aux_info);
+ gtk_object_set_data_by_id (GTK_OBJECT (widget), quark_aux_info, aux_info);
}
/* keep this in sync with gtk_window_compute_reposition() */
@@ -3945,13 +3930,11 @@ gtk_widget_set_usize (GtkWidget *widget,
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_WIDGET (widget));
- aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
+ aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
if (!aux_info)
{
- if (!aux_info_key_id)
- aux_info_key_id = g_quark_from_static_string (aux_info_key);
aux_info = gtk_widget_aux_info_new ();
- gtk_object_set_data_by_id (GTK_OBJECT (widget), aux_info_key_id, aux_info);
+ gtk_object_set_data_by_id (GTK_OBJECT (widget), quark_aux_info, aux_info);
}
if (width > -2)
@@ -3991,7 +3974,7 @@ gtk_widget_set_events (GtkWidget *widget,
g_return_if_fail (!GTK_WIDGET_NO_WINDOW (widget));
g_return_if_fail (!GTK_WIDGET_REALIZED (widget));
- eventp = gtk_object_get_data_by_id (GTK_OBJECT (widget), event_key_id);
+ eventp = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_event_mask);
if (events)
{
@@ -3999,14 +3982,12 @@ gtk_widget_set_events (GtkWidget *widget,
eventp = g_new (gint, 1);
*eventp = events;
- if (!event_key_id)
- event_key_id = g_quark_from_static_string (event_key);
- gtk_object_set_data_by_id (GTK_OBJECT (widget), event_key_id, eventp);
+ gtk_object_set_data_by_id (GTK_OBJECT (widget), quark_event_mask, eventp);
}
else if (eventp)
{
g_free (eventp);
- gtk_object_remove_data_by_id (GTK_OBJECT (widget), event_key_id);
+ gtk_object_remove_data_by_id (GTK_OBJECT (widget), quark_event_mask);
}
}
@@ -4029,7 +4010,7 @@ gtk_widget_add_events (GtkWidget *widget,
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (!GTK_WIDGET_NO_WINDOW (widget));
- eventp = gtk_object_get_data_by_id (GTK_OBJECT (widget), event_key_id);
+ eventp = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_event_mask);
if (events)
{
@@ -4040,14 +4021,12 @@ gtk_widget_add_events (GtkWidget *widget,
}
*eventp |= events;
- if (!event_key_id)
- event_key_id = g_quark_from_static_string (event_key);
- gtk_object_set_data_by_id (GTK_OBJECT (widget), event_key_id, eventp);
+ gtk_object_set_data_by_id (GTK_OBJECT (widget), quark_event_mask, eventp);
}
else if (eventp)
{
g_free (eventp);
- gtk_object_remove_data_by_id (GTK_OBJECT (widget), event_key_id);
+ gtk_object_remove_data_by_id (GTK_OBJECT (widget), quark_event_mask);
}
if (GTK_WIDGET_REALIZED (widget))
@@ -4075,15 +4054,13 @@ gtk_widget_set_extension_events (GtkWidget *widget,
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_WIDGET (widget));
- modep = gtk_object_get_data_by_id (GTK_OBJECT (widget), extension_event_key_id);
+ modep = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_extension_event_mode);
if (!modep)
modep = g_new (GdkExtensionMode, 1);
*modep = mode;
- if (!extension_event_key_id)
- extension_event_key_id = g_quark_from_static_string (extension_event_key);
- gtk_object_set_data_by_id (GTK_OBJECT (widget), extension_event_key_id, modep);
+ gtk_object_set_data_by_id (GTK_OBJECT (widget), quark_extension_event_mode, modep);
}
/**
@@ -4166,7 +4143,7 @@ gtk_widget_get_colormap (GtkWidget *widget)
return colormap;
}
- colormap = gtk_object_get_data (GTK_OBJECT (widget), colormap_key);
+ colormap = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_colormap);
if (colormap)
return colormap;
@@ -4211,10 +4188,10 @@ gtk_widget_set_colormap (GtkWidget *widget,
g_object_ref (G_OBJECT (colormap));
- gtk_object_set_data_full (GTK_OBJECT (widget),
- colormap_key,
- colormap,
- (GtkDestroyNotify) g_object_unref);
+ g_object_set_qdata_full (G_OBJECT (widget),
+ quark_colormap,
+ colormap,
+ (GtkDestroyNotify) g_object_unref);
}
/**
@@ -4235,7 +4212,7 @@ gtk_widget_get_events (GtkWidget *widget)
g_return_val_if_fail (widget != NULL, 0);
g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
- events = gtk_object_get_data_by_id (GTK_OBJECT (widget), event_key_id);
+ events = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_event_mask);
if (events)
return *events;
@@ -4259,7 +4236,7 @@ gtk_widget_get_extension_events (GtkWidget *widget)
g_return_val_if_fail (widget != NULL, 0);
g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
- mode = gtk_object_get_data_by_id (GTK_OBJECT (widget), extension_event_key_id);
+ mode = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_extension_event_mode);
if (mode)
return *mode;
@@ -4641,11 +4618,11 @@ gtk_widget_real_destroy (GtkObject *object)
gtk_grab_remove (widget);
gtk_selection_remove_all (widget);
- saved_style = gtk_object_get_data_by_id (object, saved_default_style_key_id);
+ saved_style = gtk_object_get_data_by_id (object, quark_saved_default_style);
if (saved_style)
{
gtk_style_unref (saved_style);
- gtk_object_remove_data_by_id (object, saved_default_style_key_id);
+ gtk_object_remove_data_by_id (object, quark_saved_default_style);
}
gtk_style_unref (widget->style);
@@ -4667,11 +4644,11 @@ gtk_widget_finalize (GObject *object)
gtk_grab_remove (widget);
gtk_selection_remove_all (widget);
- saved_style = gtk_object_get_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id);
+ saved_style = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_saved_default_style);
if (saved_style)
{
gtk_style_unref (saved_style);
- gtk_object_remove_data_by_id (GTK_OBJECT (widget), saved_default_style_key_id);
+ gtk_object_remove_data_by_id (GTK_OBJECT (widget), quark_saved_default_style);
}
gtk_style_unref (widget->style);
@@ -4680,15 +4657,15 @@ gtk_widget_finalize (GObject *object)
if (widget->name)
g_free (widget->name);
- aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), aux_info_key_id);
+ aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
if (aux_info)
gtk_widget_aux_info_destroy (aux_info);
- events = gtk_object_get_data_by_id (GTK_OBJECT (widget), event_key_id);
+ events = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_event_mask);
if (events)
g_free (events);
- mode = gtk_object_get_data_by_id (GTK_OBJECT (widget), extension_event_key_id);
+ mode = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_extension_event_mode);
if (mode)
g_free (mode);
@@ -4997,15 +4974,15 @@ gtk_widget_shape_combine_mask (GtkWidget *widget,
if (widget->window)
gdk_window_shape_combine_mask (widget->window, NULL, 0, 0);
- gtk_object_remove_data (GTK_OBJECT (widget), shape_info_key);
+ g_object_set_qdata (G_OBJECT (widget), quark_shape_info, NULL);
}
else
{
GTK_PRIVATE_SET_FLAG (widget, GTK_HAS_SHAPE_MASK);
shape_info = g_new (GtkWidgetShapeInfo, 1);
- gtk_object_set_data_full (GTK_OBJECT (widget), shape_info_key, shape_info,
- (GDestroyNotify)gtk_widget_shape_info_destroy);
+ g_object_set_qdata_full (G_OBJECT (widget), quark_shape_info, shape_info,
+ (GDestroyNotify) gtk_widget_shape_info_destroy);
shape_info->shape_mask = gdk_drawable_ref (shape_mask);
shape_info->offset_x = offset_x;
@@ -5081,6 +5058,150 @@ gtk_widget_unref (GtkWidget *widget)
g_object_unref ((GObject*) widget);
}
+
+/* style properties
+ */
+
+void
+gtk_widget_class_install_style_property_parser (GtkWidgetClass *class,
+ GParamSpec *pspec,
+ GtkRcPropertyParser parser)
+{
+ g_return_if_fail (GTK_IS_WIDGET_CLASS (class));
+ g_return_if_fail (G_IS_PARAM_SPEC (pspec));
+ g_return_if_fail (pspec->flags & G_PARAM_READABLE);
+ g_return_if_fail (!(pspec->flags & (G_PARAM_CONSTRUCT_ONLY | G_PARAM_CONSTRUCT)));
+
+ if (g_param_spec_pool_lookup (style_property_spec_pool, pspec->name, G_OBJECT_CLASS_TYPE (class), FALSE))
+ {
+ g_warning (G_STRLOC ": class `%s' already contains a style property named `%s'",
+ G_OBJECT_CLASS_NAME (class),
+ pspec->name);
+ return;
+ }
+
+ g_param_spec_ref (pspec);
+ g_param_spec_sink (pspec);
+ g_param_spec_set_qdata (pspec, quark_property_parser, parser);
+ g_param_spec_pool_insert (style_property_spec_pool, pspec, G_OBJECT_CLASS_TYPE (class));
+}
+
+void
+gtk_widget_class_install_style_property (GtkWidgetClass *class,
+ GParamSpec *pspec)
+{
+ gtk_widget_class_install_style_property_parser (class, pspec, NULL);
+}
+
+void
+gtk_widget_style_get_property (GtkWidget *widget,
+ const gchar *property_name,
+ GValue *value)
+{
+ GParamSpec *pspec;
+
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_return_if_fail (property_name != NULL);
+ g_return_if_fail (G_IS_VALUE (value));
+
+ g_object_ref (widget);
+ pspec = g_param_spec_pool_lookup (style_property_spec_pool,
+ property_name,
+ G_OBJECT_TYPE (widget),
+ TRUE);
+ if (!pspec)
+ g_warning ("%s: widget class `%s' has no property named `%s'",
+ G_STRLOC,
+ G_OBJECT_TYPE_NAME (widget),
+ property_name);
+ else
+ {
+ const GValue *peek_value;
+
+ peek_value = _gtk_style_peek_property_value (widget->style,
+ G_OBJECT_TYPE (widget),
+ pspec,
+ g_param_spec_get_qdata (pspec, quark_property_parser));
+
+ /* auto-conversion of the caller's value type
+ */
+ if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec))
+ g_value_copy (peek_value, value);
+ else if (g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value)))
+ g_value_transform (peek_value, value);
+ else
+ g_warning ("can't retrive style property `%s' of type `%s' as value of type `%s'",
+ pspec->name,
+ g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
+ G_VALUE_TYPE_NAME (value));
+ }
+ g_object_unref (widget);
+}
+
+void
+gtk_widget_style_get_valist (GtkWidget *widget,
+ const gchar *first_property_name,
+ va_list var_args)
+{
+ const gchar *name;
+
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+
+ g_object_ref (widget);
+
+ name = first_property_name;
+ while (name)
+ {
+ const GValue *peek_value;
+ GParamSpec *pspec;
+ gchar *error;
+
+ pspec = g_param_spec_pool_lookup (style_property_spec_pool,
+ name,
+ G_OBJECT_TYPE (widget),
+ TRUE);
+ if (!pspec)
+ {
+ g_warning ("%s: widget class `%s' has no property named `%s'",
+ G_STRLOC,
+ G_OBJECT_TYPE_NAME (widget),
+ name);
+ break;
+ }
+ /* style pspecs are always readable so we can spare that check here */
+
+ peek_value = _gtk_style_peek_property_value (widget->style,
+ G_OBJECT_TYPE (widget),
+ pspec,
+ g_param_spec_get_qdata (pspec, quark_property_parser));
+ G_VALUE_LCOPY (peek_value, var_args, G_VALUE_NOCOPY_CONTENTS, &error);
+ if (error)
+ {
+ g_warning ("%s: %s", G_STRLOC, error);
+ g_free (error);
+ break;
+ }
+
+ name = va_arg (var_args, gchar*);
+ }
+
+ g_object_unref (widget);
+}
+
+void
+gtk_widget_style_get (GtkWidget *widget,
+ const gchar *first_property_name,
+ ...)
+{
+ va_list var_args;
+
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+
+ va_start (var_args, first_property_name);
+ gtk_widget_style_get_valist (widget, first_property_name, var_args);
+ va_end (var_args);
+}
+
/**
* gtk_widget_path:
* @widget: a #GtkWidget
diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h
index 9feeb52779..3b475e410e 100644
--- a/gtk/gtkwidget.h
+++ b/gtk/gtkwidget.h
@@ -119,18 +119,18 @@ typedef enum
*/
#define GTK_WIDGET_SET_FLAGS(wid,flag) G_STMT_START{ (GTK_WIDGET_FLAGS (wid) |= (flag)); }G_STMT_END
#define GTK_WIDGET_UNSET_FLAGS(wid,flag) G_STMT_START{ (GTK_WIDGET_FLAGS (wid) &= ~(flag)); }G_STMT_END
-
-
-
-typedef struct _GtkRequisition GtkRequisition;
-typedef struct _GdkRectangle GtkAllocation;
-typedef struct _GtkSelectionData GtkSelectionData;
-typedef struct _GtkWidgetClass GtkWidgetClass;
-typedef struct _GtkWidgetAuxInfo GtkWidgetAuxInfo;
-typedef struct _GtkWidgetShapeInfo GtkWidgetShapeInfo;
-typedef void (*GtkCallback) (GtkWidget *widget,
- gpointer data);
+
+/* forward declaration to avoid excessive includes (and concurrent includes)
+ */
+typedef struct _GtkRequisition GtkRequisition;
+typedef struct _GdkRectangle GtkAllocation;
+typedef struct _GtkSelectionData GtkSelectionData;
+typedef struct _GtkWidgetClass GtkWidgetClass;
+typedef struct _GtkWidgetAuxInfo GtkWidgetAuxInfo;
+typedef struct _GtkWidgetShapeInfo GtkWidgetShapeInfo;
+typedef void (*GtkCallback) (GtkWidget *widget,
+ gpointer data);
/* A requisition is a desired amount of space which a
* widget may request.
@@ -604,6 +604,24 @@ void gtk_widget_pop_composite_child (void);
void gtk_widget_pop_style (void);
void gtk_widget_pop_colormap (void);
+/* widget style properties
+ */
+void gtk_widget_class_install_style_property (GtkWidgetClass *class,
+ GParamSpec *pspec);
+void gtk_widget_class_install_style_property_parser (GtkWidgetClass *class,
+ GParamSpec *pspec,
+ GtkRcPropertyParser parser);
+void gtk_widget_style_get_property (GtkWidget *widget,
+ const gchar *property_name,
+ GValue *value);
+void gtk_widget_style_get_valist (GtkWidget *widget,
+ const gchar *first_property_name,
+ va_list var_args);
+void gtk_widget_style_get (GtkWidget *widget,
+ const gchar *first_property_name,
+ ...);
+
+
/* Set certain default values to be used at widget creation time.
*/
void gtk_widget_set_default_style (GtkStyle *style);
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index c4921975e6..989e7b9130 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -1373,7 +1373,7 @@ gtk_window_finalize (GObject *object)
g_free (window->wmclass_name);
g_free (window->wmclass_class);
- G_OBJECT_CLASS(parent_class)->finalize (object);
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
diff --git a/gtk/testgtkrc b/gtk/testgtkrc
index 30fb41d861..4abd0853d1 100644
--- a/gtk/testgtkrc
+++ b/gtk/testgtkrc
@@ -22,14 +22,27 @@ include "testgtkrc2"
# On Windows, if you have installed gtk-engines, try this for instance:
#include "\\windows\\gtk\\themes\\Pixmap\\gtk\\gtkrc"
-#foo_number = 5
-#mouse_timeout = -7
+double-click_timeout = 42
+bell-duration = 39
+bell_duration = 40
pixmap_path "."
+style "global-style-properties"
+{
+# xthickness = 20
+ GtkSpinButton::shadow_type = etched-out
+}
+class "GtkWidget" style "global-style-properties"
+
style "defaultfont"
{
font_name = "Sans 12"
+
+ Gtest::foo = 47
+ Gtest::bar = 47
+# GtkScrollbar::spacing = 33
+# GtkButton::color = { 3, 2,45, 6, 6, 4, 23 }
}
style "myicons"
diff --git a/tests/testgtkrc b/tests/testgtkrc
index 30fb41d861..4abd0853d1 100644
--- a/tests/testgtkrc
+++ b/tests/testgtkrc
@@ -22,14 +22,27 @@ include "testgtkrc2"
# On Windows, if you have installed gtk-engines, try this for instance:
#include "\\windows\\gtk\\themes\\Pixmap\\gtk\\gtkrc"
-#foo_number = 5
-#mouse_timeout = -7
+double-click_timeout = 42
+bell-duration = 39
+bell_duration = 40
pixmap_path "."
+style "global-style-properties"
+{
+# xthickness = 20
+ GtkSpinButton::shadow_type = etched-out
+}
+class "GtkWidget" style "global-style-properties"
+
style "defaultfont"
{
font_name = "Sans 12"
+
+ Gtest::foo = 47
+ Gtest::bar = 47
+# GtkScrollbar::spacing = 33
+# GtkButton::color = { 3, 2,45, 6, 6, 4, 23 }
}
style "myicons"