got rid of g_set_error_handler(), g_set_warning_handler(),
authorTim Janik <timj@gtk.org>
Mon, 10 Sep 2001 18:03:31 +0000 (18:03 +0000)
committerTim Janik <timj@src.gnome.org>
Mon, 10 Sep 2001 18:03:31 +0000 (18:03 +0000)
Mon Sep 10 17:13:36 2001  Tim Janik  <timj@gtk.org>

        * glib/gmessages.h: got rid of g_set_error_handler(),
        g_set_warning_handler(), g_set_message_handler().

Wed Sep  5 05:24:07 2001  Tim Janik  <timj@gtk.org>

        * gobject/tmpl/gboxed.sgml: documented some functions.

        * gobject/tmpl/objects.sgml: some fixups.

Mon Sep 10 19:27:47 2001  Tim Janik  <timj@gtk.org>

        * gtype.[hc]:
        g_type_add_interface*(): implement the ability to add an interface to
        a type whose parents already conform to this interface.
        such "overriding" interfaces, when initialized, are not just initialized
        with 0, but with a copy of the interface they override.
        g_type_interface_peek_parent(): new function, return the interface
        that this interface "overrides", if any.

        * testgruntime.c: test new interface stuff.

27 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-12
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
docs/Changes-2.0.txt
docs/reference/ChangeLog
docs/reference/glib/glib-sections.txt
docs/reference/glib/tmpl/glib-unused.sgml
docs/reference/glib/tmpl/messages.sgml
docs/reference/gobject/gobject-sections.txt
docs/reference/gobject/tmpl/enumerations_flags.sgml
docs/reference/gobject/tmpl/gboxed.sgml
docs/reference/gobject/tmpl/gobject-unused.sgml
docs/reference/gobject/tmpl/objects.sgml
docs/reference/gobject/tmpl/value_arrays.sgml
glib/giochannel.h
glib/gmessages.c
glib/gmessages.h
gobject/ChangeLog
gobject/gtype.c
gobject/gtype.h
gobject/testgobject.c
gobject/testgruntime.c

index 1c9d807..f63874a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,9 +1,7 @@
-2001-09-10  Alex Larsson  <alexl@redhat.com>
+Mon Sep 10 17:13:36 2001  Tim Janik  <timj@gtk.org>
 
-       * gobject/gboxed.[ch]:
-       * gobject/gsourceclosure.c:
-       Removed is_refcounted and GBoxedInitFunc from
-       g_boxed_type_register_static().
+       * glib/gmessages.h: got rid of g_set_error_handler(),
+       g_set_warning_handler(), g_set_message_handler().
 
 Mon Sep 10 11:42:58 2001  Owen Taylor  <otaylor@redhat.com>
 
index 1c9d807..f63874a 100644 (file)
@@ -1,9 +1,7 @@
-2001-09-10  Alex Larsson  <alexl@redhat.com>
+Mon Sep 10 17:13:36 2001  Tim Janik  <timj@gtk.org>
 
-       * gobject/gboxed.[ch]:
-       * gobject/gsourceclosure.c:
-       Removed is_refcounted and GBoxedInitFunc from
-       g_boxed_type_register_static().
+       * glib/gmessages.h: got rid of g_set_error_handler(),
+       g_set_warning_handler(), g_set_message_handler().
 
 Mon Sep 10 11:42:58 2001  Owen Taylor  <otaylor@redhat.com>
 
index 1c9d807..f63874a 100644 (file)
@@ -1,9 +1,7 @@
-2001-09-10  Alex Larsson  <alexl@redhat.com>
+Mon Sep 10 17:13:36 2001  Tim Janik  <timj@gtk.org>
 
-       * gobject/gboxed.[ch]:
-       * gobject/gsourceclosure.c:
-       Removed is_refcounted and GBoxedInitFunc from
-       g_boxed_type_register_static().
+       * glib/gmessages.h: got rid of g_set_error_handler(),
+       g_set_warning_handler(), g_set_message_handler().
 
 Mon Sep 10 11:42:58 2001  Owen Taylor  <otaylor@redhat.com>
 
index 1c9d807..f63874a 100644 (file)
@@ -1,9 +1,7 @@
-2001-09-10  Alex Larsson  <alexl@redhat.com>
+Mon Sep 10 17:13:36 2001  Tim Janik  <timj@gtk.org>
 
-       * gobject/gboxed.[ch]:
-       * gobject/gsourceclosure.c:
-       Removed is_refcounted and GBoxedInitFunc from
-       g_boxed_type_register_static().
+       * glib/gmessages.h: got rid of g_set_error_handler(),
+       g_set_warning_handler(), g_set_message_handler().
 
 Mon Sep 10 11:42:58 2001  Owen Taylor  <otaylor@redhat.com>
 
index 1c9d807..f63874a 100644 (file)
@@ -1,9 +1,7 @@
-2001-09-10  Alex Larsson  <alexl@redhat.com>
+Mon Sep 10 17:13:36 2001  Tim Janik  <timj@gtk.org>
 
-       * gobject/gboxed.[ch]:
-       * gobject/gsourceclosure.c:
-       Removed is_refcounted and GBoxedInitFunc from
-       g_boxed_type_register_static().
+       * glib/gmessages.h: got rid of g_set_error_handler(),
+       g_set_warning_handler(), g_set_message_handler().
 
 Mon Sep 10 11:42:58 2001  Owen Taylor  <otaylor@redhat.com>
 
index 1c9d807..f63874a 100644 (file)
@@ -1,9 +1,7 @@
-2001-09-10  Alex Larsson  <alexl@redhat.com>
+Mon Sep 10 17:13:36 2001  Tim Janik  <timj@gtk.org>
 
-       * gobject/gboxed.[ch]:
-       * gobject/gsourceclosure.c:
-       Removed is_refcounted and GBoxedInitFunc from
-       g_boxed_type_register_static().
+       * glib/gmessages.h: got rid of g_set_error_handler(),
+       g_set_warning_handler(), g_set_message_handler().
 
 Mon Sep 10 11:42:58 2001  Owen Taylor  <otaylor@redhat.com>
 
index 1c9d807..f63874a 100644 (file)
@@ -1,9 +1,7 @@
-2001-09-10  Alex Larsson  <alexl@redhat.com>
+Mon Sep 10 17:13:36 2001  Tim Janik  <timj@gtk.org>
 
-       * gobject/gboxed.[ch]:
-       * gobject/gsourceclosure.c:
-       Removed is_refcounted and GBoxedInitFunc from
-       g_boxed_type_register_static().
+       * glib/gmessages.h: got rid of g_set_error_handler(),
+       g_set_warning_handler(), g_set_message_handler().
 
 Mon Sep 10 11:42:58 2001  Owen Taylor  <otaylor@redhat.com>
 
index 1c9d807..f63874a 100644 (file)
@@ -1,9 +1,7 @@
-2001-09-10  Alex Larsson  <alexl@redhat.com>
+Mon Sep 10 17:13:36 2001  Tim Janik  <timj@gtk.org>
 
-       * gobject/gboxed.[ch]:
-       * gobject/gsourceclosure.c:
-       Removed is_refcounted and GBoxedInitFunc from
-       g_boxed_type_register_static().
+       * glib/gmessages.h: got rid of g_set_error_handler(),
+       g_set_warning_handler(), g_set_message_handler().
 
 Mon Sep 10 11:42:58 2001  Owen Taylor  <otaylor@redhat.com>
 
index 28b8889..e670ea4 100644 (file)
@@ -40,3 +40,8 @@
     @max_tokens + 1
 
   Code depending on either of these bugs will need to be fixed.
+
+* deprecated functions that got removed:
+  g_set_error_handler(), g_set_warning_handler(),
+  g_set_message_handler(), use g_log_set_handler() instead.
+  
index f1e00a2..6e3102f 100644 (file)
@@ -1,3 +1,9 @@
+Wed Sep  5 05:24:07 2001  Tim Janik  <timj@gtk.org>
+
+       * gobject/tmpl/gboxed.sgml: documented some functions.
+
+       * gobject/tmpl/objects.sgml: some fixups.
+
 Mon Sep 10 11:37:02 2001  Owen Taylor  <otaylor@redhat.com>
 
        * glib/glib-sections.txt: Update.
index 441bbd4..3350d6f 100644 (file)
@@ -777,14 +777,6 @@ g_log_set_always_fatal
 g_log_set_fatal_mask
 g_log_default_handler
 
-<SUBSECTION>
-g_set_error_handler
-GErrorFunc
-g_set_warning_handler
-GWarningFunc
-g_set_message_handler
-</SECTION>
-
 <SECTION>
 <TITLE>Timers</TITLE>
 <FILE>timers</FILE>
index 3a95820..1314294 100644 (file)
@@ -1,3 +1,29 @@
+<!-- ##### SECTION ./tmpl/messages.sgml:Long_Description ##### -->
+<para>
+These functions provide support for logging error messages or messages
+used for debugging.
+</para>
+
+<para>
+There are several built-in levels of messages, defined in #GLogLevelFlags.
+These can be extended with user-defined levels.
+</para>
+
+
+<!-- ##### SECTION ./tmpl/messages.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/messages.sgml:Short_Description ##### -->
+versatile support for logging messages with different levels of importance.
+
+
+<!-- ##### SECTION ./tmpl/messages.sgml:Title ##### -->
+Message Logging
+
+
 <!-- ##### ENUM GChannelError ##### -->
 <para>
 
 @s2: 
 @Returns: 
 
