fixed dealing with collection/lcopy of NULL values.

Mon Dec 11 04:44:11 2000  Tim Janik  <timj@gtk.org>

	* gboxed.c: fixed dealing with collection/lcopy of NULL values.

	* gclosure.h: removed insane ramblings, added G_CALLBACK() a casting
	convenience macro.

	* Makefile.am: cleanups, marshaller generation rules.

	* gmarshal.[hc]: new files with GRuntime standard marshallers.

	* glib-genmarshal.c: fix log domain, support gruntime standard
	marshallers, suport G_TYPE_PARAM, come with extern "C" and
	#include gmarshal.h.

	* glib-genmarshal.1: reflect glib-genmarshal.c updates.

	* gobject.[hc]: implement object constructor. rework parameter
	changed notification queueing, we support queue freezes now and
	don't dispatch from an idle handler anymore.
	parameter->property rename hassle.
	implemented ::properties_changed and ::notify::* signals for
	property change notification (the later supports property names
	as details). added signal connection and named data properties.
	(g_signal_connect_object): new function to setup while_alive
	connections.
	(g_object_class_install_property): sink properties now, since they
	are initially floating.
	(g_object_steal_data):
	(g_object_set_data_full):
	(g_object_set_data):
	(g_object_get_data): set/get data by using g_datalist_*() functions
	directly.
	(g_object_queue_param_changed): nuked.
	(g_object_freeze_notify): start queueing of property changes (freeze/
	thaw calls stack).
	(g_object_notify): announce changes of a certain property directly.
	(g_object_thaw_notify): process queue of property changes, therefore
	emitting GObject::notify::detail with detail being the changed
	properties names.
	(G_OBJECT_WARN_INVALID_PROPERTY_ID): saner macro variant of former
	G_WARN_INVALID_PARAM_ID().

	* gparam.[hc]: param specs are now initially floating and need to be
	sunken with g_param_spec_sink(), support G_TYPE_PARAM values.
	added G_PARAM_CONSTRUCT and G_PARAM_CONSTRUCT_ONLY parameter flags,
	required by GObjectClass.constructor().

	* gparamspecs.[hc]: added GParamSpecParam, GParamSpecPointer and
	GParamSpecCCallback, param specs for G_TYPE_PARAM, G_TYPE_POINTER
	and G_TYPE_CCALLBACK respectively.

	* gsignal.[hc]: cleanups.
	(signal_id_lookup): after walking the anchestry, try interfaces as well.
	(g_signal_new): new function to create signals from varargs type list.
	(g_signal_connect_closure): closure connection variant that works from
	signal name+detail.
	(g_signal_connect_data): c handler connection variant that works from
	signal name+detail.
	(g_signal_emit_valist): emit signal for an instance with paraneters
	collected from a va_list.
	(g_signal_emit): emit signal, taking parameters from varargs list.
	(g_signal_emit_by_name): same as g_signal_emit, working from
	signal name+detail.
	(signal_emit_R): return whether return_value needs to be altered.

	* gtype.[hc]: set log-domain to GRuntime, i'm slowly getting to all
	the points that need to reflect the upcoming rename.
	melt g_type_conforms_to() functionality into g_type_is_a(), as that
	is what we really want (liskov substitution principle).
	assorted changes to other files due to conforms_to->is_a.

	* gvalue.[hc]: implemented g_value_set_instance() that sets a value
	from an instantiatable type via the value_table's collect_value()
	function (based on an idea from James Henstridge <james@daa.com.au>).
	cleanups/fixes.

	* gvaluetypes.[hc]: implement G_TYPE_CCALLBACK and G_TYPE_PARAM.
This commit is contained in:
Tim Janik 2000-12-12 07:32:00 +00:00 committed by Tim Janik
parent cbd74878d1
commit e773d7dba6
44 changed files with 2926 additions and 1383 deletions

View File

@ -109,6 +109,7 @@ AC_ARG_ENABLE(ansi, [ --enable-ansi turn on strict ansi [default=no]]
, enable_ansi=no)
AC_ARG_ENABLE(threads, [ --enable-threads turn on basic thread support [default=yes]
([=no] will override --with-threads)],,enable_threads=yes)
AC_ARG_ENABLE(rebuilds, [ --disable-rebuilds disable all source autogeneration rules],,enable_rebuilds=yes)
if test "x$enable_threads" != "xyes"; then
enable_threads=no
@ -163,6 +164,21 @@ AC_PROG_CC
AM_PROG_CC_STDC
AC_PROG_INSTALL
# define a MAINT-like variable REBUILD which is set if Perl
# and awk are found, so autogenerated sources can be rebuilt
AC_PROG_AWK
AC_CHECK_PROGS(PERL, perl5 perl)
# We would like indent, but don't require it.
AC_CHECK_PROG(INDENT, indent, indent)
REBUILD=\#
if test "x$enable_rebuilds" = "xyes" && \
test -n "$PERL" && \
$PERL -e 'exit !($] >= 5.002)' > /dev/null 2>&1 && \
test -n "$AWK" ; then
REBUILD=
fi
AC_SUBST(REBUILD)
dnl Initialize libtool
AM_PROG_LIBTOOL

View File

@ -209,25 +209,6 @@ g_array_remove_index().
@Returns: the #GArray.
<!-- ##### FUNCTION g_array_sort ##### -->
<para>
</para>
@array:
@compare_func:
<!-- ##### FUNCTION g_array_sort_with_data ##### -->
<para>
</para>
@array:
@compare_func:
@user_data:
<!-- ##### MACRO g_array_index ##### -->
<para>
Returns the element of a #GArray at the given index.

View File

@ -123,25 +123,6 @@ g_byte_array_remove_index().
@Returns: the #GByteArray.
<!-- ##### FUNCTION g_byte_array_sort ##### -->
<para>
</para>
@array:
@compare_func:
<!-- ##### FUNCTION g_byte_array_sort_with_data ##### -->
<para>
</para>
@array:
@compare_func:
@user_data:
<!-- ##### FUNCTION g_byte_array_set_size ##### -->
<para>
Sets the size of the #GByteArray, expanding it if necessary.

View File

@ -156,25 +156,6 @@ g_ptr_array_remove_index().
@Returns: the pointer which was removed.
<!-- ##### FUNCTION g_ptr_array_sort ##### -->
<para>
</para>
@array:
@compare_func:
<!-- ##### FUNCTION g_ptr_array_sort_with_data ##### -->
<para>
</para>
@array:
@compare_func:
@user_data:
<!-- ##### FUNCTION g_ptr_array_set_size ##### -->
<para>
Sets the size of the array, expanding it if necessary.

View File

@ -51,11 +51,11 @@ called by g_cache_remove() when the object is no longer needed (i.e. its
reference count drops to 0).
@hash_key_func: a function to create a hash value from a key.
@hash_value_func: a function to create a hash value from a value.
@key_equal_func: a function to compare two keys. It should return TRUE if
the two keys are equivalent.
@key_compare_func:
@Returns: a new #GCache.
<!-- # Unused Parameters # -->
@key_compare_func:
@key_equal_func: a function to compare two keys. It should return TRUE if
the two keys are equivalent.
<!-- ##### FUNCTION g_cache_insert ##### -->

View File

@ -47,7 +47,6 @@ g_completion_complete().
@func:
@prefix:
@cache:
@strncmp_func:
<!-- ##### FUNCTION g_completion_new ##### -->
<para>
@ -71,16 +70,6 @@ This is used when you use data structures as #GCompletion items.
@Returns: the string corresponding to the item.
<!-- ##### USER_FUNCTION GCompletionStrcmpFunc ##### -->
<para>
</para>
@s1:
@s2:
@Returns:
<!-- ##### FUNCTION g_completion_add_items ##### -->
<para>
Adds items to the #GCompletion.

View File

@ -52,56 +52,15 @@ Character Set Conversion
<!-- ##### FUNCTION g_iconv_open ##### -->
<para>
</para>
@to_codeset:
@from_codeset:
@Returns:
<!-- ##### FUNCTION g_iconv ##### -->
<para>
</para>
@converter:
@inbuf:
@inbytes_left:
@outbuf:
@outbytes_left:
@Returns:
<!-- ##### FUNCTION g_iconv_close ##### -->
<para>
</para>
@converter:
@Returns:
<!-- ##### FUNCTION g_locale_to_utf8 ##### -->
<para>
</para>
@opsysstring:
@error:
@Returns:
<!-- ##### FUNCTION g_filename_to_utf8 ##### -->
<para>
</para>
@opsysstring:
@error:
@Returns:
<!-- # Unused Parameters # -->
@error:
<!-- ##### FUNCTION g_filename_from_utf8 ##### -->
@ -110,18 +69,9 @@ Character Set Conversion
</para>
@utf8string:
@error:
@Returns:
<!-- ##### FUNCTION g_locale_from_utf8 ##### -->
<para>
</para>
@utf8string:
<!-- # Unused Parameters # -->
@error:
@Returns:
<!-- ##### ENUM GConvertError ##### -->
@ -132,5 +82,4 @@ Character Set Conversion
@G_CONVERT_ERROR_NO_CONVERSION:
@G_CONVERT_ERROR_ILLEGAL_SEQUENCE:
@G_CONVERT_ERROR_FAILED:
@G_CONVERT_ERROR_PARTIAL_INPUT:

View File

@ -93,23 +93,3 @@ File Utilities
@Returns:
<!-- ##### FUNCTION g_mkstemp ##### -->
<para>
</para>
@tmpl:
@Returns:
<!-- ##### FUNCTION g_file_open_tmp ##### -->
<para>
</para>
@tmpl:
@name_used:
@error:
@Returns:

View File

