mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-10 03:16:17 +01:00
got rid of g_set_error_handler(), g_set_warning_handler(),
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.
This commit is contained in:
parent
ae2c2ca6c3
commit
dc0b74d416
@ -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>
|
||||
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
||||
@ -51,6 +77,13 @@
|
||||
@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>
|
||||
|
||||
@ -71,6 +104,13 @@
|
||||
@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>
|
||||
|
@ -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.
|
||||
|
||||
|
||||
|
@ -234,6 +234,7 @@ g_flags_complete_type_info
|
||||
<FILE>gboxed</FILE>
|
||||
<TITLE>Boxed Types</TITLE>
|
||||
GBoxed
|
||||
GBoxedInitFunc
|
||||
GBoxedCopyFunc
|
||||
GBoxedFreeFunc
|
||||
g_boxed_copy
|
||||
|
@ -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 ##### -->
|
||||
|
@ -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:
|
||||
|
||||
|
||||
|
@ -4,6 +4,13 @@
|
||||
</para>
|
||||
|
||||
|
||||
<!-- ##### USER_FUNCTION GBoxedInitFunc ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@Returns:
|
||||
|
||||
<!-- ##### FUNCTION g_closure_add_fnotify ##### -->
|
||||
<para>
|
||||
|
||||
|
@ -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 ##### -->
|
||||
|
@ -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 ##### -->
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
219
gobject/gtype.c
219
gobject/gtype.c
@ -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;
|
||||
return iholder;
|
||||
}
|
||||
|
||||
if (!iholder->info)
|
||||
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);
|
||||
IFaceHolder *iholder;
|
||||
|
||||
g_assert (entry && entry->vtable == vtable);
|
||||
/* 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,6 +2091,37 @@ 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;
|
||||
|
@ -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,
|
||||
|
@ -20,28 +20,24 @@
|
||||
#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;
|
||||
|
||||
typedef struct
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/* --- 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);
|
||||
}
|
||||
|
||||
GType
|
||||
test_object_get_type (void)
|
||||
static void
|
||||
derived_object_test_iface_init (gpointer giface,
|
||||
gpointer iface_data)
|
||||
{
|
||||
static GType test_object_type = 0;
|
||||
TestIfaceClass *iface = giface;
|
||||
|
||||
if (!test_object_type)
|
||||
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
|
||||
derived_object_get_type (void)
|
||||
{
|
||||
static GType derived_object_type = 0;
|
||||
|
||||
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]);
|
||||
|
||||
|
@ -20,28 +20,24 @@
|
||||
#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;
|
||||
|
||||
typedef struct
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/* --- 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);
|
||||
}
|
||||
|
||||
GType
|
||||
test_object_get_type (void)
|
||||
static void
|
||||
derived_object_test_iface_init (gpointer giface,
|
||||
gpointer iface_data)
|
||||
{
|
||||
static GType test_object_type = 0;
|
||||
TestIfaceClass *iface = giface;
|
||||
|
||||
if (!test_object_type)
|
||||
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
|
||||
derived_object_get_type (void)
|
||||
{
|
||||
static GType derived_object_type = 0;
|
||||
|
||||
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]);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user