+<!-- ##### USER_FUNCTION GErrorFunc ##### -->
+<para>
+Specifies the type of function passed to g_set_error_handler().
+</para>
+
+@str: the error message.
+
 <!-- ##### USER_FUNCTION GHookFreeFunc ##### -->
 <para>
 
 @G_IO_FILE_MODE_READ_WRITE_TRUNCATE: 
 @G_IO_FILE_MODE_READ_WRITE_APPEND: 
 
+<!-- ##### USER_FUNCTION GWarningFunc ##### -->
+<para>
+Specifies the type of function passed to g_set_warning_handler().
+</para>
+
+@str: the warning message.
+
 <!-- ##### MACRO G_CHANNEL_ERROR ##### -->
 <para>
 
@@ -223,6 +263,33 @@ documentation.
 @filename: the file name.
 @Returns: the file attributes.
 
+<!-- ##### FUNCTION g_set_error_handler ##### -->
+<para>
+Sets the function to be called to handle error messages.
+This function is deprecated in favour of the new logging facilities.
+</para>
+
+@func: the function to be called to handle error messages.
+@Returns: the old error handler.
+
+<!-- ##### FUNCTION g_set_message_handler ##### -->
+<para>
+Sets the function to be called to handle messages.
+This function is deprecated in favour of the new logging facilities.
+</para>
+
+@func: the function to be called to handle normal messages.
+@Returns: the old message handler.
+
+<!-- ##### FUNCTION g_set_warning_handler ##### -->
+<para>
+Sets the function to be called to handle warning messages.
+This function is deprecated in favour of the new logging facilities.
+</para>
+
+@func: the function to be called to handle warning messages.
+@Returns: the old warning handler.
+
 <!-- ##### FUNCTION g_source_add ##### -->
 <para>
 </para>
index f88fb80..8ebe23e 100644 (file)
@@ -242,49 +242,3 @@ stderr is used for levels %G_LOG_LEVEL_ERROR, %G_LOG_LEVEL_CRITICAL, and
 @unused_data: data passed from g_log which is unused.
 
 
-<!-- ##### FUNCTION g_set_error_handler ##### -->
-<para>
-Sets the function to be called to handle error messages.
-This function is deprecated in favour of the new logging facilities.
-</para>
-
-@func: the function to be called to handle error messages.
-@Returns: the old error handler.
-
-
-<!-- ##### USER_FUNCTION GErrorFunc ##### -->
-<para>
-Specifies the type of function passed to g_set_error_handler().
-</para>
-
-@str: the error message.
-
-
-<!-- ##### FUNCTION g_set_warning_handler ##### -->
-<para>
-Sets the function to be called to handle warning messages.
-This function is deprecated in favour of the new logging facilities.
-</para>
-
-@func: the function to be called to handle warning messages.
-@Returns: the old warning handler.
-
-
-<!-- ##### USER_FUNCTION GWarningFunc ##### -->
-<para>
-Specifies the type of function passed to g_set_warning_handler().
-</para>
-
-@str: the warning message.
-
-
-<!-- ##### FUNCTION g_set_message_handler ##### -->
-<para>
-Sets the function to be called to handle messages.
-This function is deprecated in favour of the new logging facilities.
-</para>
-
-@func: the function to be called to handle normal messages.
-@Returns: the old message handler.
-
-
index 621aa75..6567f45 100644 (file)
@@ -234,6 +234,7 @@ g_flags_complete_type_info
 <FILE>gboxed</FILE>
 <TITLE>Boxed Types</TITLE>
 GBoxed
+GBoxedInitFunc
 GBoxedCopyFunc
 GBoxedFreeFunc
 g_boxed_copy
index c72b7d3..8c91f79 100644 (file)
@@ -1,12 +1,11 @@
 <!-- ##### SECTION Title ##### -->
-Enumeration and Flag Types
+Enums and Flags
 
 <!-- ##### SECTION Short_Description ##### -->
-
+Enumeration and flags types.
 
 <!-- ##### SECTION Long_Description ##### -->
 <para>
-
 </para>
 
 <!-- ##### SECTION See_Also ##### -->
index 87183cb..1e6b288 100644 (file)
@@ -1,8 +1,8 @@
 <!-- ##### SECTION Title ##### -->
-gboxed
+GBoxed
 
 <!-- ##### SECTION Short_Description ##### -->
-
+Mechanism to wrap opaque C structures registered by the type system.
 
 <!-- ##### SECTION Long_Description ##### -->
 <para>
@@ -11,52 +11,55 @@ gboxed
 
 <!-- ##### SECTION See_Also ##### -->
 <para>
-
+#GParamSpecBoxed, g_param_spec_boxed()
 </para>
 
 <!-- ##### USER_FUNCTION GBoxedCopyFunc ##### -->
 <para>
-
+This function is provided by the user and should produce a copy of the passed
+in boxed structure.
 </para>
 
-@boxed: 
-@Returns: 
+@boxed:   The boxed structure to be copied.
+@Returns: The newly created copy of the boxed structure.
 
 
 <!-- ##### USER_FUNCTION GBoxedFreeFunc ##### -->
 <para>
-
+This function is provided by the user and should free the boxed
+structure passed.
 </para>
 
-@boxed: 
+@boxed: The boxed structure to be freed.
 
 
 <!-- ##### FUNCTION g_boxed_copy ##### -->
 <para>
-
+Provide a copy of a boxed structure @src_boxed which is of type @boxed_type.
 </para>
 
-@boxed_type: 
-@src_boxed: 
-@Returns: 
+@boxed_type: The type of @src_boxed.
+@src_boxed:  The boxed structure to be copied.
+@Returns:    The newly created copy of the boxed structure.
 
 
 <!-- ##### FUNCTION g_boxed_free ##### -->
 <para>
-
+Free the boxed structure @boxed which is of type @boxed_type.
 </para>
 
-@boxed_type: 
-@boxed: 
+@boxed_type: The type of @boxed.
+@boxed:      The boxed structure to be freed.
 
 
 <!-- ##### FUNCTION g_value_set_boxed ##### -->
 <para>
-
+Assign a #GValue which is initialized with a certain boxed type a
+boxed structure of that very same type.
 </para>
 
-@value: 
-@boxed: 
+@value: The #GValue to be assigned a value to.
+@boxed: The boxed structure which has to be of the same type the #GValue got initialized with.
 
 
 <!-- ##### FUNCTION g_value_set_static_boxed ##### -->
@@ -97,14 +100,17 @@ This is an internal function introduced mainly for C marshallers.
 
 <!-- ##### FUNCTION g_boxed_type_register_static ##### -->
 <para>
-
+This function creates a new %G_TYPE_BOXED derived type id for a new
+boxed type with name @name. Boxed type handling functions have to be
+provided to copy and free opaque boxed structures of this type.
 </para>
 
-@name: 
+@name: Name of the new boxed type.
+@boxed_copy: Boxed structure copy function.
+@boxed_free: Boxed structure free function.
+@Returns: New %G_TYPE_BOXED derived type id for @name.
+<!-- # Unused Parameters # -->
 @boxed_init: 
-@boxed_copy: 
-@boxed_free: 
 @is_refcounted: 
-@Returns: 
 
 
index 0135927..7181f37 100644 (file)
@@ -4,6 +4,13 @@
 </para>
 
 
+<!-- ##### USER_FUNCTION GBoxedInitFunc ##### -->
+<para>
+
+</para>
+
+@Returns: 
+
 <!-- ##### FUNCTION g_closure_add_fnotify ##### -->
 <para>
 
index bcd3eef..904910f 100644 (file)
@@ -1,8 +1,8 @@
 <!-- ##### SECTION Title ##### -->
-The Base Object Type
+GObject
 
 <!-- ##### SECTION Short_Description ##### -->
-
+The base object type.
 
 <!-- ##### SECTION Long_Description ##### -->
 <para>
@@ -16,7 +16,8 @@ The Base Object Type
 
 <!-- ##### STRUCT GObject ##### -->
 <para>
-
+All the fields in the GObject structure are private to the #GObject implementation
+and should never be accessed directly.
 </para>
 
 @g_type_instance: 
@@ -71,26 +72,30 @@ The Base Object Type
 
 <!-- ##### MACRO G_TYPE_IS_OBJECT ##### -->
 <para>
-
+Return a boolean value of %FALSE or %TRUE indicating whether
+the passed in type id is a %G_TYPE_OBJECT or derived from it.
 </para>
 
-@type: 
+@type: Type id to check for is a %G_TYPE_OBJECT relationship.
+@Returns: %FALSE or %TRUE, indicating whether @type is a %G_TYPE_OBJECT.
 
 
 <!-- ##### MACRO G_OBJECT ##### -->
 <para>
-
+Cast a #GObject or derived pointer into a (GObject*) pointer.
+Depending on the current debugging level, this function may invoke
+certain runtime checks to identify invalid casts.
 </para>
 