@ -1,24 +1,61 @@
<!-- ##### FUNCTION g_main_remove_poll ##### -->
<para>
Removes a file descriptor from the list being polled.
</para>
@fd: the #GPollFD to remove.
<!-- ##### MACRO lseek ##### -->
<para>
</para>
<!-- ##### FUNCTION g_convert_error_quark ##### -->
<!-- ##### FUNCTION g_markup_parse_context_parse ##### -->
<para>
</para>
@context:
@text:
@text_len:
@error:
@Returns:
<!-- ##### MACRO write ##### -->
<!-- ##### STRUCT GSource ##### -->
<para>
</para>
<!-- ##### FUNCTION g_source_connect_indirect ##### -->
<para>
</para>
@source:
@callback_data:
@callback_funcs:
<!-- ##### FUNCTION g_locale_to_utf8 ##### -->
<para>
</para>
@opsysstring:
@error:
@Returns:
<!-- ##### FUNCTION g_iconv_close ##### -->
<para>
</para>
@converter:
@Returns:
<!-- ##### MACRO popen ##### -->
<para>
</para>
<!-- ##### FUNCTION g_source_set_can_recurse ##### -->
<para>
</para>
@source:
@can_recurse:
<!-- ##### MACRO pclose ##### -->
<para>
</para>
@ -40,26 +77,122 @@ the results may be needed.
See #G_PRIORITY_DEFAULT, #G_PRIORITY_DEFAULT_IDLE, #G_PRIORITY_HIGH,
#G_PRIORITY_HIGH_IDLE, and #G_PRIORITY_LOW.
<!-- ##### MACRO pclose ##### -->
<!-- ##### ENUM GMarkupError ##### -->
<para>
</para>
@G_MARKUP_ERROR_BAD_UTF8: text being parsed was not valid UTF-8
@G_MARKUP_ERROR_EMPTY: document contained nothing, or only whitespace
@G_MARKUP_ERROR_PARSE: document was ill-formed
@G_MARKUP_ERROR_UNKNOWN_ELEMENT: error should be set by #GMarkupParser functions; element wasn't known
@G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE: error should be set by #GMarkupParser functions; attribute wasn't known
@G_MARKUP_ERROR_INVALID_CONTENT: error should be set by #GMarkupParser functions; something was wrong with contents of the document, e.g. invalid attribute value
<!-- ##### FUNCTION g_main_context_add_poll ##### -->
<para>
</para>
@context:
@fd:
@priority:
<!-- ##### MACRO lseek ##### -->
<para>
</para>
<!-- ##### MACRO g_string ##### -->
<!-- ##### FUNCTION g_string_new_len ##### -->
<para>
Turns the argument into a string literal by using the '#' stringizing operator.
</para>
@x: text to convert to a literal string.
@init:
@len:
@Returns:
<!-- ##### MACRO popen ##### -->
<!-- ##### STRUCT GSourceCallbackFuncs ##### -->
<para>
</para>
@ref:
@unref:
@get:
<!-- ##### FUNCTION g_array_sort ##### -->
<para>
</para>
@array:
@compare_func:
<!-- ##### FUNCTION g_main_context_find_source_by_funcs_user_data ##### -->
<para>
</para>
@context:
@funcs:
@user_data:
@Returns:
@source_data:
<!-- ##### FUNCTION g_markup_parse_context_free ##### -->
<para>
</para>
@context:
<!-- ##### STRUCT GMarkupParseContext ##### -->
<para>
</para>
<!-- ##### MACRO access ##### -->
<!-- ##### FUNCTION g_ptr_array_sort ##### -->
<para>
</para>
@array:
@compare_func:
<!-- ##### FUNCTION g_main_context_query ##### -->
<para>
</para>
@context:
@max_priority:
@timeout:
@fds:
@n_fds:
@Returns:
<!-- ##### FUNCTION g_iconv_open ##### -->
<para>
</para>
@to_codeset:
@from_codeset:
@Returns:
<!-- ##### FUNCTION g_source_new ##### -->
<para>
</para>
@source_funcs:
@struct_size:
@Returns:
<!-- ##### MACRO getpid ##### -->
<para>
</para>
@ -78,17 +211,43 @@ priority are stored in the order in which they were added.
type of source.
@Returns: TRUE if an event source was found and removed.
<!-- ##### MACRO open ##### -->
<!-- ##### MACRO close ##### -->
<para>
</para>
<!-- ##### MACRO getpid ##### -->
<!-- ##### FUNCTION g_source_get_id ##### -->
<para>
</para>
@source:
@Returns:
<!-- ##### FUNCTION g_mkstemp ##### -->
<para>
</para>
@tmpl:
@Returns:
<!-- ##### FUNCTION g_main_context_get_poll_func ##### -->
<para>
</para>
@context:
@Returns:
<!-- ##### FUNCTION g_source_add_poll ##### -->
<para>
</para>
@source:
@fd:
<!-- ##### MACRO fdopen ##### -->
<para>
@ -96,11 +255,240 @@ type of source.
</para>
<!-- ##### MACRO close ##### -->
<!-- ##### FUNCTION g_source_get_current_time ##### -->
<para>
</para>
@source:
@timeval:
<!-- ##### USER_FUNCTION GCompletionStrcmpFunc ##### -->
<para>
</para>
@s1:
@s2:
@Returns:
<!-- ##### FUNCTION g_main_loop_new ##### -->
<para>
</para>
@context:
@is_running:
@Returns:
<!-- ##### FUNCTION g_iconv ##### -->
<para>
</para>
@converter:
@inbuf:
@inbytes_left:
@outbuf:
@outbytes_left:
@Returns:
<!-- ##### FUNCTION g_source_ref ##### -->
<para>
</para>
@source:
@Returns:
<!-- ##### FUNCTION g_byte_array_sort ##### -->
<para>
</para>
@array:
@compare_func:
<!-- ##### FUNCTION g_markup_parse_context_get_position ##### -->
<para>
</para>
@context:
@line_number:
@char_number:
<!-- ##### FUNCTION g_locale_from_utf8 ##### -->
<para>
</para>
@utf8string:
@error:
@Returns:
<!-- ##### FUNCTION g_main_loop_is_running ##### -->
<para>
</para>
@loop:
@Returns:
<!-- ##### FUNCTION g_main_context_remove_poll ##### -->
<para>
</para>
@context:
@fd:
<!-- ##### FUNCTION g_byte_array_sort_with_data ##### -->
<para>
</para>
@array:
@compare_func:
@user_data:
<!-- ##### FUNCTION g_markup_parse_context_new ##### -->
<para>
</para>
@parser:
@flags:
@user_data:
@user_data_dnotify:
@Returns:
<!-- ##### FUNCTION g_source_get_can_recurse ##### -->
<para>
</para>
@source:
@Returns:
<!-- ##### FUNCTION g_main_context_get ##### -->
<para>
</para>
@thread:
@Returns:
<!-- ##### FUNCTION g_source_remove_poll ##### -->
<para>
</para>
@source:
@fd:
<!-- ##### FUNCTION g_tree_new_with_data ##### -->
<para>
</para>
@key_compare_func:
@user_data:
@Returns:
<!-- ##### FUNCTION g_source_get_priority ##### -->
<para>
</para>
@source:
@Returns:
<!-- ##### FUNCTION g_source_connect ##### -->
<para>
</para>
@source:
@func:
@data:
@notify:
<!-- ##### FUNCTION g_main_context_iteration ##### -->
<para>
</para>
@context:
@may_block:
@Returns:
<!-- ##### FUNCTION g_main_context_dispatch ##### -->
<para>
</para>
@context:
<!-- ##### FUNCTION g_main_loop_quit ##### -->
<para>
</para>
@loop:
<!-- ##### FUNCTION g_main_context_prepare ##### -->
<para>
</para>
@context:
@priority:
@Returns:
<!-- ##### FUNCTION g_source_set_priority ##### -->
<para>
</para>
@source:
@priority:
<!-- ##### FUNCTION g_ptr_array_sort_with_data ##### -->
<para>
</para>
@array:
@compare_func:
@user_data:
<!-- ##### FUNCTION g_list_sort_with_data ##### -->
<para>
</para>
@list:
@compare_func:
@user_data:
@Returns:
<!-- ##### FUNCTION g_main_context_find_source_by_user_data ##### -->
<para>
</para>
@context:
@user_data:
@Returns:
<!-- ##### FUNCTION g_main_context_set_poll_func ##### -->
<para>
</para>
@context:
@func:
<!-- ##### MACRO getcwd ##### -->
<para>
@ -108,11 +496,71 @@ type of source.
</para>
<!-- ##### MACRO read ##### -->
<!-- ##### FUNCTION g_io_create_watch ##### -->
<para>
</para>
@channel:
@condition:
@Returns:
<!-- ##### FUNCTION g_source_unref ##### -->
<para>
</para>
@source:
<!-- ##### MACRO write ##### -->
<para>
</para>
<!-- ##### FUNCTION g_main_context_find_source_by_id ##### -->
<para>
</para>
@context:
@id:
@Returns:
<!-- ##### FUNCTION g_main_remove_poll ##### -->
<para>
Removes a file descriptor from the list being polled.
</para>
@fd: the #GPollFD to remove.
<!-- ##### MACRO access ##### -->
<para>
</para>
<!-- ##### MACRO g_string ##### -->
<para>
Turns the argument into a string literal by using the '#' stringizing operator.
</para>
@x: text to convert to a literal string.
<!-- ##### FUNCTION g_idle_source_new ##### -->
<para>
</para>
@Returns:
<!-- ##### FUNCTION g_main_context_pending ##### -->
<para>
</para>
@context:
@Returns:
<!-- ##### FUNCTION g_main_win32_get_poll_func ##### -->
<para>
@ -121,3 +569,175 @@ type of source.
@Returns:
<!-- ##### FUNCTION g_main_loop_run ##### -->
<para>
</para>
@loop:
<!-- ##### MACRO read ##### -->
<para>
</para>
<!-- ##### FUNCTION g_array_sort_with_data ##### -->
<para>
</para>
@array:
@compare_func:
@user_data:
<!-- ##### MACRO G_MARKUP_ERROR ##### -->
<para>
</para>
<!-- ##### FUNCTION g_main_context_default ##### -->
<para>
</para>
@Returns:
<!-- ##### ENUM GMarkupParseFlags ##### -->
<para>
There are no flags right now
</para>
@G_MARKUP_DO_NOT_USE_THIS_UNSUPPORTED_FLAG:
<!-- ##### FUNCTION g_slist_sort_with_data ##### -->
<para>
</para>
@list:
@compare_func:
@user_data:
@Returns:
<!-- ##### FUNCTION g_markup_parse_context_end_parse ##### -->
<para>
</para>
@context:
@error:
@Returns:
<!-- ##### FUNCTION g_source_get_context ##### -->
<para>
</para>
@source:
@Returns:
<!-- ##### FUNCTION g_timeout_source_new ##### -->
<para>
</para>
@interval:
@Returns:
<!-- ##### STRUCT GMarkupParser ##### -->
<para>
Any of the fields in #GMarkupParser can be %NULL, in which case they
will be ignored. Except for the @error function, any of these
callbacks can set an error; in particular the
%G_MARKUP_ERROR_UNKNOWN_ELEMENT, %G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
and %G_MARKUP_ERROR_INVALID_CONTENT errors are intended to be set
from these callbacks. If you set an error from a callback,
g_markup_parse_context_parse() will report that error back to its caller.
</para>
@start_element: Callback to invoke when the opening tag of an element
is seen.
@end_element: Callback to invoke when the closing tag of an element is seen
@text: Callback to invoke when some text is seen (text is always
inside an element)
@passthrough: Callback to invoke for comments and processing
instructions; if you're re-writing the parsed document, write the
passthrough text back out in the same position
@error: Callback to invoke when an error occurs
<!-- ##### USER_FUNCTION GEqualFunc ##### -->
<para>
Specifies the type of a function used to test two values for
equality. The function should return TRUE if both values are equal and
FALSE otherwise.
</para>
@a: a value.
@b: a value to compare with.
@Returns: TRUE if @a = @b; FALSE otherwise.
<!-- ##### FUNCTION g_main_loop_destroy ##### -->
<para>
</para>
@loop:
<!-- ##### FUNCTION g_file_open_tmp ##### -->
<para>
</para>
@tmpl:
@name_used:
@error:
@Returns:
<!-- ##### STRUCT GMainContext ##### -->
<para>
</para>
<!-- ##### FUNCTION g_main_context_check ##### -->
<para>
</para>
@context:
@max_priority:
@fds:
@n_fds:
@Returns:
<!-- ##### FUNCTION g_convert_error_quark ##### -->
<para>
</para>
@Returns:
<!-- ##### FUNCTION g_source_destroy ##### -->
<para>
</para>
@source:
<!-- ##### FUNCTION g_markup_escape_text ##### -->
<para>
</para>
@text:
@length:
@Returns:
<!-- ##### MACRO open ##### -->
<para>
</para>

View File

@ -69,15 +69,15 @@ Hash values are used to determine where keys are stored within the
#GHashTable data structure.
The g_direct_hash(), g_int_hash() and g_str_hash() functions are provided for
some common types of keys. If hash_func is NULL, g_direct_hash() is used.
@key_compare_func:
@Returns: a new #GHashTable.
<!-- # Unused Parameters # -->
@key_equal_func: a function to check two keys for equality. This is
used when looking up keys in the #GHashTable. The g_direct_equal(),
g_int_equal() and g_str_equal() functions are provided for the most
common types of keys. If @key_equal_func is NULL, keys are compared
directly in a similar fashion to g_direct_equal(), but without the
overhead of a function call.
@Returns: a new #GHashTable.
<!-- # Unused Parameters # -->
@key_compare_func:
<!-- ##### USER_FUNCTION GHashFunc ##### -->
@ -104,18 +104,6 @@ lookup.
@Returns: the hash value corresponding to the key.
<!-- ##### USER_FUNCTION GEqualFunc ##### -->
<para>
Specifies the type of a function used to test two values for
equality. The function should return TRUE if both values are equal and
FALSE otherwise.
</para>
@a: a value.
@b: a value to compare with.
@Returns: TRUE if @a = @b; FALSE otherwise.
<!-- ##### FUNCTION g_hash_table_insert ##### -->
<para>
Inserts a new key and value into a #GHashTable.

View File

@ -209,16 +209,6 @@ Decrements the reference count of a #GIOChannel.
@channel: a #GIOChannel.
<!-- ##### FUNCTION g_io_create_watch ##### -->
<para>
</para>
@channel:
@condition:
@Returns:
<!-- ##### FUNCTION g_io_add_watch ##### -->
<para>
Adds the #GIOChannel into the
@ -324,6 +314,6 @@ generic way.
@io_write:
@io_seek:
@io_close:
@io_create_watch:
@io_add_watch:
@io_free:

View File

@ -268,17 +268,6 @@ value if the first element comes after the second.
@Returns: the start of the sorted #GList.
<!-- ##### FUNCTION g_list_sort_with_data ##### -->
<para>
</para>
@list:
@compare_func:
@user_data:
@Returns:
<!-- ##### USER_FUNCTION GCompareFunc ##### -->
<para>
Specifies the type of a comparison function used to compare two

View File

@ -271,17 +271,6 @@ value if the first element comes after the second.
@Returns: the start of the sorted #GList.
<!-- ##### FUNCTION g_slist_sort_with_data ##### -->
<para>
</para>
@list:
@compare_func:
@user_data:
@Returns:
<!-- ##### FUNCTION g_slist_concat ##### -->
<para>
Adds the second #GSList onto the end of the first #GSList.

View File

@ -96,6 +96,7 @@ manages all available sources of events.
<graphic fileref="mainloop-states.gif" format="gif"></graphic>
</figure>
</refsect2>
<!-- ##### SECTION See_Also ##### -->
<para>
@ -108,50 +109,7 @@ of a GLib or GTK+ application.
</para>
<!-- ##### FUNCTION g_main_loop_new ##### -->
<para>
</para>
@context:
@is_running:
@Returns:
<!-- ##### FUNCTION g_main_loop_destroy ##### -->
<para>
</para>
@loop:
<!-- ##### FUNCTION g_main_loop_run ##### -->
<para>
</para>
@loop:
<!-- ##### FUNCTION g_main_loop_quit ##### -->
<para>
</para>
@loop:
<!-- ##### FUNCTION g_main_loop_is_running ##### -->
<para>
</para>
@loop:
@Returns:
<!-- ##### MACRO g_main_new ##### -->
<!-- ##### FUNCTION g_main_new ##### -->
<para>
Creates a new #GMainLoop for the default main loop. A compatibility
macro, see g_main_loop_new().
@ -162,7 +120,7 @@ very important since calling g_main_run() will set this to TRUE anyway.
@Returns: a new #GMainLoop.
<!-- ##### MACRO g_main_destroy ##### -->
<!-- ##### FUNCTION g_main_destroy ##### -->
<para>
Frees the memory allocated for the #GMainLoop. A compatibility macro, see
g_main_loop_destroy().
@ -171,7 +129,7 @@ g_main_loop_destroy().
@loop: a #GMainLoop.
<!-- ##### MACRO g_main_run ##### -->
<!-- ##### FUNCTION g_main_run ##### -->
<para>
Runs a main loop until it stops running. A compatibility macro, see g_main_loop_run().
</para>
@ -179,7 +137,7 @@ Runs a main loop until it stops running. A compatibility macro, see g_main_loop_
@loop: a #GMainLoop.
<!-- ##### MACRO g_main_quit ##### -->
<!-- ##### FUNCTION g_main_quit ##### -->
<para>
Stops the #GMainLoop. If g_main_run() was called to run the #GMainLoop,
it will now return. A compatibility macro, see g_main_loop_quit().
@ -188,7 +146,7 @@ it will now return. A compatibility macro, see g_main_loop_quit().
@loop: a #GMainLoop.
<!-- ##### MACRO g_main_is_running ##### -->
<!-- ##### FUNCTION g_main_is_running ##### -->
<para>
Checks if the main loop is running. A compatibility macro, see
g_main_loop_is_running().
@ -243,40 +201,7 @@ It is not used within GLib or GTK+.
<!-- ##### STRUCT GMainContext ##### -->
<para>
</para>
<!-- ##### FUNCTION g_main_context_get ##### -->
<para>
</para>
@thread:
@Returns:
<!-- ##### FUNCTION g_main_context_default ##### -->
<para>
</para>
@Returns:
<!-- ##### FUNCTION g_main_context_iteration ##### -->
<para>
</para>
@context:
@may_block:
@Returns:
<!-- ##### MACRO g_main_iteration ##### -->
<!-- ##### FUNCTION g_main_iteration ##### -->
<para>
Runs a single iteration for the default #GMainContext.
A compatibility macro, see g_main_context_iteration().
@ -289,16 +214,7 @@ processed.
@Returns: TRUE if more events are pending.
<!-- ##### FUNCTION g_main_context_pending ##### -->
<para>
</para>
@context:
@Returns:
<!-- ##### MACRO g_main_pending ##### -->
<!-- ##### FUNCTION g_main_pending ##### -->
<para>
Checks if any events are pending for the default #GMainContext
(i.e. ready to be processed). A compatibility macro, see
@ -308,100 +224,6 @@ g_main_context_pending().
@Returns: %TRUE if any events are pending.
<!-- ##### FUNCTION g_main_context_find_source_by_id ##### -->
<para>
</para>
@context:
@id:
@Returns:
<!-- ##### FUNCTION g_main_context_find_source_by_user_data ##### -->
<para>
</para>
@context:
@user_data:
@Returns:
<!-- ##### FUNCTION g_main_context_find_source_by_funcs_user_data ##### -->
<para>
</para>
@context:
@funcs:
@user_data:
@Returns:
<!-- # Unused Parameters # -->
@source_data:
<!-- ##### FUNCTION g_main_context_prepare ##### -->
<para>
</para>
@context:
@priority:
@Returns:
<!-- ##### FUNCTION g_main_context_query ##### -->
<para>
</para>
@context:
@max_priority:
@timeout:
@fds:
@n_fds:
@Returns:
<!-- ##### FUNCTION g_main_context_check ##### -->
<para>
</para>
@context:
@max_priority:
@fds:
@n_fds:
@Returns:
<!-- ##### FUNCTION g_main_context_dispatch ##### -->
<para>
</para>
@context:
<!-- ##### FUNCTION g_main_context_set_poll_func ##### -->
<para>
</para>
@context:
@func:
<!-- ##### FUNCTION g_main_context_get_poll_func ##### -->
<para>
</para>
@context:
@Returns:
<!-- ##### USER_FUNCTION GPollFunc ##### -->
<para>
Specifies the type of function passed to g_main_set_poll_func().
@ -417,26 +239,7 @@ The semantics of the function should match those of the
or -1 if an error occurred.
<!-- ##### FUNCTION g_main_context_add_poll ##### -->
<para>
</para>
@context:
@fd:
@priority:
<!-- ##### FUNCTION g_main_context_remove_poll ##### -->
<para>
</para>
@context:
@fd:
<!-- ##### MACRO g_main_set_poll_func ##### -->
<!-- ##### FUNCTION g_main_set_poll_func ##### -->
<para>
Sets the function to use for the handle polling of file descriptors
for the default main context. This is a compatability macro, see
@ -446,15 +249,6 @@ g_main_context_set_poll_func() for full details.
@func: the function to call to poll all file descriptors.
<!-- ##### FUNCTION g_timeout_source_new ##### -->
<para>
</para>
@interval:
@Returns:
<!-- ##### FUNCTION g_timeout_add ##### -->
<para>
</para>
@ -477,14 +271,6 @@ g_main_context_set_poll_func() for full details.
@Returns:
<!-- ##### FUNCTION g_idle_source_new ##### -->
<para>
</para>
@Returns:
<!-- ##### FUNCTION g_idle_add ##### -->
<para>
</para>
@ -501,10 +287,10 @@ g_main_context_set_poll_func() for full details.
@priority:
@function:
@data:
@notify:
@destroy:
@Returns:
<!-- # Unused Parameters # -->
@destroy:
@notify:
<!-- ##### FUNCTION g_idle_remove_by_data ##### -->
@ -550,12 +336,6 @@ poll() function to indicate which events occurred.
@events:
@revents:
<!-- ##### STRUCT GSource ##### -->
<para>
</para>
<!-- ##### STRUCT GSourceFuncs ##### -->
<para>
The #GSourceFuncs struct contains a table of functions used to handle
@ -636,122 +416,20 @@ the required condition has been met, and returns TRUE if so.
@dispatch:
@destroy:
<!-- ##### STRUCT GSourceCallbackFuncs ##### -->
<para>
</para>
@ref:
@unref:
@get:
<!-- ##### FUNCTION g_source_new ##### -->
<para>
</para>
@source_funcs:
@struct_size:
@Returns:
<!-- ##### FUNCTION g_source_ref ##### -->
<para>
</para>
@source:
@Returns:
<!-- ##### FUNCTION g_source_unref ##### -->
<para>
</para>
@source:
<!-- ##### FUNCTION g_source_add ##### -->
<para>
</para>
@priority:
@can_recurse:
@funcs:
@source_data:
@user_data:
@notify:
@Returns:
<!-- # Unused Parameters # -->
@source:
@context:
@Returns:
<!-- ##### FUNCTION g_source_destroy ##### -->
<para>
</para>
@source:
<!-- ##### FUNCTION g_source_set_priority ##### -->
<para>
</para>
@source:
@priority:
<!-- ##### FUNCTION g_source_get_priority ##### -->
<para>
</para>
@source:
@Returns:
<!-- ##### FUNCTION g_source_set_can_recurse ##### -->
<para>
</para>
@source:
@can_recurse:
<!-- ##### FUNCTION g_source_get_can_recurse ##### -->
<para>
</para>
@source:
@Returns:
<!-- ##### FUNCTION g_source_get_id ##### -->
<para>
</para>
@source:
@Returns:
<!-- ##### FUNCTION g_source_get_context ##### -->
<para>
</para>
@source:
@Returns:
<!-- ##### FUNCTION g_source_connect ##### -->
<para>
</para>
@source:
@func:
@data:
@notify:
<!-- ##### USER_FUNCTION GSourceFunc ##### -->
@ -765,43 +443,6 @@ of the above functions.
@Returns: it should return FALSE if the source should be removed.
<!-- ##### FUNCTION g_source_connect_indirect ##### -->
<para>
</para>
@source:
@callback_data:
@callback_funcs:
<!-- ##### FUNCTION g_source_add_poll ##### -->
<para>
</para>
@source:
@fd:
<!-- ##### FUNCTION g_source_remove_poll ##### -->
<para>
</para>
@source:
@fd:
<!-- ##### FUNCTION g_source_get_current_time ##### -->
<para>
</para>
@source:
@timeval:
<!-- ##### FUNCTION g_source_remove ##### -->
<para>
</para>