-@object: 
+@object: Object which is subject to casting.
 
 
 <!-- ##### MACRO G_IS_OBJECT ##### -->
 <para>
-
+Check whether a valid #GTypeInstance pointer is of type %G_TYPE_OBJECT.
 </para>
 
-@object: 
+@object: Instance to check for being a %G_TYPE_OBJECT.
 
 
 <!-- ##### MACRO G_OBJECT_CLASS ##### -->
@@ -119,10 +124,11 @@ The Base Object Type
 
 <!-- ##### MACRO G_OBJECT_TYPE ##### -->
 <para>
-
+Return the type id of an object.
 </para>
 
-@object: 
+@object: Object to return the type id for.
+@Returns: Type id of @object.
 
 
 <!-- ##### MACRO G_OBJECT_TYPE_NAME ##### -->
@@ -256,8 +262,8 @@ lifetime of @object. When the @object is finalized, @weak_pointer will
 be set to %NULL.
 </para>
 
-@object: the object that should be weak referenced.
-@weak_pointer_location: the memory address of a pointer.
+@object: The object that should be weak referenced.
+@weak_pointer_location: The memory address of a pointer.
 
 
 <!-- ##### FUNCTION g_object_remove_weak_pointer ##### -->
@@ -267,8 +273,8 @@ using g_object_add_weak_pointer(). The @weak_pointer_location has
 to match the one used with g_object_add_weak_pointer().
 </para>
 
-@object: the object that is weak referenced.
-@weak_pointer_location: the memory address of a pointer.
+@object: The object that is weak referenced.
+@weak_pointer_location: The memory address of a pointer.
 
 
 <!-- ##### FUNCTION g_object_connect ##### -->
@@ -302,8 +308,6 @@ to match the one used with g_object_add_weak_pointer().
 @first_property_name: 
 @Varargs: 
 @Returns: 
-<!-- # Unused Parameters # -->
-@first_param_name: 
 
 
 <!-- ##### FUNCTION g_object_get ##### -->
@@ -314,8 +318,6 @@ to match the one used with g_object_add_weak_pointer().
 @object: 
 @first_property_name: 
 @Varargs: 
-<!-- # Unused Parameters # -->
-@first_param_name: 
 
 
 <!-- ##### FUNCTION g_object_notify ##### -->
@@ -454,8 +456,6 @@ to match the one used with g_object_add_weak_pointer().
 @first_property_name: 
 @var_args: 
 @Returns: 
-<!-- # Unused Parameters # -->
-@first_param_name: 
 
 
 <!-- ##### FUNCTION g_object_set_valist ##### -->
@@ -466,8 +466,6 @@ to match the one used with g_object_add_weak_pointer().
 @object: 
 @first_property_name: 
 @var_args: 
-<!-- # Unused Parameters # -->
-@first_param_name: 
 
 
 <!-- ##### FUNCTION g_object_get_valist ##### -->
@@ -478,8 +476,6 @@ to match the one used with g_object_add_weak_pointer().
 @object: 
 @first_property_name: 
 @var_args: 
-<!-- # Unused Parameters # -->
-@first_param_name: 
 
 
 <!-- ##### FUNCTION g_object_watch_closure ##### -->
index 1c77eaa..a1d9f8d 100644 (file)
@@ -13,7 +13,7 @@ in order for it to be used as a boxed type through %G_TYPE_VALUE_ARRAY.
 
 <!-- ##### SECTION See_Also ##### -->
 <para>
-#GValue, #GParamSpecValueArray
+#GValue, #GParamSpecValueArray, g_param_spec_value_array()
 </para>
 
 <!-- ##### STRUCT GValueArray ##### -->
index be6b8aa..89b327d 100644 (file)
@@ -98,7 +98,7 @@ typedef enum
   G_IO_FLAG_IS_SEEKABLE = 1 << 4,      /* Read only flag */
   G_IO_FLAG_MASK = (1 << 5) - 1,
   G_IO_FLAG_GET_MASK = G_IO_FLAG_MASK,
-  G_IO_FLAG_SET_MASK = G_IO_FLAG_APPEND | G_IO_FLAG_NONBLOCK,
+  G_IO_FLAG_SET_MASK = G_IO_FLAG_APPEND | G_IO_FLAG_NONBLOCK
 } GIOFlags;
 
 struct _GIOChannel
index 11d0c34..5c76179 100644 (file)
@@ -85,9 +85,6 @@ static GLogDomain    *g_log_domains = NULL;
 static GLogLevelFlags g_log_always_fatal = G_LOG_FATAL_MASK;
 static GPrintFunc     glib_print_func = NULL;
 static GPrintFunc     glib_printerr_func = NULL;
-static GErrorFunc     glib_error_func = NULL;
-static GWarningFunc   glib_warning_func = NULL;
-static GPrintFunc     glib_message_func = NULL;
 
 static GPrivate* g_log_depth = NULL;
 
@@ -581,9 +578,6 @@ g_log_default_handler (const gchar    *log_domain,
   GFileDescriptor fd;
   gboolean in_recursion;
   gboolean is_fatal;  
-  GErrorFunc local_glib_error_func;
-  GWarningFunc local_glib_warning_func;
-  GPrintFunc local_glib_message_func;
   
   in_recursion = (log_level & G_LOG_FLAG_RECURSION) != 0;
   is_fatal = (log_level & G_LOG_FLAG_FATAL) != 0;
@@ -602,21 +596,9 @@ g_log_default_handler (const gchar    *log_domain,
   fd = (log_level > G_LOG_LEVEL_MESSAGE) ? 1 : 2;
 #endif
   
-  g_mutex_lock (g_messages_lock);
-  local_glib_error_func = glib_error_func;
-  local_glib_warning_func = glib_warning_func;
-  local_glib_message_func = glib_message_func;
-  g_mutex_unlock (g_messages_lock);
-
   switch (log_level)
     {
     case G_LOG_LEVEL_ERROR:
-      if (!log_domain && local_glib_error_func)
-       {
-         /* compatibility code */
-         local_glib_error_func (message);  
-         return;
-       }
       /* use write(2) for output, in case we are out of memeory */
       ensure_stdout_valid ();
       write (fd, "\n", 1);
@@ -662,12 +644,6 @@ g_log_default_handler (const gchar    *log_domain,
        write (fd, "\n", 1);
       break;
     case G_LOG_LEVEL_WARNING:
-      if (!log_domain && local_glib_warning_func)
-       {
-         /* compatibility code */
-         local_glib_warning_func (message);
-         return;
-       }
       ensure_stdout_valid ();
       write (fd, "\n", 1);
       g_log_write_prefix (fd, log_level);
@@ -690,12 +666,6 @@ g_log_default_handler (const gchar    *log_domain,
        write (fd, "\n", 1);
       break;
     case G_LOG_LEVEL_MESSAGE:
-      if (!log_domain && local_glib_message_func)
-       {
-         /* compatibility code */
-         local_glib_message_func (message);
-         return;
-       }
       ensure_stdout_valid ();
 
       g_log_write_prefix (fd, log_level);
@@ -884,48 +854,6 @@ g_printerr (const gchar *format,
   g_free (string);
 }
 
-/* compatibility code */
-GErrorFunc
-g_set_error_handler (GErrorFunc func)
-{
-  GErrorFunc old_error_func;
-  
-  g_mutex_lock (g_messages_lock);
-  old_error_func = glib_error_func;
-  glib_error_func = func;
-  g_mutex_unlock (g_messages_lock);
-  return old_error_func;
-}
-
-/* compatibility code */
-GWarningFunc
-g_set_warning_handler (GWarningFunc func)
-{
-  GWarningFunc old_warning_func;
-  
-  g_mutex_lock (g_messages_lock);
-  old_warning_func = glib_warning_func;
-  glib_warning_func = func;
-  g_mutex_unlock (g_messages_lock);
-  
-  return old_warning_func;
-}
-
-/* compatibility code */
-GPrintFunc
-g_set_message_handler (GPrintFunc func)
-{
-  GPrintFunc old_message_func;
-  
-  g_mutex_lock (g_messages_lock);
-  old_message_func = glib_message_func;
-  glib_message_func = func;
-  g_mutex_unlock (g_messages_lock);
-  
-  return old_message_func;
-}
-
 #ifndef MB_LEN_MAX
 #  define MB_LEN_MAX 8
 #endif
index beedda5..9fc556f 100644 (file)
@@ -170,12 +170,6 @@ void            g_printerr              (const gchar    *format,
                                          ...) G_GNUC_PRINTF (1, 2);
 GPrintFunc      g_set_printerr_handler  (GPrintFunc      func);
 
-/* deprecated compatibility functions, use g_log_set_handler() instead */
-typedef void            (*GErrorFunc)           (const gchar *str);
-typedef void            (*GWarningFunc)         (const gchar *str);
-GErrorFunc   g_set_error_handler   (GErrorFunc   func);
-GWarningFunc g_set_warning_handler (GWarningFunc func);
-GPrintFunc   g_set_message_handler (GPrintFunc func);
 
 /* Provide macros for error handling. The "assert" macros will
  *  exit on failure. The "return" macros will exit the current
index 8e1fc00..0b0e397 100644 (file)
@@ -1,3 +1,22 @@
+Mon Sep 10 19:27:47 2001  Tim Janik  <timj@gtk.org>
+
+       * gtype.[hc]:
+       g_type_add_interface*(): implement the ability to add an interface to
+       a type whose parents already conform to this interface.
+       such "overriding" interfaces, when initialized, are not just initialized
+       with 0, but with a copy of the interface they override.
+       g_type_interface_peek_parent(): new function, return the interface
+       that this interface "overrides", if any.
+
+       * testgruntime.c: test new interface stuff.
+
+2001-09-10  Alex Larsson  <alexl@redhat.com>
+
+        * gobject/gboxed.[ch]:
+        * gobject/gsourceclosure.c:
+        Removed is_refcounted and GBoxedInitFunc from
+        g_boxed_type_register_static().
+
 Sat Sep  8 14:13:57 2001  Owen Taylor  <otaylor@redhat.com>
 
        * gobject/Makefile.am: Move gbsearcharray.[ch] to glib
index 5df44e7..af4fc46 100644 (file)
@@ -132,6 +132,8 @@ static inline gpointer                      type_get_qdata_L                (TypeNode               *node,
 static inline void                     type_set_qdata_W                (TypeNode               *node,
                                                                         GQuark                  quark,
                                                                         gpointer                data);
+static IFaceHolder*                    type_iface_peek_holder_L        (TypeNode               *iface,
+                                                                        GType                   instance_type);
 
 
 /* --- structures --- */
@@ -333,10 +335,14 @@ type_node_any_new_W (TypeNode             *pnode,
        }
       else
        {
+         guint j;
+
          CLASSED_NODE_N_IFACES (node) = CLASSED_NODE_N_IFACES (pnode);
          CLASSED_NODE_IFACES_ENTRIES (node) = g_memdup (CLASSED_NODE_IFACES_ENTRIES (pnode),
                                                         sizeof (CLASSED_NODE_IFACES_ENTRIES (pnode)[0]) *
                                                         CLASSED_NODE_N_IFACES (node));
+         for (j = 0; j < CLASSED_NODE_N_IFACES (node); j++)
+           CLASSED_NODE_IFACES_ENTRIES (node)[j].vtable = NULL;
        }
       
       i = pnode->n_children++;
@@ -778,8 +784,8 @@ check_type_info_L (TypeNode        *pnode,
 }
 
 static TypeNode*
-find_conforming_type_L (TypeNode *pnode,
-                       TypeNode *iface)
+find_conforming_child_type_L (TypeNode *pnode,
+                             TypeNode *iface)
 {
   TypeNode *node = NULL;
   guint i;
@@ -788,7 +794,7 @@ find_conforming_type_L (TypeNode *pnode,
     return pnode;
   
   for (i = 0; i < pnode->n_children && !node; i++)
-    node = find_conforming_type_L (lookup_type_node_L (pnode->children[i]), iface);
+    node = find_conforming_child_type_L (lookup_type_node_L (pnode->children[i]), iface);
   
   return node;
 }
@@ -799,6 +805,7 @@ check_add_interface_L (GType instance_type,
 {
   TypeNode *node = lookup_type_node_L (instance_type);
   TypeNode *iface = lookup_type_node_L (iface_type);
+  IFaceEntry *entry;
   TypeNode *tnode;
   
   if (!node || !node->is_instantiatable)
@@ -824,7 +831,20 @@ check_add_interface_L (GType instance_type,
                 NODE_NAME (tnode));
       return FALSE;
     }
-  tnode = find_conforming_type_L (node, iface);  // FIXME: iface overriding
+  /* allow overriding of interface type introduced for parent type */
+  entry = type_lookup_iface_entry_L (node, iface);
+  if (entry && entry->vtable == NULL && !type_iface_peek_holder_L (iface, NODE_TYPE (node)))
+    {
+      /* ok, we do conform to this interface already, but the interface vtable was not
+       * yet intialized, and we just conform to the interface because it got added to
+       * one of our parents. so we allow overriding of holder info here.
+       */
+      return TRUE;
+    }
+  /* check whether one of our children already conforms (or whether the interface
+   * got added to this node already)
+   */
+  tnode = find_conforming_child_type_L (node, iface);  /* tnode is_a node */
   if (tnode)
     {
       g_warning ("cannot add interface type `%s' to type `%s', since type `%s' already conforms to interface",
@@ -1044,9 +1064,12 @@ type_node_add_iface_entry_W (TypeNode *node,
   for (i = 0; i < CLASSED_NODE_N_IFACES (node); i++)
     if (entries[i].iface_type == iface_type)
       {
-       g_warning ("failed to add interface, type `%s' already conforms to interface type `%s'",
-                  type_descriptive_name_L (NODE_TYPE (node)),
-                  type_descriptive_name_L (iface_type));
+       /* this can (should) only happen if our parent type already conformed
+        * to iface_type and node got it's own holder info. here, our
+        * children should already have entries with NULL vtables, so
+        * we're actually done.
+        */
+       g_assert (entries[i].vtable == NULL);
        return;
       }
     else if (entries[i].iface_type > iface_type)
@@ -1206,17 +1229,27 @@ g_type_interface_add_prerequisite (GType interface_type,
 }
 
 static IFaceHolder*
-type_iface_retrive_holder_info_Wm (TypeNode *iface,
-                                  GType     instance_type)
+type_iface_peek_holder_L (TypeNode *iface,
+                         GType     instance_type)
 {
-  IFaceHolder *iholder = iface_node_get_holders_L (iface);
-  
+  IFaceHolder *iholder;
+
   g_assert (NODE_IS_IFACE (iface));
-  
-  while (iholder->instance_type != instance_type)
+
+  iholder = iface_node_get_holders_L (iface);
+  while (iholder && iholder->instance_type != instance_type)
     iholder = iholder->next;
-  
-  if (!iholder->info)
+  return iholder;
+}
+
+static IFaceHolder*
+type_iface_retrive_holder_info_Wm (TypeNode *iface,
+                                  GType     instance_type,
+                                  gboolean  need_info)
+{
+  IFaceHolder *iholder = type_iface_peek_holder_L (iface, instance_type);
+
+  if (iholder && !iholder->info && need_info)
     {
       GInterfaceInfo tmp_info;
       
@@ -1239,7 +1272,7 @@ type_iface_retrive_holder_info_Wm (TypeNode *iface,
       iholder->info = g_memdup (&tmp_info, sizeof (tmp_info));
     }
   
-  return iholder;
+  return iholder;      /* we don't modify write lock upon returning NULL */
 }
 
 static void
@@ -1372,37 +1405,33 @@ g_type_free_instance (GTypeInstance *instance)
   g_type_class_unref (class);
 }
 
-static void
-type_propagate_iface_vtable_W (TypeNode       *pnode,
-                              TypeNode       *iface,
-                              GTypeInterface *vtable)
-{
-  IFaceEntry *entry = type_lookup_iface_entry_L (pnode, iface);
-  guint i;
-  
-  entry->vtable = vtable;
-  for (i = 0; i < pnode->n_children; i++)
-    {
-      TypeNode *node = lookup_type_node_L (pnode->children[i]);
-      
-      type_propagate_iface_vtable_W (node, iface, vtable);
-    }
-}
-
-static void
+static gboolean
 type_iface_vtable_init_Wm (TypeNode *iface,
                           TypeNode *node)
 {
-#ifndef G_DISABLE_ASSERT
   IFaceEntry *entry = type_lookup_iface_entry_L (node, iface);
-#endif
-  IFaceHolder *iholder = type_iface_retrive_holder_info_Wm (iface, NODE_TYPE (node));
-  GTypeInterface *vtable;
+  IFaceHolder *iholder;
+  GTypeInterface *vtable = NULL;
+  TypeNode *pnode;
+
+  /* type_iface_retrive_holder_info_Wm() doesn't modify write lock for returning NULL */
+  iholder = type_iface_retrive_holder_info_Wm (iface, NODE_TYPE (node), TRUE);
+  if (!iholder)
+    return FALSE;      /* we don't modify write lock upon FALSE */
   
   g_assert (iface->data && entry && entry->vtable == NULL && iholder && iholder->info);
   
-  vtable = g_malloc0 (iface->data->iface.vtable_size);
-  type_propagate_iface_vtable_W (node, iface, vtable);
+  pnode = lookup_type_node_L (NODE_PARENT_TYPE (node));
+  if (pnode)   /* want to copy over parent iface contents */
+    {
+      IFaceEntry *pentry = type_lookup_iface_entry_L (pnode, iface);
+
+      if (pentry)
+       vtable = g_memdup (pentry->vtable, iface->data->iface.vtable_size);
+    }
+  if (!vtable)
+    vtable = g_malloc0 (iface->data->iface.vtable_size);
+  entry->vtable = vtable;
   vtable->g_type = NODE_TYPE (iface);
   vtable->g_instance_type = NODE_TYPE (node);
   
@@ -1415,25 +1444,25 @@ type_iface_vtable_init_Wm (TypeNode *iface,
        iholder->info->interface_init (vtable, iholder->info->interface_data);
       G_WRITE_LOCK (&type_rw_lock);
     }
+  return TRUE; /* write lock modified */
 }
 
-static void
+static gboolean
 type_iface_vtable_finalize_Wm (TypeNode       *iface,
                               TypeNode       *node,
                               GTypeInterface *vtable)
 {
-#ifndef G_DISABLE_ASSERT
   IFaceEntry *entry = type_lookup_iface_entry_L (node, iface);
-#endif
-  IFaceHolder *iholder = iface_node_get_holders_L (iface);
-  
-  g_assert (entry && entry->vtable == vtable);
+  IFaceHolder *iholder;
+
+  /* type_iface_retrive_holder_info_Wm() doesn't modify write lock for returning NULL */
+  iholder = type_iface_retrive_holder_info_Wm (iface, NODE_TYPE (node), FALSE);
+  if (!iholder)
+    return FALSE;      /* we don't modify write lock upon FALSE */
   
-  while (iholder->instance_type != NODE_TYPE (node))
-    iholder = iholder->next;
-  g_assert (iholder && iholder->info);
+  g_assert (entry && entry->vtable == vtable && iholder->info);
   
-  type_propagate_iface_vtable_W (node, iface, NULL);
+  entry->vtable = NULL;
   if (iholder->info->interface_finalize || iface->data->iface.vtable_finalize_base)
     {
       G_WRITE_UNLOCK (&type_rw_lock);
@@ -1448,6 +1477,8 @@ type_iface_vtable_finalize_Wm (TypeNode       *iface,
   g_free (vtable);
   
   type_iface_blow_holder_info_Wm (iface, NODE_TYPE (node));
+
+  return TRUE; /* write lock modified */
 }
 
 static void
@@ -1457,7 +1488,7 @@ type_class_init_Wm (TypeNode   *node,
   GSList *slist, *init_slist = NULL;
   GTypeClass *class;
   IFaceEntry *entry;
-  TypeNode *bnode;
+  TypeNode *bnode, *pnode;
   guint i;
   
   g_assert (node->is_classed && node->data &&
@@ -1498,14 +1529,38 @@ type_class_init_Wm (TypeNode   *node,
   
   G_WRITE_LOCK (&type_rw_lock);
   
-  /* ok, we got the class done, now initialize all interfaces */
-  for (entry = NULL, i = 0; i < CLASSED_NODE_N_IFACES (node); i++)
-    if (!CLASSED_NODE_IFACES_ENTRIES (node)[i].vtable)
-      entry = CLASSED_NODE_IFACES_ENTRIES (node) + i;
+  /* ok, we got the class done, now initialize all interfaces, either
+   * from parent, or through our holder info
+   */
+  pnode = lookup_type_node_L (NODE_PARENT_TYPE (node));
+  entry = CLASSED_NODE_IFACES_ENTRIES (node) + 0;
   while (entry)
     {
-      type_iface_vtable_init_Wm (lookup_type_node_L (entry->iface_type), node);
+      g_assert (entry->vtable == NULL);
       
+      if (!type_iface_vtable_init_Wm (lookup_type_node_L (entry->iface_type), node))
+       {
+         guint j;
+
+         /* type_iface_vtable_init_Wm() doesn't modify write lock upon FALSE,
+          * need to get this interface from parent
+          */
+         g_assert (pnode != NULL);
+
+         for (j = 0; j < CLASSED_NODE_N_IFACES (pnode); j++)
+           {
+             IFaceEntry *pentry = CLASSED_NODE_IFACES_ENTRIES (pnode) + j;
+
+             if (pentry->iface_type == entry->iface_type)
+               {
+                 entry->vtable = pentry->vtable;
+                 break;
+               }
+           }
+         g_assert (entry->vtable != NULL);
+       }
+
+      /* refetch entry, IFACES_ENTRIES might be modified */
       for (entry = NULL, i = 0; i < CLASSED_NODE_N_IFACES (node); i++)
        if (!CLASSED_NODE_IFACES_ENTRIES (node)[i].vtable)
          entry = CLASSED_NODE_IFACES_ENTRIES (node) + i;
@@ -1530,8 +1585,15 @@ type_data_finalize_class_ifaces_Wm (TypeNode *node)
       entry = CLASSED_NODE_IFACES_ENTRIES (node) + i;
   while (entry)
     {
-      type_iface_vtable_finalize_Wm (lookup_type_node_L (entry->iface_type), node, entry->vtable);
+      if (!type_iface_vtable_finalize_Wm (lookup_type_node_L (entry->iface_type), node, entry->vtable))
+       {
+         /* type_iface_vtable_finalize_Wm() doesn't modify write lock upon FALSE,
+          * iface vtable came from parent
+          */
+         entry->vtable = NULL;
+       }
       
+      /* refetch entry, IFACES_ENTRIES might be modified */
       for (entry = NULL, i = 0; i < CLASSED_NODE_N_IFACES (node); i++)
        if (CLASSED_NODE_IFACES_ENTRIES (node)[i].vtable &&
            CLASSED_NODE_IFACES_ENTRIES (node)[i].vtable->g_instance_type == NODE_TYPE (node))
@@ -1835,7 +1897,14 @@ g_type_add_interface_static (GType                 instance_type,
       TypeNode *iface = lookup_type_node_L (interface_type);
       
       if (check_interface_info_L (iface, NODE_TYPE (node), info))
-       type_add_interface_W (node, iface, info, NULL);
+       {
+         type_add_interface_W (node, iface, info, NULL);
+         /* if we have a class already, the interface vtable needs to
+          * be initialized as well
+          */
+         if (node->data && node->data->class.class)
+           type_iface_vtable_init_Wm (iface, node);
+       }
     }
   G_WRITE_UNLOCK (&type_rw_lock);
 }
@@ -1863,6 +1932,11 @@ g_type_add_interface_dynamic (GType        instance_type,
       TypeNode *iface = lookup_type_node_L (interface_type);
       
       type_add_interface_W (node, iface, NULL, plugin);
+      /* if we have a class already, the interface vtable needs to
+       * be initialized as well
+       */
+      if (node->data && node->data->class.class)
+       type_iface_vtable_init_Wm (iface, node);
     }
   G_WRITE_UNLOCK (&type_rw_lock);
 }
@@ -1978,7 +2052,7 @@ gpointer
 g_type_class_peek_parent (gpointer g_class)
 {
   TypeNode *node;
-  gpointer class;
+  gpointer class = NULL;
   
   g_return_val_if_fail (g_class != NULL, NULL);
   
@@ -1989,8 +2063,8 @@ g_type_class_peek_parent (gpointer g_class)
       node = lookup_type_node_L (NODE_PARENT_TYPE (node));
       class = node->data->class.class;
     }
-  else
-    class = NULL;
+  else if (NODE_PARENT_TYPE (node))
+    g_warning (G_STRLOC ": invalid class pointer `%p'", g_class);
   G_READ_UNLOCK (&type_rw_lock);
   
   return class;
@@ -2017,11 +2091,42 @@ g_type_interface_peek (gpointer instance_class,
       if (entry && entry->vtable)
        vtable = entry->vtable;
     }
+  else
+    g_warning (G_STRLOC ": invalid class pointer `%p'", class);
   G_READ_UNLOCK (&type_rw_lock);
   
   return vtable;
 }
 
+gpointer
+g_type_interface_peek_parent (gpointer g_iface)
+{
+  TypeNode *node;
+  TypeNode *iface;
+  gpointer vtable = NULL;
+  GTypeInterface *iface_class = g_iface;
+
+  g_return_val_if_fail (g_iface != NULL, NULL);
+
+  G_READ_LOCK (&type_rw_lock);
+  iface = lookup_type_node_L (iface_class->g_type);
+  node = lookup_type_node_L (iface_class->g_instance_type);
+  if (node)
+    node = lookup_type_node_L (NODE_PARENT_TYPE (node));
+  if (node && node->is_instantiatable && iface)
+    {
+      IFaceEntry *entry = type_lookup_iface_entry_L (node, iface);
+
+      if (entry && entry->vtable)
+       vtable = entry->vtable;
+    }
+  else if (node)
+    g_warning (G_STRLOC ": invalid interface pointer `%p'", g_iface);
+  G_READ_UNLOCK (&type_rw_lock);
+
+  return vtable;
+}
+
 G_CONST_RETURN gchar*
 g_type_name (GType type)
 {
index 5ae806d..64f8285 100644 (file)
@@ -200,6 +200,7 @@ void                  g_type_class_unref             (gpointer         g_class);
 gpointer              g_type_class_peek_parent       (gpointer         g_class);
 gpointer              g_type_interface_peek          (gpointer         instance_class,
                                                      GType            iface_type);
+gpointer              g_type_interface_peek_parent   (gpointer         g_iface);
 
 /* g_free() the returned arrays */
 GType*                g_type_children                (GType            type,
index ef8a755..e7d5216 100644 (file)
 #define        G_LOG_DOMAIN "TestObject"
 #include       <glib-object.h>
 
-#define TEST_TYPE_OBJECT            (test_object_get_type ())
-#define TEST_OBJECT(object)         (G_TYPE_CHECK_INSTANCE_CAST ((object), TEST_TYPE_OBJECT, TestObject))
-#define TEST_OBJECT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_OBJECT, TestObjectClass))
-#define TEST_IS_OBJECT(object)      (G_TYPE_CHECK_INSTANCE_TYPE ((object), TEST_TYPE_OBJECT))
-#define TEST_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TEST_TYPE_OBJECT))
-#define TEST_OBJECT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_TYPE_OBJECT, TestObjectClass))
-
-typedef struct _TestIface TestIface;
-typedef struct
-{
-  GTypeInterface base_iface;
-} TestIfaceClass;
-typedef struct
-{
-  GObject parent_instance;
-} TestObject;
 
+/* --- TestIface --- */
 #define TEST_TYPE_IFACE           (test_iface_get_type ())
 #define TEST_IFACE(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_IFACE, TestIface))
 #define TEST_IS_IFACE(obj)       (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_IFACE))
-#define TEST_IFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), TEST_TYPE_IFACE, TestIfaceClass))
-
+#define TEST_IFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE, TestIfaceClass))
+typedef struct _TestIface      TestIface;
+typedef struct _TestIfaceClass TestIfaceClass;
+struct _TestIfaceClass
+{
+  GTypeInterface base_iface;
+  void (*print_string) (TestIface      *tiobj,
+                        const gchar    *string);
+};
+static void    iface_base_init         (TestIfaceClass *iface);
+static void    iface_base_finalize     (TestIfaceClass *iface);
+static void    print_foo               (TestIface      *tiobj,
+                                        const gchar    *string);
 GType
 test_iface_get_type (void)
 {
@@ -52,8 +48,8 @@ test_iface_get_type (void)
       static const GTypeInfo test_iface_info =
       {
        sizeof (TestIfaceClass),
-       NULL,           /* base_init */
-       NULL,           /* base_finalize */
+       (GBaseInitFunc) iface_base_init,                /* base_init */
+       (GBaseFinalizeFunc) iface_base_finalize,        /* base_finalize */
       };
 
       test_iface_type = g_type_register_static (G_TYPE_INTERFACE, "TestIface", &test_iface_info, 0);
@@ -62,21 +58,141 @@ test_iface_get_type (void)
 
   return test_iface_type;
 }
+static guint iface_base_init_count = 0;
+static void
+iface_base_init (TestIfaceClass *iface)
+{
+  iface_base_init_count++;
+  if (iface_base_init_count == 1)
+    {
+      /* add signals here */
+    }
+}
+static void
+iface_base_finalize (TestIfaceClass *iface)
+{
+  iface_base_init_count--;
+  if (iface_base_init_count == 0)
+    {
+      /* destroy signals here */
+    }
+}
+static void
+print_foo (TestIface   *tiobj,
+          const gchar *string)
+{
+  if (!string)
+    string = "<NULL>";
+  g_print ("Iface-FOO: \"%s\" from %p\n", string, tiobj);
+}
+static void
+test_object_test_iface_init (gpointer giface,
+                            gpointer iface_data)
+{
+  TestIfaceClass *iface = giface;
+
+  g_assert (iface_data == GUINT_TO_POINTER (42));
+
+  g_assert (G_TYPE_FROM_INTERFACE (iface) == TEST_TYPE_IFACE);
+
+  /* assert iface_base_init() was already called */
+  g_assert (iface_base_init_count > 0);
+
+  /* initialize stuff */
+  iface->print_string = print_foo;
+}
+void
+iface_print_string (TestIface   *tiobj,
+                   const gchar *string)
+{
+  TestIfaceClass *iface;
+
+  g_return_if_fail (TEST_IS_IFACE (tiobj));
+  g_return_if_fail (G_IS_OBJECT (tiobj)); /* ensured through prerequisite */
+
+  iface = TEST_IFACE_GET_CLASS (tiobj);
+  g_object_ref (tiobj);
+  iface->print_string (tiobj, string);
+  g_object_unref (tiobj);
+}
 
-typedef struct
+
+/* --- TestObject --- */
+#define TEST_TYPE_OBJECT            (test_object_get_type ())
+#define TEST_OBJECT(object)         (G_TYPE_CHECK_INSTANCE_CAST ((object), TEST_TYPE_OBJECT, TestObject))
+#define TEST_OBJECT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_OBJECT, TestObjectClass))
+#define TEST_IS_OBJECT(object)      (G_TYPE_CHECK_INSTANCE_TYPE ((object), TEST_TYPE_OBJECT))
+#define TEST_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TEST_TYPE_OBJECT))
+#define TEST_OBJECT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_TYPE_OBJECT, TestObjectClass))
+typedef struct _TestObject      TestObject;
+typedef struct _TestObjectClass TestObjectClass;
+struct _TestObject
+{
+  GObject parent_instance;
+};
+struct _TestObjectClass
 {
   GObjectClass parent_class;
 
   gchar* (*test_signal) (TestObject *tobject,
                         TestIface  *iface_object,
                         gpointer    tdata);
-} TestObjectClass;
+};
+static void    test_object_class_init  (TestObjectClass        *class);
+static void    test_object_init        (TestObject             *tobject);
+static gboolean        test_signal_accumulator (GSignalInvocationHint  *ihint,
+                                        GValue                 *return_accu,
+                                        const GValue           *handler_return,
+                                        gpointer                data);
+static gchar*  test_object_test_signal (TestObject             *tobject,
+                                        TestIface              *iface_object,
+                                        gpointer                tdata);
+GType
+test_object_get_type (void)
+{
+  static GType test_object_type = 0;
+
+  if (!test_object_type)
+    {
+      static const GTypeInfo test_object_info =
+      {
+       sizeof (TestObjectClass),
+       NULL,           /* base_init */
+       NULL,           /* base_finalize */
+       (GClassInitFunc) test_object_class_init,
+       NULL,           /* class_finalize */
+       NULL,           /* class_data */
+       sizeof (TestObject),
+       5,              /* n_preallocs */
+       (GInstanceInitFunc) test_object_init,
+      };
+      GInterfaceInfo iface_info = { test_object_test_iface_init, NULL, GUINT_TO_POINTER (42) };
+
+      test_object_type = g_type_register_static (G_TYPE_OBJECT, "TestObject", &test_object_info, 0);
+      g_type_add_interface_static (test_object_type, TEST_TYPE_IFACE, &iface_info);
+    }
+
+  return test_object_type;
+}
+static void
+test_object_class_init (TestObjectClass *class)
+{
+  /*  GObjectClass *gobject_class = G_OBJECT_CLASS (class); */
+
+  class->test_signal = test_object_test_signal;
 
+  g_signal_new ("test-signal",
+               G_OBJECT_CLASS_TYPE (class),
+               G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST | G_SIGNAL_RUN_CLEANUP,
+               G_STRUCT_OFFSET (TestObjectClass, test_signal),
+               test_signal_accumulator, NULL,
+               g_cclosure_marshal_STRING__OBJECT_POINTER,
+               G_TYPE_STRING, 2, TEST_TYPE_IFACE, G_TYPE_POINTER);
+}
 static void
 test_object_init (TestObject *tobject)
 {
 }
-
 static gboolean
 test_signal_accumulator (GSignalInvocationHint *ihint,
                         GValue                *return_accu,
@@ -98,7 +214,6 @@ test_signal_accumulator (GSignalInvocationHint *ihint,
 
   return TRUE;
 }
-
 static gchar*
 test_object_test_signal (TestObject *tobject,
                         TestIface  *iface_object,
@@ -111,57 +226,90 @@ test_object_test_signal (TestObject *tobject,
   return g_strdup ("<default_handler>");
 }
 
+
+/* --- TestIface for DerivedObject --- */
 static void
-test_object_class_init (TestObjectClass *class)
+print_bar (TestIface   *tiobj,
+          const gchar *string)
 {
-  /*  GObjectClass *gobject_class = G_OBJECT_CLASS (class); */
+  TestIfaceClass *parent_iface;
 
-  class->test_signal = test_object_test_signal;
+  g_return_if_fail (TEST_IS_IFACE (tiobj));
 
-  g_signal_new ("test-signal",
-               G_OBJECT_CLASS_TYPE (class),
-               G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST | G_SIGNAL_RUN_CLEANUP,
-               G_STRUCT_OFFSET (TestObjectClass, test_signal),
-               test_signal_accumulator, NULL,
-               g_cclosure_marshal_STRING__OBJECT_POINTER,
-               G_TYPE_STRING, 2, TEST_TYPE_IFACE, G_TYPE_POINTER);
+  if (!string)
+    string = "<NULL>";
+  g_print ("Iface-BAR: \"%s\" from %p\n", string, tiobj);
+
+  g_print ("chaining: ");
+  parent_iface = g_type_interface_peek_parent (TEST_IFACE_GET_CLASS (tiobj));
+  parent_iface->print_string (tiobj, string);
+
+  g_assert (g_type_interface_peek_parent (parent_iface) == NULL);
+}
+
+static void
+derived_object_test_iface_init (gpointer giface,
+                               gpointer iface_data)
+{
+  TestIfaceClass *iface = giface;
+
+  g_assert (iface_data == GUINT_TO_POINTER (87));
+
+  g_assert (G_TYPE_FROM_INTERFACE (iface) == TEST_TYPE_IFACE);
+
+  /* assert test_object_test_iface_init() was already called */
+  g_assert (iface->print_string == print_foo);
+
+  /* override stuff */
+  iface->print_string = print_bar;
 }
 
+
+/* --- DerivedObject --- */
+#define DERIVED_TYPE_OBJECT            (derived_object_get_type ())
+#define DERIVED_OBJECT(object)         (G_TYPE_CHECK_INSTANCE_CAST ((object), DERIVED_TYPE_OBJECT, DerivedObject))
+#define DERIVED_OBJECT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), DERIVED_TYPE_OBJECT, DerivedObjectClass))
+#define DERIVED_IS_OBJECT(object)      (G_TYPE_CHECK_INSTANCE_TYPE ((object), DERIVED_TYPE_OBJECT))
+#define DERIVED_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DERIVED_TYPE_OBJECT))
+#define DERIVED_OBJECT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), DERIVED_TYPE_OBJECT, DerivedObjectClass))
+typedef struct _TestObject      DerivedObject;
+typedef struct _TestObjectClass DerivedObjectClass;
 GType
-test_object_get_type (void)
+derived_object_get_type (void)
 {
-  static GType test_object_type = 0;
+  static GType derived_object_type = 0;
 
-  if (!test_object_type)
+  if (!derived_object_type)
     {
-      static const GTypeInfo test_object_info =
+      static const GTypeInfo derived_object_info =
       {
-       sizeof (TestObjectClass),
+       sizeof (DerivedObjectClass),
        NULL,           /* base_init */
        NULL,           /* base_finalize */
-       (GClassInitFunc) test_object_class_init,
+       NULL,           /* class_init */
        NULL,           /* class_finalize */
        NULL,           /* class_data */
-       sizeof (TestObject),
+       sizeof (DerivedObject),
        5,              /* n_preallocs */
-       (GInstanceInitFunc) test_object_init,
+       NULL,           /* instance_init */
       };
-      GInterfaceInfo iface_info = { NULL, NULL, NULL };
+      GInterfaceInfo iface_info = { derived_object_test_iface_init, NULL, GUINT_TO_POINTER (87) };
 
-      test_object_type = g_type_register_static (G_TYPE_OBJECT, "TestObject", &test_object_info, 0);
-      g_type_add_interface_static (test_object_type, TEST_TYPE_IFACE, &iface_info);
+      derived_object_type = g_type_register_static (TEST_TYPE_OBJECT, "DerivedObject", &derived_object_info, 0);
+      g_type_add_interface_static (derived_object_type, TEST_TYPE_IFACE, &iface_info);
     }
 
-  return test_object_type;
+  return derived_object_type;
 }
 
 
-
+/* --- main --- */
 int
 main (int   argc,
       char *argv[])
 {
-  TestObject *tobject, *sigarg;
+  TestObject *sigarg;
+  DerivedObject *dobject;
   gchar *string = NULL;
 
   g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) |
@@ -169,14 +317,24 @@ main (int   argc,
                          G_LOG_LEVEL_CRITICAL);
   g_type_init_with_debug_flags (G_TYPE_DEBUG_OBJECTS | G_TYPE_DEBUG_SIGNALS);
 
-  tobject = g_object_new (TEST_TYPE_OBJECT, NULL);
+  /* to test past class initialization interface setups, create the class here */
+  g_type_class_ref (TEST_TYPE_OBJECT);
+
+  dobject = g_object_new (DERIVED_TYPE_OBJECT, NULL);
   sigarg = g_object_new (TEST_TYPE_OBJECT, NULL);
-  g_signal_emit_by_name (tobject, "test-signal", sigarg, NULL, &string);
+
+  g_print ("MAIN: emit test-signal:\n");
+  g_signal_emit_by_name (dobject, "test-signal", sigarg, NULL, &string);
   g_message ("signal return: \"%s\"", string);
+  g_assert (strcmp (string, "<default_handler><default_handler>") == 0);
   g_free (string);
+
+  g_print ("MAIN: call iface print-string on test and derived object:\n");
+  iface_print_string (TEST_IFACE (sigarg), "iface-string-from-test-type");
+  iface_print_string (TEST_IFACE (dobject), "iface-string-from-derived-type");
   
   g_object_unref (sigarg);
-  g_object_unref (tobject);
+  g_object_unref (dobject);
 
   g_message ("%s done", argv[0]);
 
index ef8a755..e7d5216 100644 (file)
 #define        G_LOG_DOMAIN "TestObject"
 #include       <glib-object.h>
 
-#define TEST_TYPE_OBJECT            (test_object_get_type ())
-#define TEST_OBJECT(object)         (G_TYPE_CHECK_INSTANCE_CAST ((object), TEST_TYPE_OBJECT, TestObject))
-#define TEST_OBJECT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_OBJECT, TestObjectClass))
-#define TEST_IS_OBJECT(object)      (G_TYPE_CHECK_INSTANCE_TYPE ((object), TEST_TYPE_OBJECT))
-#define TEST_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TEST_TYPE_OBJECT))
-#define TEST_OBJECT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_TYPE_OBJECT, TestObjectClass))
-
-typedef struct _TestIface TestIface;
-typedef struct
-{
-  GTypeInterface base_iface;
-} TestIfaceClass;
-typedef struct
-{
-  GObject parent_instance;
-} TestObject;
 
+/* --- TestIface --- */
 #define TEST_TYPE_IFACE           (test_iface_get_type ())
 #define TEST_IFACE(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_IFACE, TestIface))
 #define TEST_IS_IFACE(obj)       (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_IFACE))
-#define TEST_IFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), TEST_TYPE_IFACE, TestIfaceClass))
-
+#define TEST_IFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE, TestIfaceClass))
+typedef struct _TestIface      TestIface;
+typedef struct _TestIfaceClass TestIfaceClass;
+struct _TestIfaceClass
+{
+  GTypeInterface base_iface;
+  void (*print_string) (TestIface      *tiobj,
+                        const gchar    *string);
+};
+static void    iface_base_init         (TestIfaceClass *iface);
+static void    iface_base_finalize     (TestIfaceClass *iface);
+static void    print_foo               (TestIface      *tiobj,
+                                        const gchar    *string);
 GType
 test_iface_get_type (void)
 {
@@ -52,8 +48,8 @@ test_iface_get_type (void)
       static const GTypeInfo test_iface_info =
       {
        sizeof (TestIfaceClass),
-       NULL,           /* base_init */
-       NULL,           /* base_finalize */
+       (GBaseInitFunc) iface_base_init,                /* base_init */
+       (GBaseFinalizeFunc) iface_base_finalize,        /* base_finalize */
       };
 
       test_iface_type = g_type_register_static (G_TYPE_INTERFACE, "TestIface", &test_iface_info, 0);
@@ -62,21 +58,141 @@ test_iface_get_type (void)
 
   return test_iface_type;
 }
+static guint iface_base_init_count = 0;
+static void
+iface_base_init (TestIfaceClass *iface)
+{
+  iface_base_init_count++;
+  if (iface_base_init_count == 1)
+    {
+      /* add signals here */
+    }
+}
+static void
+iface_base_finalize (TestIfaceClass *iface)
+{
+  iface_base_init_count--;
+  if (iface_base_init_count == 0)
+    {
+      /* destroy signals here */
+    }
+}
+static void
+print_foo (TestIface   *tiobj,
+          const gchar *string)
+{
+  if (!string)
+    string = "<NULL>";
+  g_print ("Iface-FOO: \"%s\" from %p\n", string, tiobj);
+}
+static void
+test_object_test_iface_init (gpointer giface,
+                            gpointer iface_data)
+{
+  TestIfaceClass *iface = giface;
+
+  g_assert (iface_data == GUINT_TO_POINTER (42));
+
+  g_assert (G_TYPE_FROM_INTERFACE (iface) == TEST_TYPE_IFACE);
+
+  /* assert iface_base_init() was already called */
+  g_assert (iface_base_init_count > 0);
+
+  /* initialize stuff */
+  iface->print_string = print_foo;
+}
+void
+iface_print_string (TestIface   *tiobj,
+                   const gchar *string)
+{
+  TestIfaceClass *iface;
+
+  g_return_if_fail (TEST_IS_IFACE (tiobj));
+  g_return_if_fail (G_IS_OBJECT (tiobj)); /* ensured through prerequisite */
+
+  iface = TEST_IFACE_GET_CLASS (tiobj);
+  g_object_ref (tiobj);
+  iface->print_string (tiobj, string);
+  g_object_unref (tiobj);
+}
 
-typedef struct
+
+/* --- TestObject --- */
+#define TEST_TYPE_OBJECT            (test_object_get_type ())
+#define TEST_OBJECT(object)         (G_TYPE_CHECK_INSTANCE_CAST ((object), TEST_TYPE_OBJECT, TestObject))
+#define TEST_OBJECT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_OBJECT, TestObjectClass))
+#define TEST_IS_OBJECT(object)      (G_TYPE_CHECK_INSTANCE_TYPE ((object), TEST_TYPE_OBJECT))
+#define TEST_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TEST_TYPE_OBJECT))
+#define TEST_OBJECT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_TYPE_OBJECT, TestObjectClass))
+typedef struct _TestObject      TestObject;
+typedef struct _TestObjectClass TestObjectClass;
+struct _TestObject
+{
+  GObject parent_instance;
+};
+struct _TestObjectClass
 {
   GObjectClass parent_class;
 
   gchar* (*test_signal) (TestObject *tobject,
                         TestIface  *iface_object,
                         gpointer    tdata);
-} TestObjectClass;
+};
+static void    test_object_class_init  (TestObjectClass        *class);
+static void    test_object_init        (TestObject             *tobject);
+static gboolean        test_signal_accumulator (GSignalInvocationHint  *ihint,
+                                        GValue                 *return_accu,
+                                        const GValue           *handler_return,
+                                        gpointer                data);
+static gchar*  test_object_test_signal (TestObject             *tobject,
+                                        TestIface              *iface_object,
+                                        gpointer                tdata);
+GType
+test_object_get_type (void)
+{
+  static GType test_object_type = 0;
+
+  if (!test_object_type)
+    {
+      static const GTypeInfo test_object_info =
+      {
+       sizeof (TestObjectClass),
+       NULL,           /* base_init */
+       NULL,           /* base_finalize */
+       (GClassInitFunc) test_object_class_init,
+       NULL,           /* class_finalize */
+       NULL,           /* class_data */
+       sizeof (TestObject),
+       5,              /* n_preallocs */
+       (GInstanceInitFunc) test_object_init,
+      };
+      GInterfaceInfo iface_info = { test_object_test_iface_init, NULL, GUINT_TO_POINTER (42) };
+
+      test_object_type = g_type_register_static (G_TYPE_OBJECT, "TestObject", &test_object_info, 0);
+      g_type_add_interface_static (test_object_type, TEST_TYPE_IFACE, &iface_info);
+    }
+
+  return test_object_type;
+}
+static void
+test_object_class_init (TestObjectClass *class)
+{
+  /*  GObjectClass *gobject_class = G_OBJECT_CLASS (class); */
+
+  class->test_signal = test_object_test_signal;
 
+  g_signal_new ("test-signal",
+               G_OBJECT_CLASS_TYPE (class),
+               G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST | G_SIGNAL_RUN_CLEANUP,
+               G_STRUCT_OFFSET (TestObjectClass, test_signal),
+               test_signal_accumulator, NULL,
+               g_cclosure_marshal_STRING__OBJECT_POINTER,
+               G_TYPE_STRING, 2, TEST_TYPE_IFACE, G_TYPE_POINTER);
+}
 static void
 test_object_init (TestObject *tobject)
 {
 }
-
 static gboolean
 test_signal_accumulator (GSignalInvocationHint *ihint,
                         GValue                *return_accu,
@@ -98,7 +214,6 @@ test_signal_accumulator (GSignalInvocationHint *ihint,
 
   return TRUE;
 }
-
 static gchar*
 test_object_test_signal (TestObject *tobject,
                         TestIface  *iface_object,
@@ -111,57 +226,90 @@ test_object_test_signal (TestObject *tobject,
   return g_strdup ("<default_handler>");
 }
 
+
+/* --- TestIface for DerivedObject --- */
 static void
-test_object_class_init (TestObjectClass *class)
+print_bar (TestIface   *tiobj,
+          const gchar *string)
 {
-  /*  GObjectClass *gobject_class = G_OBJECT_CLASS (class); */
+  TestIfaceClass *parent_iface;
 
-  class->test_signal = test_object_test_signal;
+  g_return_if_fail (TEST_IS_IFACE (tiobj));
 
-  g_signal_new ("test-signal",
-               G_OBJECT_CLASS_TYPE (class),
-               G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST | G_SIGNAL_RUN_CLEANUP,
-               G_STRUCT_OFFSET (TestObjectClass, test_signal),
-               test_signal_accumulator, NULL,
-               g_cclosure_marshal_STRING__OBJECT_POINTER,
-               G_TYPE_STRING, 2, TEST_TYPE_IFACE, G_TYPE_POINTER);
+  if (!string)
+    string = "<NULL>";
+  g_print ("Iface-BAR: \"%s\" from %p\n", string, tiobj);
+
+  g_print ("chaining: ");
+  parent_iface = g_type_interface_peek_parent (TEST_IFACE_GET_CLASS (tiobj));
+  parent_iface->print_string (tiobj, string);
+
+  g_assert (g_type_interface_peek_parent (parent_iface) == NULL);
+}
+
+static void
+derived_object_test_iface_init (gpointer giface,
+                               gpointer iface_data)
+{
+  TestIfaceClass *iface = giface;
+
+  g_assert (iface_data == GUINT_TO_POINTER (87));
+
+  g_assert (G_TYPE_FROM_INTERFACE (iface) == TEST_TYPE_IFACE);
+
+  /* assert test_object_test_iface_init() was already called */
+  g_assert (iface->print_string == print_foo);
+
+  /* override stuff */
+  iface->print_string = print_bar;
 }
 
+
+/* --- DerivedObject --- */
+#define DERIVED_TYPE_OBJECT            (derived_object_get_type ())
+#define DERIVED_OBJECT(object)         (G_TYPE_CHECK_INSTANCE_CAST ((object), DERIVED_TYPE_OBJECT, DerivedObject))
+#define DERIVED_OBJECT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), DERIVED_TYPE_OBJECT, DerivedObjectClass))
+#define DERIVED_IS_OBJECT(object)      (G_TYPE_CHECK_INSTANCE_TYPE ((object), DERIVED_TYPE_OBJECT))
+#define DERIVED_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DERIVED_TYPE_OBJECT))
+#define DERIVED_OBJECT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), DERIVED_TYPE_OBJECT, DerivedObjectClass))
+typedef struct _TestObject      DerivedObject;
+typedef struct _TestObjectClass DerivedObjectClass;
 GType
-test_object_get_type (void)
+derived_object_get_type (void)
 {
-  static GType test_object_type = 0;
+  static GType derived_object_type = 0;
 
-  if (!test_object_type)
+  if (!derived_object_type)
     {
-      static const GTypeInfo test_object_info =
+      static const GTypeInfo derived_object_info =
       {
-       sizeof (TestObjectClass),
+       sizeof (DerivedObjectClass),
        NULL,           /* base_init */
        NULL,           /* base_finalize */
-       (GClassInitFunc) test_object_class_init,
+       NULL,           /* class_init */
        NULL,           /* class_finalize */
        NULL,           /* class_data */
-       sizeof (TestObject),
+       sizeof (DerivedObject),
        5,              /* n_preallocs */
-       (GInstanceInitFunc) test_object_init,
+       NULL,           /* instance_init */
       };
-      GInterfaceInfo iface_info = { NULL, NULL, NULL };
+      GInterfaceInfo iface_info = { derived_object_test_iface_init, NULL, GUINT_TO_POINTER (87) };
 
-      test_object_type = g_type_register_static (G_TYPE_OBJECT, "TestObject", &test_object_info, 0);
-      g_type_add_interface_static (test_object_type, TEST_TYPE_IFACE, &iface_info);
+      derived_object_type = g_type_register_static (TEST_TYPE_OBJECT, "DerivedObject", &derived_object_info, 0);
+      g_type_add_interface_static (derived_object_type, TEST_TYPE_IFACE, &iface_info);
     }
 
-  return test_object_type;
+  return derived_object_type;
 }
 
 
-
+/* --- main --- */
 int
 main (int   argc,
       char *argv[])
 {
-  TestObject *tobject, *sigarg;
+  TestObject *sigarg;
+  DerivedObject *dobject;
   gchar *string = NULL;
 
   g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) |
@@ -169,14 +317,24 @@ main (int   argc,
                          G_LOG_LEVEL_CRITICAL);
   g_type_init_with_debug_flags (G_TYPE_DEBUG_OBJECTS | G_TYPE_DEBUG_SIGNALS);
 
-  tobject = g_object_new (TEST_TYPE_OBJECT, NULL);
+  /* to test past class initialization interface setups, create the class here */
+  g_type_class_ref (TEST_TYPE_OBJECT);
+
+  dobject = g_object_new (DERIVED_TYPE_OBJECT, NULL);
   sigarg = g_object_new (TEST_TYPE_OBJECT, NULL);
-  g_signal_emit_by_name (tobject, "test-signal", sigarg, NULL, &string);
+
+  g_print ("MAIN: emit test-signal:\n");
+  g_signal_emit_by_name (dobject, "test-signal", sigarg, NULL, &string);
   g_message ("signal return: \"%s\"", string);
+  g_assert (strcmp (string, "<default_handler><default_handler>") == 0);
   g_free (string);
+
+  g_print ("MAIN: call iface print-string on test and derived object:\n");
+  iface_print_string (TEST_IFACE (sigarg), "iface-string-from-test-type");
+  iface_print_string (TEST_IFACE (dobject), "iface-string-from-derived-type");
   
   g_object_unref (sigarg);
-  g_object_unref (tobject);
+  g_object_unref (dobject);
 
   g_message ("%s done", argv[0]);