View File

@ -87,118 +87,3 @@ Character references
</para>
<!-- ##### ENUM GMarkupError ##### -->
<para>
</para>
@G_MARKUP_ERROR_BAD_UTF8: text being parsed was not valid UTF-8
@G_MARKUP_ERROR_EMPTY: document contained nothing, or only whitespace
@G_MARKUP_ERROR_PARSE: document was ill-formed
@G_MARKUP_ERROR_UNKNOWN_ELEMENT: error should be set by #GMarkupParser functions; element wasn't known
@G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE: error should be set by #GMarkupParser functions; attribute wasn't known
@G_MARKUP_ERROR_INVALID_CONTENT: error should be set by #GMarkupParser functions; something was wrong with contents of the document, e.g. invalid attribute value
<!-- ##### MACRO G_MARKUP_ERROR ##### -->
<para>
</para>
<!-- ##### ENUM GMarkupParseFlags ##### -->
<para>
There are no flags right now
</para>
@G_MARKUP_DO_NOT_USE_THIS_UNSUPPORTED_FLAG:
<!-- ##### STRUCT GMarkupParseContext ##### -->
<para>
</para>
<!-- ##### STRUCT GMarkupParser ##### -->
<para>
Any of the fields in #GMarkupParser can be %NULL, in which case they
will be ignored. Except for the @error function, any of these
callbacks can set an error; in particular the
%G_MARKUP_ERROR_UNKNOWN_ELEMENT, %G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
and %G_MARKUP_ERROR_INVALID_CONTENT errors are intended to be set
from these callbacks. If you set an error from a callback,
g_markup_parse_context_parse() will report that error back to its caller.
</para>
@start_element: Callback to invoke when the opening tag of an element
is seen.
@end_element: Callback to invoke when the closing tag of an element is seen
@text: Callback to invoke when some text is seen (text is always
inside an element)
@passthrough: Callback to invoke for comments and processing
instructions; if you're re-writing the parsed document, write the
passthrough text back out in the same position
@error: Callback to invoke when an error occurs
<!-- ##### FUNCTION g_markup_escape_text ##### -->
<para>
</para>
@text:
@length:
@Returns:
<!-- ##### FUNCTION g_markup_parse_context_end_parse ##### -->
<para>
</para>
@context:
@error:
@Returns:
<!-- ##### FUNCTION g_markup_parse_context_free ##### -->
<para>
</para>
@context:
<!-- ##### FUNCTION g_markup_parse_context_get_position ##### -->
<para>
</para>
@context:
@line_number:
@char_number:
<!-- ##### FUNCTION g_markup_parse_context_new ##### -->
<para>
</para>
@parser:
@flags:
@user_data:
@user_data_dnotify:
@Returns:
<!-- ##### FUNCTION g_markup_parse_context_parse ##### -->
<para>
</para>
@context:
@text:
@text_len:
@error:
@Returns:

View File

@ -83,9 +83,9 @@ Note that this must be called before any records are added to the #GRelation.
@relation: a #GRelation.
@field: the field to index, counting from 0.
@hash_func: a function to produce a hash value from the field data.
@key_equal_func: a function to compare two values of the given field.
<!-- # Unused Parameters # -->
@key_compare_func:
<!-- # Unused Parameters # -->
@key_equal_func: a function to compare two values of the given field.
<!-- ##### FUNCTION g_relation_insert ##### -->

View File

@ -36,13 +36,13 @@ Shell-related Utilities
</para>
@command_line:
@argcp:
@argvp:
@argc:
@argv:
@error:
@Returns:
<!-- # Unused Parameters # -->
@argc:
@argv:
@argcp:
@argvp:
<!-- ##### FUNCTION g_shell_quote ##### -->

View File

@ -45,16 +45,6 @@ Creates a new #GString, initialized with the given string.
@Returns: the new #GString.
<!-- ##### FUNCTION g_string_new_len ##### -->
<para>
</para>
@init:
@len:
@Returns:
<!-- ##### FUNCTION g_string_sized_new ##### -->
<para>
Creates a new GString, with enough space for @dfl_size characters.

View File

@ -61,16 +61,6 @@ second.
@Returns: a new #GTree.
<!-- ##### FUNCTION g_tree_new_with_data ##### -->
<para>
</para>
@key_compare_func:
@user_data:
@Returns:
<!-- ##### FUNCTION g_tree_insert ##### -->
<para>
Inserts a key/value pair into a #GTree.

View File

@ -1,3 +1,82 @@
Mon Dec 11 04:44:11 2000 Tim Janik <timj@gtk.org>
* gboxed.c: fixed dealing with collection/lcopy of NULL values.
* gclosure.h: removed insane ramblings, added G_CALLBACK() a casting
convenience macro.
* Makefile.am: cleanups, marshaller generation rules.
* gmarshal.[hc]: new files with GRuntime standard marshallers.
* glib-genmarshal.c: fix log domain, support gruntime standard
marshallers, suport G_TYPE_PARAM, come with extern "C" and
#include gmarshal.h.
* glib-genmarshal.1: reflect glib-genmarshal.c updates.
* gobject.[hc]: implement object constructor. rework parameter
changed notification queueing, we support queue freezes now and
don't dispatch from an idle handler anymore.
parameter->property rename hassle.
implemented ::properties_changed and ::notify::* signals for
property change notification (the later supports property names
as details). added signal connection and named data properties.
(g_signal_connect_object): new function to setup while_alive
connections.
(g_object_class_install_property): sink properties now, since they
are initially floating.
(g_object_steal_data):
(g_object_set_data_full):
(g_object_set_data):
(g_object_get_data): set/get data by using g_datalist_*() functions
directly.
(g_object_queue_param_changed): nuked.
(g_object_freeze_notify): start queueing of property changes (freeze/
thaw calls stack).
(g_object_notify): announce changes of a certain property directly.
(g_object_thaw_notify): process queue of property changes, therefore
emitting GObject::notify::detail with detail being the changed
properties names.
(G_OBJECT_WARN_INVALID_PROPERTY_ID): saner macro variant of former
G_WARN_INVALID_PARAM_ID().
* gparam.[hc]: param specs are now initially floating and need to be
sunken with g_param_spec_sink(), support G_TYPE_PARAM values.
added G_PARAM_CONSTRUCT and G_PARAM_CONSTRUCT_ONLY parameter flags,
required by GObjectClass.constructor().
* gparamspecs.[hc]: added GParamSpecParam, GParamSpecPointer and
GParamSpecCCallback, param specs for G_TYPE_PARAM, G_TYPE_POINTER
and G_TYPE_CCALLBACK respectively.
* gsignal.[hc]: cleanups.
(signal_id_lookup): after walking the anchestry, try interfaces as well.
(g_signal_new): new function to create signals from varargs type list.
(g_signal_connect_closure): closure connection variant that works from
signal name+detail.
(g_signal_connect_data): c handler connection variant that works from
signal name+detail.
(g_signal_emit_valist): emit signal for an instance with paraneters
collected from a va_list.
(g_signal_emit): emit signal, taking parameters from varargs list.
(g_signal_emit_by_name): same as g_signal_emit, working from
signal name+detail.
(signal_emit_R): return whether return_value needs to be altered.
* gtype.[hc]: set log-domain to GRuntime, i'm slowly getting to all
the points that need to reflect the upcoming rename.
melt g_type_conforms_to() functionality into g_type_is_a(), as that
is what we really want (liskov substitution principle).
assorted changes to other files due to conforms_to->is_a.
* gvalue.[hc]: implemented g_value_set_instance() that sets a value
from an instantiatable type via the value_table's collect_value()
function (based on an idea from James Henstridge <james@daa.com.au>).
cleanups/fixes.
* gvaluetypes.[hc]: implement G_TYPE_CCALLBACK and G_TYPE_PARAM.
Wed Nov 29 13:30:05 2000 Tim Janik <timj@gtk.org>
* gsignal.c (handlers_find): fix elliots "logic fix" that dereferences

View File

@ -1,28 +1,31 @@
# GObject - GLib Type, Object, Parameter and Signal Library
# GRuntime - GLib Type, Object, Parameter and Signal Library
# Copyright (C) 1997,98,99,2000 Tim Janik and Red Hat, Inc.
#
## Process this file with automake to produce Makefile.in
INCLUDES = -I$(top_srcdir) -I$(top_builddir) @GLIB_DEBUG_FLAGS@
INCLUDES = @STRIP_BEGIN@ \
-DG_LOG_DOMAIN=g_log_domain_gruntime \
-I$(top_srcdir) \
-I$(top_builddir) \
@GLIB_DEBUG_FLAGS@ \
@STRIP_END@
# libraries to compile and install
lib_LTLIBRARIES = libgobject-1.3.la
# provide g_logv() domain
AM_CFLAGS = -DG_LOG_DOMAIN=g_log_domain_gobject
# libtool stuff: set version and export symbols for resolving
libgobjectincludedir = $(includedir)/glib-2.0/gobject
libgobject_1_3_la_LDFLAGS = \
libgobject_1_3_la_LDFLAGS = @STRIP_BEGIN@ \
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \
-export-dynamic
-export-dynamic \
@STRIP_END@
libgobject_1_3_la_LIBADD = # $(libglib)
#
# setup source file variables
#
# GObject header files for public installation (non-generated)
gobject_public_h_sources = @STRIP_BEGIN@ \
# GRuntime header files for public installation (non-generated)
gruntime_public_h_sources = @STRIP_BEGIN@ \
gboxed.h \
gbsearcharray.h \
gclosure.h \
@ -38,12 +41,10 @@ gobject_public_h_sources = @STRIP_BEGIN@ \
gvaluecollector.h \
gvaluetypes.h \
@STRIP_END@
# private GObject header files
gobject_private_h_sources =
# GObject C sources to build the library from
gobject_c_sources = @STRIP_BEGIN@ \
# GRuntime header files that don't get installed
gruntime_private_h_sources =
# GRuntime C sources to build the library from
gruntime_c_sources = @STRIP_BEGIN@ \
gboxed.c \
gbsearcharray.c \
gclosure.c \
@ -59,23 +60,85 @@ gobject_c_sources = @STRIP_BEGIN@ \
gvaluetypes.c \
@STRIP_END@
# we use our own built_sources variable rules to avoid automake's
# BUILT_SOURCES oddities
# we generate frequently rebuild files piggyback on a stamp file, so sources
# depending on them only get rebuild when the built source actually changed
# content
# built sources that get installed with the header files
gruntime_built_public_sources = @STRIP_BEGIN@ \
gmarshal.h \
@STRIP_END@
# built sources that don't get installed
gruntime_built_sources = @STRIP_BEGIN@ \
stamp-gmarshal.h \
gmarshal.c \
${gruntime_built_public_sources} \
@STRIP_END@
# non-header sources (headers should be specified in the above variables)
# that don't serve as direct make target sources, i.e. they don't have
# their own .lo rules and don't get publically installed
gobject_extra_sources =
gruntime_extra_sources = @STRIP_BEGIN@ \
gmarshal.list \
gmarshal.strings \
@STRIP_END@
#
# setup GObject sources and their dependancies
# setup GRuntime sources and their dependancies
#
gobject_h_sources = $(gobject_private_h_sources) $(gobject_public_h_sources) # $(gobject_built_public_sources)
libgobjectinclude_HEADERS = $(gobject_public_h_sources) # $(gobject_built_public_sources)
libgobject_1_3_la_SOURCES = $(gobject_c_sources)
MAINTAINERCLEANFILES +=
# $(gobject_built_public_sources) $(gobject_built_sources)
gruntime_target_headers = $(gruntime_public_h_sources) $(gruntime_built_public_sources)
gruntime_target_sources = $(gruntime_c_sources)
MAINTAINERCLEANFILES += $(gruntime_built_sources)
EXTRA_HEADERS +=
EXTRA_DIST += $(gobject_private_h_sources)
EXTRA_DIST += $(gobject_extra_sources)
# $(gobject_built_sources) $(gobject_built_public_sources)
EXTRA_DIST += $(gruntime_private_h_sources) $(gruntime_extra_sources)
EXTRA_DIST += $(gruntime_built_sources)
#
# rules to generate built sources
#
# setup autogeneration dependancies
gen_sources = xgen-gmh xgen-gmc xgen-gms
CLEANFILES += $(gen_sources)
Makefile: oldest-source-stamp # oh boy, does automake SUCK!
oldest-source-stamp: $(gruntime_built_sources)
$(OBJECTS): oldest-source-stamp ${gruntime_built_public_sources} # this is our oldest file, used for implicit auto-generation deps
# initial creation of the real stamp-* files
gmarshal.h: # never add deps here
test -f "$(srcdir)/$@" || touch $(srcdir)/$@
# normal autogeneration rules
# all autogenerated files need to be generated in the srcdir,
# so old versions get remade and are not confused with newer
# versions in the build dir. thus a development setup requires
# srcdir to be writable, passing --disable-rebuilds to
# ../configure will supress all autogeneration rules.
$(srcdir)/stamp-gmarshal.h: @REBUILD@ gmarshal.list gmarshal.h glib-genmarshal
cd $(srcdir) \
&& echo "#ifndef __G_MARSHAL_H__" > xgen-gmh \
&& echo "#define __G_MARSHAL_H__" >> xgen-gmh \
&& ./glib-genmarshal --nostdinc --prefix=g_cclosure_marshal gmarshal.list --header >> xgen-gmh \
&& echo "#endif /* __G_MARSHAL_H__ */" >> xgen-gmh \
&& (cmp -s xgen-gmh gmarshal.h || cp xgen-gmh gmarshal.h) \
&& rm -f xgen-gmh xgen-gmh~ \
&& echo timestamp > $(@F)
$(srcdir)/gmarshal.c: @REBUILD@ $(srcdir)/stamp-gmarshal.h
cd $(srcdir) \
&& ./glib-genmarshal --nostdinc --prefix=g_cclosure_marshal gmarshal.list --body >> xgen-gmc \
&& cp xgen-gmc gmarshal.c \
&& rm -f xgen-gmc xgen-gmc~
$(srcdir)/gmarshal.strings: @REBUILD@ $(srcdir)/gmarshal.list
cd $(srcdir) \
&& grep '^[A-Z]' $(srcdir)/gmarshal.list \
| sed -e 's/^/"g_cclosure_marshal_/' -e 's/:/__/' -e 's/,/_/g' -e 's/$$/",/' > xgen-gms \
&& cp xgen-gms gmarshal.strings \
&& rm -f xgen-gms xgen-gms~
glib-genmarshal.o: gmarshal.strings
# target platform:
libgobjectinclude_HEADERS = $(gruntime_target_headers)
libgobject_1_3_la_SOURCES = $(gruntime_target_sources)
#
# programs to compile and install
@ -86,8 +149,8 @@ gobject_query_SOURCES = gobject-query.c
glib_genmarshal_SOURCES = glib-genmarshal.c
# link programs against libgobject
progs_LDADD = ../libglib-1.3.la libgobject-1.3.la
glib_genmarshal_LDADD = ../libglib-1.3.la # can't have libgobject here
gobject_query_LDADD = $(progs_LDADD)
glib_genmarshal_LDADD = $(progs_LDADD)
#
# manual pages to install
@ -123,4 +186,3 @@ dist-hook: $(BUILT_EXTRA_DIST)
for f in $$files; do \
if test -f $$f; then d=.; else d=$(srcdir); fi; \
cp $$d/$$f $(distdir) || exit 1; done

View File

@ -127,7 +127,7 @@ boxed_proxy_collect_value (GValue *value,
key.type = value->g_type;
node = g_bsearch_array_lookup (&boxed_bsa, &key);
value->data[0].v_pointer = node->copy (collect_value->v_pointer);
value->data[0].v_pointer = collect_value->v_pointer ? node->copy (collect_value->v_pointer) : NULL;
*collect_type = 0;
return NULL;
@ -147,7 +147,7 @@ boxed_proxy_lcopy_value (const GValue *value,
key.type = value->g_type;
node = g_bsearch_array_lookup (&boxed_bsa, &key);
*boxed_p = node->copy (value->data[0].v_pointer);
*boxed_p = value->data[0].v_pointer ? node->copy (value->data[0].v_pointer) : NULL;
*collect_type = 0;
return NULL;

View File

@ -524,7 +524,7 @@ g_type_iface_meta_marshal (GClosure *closure,
}
GClosure*
g_signal_type_closure_new (GType itype,
g_signal_type_cclosure_new (GType itype,
guint struct_offset)
{
GClosure *closure;

View File

@ -32,6 +32,7 @@ extern "C" {
/* --- defines --- */
#define G_CLOSURE_NEEDS_MARSHAL(closure) (((GClosure*) (closure))->marshal == NULL)
#define G_CCLOSURE_SWAP_DATA(cclosure) (((GClosure*) (closure))->derivative_flag)
#define G_CALLBACK(f) ((GCallback) (f))
/* -- typedefs --- */
@ -105,7 +106,7 @@ GClosure* g_cclosure_new (GCallback callback_func,
GClosure* g_cclosure_new_swap (GCallback callback_func,
gpointer user_data,
GClosureNotify destroy_data);
GClosure* g_signal_type_closure_new (GType itype,
GClosure* g_signal_type_cclosure_new (GType itype,
guint struct_offset);
@ -146,35 +147,14 @@ void g_closure_invoke (GClosure *closure,
/* FIXME:
data_object::destroy -> closure_invalidate();
closure_invalidate() -> disconnect(closure);
disconnect(closure) -> (unlink) closure_unref();
closure_finalize() -> g_free (data_string);
1) need GObject and GType in glib
2) need GParam
3) need to resolve dtor cycles
4) need GSignal move
5) destroy on last caller ref or last data ref?
OK: data_object::destroy -> closure_invalidate();
MIS: closure_invalidate() -> disconnect(closure);
MIS: disconnect(closure) -> (unlink) closure_unref();
OK: closure_finalize() -> g_free (data_string);
random remarks:
- don't mandate signals for GObject
- OTOH, don't mandate GObject for GSignal
- need marshaller repo with decent aliasing to base types
- provide marshaller collection, virtually covering anything out there
- at that point, still need GSignalCMarhsaller to g_signal_new() ?
- can we combine varargs collect mechanisms with marshaller stubs?
for out values (i.e. returntypes), that might get rid of the following
point...
- char* return signals with connections ala:
connect({ return "static data that can't work"; }),
connect({ return g_strdup ("properly duplicated string"); })
won't work anymore. CRASH
problems:
- accumulator needs gboolean to indicate EMISSION_STOP
- accumulator needs data
*/

View File

@ -35,6 +35,10 @@ Specify marshaller prefix. The default prefix is `\fIg_cclosure_marshal\fP'.
\fI--skip-source
Skip source location remarks in generated comments.
.TP
\fI--nostdinc
Do not use the standard GRuntime marshallers, and skip gmarshal.h include
directive in generated header files.
.TP
\fI--g-fatal-warnings
Make warnings fatal, that is, exit immediately once a warning occours.
.TP
@ -118,6 +122,8 @@ for string types (gchar*)
\fIBOXED
for boxed (anonymous but reference counted) types (GBoxed*)
.TP 12
\fIPARAM
for GParamSpec or derived types (GParamSpec*)
\fIPOINTER
for anonymous pointer types (gpointer)
.TP 12

View File

@ -18,7 +18,13 @@
*/
#include "config.h"
#include <glib-object.h>
/* ok, this is a bit hackish, have to provide gruntime log domain as
* we don't link against -lgruntime
*/
char *g_log_domain_gruntime = "GLib-Genmarshal";
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
@ -108,11 +114,13 @@ static GScannerConfig scanner_config_template =
FALSE /* symbol_2_token */,
FALSE /* scope_0_fallback */,
};
static gchar *marshaller_prefix = "g_cclosure_marshal";
static gchar *std_marshaller_prefix = "g_cclosure_marshal";
static gchar *marshaller_prefix = "g_cclosure_user_marshal";
static GHashTable *marshallers = NULL;
static gboolean gen_cheader = FALSE;
static gboolean gen_cbody = FALSE;
static gboolean skip_ploc = FALSE;
static gboolean std_includes = TRUE;
/* --- functions --- */
@ -142,12 +150,14 @@ complete_arg (Argument *arg,
{ "STRING", "POINTER", "as_pointer", "gpointer", },
{ "BOXED", "POINTER", "as_pointer", "gpointer", },
{ "POINTER", "POINTER", "as_pointer", "gpointer", },
{ "PARAM", "POINTER", "as_pointer", "gpointer", },
{ "OBJECT", "POINTER", "as_pointer", "gpointer", },
};
static const Argument out_arguments[] = {
{ "STRING", "STRING", "string", "gchar*", },
{ "BOXED", "BOXED", "boxed", "gpointer", },
{ "POINTER", "POINTER", "pointer", "gpointer", },
{ "PARAM", "PARAM", "param", "GParamSpec*", },
{ "OBJECT", "OBJECT", "object", "GObject*", },
};
const guint n_inout_arguments = sizeof (inout_arguments) / sizeof (inout_arguments[0]);
@ -201,7 +211,7 @@ pad (const gchar *string)
{
g_free (buffer);
buffer = g_strdup_printf ("%s ", string);
g_warning ("overfull string (%lu bytes) for padspace", strlen (string));
g_warning ("overfull string (%u bytes) for padspace", (guint) strlen (string));
return buffer;
}
@ -241,17 +251,39 @@ generate_marshal (const gchar *signame,
{
guint ind, a;
GList *node;
gchar *tmp = g_strconcat (marshaller_prefix, "_", signame, NULL);
gboolean have_std_marshaller = FALSE;
if (g_hash_table_lookup (marshallers, signame))
/* here we have to make sure a marshaller named <marshaller_prefix>_<signame>
* exists. we might have put it out already, can revert to a standard marshaller
* provided by glib, or need to generate one.
*/
if (g_hash_table_lookup (marshallers, tmp))
{
/* done, marshaller already generated */
g_free (tmp);
return;
}
else
{
gchar *tmp = g_strdup (signame);
/* need to alias/generate marshaller, register name */
g_hash_table_insert (marshallers, tmp, tmp);
}
if (gen_cheader)
/* can we revert to a standard marshaller? */
if (std_includes)
{
tmp = g_strconcat (std_marshaller_prefix, "_", signame, NULL);
have_std_marshaller = g_hash_table_lookup (marshallers, tmp) != NULL;
g_free (tmp);
}
if (gen_cheader && have_std_marshaller)
{
fprintf (fout, "#define %s_%s\t%s_%s\n", marshaller_prefix, signame, std_marshaller_prefix, signame);
}
if (gen_cheader && !have_std_marshaller)
{
ind = fprintf (fout, "extern void ");
ind += fprintf (fout, "%s_%s (", marshaller_prefix, signame);
@ -262,7 +294,7 @@ generate_marshal (const gchar *signame,
fprintf (fout, "%sgpointer invocation_hint,\n", indent (ind));
fprintf (fout, "%sgpointer marshal_data);\n", indent (ind));
}
if (gen_cbody)
if (gen_cbody && !have_std_marshaller)
{
/* cfile marhsal header */
fprintf (fout, "void\n");
@ -352,7 +384,7 @@ generate_marshal (const gchar *signame,
static void
process_signature (Signature *sig)
{
gchar *pname, *sname;
gchar *pname, *sname, *tmp;
GList *node;
/* lookup and complete info on arguments */
@ -400,18 +432,19 @@ process_signature (Signature *sig)
fprintf (fout, " (%s)", sig->ploc);
fprintf (fout, " */\n");
/* generate signature marshaller */
/* ensure technical marshaller exists (<marshaller_prefix>_<sname>) */
generate_marshal (sname, sig);
/* put out marshaler alias if required */
if (gen_cheader && !g_hash_table_lookup (marshallers, pname))
/* put out marshaller alias for requested name if required (<marshaller_prefix>_<pname>) */
tmp = g_strconcat (marshaller_prefix, "_", pname, NULL);
if (gen_cheader && !g_hash_table_lookup (marshallers, tmp))
{
gchar *tmp = g_strdup (pname);
fprintf (fout, "#define %s_%s\t%s_%s\n", marshaller_prefix, pname, marshaller_prefix, sname);
g_hash_table_insert (marshallers, tmp, tmp);
}
else
g_free (tmp);
g_free (pname);
g_free (sname);
@ -482,6 +515,9 @@ int
main (int argc,
char *argv[])
{
const gchar *gruntime_marshallers[] = {
#include "gmarshal.strings"
};
GScanner *scanner;
GSList *slist, *files = NULL;
gint i;
@ -502,6 +538,24 @@ main (int argc,
fout = stdout;
marshallers = g_hash_table_new (g_str_hash, g_str_equal);
/* add GRuntime standard marshallers */
if (std_includes)
for (i = 0; i < sizeof (gruntime_marshallers) / sizeof (gruntime_marshallers[0]); i++)
{
gchar *tmp = g_strdup (gruntime_marshallers[i]);
g_hash_table_insert (marshallers, tmp, tmp);
}
/* put out initial heading */
fprintf (fout, "\n");
if (gen_cheader)
{
if (std_includes)
fprintf (fout, "#include\t<gobject/gmarshal.h>\n\n");
fprintf (fout, "#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n");
}
/* process input files */
for (slist = files; slist; slist = slist->next)
{
@ -579,6 +633,13 @@ main (int argc,
close (fd);
}
/* put out trailer */
if (gen_cheader)
{
fprintf (fout, "\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n");
}
fprintf (fout, "\n");
/* clean up */
g_slist_free (files);
g_scanner_destroy (scanner);
@ -613,6 +674,16 @@ parse_args (gint *argc_p,
skip_ploc = TRUE;
argv[i] = NULL;
}
else if (strcmp ("--nostdinc", argv[i]) == 0)
{
std_includes = FALSE;
argv[i] = NULL;
}
else if (strcmp ("--stdinc", argv[i]) == 0)
{
std_includes = TRUE;
argv[i] = NULL;
}
else if ((strcmp ("--prefix", argv[i]) == 0) ||
(strncmp ("--prefix=", argv[i], 9) == 0))
{
@ -694,6 +765,7 @@ print_blurb (FILE *bout,
fprintf (bout, " --body generate C code\n");
fprintf (bout, " --prefix=string specify marshaller prefix\n");
fprintf (bout, " --skip-source skip source location comments\n");
fprintf (bout, " --stdinc, --nostdinc include/use GRuntime standard marshallers\n");
fprintf (bout, " -h, --help show this help message\n");
fprintf (bout, " -v, --version print version informations\n");
fprintf (bout, " --g-fatal-warnings make warnings fatal (abort)\n");

File diff suppressed because it is too large Load Diff

View File

@ -43,20 +43,18 @@ extern "C" {
#define G_OBJECT_CLASS_NAME(class) (g_type_name (G_OBJECT_CLASS_TYPE (class)))
#define G_IS_VALUE_OBJECT(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_OBJECT))
#define G_NOTIFY_PRIORITY (G_PRIORITY_HIGH_IDLE + 20)
/* --- typedefs & structures --- */
typedef struct _GObject GObject;
typedef struct _GObjectClass GObjectClass;
typedef struct _GObjectConstructParam GObjectConstructParam;
typedef void (*GObjectGetParamFunc) (GObject *object,
guint param_id,
typedef void (*GObjectGetPropertyFunc) (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec,
const gchar *trailer);
typedef void (*GObjectSetParamFunc) (GObject *object,
guint param_id,
typedef void (*GObjectSetPropertyFunc) (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec,
const gchar *trailer);
@ -73,69 +71,81 @@ struct _GObjectClass
{
GTypeClass g_type_class;
guint n_param_specs;
GParamSpec **param_specs;
/* private, these fields might vanish */
guint n_property_specs;
GParamSpec **property_specs;
GObject* (*constructor) (GType type, // FIXME!!!
guint n_construct_params,
/* public overridable methods */
GObject* (*constructor) (GType type,
guint n_construct_properties,
GObjectConstructParam *construct_params);
void (*get_param) (GObject *object,
guint param_id,
void (*get_property) (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec,
const gchar *trailer);
void (*set_param) (GObject *object,
guint param_id,
void (*set_property) (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec,
const gchar *trailer);
void (*queue_param_changed) (GObject *object,
GParamSpec *pspec);
void (*dispatch_param_changed) (GObject *object,
GParamSpec *pspec);
void (*shutdown) (GObject *object);
void (*finalize) (GObject *object);
/*< private >*/
void (*dispatch_properties_changed) (GObject *object,
guint n_pspecs,
GParamSpec **pspecs);
/* signals */
void (*properties_changed) (GObject *object,
guint n_pspecs,
GParamSpec **pspecs);
void (*notify) (GObject *object,
GParamSpec *pspec);
};
struct _GObjectConstructParam
{
GParamSpec *pspec;
GValue *value;
gchar *trailer;
const gchar *trailer;
};
/* --- prototypes --- */
void g_object_class_install_param (GObjectClass *oclass,
guint param_id,
GParamSpec *pspec /* +1 ref */);
GParamSpec* g_object_class_find_param_spec (GObjectClass *oclass,
const gchar *param_name);
void g_object_class_install_property (GObjectClass *oclass,
guint property_id,
GParamSpec *pspec);
GParamSpec* g_object_class_find_property (GObjectClass *oclass,
const gchar *property_name);
gpointer g_object_new (GType object_type,
const gchar *first_param_name,
const gchar *first_property_name,
...);
gpointer g_object_new_valist (GType object_type,
const gchar *first_param_name,
const gchar *first_property_name,
va_list var_args);
void g_object_set (GObject *object,
const gchar *first_param_name,
const gchar *first_property_name,
...);
void g_object_get (GObject *object,
const gchar *first_param_name,
const gchar *first_property_name,
...);
void g_object_set_valist (GObject *object,
const gchar *first_param_name,
const gchar *first_property_name,
va_list var_args);
void g_object_get_valist (GObject *object,
const gchar *first_param_name,
const gchar *first_property_name,
va_list var_args);
void g_object_set_param (GObject *object,
const gchar *param_name,
void g_object_set_property (GObject *object,
const gchar *property_name,
const GValue *value);
void g_object_get_param (GObject *object,
const gchar *param_name,
void g_object_get_property (GObject *object,
const gchar *property_name,
GValue *value);
void g_object_queue_param_changed (GObject *object,
const gchar *param_name);
void g_object_freeze_notify (GObject *object);
void g_object_notify (GObject *object,
const gchar *property_name);
void g_object_thaw_notify (GObject *object);
GObject* g_object_ref (GObject *object);
void g_object_unref (GObject *object);
gpointer g_object_get_qdata (GObject *object,
@ -172,17 +182,23 @@ void g_value_set_object (GValue *value,
GObject *v_object);
GObject* g_value_get_object (const GValue *value);
GObject* g_value_dup_object (const GValue *value);
guint g_signal_connect_object (gpointer instance,
const gchar *detailed_signal,
GCallback c_handler,
gpointer gobject,
gboolean swapped,
gboolean after);
/* --- implementation macros --- */
#define G_WARN_INVALID_PARAM_ID(object, param_id, pspec) \
#define G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec) \
G_STMT_START { \
GObject *_object = (GObject*) (object); \
GParamSpec *_pspec = (GParamSpec*) (pspec); \
guint _param_id = (param_id); \
g_warning ("%s: invalid parameter id %u for \"%s\" of type `%s' in `%s'", \
guint _property_id = (property_id); \
g_warning ("%s: invalid property id %u for \"%s\" of type `%s' in `%s'", \
G_STRLOC, \
_param_id, \
_property_id, \
_pspec->name, \
g_type_name (G_PARAM_SPEC_TYPE (_pspec)), \
G_OBJECT_TYPE_NAME (_object)); \

View File

@ -19,12 +19,14 @@
#include "gparam.h"
#include "gvaluecollector.h"
#include <string.h>
/* --- defines --- */
#define G_PARAM_SPEC_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), G_TYPE_PARAM, GParamSpecClass))
#define PSPEC_APPLIES_TO_VALUE(pspec, value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_PARAM_SPEC_VALUE_TYPE (pspec)))
/* --- prototypes --- */
@ -34,6 +36,23 @@ static void g_param_spec_class_init (GParamSpecClass *class,
gpointer class_data);
static void g_param_spec_init (GParamSpec *pspec);
static void g_param_spec_finalize (GParamSpec *pspec);
static void value_param_init (GValue *value);
static void value_param_free_value (GValue *value);
static void value_param_copy_value (const GValue *src_value,
GValue *dest_value);
static gpointer value_param_peek_pointer (const GValue *value);
static gchar* value_param_collect_value (GValue *value,
guint nth_value,
GType *collect_type,
GTypeCValue *collect_value);
static gchar* value_param_lcopy_value (const GValue *value,
guint nth_value,
GType *collect_type,
GTypeCValue *collect_value);
/* --- variables --- */
static GQuark quark_floating = 0;
/* --- functions --- */
@ -46,6 +65,16 @@ g_param_type_init (void) /* sync with gtype.c */
G_TYPE_FLAG_DERIVABLE |
G_TYPE_FLAG_DEEP_DERIVABLE),
};
static const GTypeValueTable param_value_table = {
value_param_init, /* value_init */
value_param_free_value, /* value_free */
value_param_copy_value, /* value_copy */
value_param_peek_pointer, /* value_peek_pointer */
G_VALUE_COLLECT_POINTER, /* collect_type */
value_param_collect_value, /* collect_value */
G_VALUE_COLLECT_POINTER, /* lcopy_type */
value_param_lcopy_value, /* lcopy_value */
};
static const GTypeInfo param_spec_info = {
sizeof (GParamSpecClass),
@ -59,7 +88,7 @@ g_param_type_init (void) /* sync with gtype.c */
0, /* n_preallocs */
(GInstanceInitFunc) g_param_spec_init,
NULL, /* value_table */
&param_value_table,
};
GType type;
@ -81,6 +110,8 @@ static void
g_param_spec_class_init (GParamSpecClass *class,
gpointer class_data)
{
quark_floating = g_quark_from_static_string ("GParamSpec-floating");
class->value_type = G_TYPE_NONE;
class->finalize = g_param_spec_finalize;
class->value_set_default = NULL;
@ -98,6 +129,7 @@ g_param_spec_init (GParamSpec *pspec)
pspec->owner_type = 0;
pspec->qdata = NULL;
pspec->ref_count = 1;
g_datalist_id_set_data (&pspec->qdata, quark_floating, GUINT_TO_POINTER (TRUE));
}
static void
@ -129,11 +161,28 @@ g_param_spec_unref (GParamSpec *pspec)
g_return_if_fail (G_IS_PARAM_SPEC (pspec));
g_return_if_fail (pspec->ref_count > 0);
/* sync with _sink */
pspec->ref_count -= 1;
if (pspec->ref_count == 0)
G_PARAM_SPEC_GET_CLASS (pspec)->finalize (pspec);
}
void
g_param_spec_sink (GParamSpec *pspec)
{
g_return_if_fail (G_IS_PARAM_SPEC (pspec));
g_return_if_fail (pspec->ref_count > 0);
if (g_datalist_id_remove_no_notify (&pspec->qdata, quark_floating))
{
/* sync with _unref */
if (pspec->ref_count > 1)
pspec->ref_count -= 1;
else
g_param_spec_unref (pspec);
}
}
gpointer
g_param_spec_internal (GType param_type,
const gchar *name,
@ -204,7 +253,7 @@ g_param_value_set_default (GParamSpec *pspec,
{
g_return_if_fail (G_IS_PARAM_SPEC (pspec));
g_return_if_fail (G_IS_VALUE (value));
g_return_if_fail (G_IS_PARAM_VALUE (pspec, value));
g_return_if_fail (PSPEC_APPLIES_TO_VALUE (pspec, value));
g_value_reset (value);
G_PARAM_SPEC_GET_CLASS (pspec)->value_set_default (pspec, value);
@ -219,7 +268,7 @@ g_param_value_defaults (GParamSpec *pspec,
g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE);
g_return_val_if_fail (G_IS_VALUE (value), FALSE);
g_return_val_if_fail (G_IS_PARAM_VALUE (pspec, value), FALSE);
g_return_val_if_fail (PSPEC_APPLIES_TO_VALUE (pspec, value), FALSE);
g_value_init (&dflt_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
G_PARAM_SPEC_GET_CLASS (pspec)->value_set_default (pspec, &dflt_value);
@ -235,7 +284,7 @@ g_param_value_validate (GParamSpec *pspec,
{
g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE);
g_return_val_if_fail (G_IS_VALUE (value), FALSE);
g_return_val_if_fail (G_IS_PARAM_VALUE (pspec, value), FALSE);
g_return_val_if_fail (PSPEC_APPLIES_TO_VALUE (pspec, value), FALSE);
if (G_PARAM_SPEC_GET_CLASS (pspec)->value_validate)
{
@ -265,14 +314,90 @@ g_param_values_cmp (GParamSpec *pspec,
g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), 0);
g_return_val_if_fail (G_IS_VALUE (value1), 0);
g_return_val_if_fail (G_IS_VALUE (value2), 0);
g_return_val_if_fail (G_IS_PARAM_VALUE (pspec, value1), 0);
g_return_val_if_fail (G_IS_PARAM_VALUE (pspec, value2), 0);
g_return_val_if_fail (PSPEC_APPLIES_TO_VALUE (pspec, value1), 0);
g_return_val_if_fail (PSPEC_APPLIES_TO_VALUE (pspec, value2), 0);
cmp = G_PARAM_SPEC_GET_CLASS (pspec)->values_cmp (pspec, value1, value2);
return CLAMP (cmp, -1, 1);
}
static void
value_param_init (GValue *value)
{
value->data[0].v_pointer = NULL;
}
static void
value_param_free_value (GValue *value)
{
if (value->data[0].v_pointer)
g_param_spec_unref (value->data[0].v_pointer);
}
static void
value_param_copy_value (const GValue *src_value,
GValue *dest_value)
{
dest_value->data[0].v_pointer = (src_value->data[0].v_pointer
? g_param_spec_ref (src_value->data[0].v_pointer)
: NULL);
}
static gpointer
value_param_peek_pointer (const GValue *value)
{
return value->data[0].v_pointer;
}
static gchar*
value_param_collect_value (GValue *value,
guint nth_value,
GType *collect_type,
GTypeCValue *collect_value)
{
if (collect_value->v_pointer)
{
GParamSpec *param = collect_value->v_pointer;
if (param->g_type_instance.g_class == NULL)
return g_strconcat ("invalid unclassed param spec pointer for value type `",
G_VALUE_TYPE_NAME (value),
"'",
NULL);
else if (!g_type_is_a (G_PARAM_SPEC_TYPE (param), G_VALUE_TYPE (value)))
return g_strconcat ("invalid param spec type `",
G_PARAM_SPEC_TYPE_NAME (param),
"' for value type `",
G_VALUE_TYPE_NAME (value),
"'",
NULL);
value->data[0].v_pointer = g_param_spec_ref (param);
}
else
value->data[0].v_pointer = NULL;
*collect_type = 0;
return NULL;
}
static gchar*
value_param_lcopy_value (const GValue *value,
guint nth_value,
GType *collect_type,
GTypeCValue *collect_value)
{
GParamSpec **param_p = collect_value->v_pointer;
if (!param_p)
return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
*param_p = value->data[0].v_pointer ? g_param_spec_ref (value->data[0].v_pointer) : NULL;
*collect_type = 0;
return NULL;
}
static guint
param_spec_hash (gconstpointer key_spec)
{
@ -468,3 +593,34 @@ g_param_type_register_static (const gchar *name,
return g_type_register_static (G_TYPE_PARAM, name, &info, 0);
}
void
g_value_set_param (GValue *value,
GParamSpec *param)
{
g_return_if_fail (G_IS_VALUE_PARAM (value));
if (param)
g_return_if_fail (G_IS_PARAM_SPEC (param));
if (value->data[0].v_pointer)
g_param_spec_unref (value->data[0].v_pointer);
value->data[0].v_pointer = param;
if (value->data[0].v_pointer)
g_param_spec_ref (value->data[0].v_pointer);
}
GParamSpec*
g_value_get_param (const GValue *value)
{
g_return_val_if_fail (G_IS_VALUE_PARAM (value), NULL);
return value->data[0].v_pointer;
}
GParamSpec*
g_value_dup_param (const GValue *value)
{
g_return_val_if_fail (G_IS_VALUE_PARAM (value), NULL);
return value->data[0].v_pointer ? g_param_spec_ref (value->data[0].v_pointer) : NULL;
}

View File

@ -37,8 +37,8 @@ extern "C" {
#define G_PARAM_SPEC(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM, GParamSpec))
#define G_IS_PARAM_SPEC(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM))
#define G_PARAM_SPEC_GET_CLASS(pspec) (G_TYPE_INSTANCE_GET_CLASS ((pspec), G_TYPE_PARAM, GParamSpecClass))
#define G_IS_PARAM_VALUE(pspec, value) (g_type_is_a (G_VALUE_TYPE (value), G_PARAM_SPEC_VALUE_TYPE (pspec))) /* FIXME */
#define G_PARAM_SPEC_VALUE_TYPE(pspec) (G_PARAM_SPEC_GET_CLASS (pspec)->value_type)
#define G_IS_VALUE_PARAM(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_PARAM))
/* --- flags --- */
@ -46,15 +46,31 @@ typedef enum
{
G_PARAM_READABLE = 1 << 0,
G_PARAM_WRITABLE = 1 << 1,
G_PARAM_MASK = 0x000f,
G_PARAM_CONSTRUCT = 1 << 2,
G_PARAM_CONSTRUCT_ONLY = 1 << 3,
#define G_PARAM_MASK (0x000f)
/* bits in the range 0xfff0 are reserved for 3rd party usage */
G_PARAM_USER_MASK = 0xfff0
#define G_PARAM_USER_MASK (0xfff0)
} GParamFlags;
/* --- typedefs & structures --- */
typedef struct _GParamSpecClass GParamSpecClass;
typedef struct _GParamSpec GParamSpec;
typedef struct _GParamSpecClass GParamSpecClass;
struct _GParamSpec
{
GTypeInstance g_type_instance;
gchar *name;
gchar *nick;
gchar *blurb;
GParamFlags flags;
/*< private >*/
GType owner_type;
GData *qdata;
guint ref_count;
};
struct _GParamSpecClass
{
GTypeClass g_type_class;
@ -72,25 +88,12 @@ struct _GParamSpecClass
const GValue *value1,
const GValue *value2);
};
struct _GParamSpec
{
GTypeInstance g_instance;
gchar *name;
gchar *nick;
gchar *blurb;
GParamFlags flags;
/*< private >*/
GType owner_type;
GData *qdata;
guint ref_count;
};
/* --- prototypes --- */
GParamSpec* g_param_spec_ref (GParamSpec *pspec);
void g_param_spec_unref (GParamSpec *pspec);
void g_param_spec_sink (GParamSpec *pspec);
gpointer g_param_spec_get_qdata (GParamSpec *pspec,
GQuark quark);
void g_param_spec_set_qdata (GParamSpec *pspec,
@ -111,6 +114,10 @@ gboolean g_param_value_validate (GParamSpec *pspec,
gint g_param_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2);
void g_value_set_param (GValue *value,
GParamSpec *param);
GParamSpec* g_value_get_param (const GValue *value);
GParamSpec* g_value_dup_param (const GValue *value);
/* --- convenience functions --- */

View File

@ -540,6 +540,103 @@ param_string_values_cmp (GParamSpec *pspec,
return strcmp (value1->data[0].v_pointer, value2->data[0].v_pointer);
}
static void
param_spec_param_init (GParamSpec *pspec)
{
GParamSpecParam *spec = G_PARAM_SPEC_PARAM (pspec);
spec->param_type = G_TYPE_PARAM;
}
static void
param_param_set_default (GParamSpec *pspec,
GValue *value)
{
value->data[0].v_pointer = NULL;
}
static gboolean
param_param_validate (GParamSpec *pspec,
GValue *value)
{
GParamSpecParam *spec = G_PARAM_SPEC_PARAM (pspec);
GParamSpec *param = value->data[0].v_pointer;
guint changed = 0;
if (param && !g_type_is_a (G_PARAM_SPEC_TYPE (param), spec->param_type))
{
g_param_spec_unref (param);
value->data[0].v_pointer = NULL;
changed++;
}
return changed;
}
static void
param_spec_pointer_init (GParamSpec *pspec)
{
/* GParamSpecPointer *spec = G_PARAM_SPEC_POINTER (pspec); */
}
static void
param_pointer_set_default (GParamSpec *pspec,
GValue *value)
{
value->data[0].v_pointer = NULL;
}
static gboolean
param_pointer_validate (GParamSpec *pspec,
GValue *value)
{
/* GParamSpecPointer *spec = G_PARAM_SPEC_POINTER (pspec); */
guint changed = 0;
return changed;
}
static gint
param_pointer_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2)
{
return value1->data[0].v_pointer != value2->data[0].v_pointer;
}
static void
param_spec_ccallback_init (GParamSpec *pspec)
{
/* GParamSpecCCallback *spec = G_PARAM_SPEC_CCALLBACK (pspec); */
}
static void
param_ccallback_set_default (GParamSpec *pspec,
GValue *value)
{
value->data[0].v_pointer = NULL;
value->data[1].v_pointer = NULL;
}
static gboolean
param_ccallback_validate (GParamSpec *pspec,
GValue *value)
{
/* GParamSpecCCallback *spec = G_PARAM_SPEC_CCALLBACK (pspec); */
guint changed = 0;
return changed;
}
static gint
param_ccallback_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2)
{
return (value1->data[0].v_pointer != value2->data[0].v_pointer ||
value1->data[1].v_pointer != value2->data[1].v_pointer);
}
static void
param_spec_object_init (GParamSpec *pspec)
{
@ -919,6 +1016,57 @@ g_param_spec_types_init (void) /* sync with gtype.c */
g_assert (type == G_TYPE_PARAM_STRING);
}
/* G_TYPE_PARAM_PARAM
*/
{
static const GParamSpecTypeInfo pspec_info = {
sizeof (GParamSpecParam), /* instance_size */
16, /* n_preallocs */
param_spec_param_init, /* instance_init */
G_TYPE_PARAM, /* value_type */
NULL, /* finalize */
param_param_set_default, /* value_set_default */
param_param_validate, /* value_validate */
param_pointer_values_cmp, /* values_cmp */
};
type = g_param_type_register_static ("GParamParam", &pspec_info);
g_assert (type == G_TYPE_PARAM_PARAM);
}
/* G_TYPE_PARAM_POINTER
*/
{
static const GParamSpecTypeInfo pspec_info = {
sizeof (GParamSpecPointer), /* instance_size */
0, /* n_preallocs */
param_spec_pointer_init, /* instance_init */
G_TYPE_POINTER, /* value_type */
NULL, /* finalize */
param_pointer_set_default, /* value_set_default */
param_pointer_validate, /* value_validate */
param_pointer_values_cmp, /* values_cmp */
};
type = g_param_type_register_static ("GParamPointer", &pspec_info);
g_assert (type == G_TYPE_PARAM_POINTER);
}
/* G_TYPE_PARAM_CCALLBACK
*/
{
static const GParamSpecTypeInfo pspec_info = {
sizeof (GParamSpecCCallback), /* instance_size */
0, /* n_preallocs */
param_spec_ccallback_init, /* instance_init */
G_TYPE_CCALLBACK, /* value_type */
NULL, /* finalize */
param_ccallback_set_default, /* value_set_default */
param_ccallback_validate, /* value_validate */
param_ccallback_values_cmp, /* values_cmp */
};
type = g_param_type_register_static ("GParamCCallback", &pspec_info);
g_assert (type == G_TYPE_PARAM_CCALLBACK);
}
/* G_TYPE_PARAM_OBJECT
*/
{
@ -1280,6 +1428,59 @@ g_param_spec_string_c (const gchar *name,
return G_PARAM_SPEC (sspec);
}
GParamSpec*
g_param_spec_param (const gchar *name,
const gchar *nick,
const gchar *blurb,
GType param_type,
GParamFlags flags)
{
GParamSpecParam *pspec;
g_return_val_if_fail (G_TYPE_IS_PARAM (param_type), NULL);
pspec = g_param_spec_internal (G_TYPE_PARAM_PARAM,
name,
nick,
blurb,
flags);
pspec->param_type = param_type;
return G_PARAM_SPEC (pspec);
}
GParamSpec*
g_param_spec_pointer (const gchar *name,
const gchar *nick,
const gchar *blurb,
GParamFlags flags)
{
GParamSpecPointer *pspec;
pspec = g_param_spec_internal (G_TYPE_PARAM_POINTER,
name,
nick,
blurb,
flags);
return G_PARAM_SPEC (pspec);
}
GParamSpec*
g_param_spec_ccallback (const gchar *name,
const gchar *nick,
const gchar *blurb,
GParamFlags flags)
{
GParamSpecCCallback *cspec;
cspec = g_param_spec_internal (G_TYPE_PARAM_CCALLBACK,
name,
nick,
blurb,
flags);
return G_PARAM_SPEC (cspec);
}
GParamSpec*
g_param_spec_object (const gchar *name,
const gchar *nick,

View File

@ -57,6 +57,12 @@ extern "C" {
#define G_PARAM_SPEC_DOUBLE(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_DOUBLE, GParamSpecDouble))
#define G_IS_PARAM_SPEC_STRING(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_STRING))
#define G_PARAM_SPEC_STRING(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_STRING, GParamSpecString))
#define G_IS_PARAM_SPEC_PARAM(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_PARAM))
#define G_PARAM_SPEC_PARAM(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_PARAM, GParamSpecParam))
#define G_IS_PARAM_SPEC_POINTER(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_POINTER))
#define G_PARAM_SPEC_POINTER(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_POINTER, GParamSpecPointer))
#define G_IS_PARAM_SPEC_CCALLBACK(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_CCALLBACK))
#define G_PARAM_SPEC_CCALLBACK(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_CCALLBACK, GParamSpecCCallback))
#define G_IS_PARAM_SPEC_OBJECT(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_OBJECT))
#define G_PARAM_SPEC_OBJECT(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_OBJECT, GParamSpecObject))
@ -74,6 +80,9 @@ typedef struct _GParamSpecFlags GParamSpecFlags;
typedef struct _GParamSpecFloat GParamSpecFloat;
typedef struct _GParamSpecDouble GParamSpecDouble;
typedef struct _GParamSpecString GParamSpecString;
typedef struct _GParamSpecParam GParamSpecParam;
typedef struct _GParamSpecPointer GParamSpecPointer;
typedef struct _GParamSpecCCallback GParamSpecCCallback;
typedef struct _GParamSpecObject GParamSpecObject;
struct _GParamSpecChar
{
@ -172,6 +181,20 @@ struct _GParamSpecString
guint null_fold_if_empty : 1;
guint ensure_non_null : 1;
};
struct _GParamSpecParam
{
GParamSpec parent_instance;
GType param_type;
};
struct _GParamSpecPointer
{
GParamSpec parent_instance;
};
struct _GParamSpecCCallback
{
GParamSpec parent_instance;
};
struct _GParamSpecObject
{
GParamSpec parent_instance;
@ -264,6 +287,19 @@ GParamSpec* g_param_spec_string_c (const gchar *name,
const gchar *blurb,
const gchar *default_value,
GParamFlags flags);
GParamSpec* g_param_spec_param (const gchar *name,
const gchar *nick,
const gchar *blurb,
GType param_type,
GParamFlags flags);
GParamSpec* g_param_spec_pointer (const gchar *name,
const gchar *nick,
const gchar *blurb,
GParamFlags flags);
GParamSpec* g_param_spec_ccallback (const gchar *name,
const gchar *nick,
const gchar *blurb,
GParamFlags flags);
GParamSpec* g_param_spec_object (const gchar *name,
const gchar *nick,
const gchar *blurb,

View File

@ -22,12 +22,13 @@
#include <string.h>
#include "gsignal.h"
#include "gbsearcharray.h"
#include "gvaluecollector.h"
/* pre allocation configurations
*/
#define MAX_STACK_VALUES (16)
#define BSA_PRE_ALLOC (20)
#define HANDLER_PRE_ALLOC (48)
#define EMISSION_PRE_ALLOC (16)
@ -131,7 +132,7 @@ static inline Emission* emission_find (Emission *emission_list,
guint signal_id,
GQuark detail,
gpointer instance);
static void signal_emit_R (SignalNode *node,
static gboolean signal_emit_R (SignalNode *node,
GQuark detail,
gpointer instance,
GValue *return_value,
@ -233,21 +234,43 @@ static inline guint
signal_id_lookup (GQuark quark,
GType itype)
{
do
{
SignalKey key, *signal_key;
GType *ifaces, type = itype;
SignalKey key;
guint n_ifaces;
key.itype = itype;
key.quark = quark;
/* try looking up signals for this type and its anchestors */
do
{
SignalKey *signal_key;
key.itype = type;
signal_key = g_bsearch_array_lookup (&g_signal_key_bsa, &key);
if (signal_key)
return signal_key->signal_id;
itype = g_type_parent (itype);
type = g_type_parent (type);
}
while (itype);
while (type);
/* no luck, try interfaces it exports */
ifaces = g_type_interfaces (itype, &n_ifaces);
while (n_ifaces--)
{
SignalKey *signal_key;
key.itype = ifaces[n_ifaces];
signal_key = g_bsearch_array_lookup (&g_signal_key_bsa, &key);
if (signal_key)
{
g_free (ifaces);
return signal_key->signal_id;
}
}
g_free (ifaces);
return 0;
}
@ -515,7 +538,7 @@ handler_insert (guint signal_id,
{
HandlerList *hlist;
g_assert (handler->prev == NULL && handler->next == NULL); // FIXME: paranoid
g_assert (handler->prev == NULL && handler->next == NULL); /* paranoid */
hlist = handler_list_ensure (signal_id, instance);
if (!hlist->handlers)
@ -671,7 +694,7 @@ g_signal_stop_emission (gpointer instance,
G_UNLOCK (g_signal_mutex);
return;
}
if (node && g_type_conforms_to (G_TYPE_FROM_INSTANCE (instance), node->itype))
if (node && g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype))
{
Emission *emission_list = node->flags & G_SIGNAL_NO_RECURSE ? g_restart_emissions : g_recursive_emissions;
Emission *emission = emission_find (emission_list, signal_id, detail, instance);
@ -859,6 +882,44 @@ g_signal_list_ids (GType itype,
return (guint *) g_array_free (result, FALSE);
}
guint
g_signal_new (const gchar *signal_name,
GType itype,
GSignalFlags signal_flags,
GClosure *class_closure,
GSignalAccumulator accumulator,
GSignalCMarshaller c_marshaller,
GType return_type,
guint n_params,
...)
{
GType *param_types;
guint i;
va_list args;
guint signal_id;
if (n_params > 0)
{
param_types = g_new (GType, n_params);
va_start (args, n_params);
for (i = 0; i < n_params; i++)
param_types[i] = va_arg (args, GType);
va_end (args);
}
else
param_types = NULL;
signal_id = g_signal_newv (signal_name, itype, signal_flags,
class_closure, accumulator, c_marshaller,
return_type, n_params, param_types);
g_free (param_types);
return signal_id;
}
guint
g_signal_newv (const gchar *signal_name,
GType itype,
@ -1023,13 +1084,13 @@ g_signal_connect_closure_by_id (gpointer instance,
G_LOCK (g_signal_mutex);
node = LOOKUP_SIGNAL_NODE (signal_id);
if (node && detail && !(node->flags & G_SIGNAL_DETAILED))
if (node)
{
if (detail && !(node->flags & G_SIGNAL_DETAILED))
g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
G_UNLOCK (g_signal_mutex);
return 0;
}
if (node && g_type_conforms_to (G_TYPE_FROM_INSTANCE (instance), node->itype))
else if (!g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype))
g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance);
else
{
Handler *handler = handler_new (after);
@ -1040,6 +1101,7 @@ g_signal_connect_closure_by_id (gpointer instance,
if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (closure))
g_closure_set_marshal (closure, node->c_marshaller);
}
}
else
g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance);
G_UNLOCK (g_signal_mutex);
@ -1047,6 +1109,97 @@ g_signal_connect_closure_by_id (gpointer instance,
return handler_id;
}
guint
g_signal_connect_closure (gpointer instance,
const gchar *detailed_signal,
GClosure *closure,
gboolean after)
{
guint signal_id, handler_id = 0;
GQuark detail = 0;
GType itype;
g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
g_return_val_if_fail (detailed_signal != NULL, 0);
g_return_val_if_fail (closure != NULL, 0);
G_LOCK (g_signal_mutex);
itype = G_TYPE_FROM_INSTANCE (instance);
signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE);
if (signal_id)
{
SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id);
if (detail && !(node->flags & G_SIGNAL_DETAILED))
g_warning ("%s: signal `%s' does not support details", G_STRLOC, detailed_signal);
else if (!g_type_is_a (itype, node->itype))
g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance);
else
{
Handler *handler = handler_new (after);
handler_id = handler->id;
handler->detail = detail;
handler->closure = g_closure_ref (closure);
handler_insert (signal_id, instance, handler);
if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (handler->closure))
g_closure_set_marshal (handler->closure, node->c_marshaller);
}
}
else
g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance);
G_UNLOCK (g_signal_mutex);
return handler_id;
}
guint
g_signal_connect_data (gpointer instance,
const gchar *detailed_signal,
GCallback c_handler,
gpointer data,
GClosureNotify destroy_data,
gboolean swapped,
gboolean after)
{
guint signal_id, handler_id = 0;
GQuark detail = 0;
GType itype;
g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
g_return_val_if_fail (detailed_signal != NULL, 0);
g_return_val_if_fail (c_handler != NULL, 0);
G_LOCK (g_signal_mutex);
itype = G_TYPE_FROM_INSTANCE (instance);
signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE);
if (signal_id)
{
SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id);
if (detail && !(node->flags & G_SIGNAL_DETAILED))
g_warning ("%s: signal `%s' does not support details", G_STRLOC, detailed_signal);
else if (!g_type_is_a (itype, node->itype))
g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance);
else
{
Handler *handler = handler_new (after);
handler_id = handler->id;
handler->detail = detail;
handler->closure = g_closure_ref ((swapped ? g_cclosure_new_swap : g_cclosure_new) (c_handler, data, destroy_data));
handler_insert (signal_id, instance, handler);
if (node->c_marshaller && G_CLOSURE_NEEDS_MARSHAL (handler->closure))
g_closure_set_marshal (handler->closure, node->c_marshaller);
}
}
else
g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance);
G_UNLOCK (g_signal_mutex);
return handler_id;
}
void
g_signal_handler_block (gpointer instance,
guint handler_id)
@ -1342,9 +1495,9 @@ g_signal_emitv (const GValue *instance_and_params,
GQuark detail,
GValue *return_value)
{
SignalNode *node;
gpointer instance;
const GValue *param_values;
gpointer instance;
SignalNode *node;
guint i;
g_return_if_fail (instance_and_params != NULL);
@ -1356,13 +1509,13 @@ g_signal_emitv (const GValue *instance_and_params,
G_LOCK (g_signal_mutex);
node = LOOKUP_SIGNAL_NODE (signal_id);
#ifndef G_DISABLE_CHECKS
if (!node || !g_type_conforms_to (G_TYPE_FROM_INSTANCE (instance), node->itype))
if (!node || !g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype))
{
g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance);
G_UNLOCK (g_signal_mutex);
return;
}
#ifndef G_DISABLE_CHECKS
if (detail && !(node->flags & G_SIGNAL_DETAILED))
{
g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
@ -1372,7 +1525,8 @@ g_signal_emitv (const GValue *instance_and_params,
for (i = 0; i < node->n_params; i++)
if (!G_VALUE_HOLDS (param_values + i, node->param_types[i]))
{
g_critical (G_STRLOC ": value for `%s' parameter %u for signal \"%s\" is of type `%s'",
g_critical ("%s: value for `%s' parameter %u for signal \"%s\" is of type `%s'",
G_STRLOC,
g_type_name (node->param_types[i]),
i,
node->name,
@ -1384,7 +1538,8 @@ g_signal_emitv (const GValue *instance_and_params,
{
if (!return_value)
{
g_critical (G_STRLOC ": return value `%s' for signal \"%s\" is (NULL)",
g_critical ("%s: return value `%s' for signal \"%s\" is (NULL)",
G_STRLOC,
g_type_name (node->return_type),
node->name);
G_UNLOCK (g_signal_mutex);
@ -1392,7 +1547,8 @@ g_signal_emitv (const GValue *instance_and_params,
}
else if (!node->accumulator && !G_VALUE_HOLDS (return_value, node->return_type))
{
g_critical (G_STRLOC ": return value `%s' for signal \"%s\" is of type `%s'",
g_critical ("%s: return value `%s' for signal \"%s\" is of type `%s'",
G_STRLOC,
g_type_name (node->return_type),
node->name,
G_VALUE_TYPE_NAME (return_value));
@ -1405,11 +1561,145 @@ g_signal_emitv (const GValue *instance_and_params,
#endif /* !G_DISABLE_CHECKS */
signal_emit_R (node, detail, instance, return_value, instance_and_params);
G_UNLOCK (g_signal_mutex);
}
static void
void
g_signal_emit_valist (gpointer instance,
guint signal_id,
GQuark detail,
va_list var_args)
{
GValue *instance_and_params, stack_values[MAX_STACK_VALUES], *free_me = NULL;
GValue *param_values;
SignalNode *node;
guint i;
g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
g_return_if_fail (signal_id > 0);
G_LOCK (g_signal_mutex);
node = LOOKUP_SIGNAL_NODE (signal_id);
if (!node || !g_type_is_a (G_TYPE_FROM_INSTANCE (instance), node->itype))
{
g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance);
G_UNLOCK (g_signal_mutex);
return;
}
#ifndef G_DISABLE_CHECKS
if (detail && !(node->flags & G_SIGNAL_DETAILED))
{
g_warning ("%s: signal id `%u' does not support detail (%u)", G_STRLOC, signal_id, detail);
G_UNLOCK (g_signal_mutex);
return;
}
#endif /* !G_DISABLE_CHECKS */
if (node->n_params < MAX_STACK_VALUES)
instance_and_params = stack_values;
else
{
free_me = g_new (GValue, node->n_params + 1);
instance_and_params = free_me;
}
param_values = instance_and_params + 1;
for (i = 0; i < node->n_params; i++)
{
gchar *error;
param_values[i].g_type = 0;
g_value_init (param_values + i, node->param_types[i]);
G_VALUE_COLLECT (param_values + i, var_args, &error);
if (error)
{
g_warning ("%s: %s", G_STRLOC, error);
g_free (error);
/* we purposely leak the value here, it might not be
* in a sane state if an error condition occoured
*/
while (i--)
g_value_unset (param_values + i);
G_UNLOCK (g_signal_mutex);
g_free (free_me);
return;
}
}
instance_and_params->g_type = 0;
g_value_init (instance_and_params, node->itype);
g_value_set_instance (instance_and_params, instance);
if (node->return_type == G_TYPE_NONE)
signal_emit_R (node, detail, instance, NULL, instance_and_params);
else
{
GValue return_value = { 0, };
gchar *error = NULL;
g_value_init (&return_value, node->return_type);
if (signal_emit_R (node, detail, instance, &return_value, instance_and_params))
G_VALUE_LCOPY (&return_value, var_args, &error);
if (!error)
g_value_unset (&return_value);
else
{
g_warning ("%s: %s", G_STRLOC, error);
g_free (error);
/* we purposely leak the value here, it might not be
* in a sane state if an error condition occoured
*/
}
}
for (i = 0; i < node->n_params; i++)
g_value_unset (param_values + i);
g_value_unset (instance_and_params);
if (free_me)
g_free (free_me);
G_UNLOCK (g_signal_mutex);
}
void
g_signal_emit (gpointer instance,
guint signal_id,
GQuark detail,
...)
{
va_list var_args;
va_start (var_args, detail);
g_signal_emit_valist (instance, signal_id, detail, var_args);
va_end (var_args);
}
void
g_signal_emit_by_name (gpointer instance,
const gchar *detailed_signal,
...)
{
GQuark detail = 0;
guint signal_id;
g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
g_return_if_fail (detailed_signal != NULL);
G_LOCK (g_signal_mutex);
signal_id = signal_parse_name (detailed_signal, G_TYPE_FROM_INSTANCE (instance), &detail, TRUE);
G_UNLOCK (g_signal_mutex);
if (signal_id)
{
va_list var_args;
va_start (var_args, detailed_signal);
g_signal_emit_valist (instance, signal_id, detail, var_args);
va_end (var_args);
}
else
g_warning ("%s: signal name `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance);
}
static gboolean
signal_emit_R (SignalNode *node,
GQuark detail,
gpointer instance,
@ -1422,9 +1712,10 @@ signal_emit_R (SignalNode *node,
GClosure *class_closure;
HandlerList *hlist;
Handler *handler_list = NULL;
GValue accu;
GValue accu = { 0, };
gboolean accu_used = FALSE;
guint signal_id = node->signal_id;
gboolean return_value_altered = FALSE;
if (node->flags & G_SIGNAL_NO_RECURSE)
{
@ -1433,18 +1724,14 @@ signal_emit_R (SignalNode *node,
if (emission)
{
*emission->state_p = EMISSION_RESTART;
return;
return return_value_altered;
}
}
ihint.signal_id = node->signal_id;
ihint.detail = detail;
accumulator = node->accumulator;
if (accumulator)
{
G_UNLOCK (g_signal_mutex);
g_value_init (&accu, node->return_type);
G_LOCK (g_signal_mutex);
}
emission_push ((node->flags & G_SIGNAL_NO_RECURSE) ? &g_restart_emissions : &g_recursive_emissions,
signal_id, detail, instance, &emission_state);
class_closure = node->class_closure;
@ -1486,6 +1773,7 @@ signal_emit_R (SignalNode *node,
instance_and_params,
&ihint);
G_LOCK (g_signal_mutex);
return_value_altered = TRUE;
if (emission_state == EMISSION_STOP)
goto EMIT_CLEANUP;
@ -1545,6 +1833,7 @@ signal_emit_R (SignalNode *node,
instance_and_params,
&ihint);
G_LOCK (g_signal_mutex);
return_value_altered = TRUE;
tmp = emission_state == EMISSION_RUN ? handler->next : NULL;
}
@ -1593,6 +1882,7 @@ signal_emit_R (SignalNode *node,
instance_and_params,
&ihint);
G_LOCK (g_signal_mutex);
return_value_altered = TRUE;
if (emission_state == EMISSION_STOP)
goto EMIT_CLEANUP;
@ -1634,6 +1924,7 @@ signal_emit_R (SignalNode *node,
instance_and_params,
&ihint);
G_LOCK (g_signal_mutex);
return_value_altered = TRUE;
tmp = emission_state == EMISSION_RUN ? handler->next : NULL;
}
@ -1692,9 +1983,12 @@ signal_emit_R (SignalNode *node,
emission_pop ((node->flags & G_SIGNAL_NO_RECURSE) ? &g_restart_emissions : &g_recursive_emissions, &emission_state);
if (accumulator)
{
G_UNLOCK (g_signal_mutex);
g_value_unset (&accu);
G_LOCK (g_signal_mutex);
}
return return_value_altered;
}
/* compile standard marshallers */
#include "gvaluetypes.h"
#include "gmarshal.c"

View File

@ -23,6 +23,7 @@
#include <gobject/gclosure.h>
#include <gobject/gvalue.h>
#include <gobject/gparam.h>
#include <gobject/gmarshal.h>
#ifdef __cplusplus
@ -86,6 +87,15 @@ struct _GSignalQuery
/* --- signals --- */
guint g_signal_new (const gchar *signal_name,
GType itype,
GSignalFlags signal_flags,
GClosure *class_closure,
GSignalAccumulator accumulator,
GSignalCMarshaller c_marshaller,
GType return_type,
guint n_params,
...);
guint g_signal_newv (const gchar *signal_name,
GType itype,
GSignalFlags signal_flags,
@ -99,6 +109,17 @@ void g_signal_emitv (const GValue *instance_and_params,
guint signal_id,
GQuark detail,
GValue *return_value);
void g_signal_emit_valist (gpointer instance,
guint signal_id,
GQuark detail,
va_list var_args);
void g_signal_emit (gpointer instance,
guint signal_id,
GQuark detail,
...);
void g_signal_emit_by_name (gpointer instance,
const gchar *detailed_signal,
...);
guint g_signal_lookup (const gchar *name,
GType itype);
gchar* g_signal_name (guint signal_id);
@ -127,6 +148,17 @@ guint g_signal_connect_closure_by_id (gpointer instance,
GQuark detail,
GClosure *closure,
gboolean after);
guint g_signal_connect_closure (gpointer instance,
const gchar *detailed_signal,
GClosure *closure,
gboolean after);
guint g_signal_connect_data (gpointer instance,
const gchar *detailed_signal,
GCallback c_handler,
gpointer data,
GClosureNotify destroy_data,
gboolean swapped,
gboolean after);
void g_signal_handler_block (gpointer instance,
guint handler_id);
void g_signal_handler_unblock (gpointer instance,

View File

@ -21,7 +21,7 @@
#include "gtypeplugin.h"
#include <string.h>
#define FIXME_DISABLE_PREALLOCATIONS
#undef FIXME_DISABLE_PREALLOCATIONS
/* NOTE: some functions (some internal variants and exported ones)
* invalidate data portions of the TypeNodes. if external functions/callbacks
@ -173,7 +173,7 @@ static GQuark quark_type_flags = 0;
/* --- externs --- */
const char *g_log_domain_gobject = "GLib-Object";
const char *g_log_domain_gruntime = "GRuntime";
/* --- type nodes --- */
@ -796,7 +796,7 @@ type_data_make (TypeNode *node,
*vtable = *value_table;
node->data->common.value_table = vtable;
g_assert (node->data->common.value_table != NULL); /* FIXME: paranoid */
g_assert (node->data->common.value_table != NULL); /* paranoid */
}
static inline void
@ -1024,7 +1024,7 @@ g_type_free_instance (GTypeInstance *instance)
}
instance->g_class = NULL;
memset (instance, 0xaa, node->data->instance.instance_size); // FIXME
memset (instance, 0xaa, node->data->instance.instance_size); // FIXME: debugging hack
if (node->data->instance.n_preallocs)
g_chunk_free (instance, node->data->instance.mem_chunk);
else
@ -1667,6 +1667,7 @@ g_type_next_base (GType type,
return 0;
}
#if 0
gboolean
g_type_is_a (GType type,
GType is_a_type)
@ -1688,9 +1689,10 @@ g_type_is_a (GType type,
return FALSE;
}
#endif
gboolean
g_type_conforms_to (GType type,
g_type_is_a (GType type,
GType iface_type)
{
if (type != iface_type)
@ -1807,7 +1809,7 @@ g_type_get_qdata (GType type,
QData *qdatas = gdata->qdatas - 1;
guint n_qdatas = gdata->n_qdatas;
do /* FIXME: should optimize qdata lookups for <= 4 */
do
{
guint i;
QData *check;
@ -1943,12 +1945,12 @@ g_type_fundamental_last (void)
}
gboolean
g_type_instance_conforms_to (GTypeInstance *type_instance,
g_type_instance_is_a (GTypeInstance *type_instance,
GType iface_type)
{
return (type_instance && type_instance->g_class &&
G_TYPE_IS_INSTANTIATABLE (type_instance->g_class->g_type) &&
g_type_conforms_to (type_instance->g_class->g_type, iface_type));
g_type_is_a (type_instance->g_class->g_type, iface_type));
}
gboolean
@ -1960,7 +1962,7 @@ g_type_class_is_a (GTypeClass *type_class,
}
gboolean
g_type_value_conforms_to (GValue *value,
g_type_value_is_a (GValue *value,
GType type)
{
TypeNode *node;
@ -1974,7 +1976,7 @@ g_type_value_conforms_to (GValue *value,
#endif
if (!node || !node->data || node->data->common.ref_count < 1 ||
!node->data->common.value_table->value_init ||
!g_type_conforms_to (value->g_type, type))
!g_type_is_a (value->g_type, type))
return FALSE;
return TRUE;
@ -1983,7 +1985,7 @@ g_type_value_conforms_to (GValue *value,
gboolean
g_type_check_value (GValue *value)
{
return value && g_type_value_conforms_to (value, value->g_type);
return value && g_type_value_is_a (value, value->g_type);
}
GTypeInstance*
@ -2009,7 +2011,7 @@ g_type_check_instance_cast (GTypeInstance *type_instance,
type_descriptive_name (iface_type));
return type_instance;
}
if (!g_type_conforms_to (type_instance->g_class->g_type, iface_type))
if (!g_type_is_a (type_instance->g_class->g_type, iface_type))
{
g_warning ("invalid cast from `%s' to `%s'",
type_descriptive_name (type_instance->g_class->g_type),
@ -2125,7 +2127,7 @@ g_type_init (void)
memset (&info, 0, sizeof (info));
node = type_node_fundamental_new (G_TYPE_INTERFACE, "GInterface", G_TYPE_FLAG_DERIVABLE);
type = NODE_TYPE (node);
type_data_make (node, &info, NULL); /* FIXME */
type_data_make (node, &info, NULL);
g_assert (type == G_TYPE_INTERFACE);
/* G_TYPE_TYPE_PLUGIN

View File

@ -19,7 +19,7 @@
#ifndef __G_TYPE_H__
#define __G_TYPE_H__
extern const char *g_log_domain_gobject;
extern const char *g_log_domain_gruntime;
#include <glib.h>
@ -62,6 +62,7 @@ typedef enum /*< skip >*/
G_TYPE_PARAM,
G_TYPE_BOXED,
G_TYPE_POINTER,
G_TYPE_CCALLBACK,
G_TYPE_OBJECT,
/* the following reserved ids should vanish soon */
@ -79,7 +80,6 @@ typedef enum /*< skip >*/
G_TYPE_LAST_RESERVED_FUNDAMENTAL,
/* derived type ids */
/* FIXME: G_TYPE_PARAM_INTERFACE */
G_TYPE_PARAM_CHAR = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 1),
G_TYPE_PARAM_UCHAR = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 2),
G_TYPE_PARAM_BOOLEAN = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 3),
@ -92,8 +92,10 @@ typedef enum /*< skip >*/
G_TYPE_PARAM_FLOAT = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 10),
G_TYPE_PARAM_DOUBLE = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 11),
G_TYPE_PARAM_STRING = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 12),
/* FIXME: G_TYPE_PARAM_PARAM */
G_TYPE_PARAM_OBJECT = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 13)
G_TYPE_PARAM_PARAM = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 13),
G_TYPE_PARAM_POINTER = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 14),
G_TYPE_PARAM_CCALLBACK = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 15),
G_TYPE_PARAM_OBJECT = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 16)
} GTypeFundamentals;
@ -174,8 +176,6 @@ GType g_type_next_base (GType type,
GType base_type);
gboolean g_type_is_a (GType type,
GType is_a_type);
gboolean g_type_conforms_to (GType type,
GType iface_type);
guint g_type_fundamental_branch_last (GType type);
gpointer g_type_class_ref (GType type);
gpointer g_type_class_peek (GType type);
@ -317,10 +317,10 @@ gboolean g_type_class_is_a (GTypeClass *g_class,
GType is_a_type);
GTypeInstance* g_type_check_instance_cast (GTypeInstance *instance,
GType iface_type);
gboolean g_type_instance_conforms_to (GTypeInstance *instance,
gboolean g_type_instance_is_a (GTypeInstance *instance,
GType iface_type);
gboolean g_type_check_value (GValue *value);
gboolean g_type_value_conforms_to (GValue *value,
gboolean g_type_value_is_a (GValue *value,
GType type);
gboolean g_type_check_instance (GTypeInstance *instance);
GTypeValueTable* g_type_value_table_peek (GType type);
@ -336,9 +336,9 @@ GTypeValueTable* g_type_value_table_peek (GType type);
# define _G_TYPE_CCC(cp, gt, ct) ((ct*) cp)
#endif /* G_DISABLE_CAST_CHECKS */
#define _G_TYPE_CHI(ip) (g_type_check_instance ((GTypeInstance*) ip))
#define _G_TYPE_CIT(ip, gt) (g_type_instance_conforms_to ((GTypeInstance*) ip, gt))
#define _G_TYPE_CIT(ip, gt) (g_type_instance_is_a ((GTypeInstance*) ip, gt))
#define _G_TYPE_CCT(cp, gt) (g_type_class_is_a ((GTypeClass*) cp, gt))
#define _G_TYPE_CVT(vl, gt) (g_type_value_conforms_to ((GValue*) vl, gt))
#define _G_TYPE_CVT(vl, gt) (g_type_value_is_a ((GValue*) vl, gt))
#define _G_TYPE_CHV(vl) (g_type_check_value ((GValue*) vl))
#define _G_TYPE_IGC(ip, gt, ct) ((ct*) (((GTypeInstance*) ip)->g_class))
#define _G_TYPE_IGI(ip, gt, ct) ((ct*) g_type_interface_peek (((GTypeInstance*) ip)->g_class, gt))

View File

@ -406,7 +406,7 @@ g_type_module_add_interface (GTypeModule *module,
g_return_if_fail (module != NULL);
g_return_if_fail (interface_info != NULL);
if (g_type_conforms_to (instance_type, interface_type))
if (g_type_is_a (instance_type, interface_type))
{
GTypePlugin *old_plugin = g_type_interface_get_plugin (instance_type,
interface_type);

View File

@ -20,6 +20,7 @@
#include <string.h>
#include "gvalue.h"
#include "gvaluecollector.h"
/* --- typedefs & structures --- */
@ -110,6 +111,54 @@ g_value_get_as_pointer (const GValue *value)
return value_table->value_peek_pointer (value);
}
void
g_value_set_instance (GValue *value,
gpointer instance)
{
g_return_if_fail (G_IS_VALUE (value));
g_value_reset (value);
if (instance)
{
GType g_type = G_VALUE_TYPE (value);
GTypeValueTable *value_table = g_type_value_table_peek (g_type);
GTypeCValue cvalue = { 0, };
guint nth_value = 0;
guint collect_type = value_table->collect_type;
gchar *error_msg;
g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
g_return_if_fail (g_type_is_a (G_TYPE_FROM_INSTANCE (instance), G_VALUE_TYPE (value)));
g_return_if_fail (value_table->collect_type == G_VALUE_COLLECT_POINTER);
cvalue.v_pointer = instance;
error_msg = value_table->collect_value (value, nth_value++, &collect_type, &cvalue);
/* this shouldn't be triggered, instance types should collect just one pointer,
* but since we have to follow the calling conventions for collect_value(),
* we can attempt to feed them with 0s if they insist on extra args.
*/
while (collect_type && !error_msg)
{
memset (&cvalue, 0, sizeof (cvalue));
error_msg = value_table->collect_value (value, nth_value++, &collect_type, &cvalue);
}
if (error_msg)
{
g_warning ("%s: %s", G_STRLOC, error_msg);
g_free (error_msg);
/* we purposely leak the value here, it might not be
* in a sane state if an error condition occoured
*/
memset (value, 0, sizeof (*value));
value->g_type = g_type;
value_table->value_init (value);
}
}
}
void
g_value_unset (GValue *value)
{
@ -127,11 +176,12 @@ g_value_unset (GValue *value)
void
g_value_reset (GValue *value)
{
GTypeValueTable *value_table = g_type_value_table_peek (G_VALUE_TYPE (value));
GTypeValueTable *value_table;
GType g_type;
g_return_if_fail (G_IS_VALUE (value));
value_table = g_type_value_table_peek (G_VALUE_TYPE (value));
g_type = G_VALUE_TYPE (value);
if (value_table->value_free)

View File

@ -69,6 +69,8 @@ void g_value_reset (GValue *value);
void g_value_unset (GValue *value);
gboolean g_value_fits_pointer (const GValue *value);
gpointer g_value_get_as_pointer (const GValue *value);
void g_value_set_instance (GValue *value,
gpointer instance);
/* --- implementation details --- */

View File

@ -71,9 +71,8 @@ G_STMT_START { \
g_value_reset (_value); \
while (_collect_type && !_error_msg) \
{ \
GTypeCValue _cvalue; \
GTypeCValue _cvalue = { 0, }; \
\
memset (&_cvalue, 0, sizeof (_cvalue)); \
switch (_collect_type) \
{ \
case G_VALUE_COLLECT_INT: \
@ -117,9 +116,8 @@ G_STMT_START { \
\
while (_lcopy_type && !_error_msg) \
{ \
GTypeCValue _cvalue; \
GTypeCValue _cvalue = { 0, }; \
\
memset (&_cvalue, 0, sizeof (_cvalue)); \
switch (_lcopy_type) \
{ \
case G_VALUE_COLLECT_INT: \

View File

@ -264,7 +264,7 @@ value_string_lcopy_value (const GValue *value,
static void
value_pointer_init (GValue *value)
{
value->data[0].v_pointer = 0;
value->data[0].v_pointer = NULL;
}
static void
@ -309,6 +309,76 @@ value_pointer_lcopy_value (const GValue *value,
return NULL;
}
static void
value_ccallback_init (GValue *value)
{
value->data[0].v_pointer = NULL;
value->data[1].v_pointer = NULL;
}
static void
value_ccallback_copy (const GValue *src_value,
GValue *dest_value)
{
dest_value->data[0].v_pointer = src_value->data[0].v_pointer;
dest_value->data[1].v_pointer = src_value->data[1].v_pointer;
}
static gchar*
value_ccallback_collect_value (GValue *value,
guint nth_value,
GType *collect_type,
GTypeCValue *collect_value)
{
gchar *error = NULL;
switch (nth_value)
{
case 0:
value->data[0].v_pointer = collect_value->v_pointer;
*collect_type = G_VALUE_COLLECT_POINTER;
if (!value->data[0].v_pointer)
error = g_strconcat ("invalid (NULL) pointer callback function for value type `",
G_VALUE_TYPE_NAME (value),
"'",
NULL);
break;
case 1:
value->data[1].v_pointer = collect_value->v_pointer;
*collect_type = 0;
break;
}
return error;
}
static gchar*
value_ccallback_lcopy_value (const GValue *value,
guint nth_value,
GType *collect_type,
GTypeCValue *collect_value)
{
gpointer *pointer_p = collect_value->v_pointer;
if (!pointer_p)
return g_strdup_printf ("%s location for `%s' passed as NULL",
nth_value ? "data" : "callback",
G_VALUE_TYPE_NAME (value));
switch (nth_value)
{
case 0:
*pointer_p = value->data[0].v_pointer;
*collect_type = G_VALUE_COLLECT_POINTER;
break;
case 1:
*pointer_p = value->data[1].v_pointer;
*collect_type = 0;
break;
}
return NULL;
}
/* --- type initialization --- */
void
@ -478,6 +548,24 @@ g_value_types_init (void) /* sync with gtype.c */
type = g_type_register_fundamental (G_TYPE_POINTER, "gpointer", &info, &finfo, 0);
g_assert (type == G_TYPE_POINTER);
}
/* G_TYPE_CCALLBACK
*/
{
static const GTypeValueTable value_table = {
value_ccallback_init, /* value_init */
NULL, /* value_free */
value_ccallback_copy, /* value_copy */
NULL, /* value_peek_pointer */
G_VALUE_COLLECT_POINTER, /* collect_type */
value_ccallback_collect_value, /* collect_value */
G_VALUE_COLLECT_POINTER, /* lcopy_type */
value_ccallback_lcopy_value, /* lcopy_value */
};
info.value_table = &value_table;
type = g_type_register_fundamental (G_TYPE_CCALLBACK, "GCCallback", &info, &finfo, 0);
g_assert (type == G_TYPE_CCALLBACK);
}
}
@ -692,3 +780,27 @@ g_value_get_pointer (const GValue *value)
return value->data[0].v_pointer;
}
void
g_value_set_ccallback (GValue *value,
gpointer callback_func,
gpointer callback_data)
{
g_return_if_fail (G_IS_VALUE_CCALLBACK (value));
value->data[0].v_pointer = callback_func;
value->data[1].v_pointer = callback_data;
}
void
g_value_get_ccallback (const GValue *value,
gpointer *callback_func,
gpointer *callback_data)
{
g_return_if_fail (G_IS_VALUE_CCALLBACK (value));
if (callback_func)
*callback_func = value->data[0].v_pointer;
if (callback_data)
*callback_data = value->data[1].v_pointer;
}

View File

@ -42,6 +42,7 @@ extern "C" {
#define G_IS_VALUE_DOUBLE(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_DOUBLE))
#define G_IS_VALUE_STRING(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_STRING))
#define G_IS_VALUE_POINTER(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_POINTER))
#define G_IS_VALUE_CCALLBACK(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_CCALLBACK))
/* --- prototypes --- */
@ -81,7 +82,12 @@ gchar* g_value_dup_string (const GValue *value);
void g_value_set_pointer (GValue *value,
gpointer v_pointer);
gpointer g_value_get_pointer (const GValue *value);
void g_value_set_ccallback (GValue *value,
gpointer callback_func,
gpointer callback_data);
void g_value_get_ccallback (const GValue *value,
gpointer *callback_func,
gpointer *callback_data);

View File

@ -16,7 +16,7 @@ GLIB_VER = @GLIB_MAJOR_VERSION@.@GLIB_MINOR_VERSION@
# Nothing much configurable below
INCLUDES = -I .. -I .
DEFINES = -DHAVE_CONFIG_H -DGOBJECT_COMPILATION -DG_LOG_DOMAIN=g_log_domain_gobject
DEFINES = -DHAVE_CONFIG_H -DGOBJECT_COMPILATION -DG_LOG_DOMAIN=g_log_domain_gruntime
BUILD_DLL = ../build-dll

View File

@ -13,7 +13,7 @@ GLIB_VER = @GLIB_MAJOR_VERSION@.@GLIB_MINOR_VERSION@
# Nothing much configurable below
INCLUDES = -I .. -I .
DEFINES = -DHAVE_CONFIG_H -DGOBJECT_COMPILATION -DG_LOG_DOMAIN=g_log_domain_gobject
DEFINES = -DHAVE_CONFIG_H -DGOBJECT_COMPILATION -DG_LOG_DOMAIN=g_log_domain_gruntime
all : \
gobject-$(GLIB_VER).dll \