Glib
view release on metacpan or search on metacpan
MODULE = Glib::Signal PACKAGE = Glib::Object PREFIX = g_
##
##/* --- typedefs --- */
##typedef struct _GSignalQuery GSignalQuery;
##typedef struct _GSignalInvocationHint GSignalInvocationHint;
##typedef GClosureMarshal GSignalCMarshaller;
##typedef gboolean (*GSignalEmissionHook) (GSignalInvocationHint *ihint,
## guint n_param_values,
## const GValue *param_values,
## gpointer data);
##typedef gboolean (*GSignalAccumulator) (GSignalInvocationHint *ihint,
## GValue *return_accu,
## const GValue *handler_return,
## gpointer data);
###
### ## creating signals ##
### new signals are currently created as a byproduct of Glib::Type::register
###
## g_signal_newv
## g_signal_new_valist
## g_signal_new
###
### ## emitting signals ##
### all versions of g_signal_emit go through Glib::Object::signal_emit,
### which is mostly equivalent to g_signal_emit_by_name.
###
## g_signal_emitv
## g_signal_emit_valist
## g_signal_emit
## g_signal_emit_by_name
## heavily borrowed from gtk-perl and goran's code in gtk2-perl, which
## was inspired by pygtk's pyobject.c::pygobject_emit
=for apidoc
=for signature retval = $object->signal_emit ($name, ...)
=for arg name (string) the name of the signal
=for arg ... (list) any arguments to pass to handlers.
Emit the signal I<name> on I<$object>. The number and types of additional
arguments in I<...> are determined by the signal; similarly, the presence
and type of return value depends on the signal being emitted.
=cut
void
g_signal_emit (instance, name, ...)
GObject * instance
char * name
PREINIT:
guint signal_id, i;
GQuark detail;
GSignalQuery query;
GValue * params;
PPCODE:
#define ARGOFFSET 2
signal_id = parse_signal_name_or_croak
(name, G_OBJECT_TYPE (instance), &detail);
g_signal_query (signal_id, &query);
if (((guint)(items-ARGOFFSET)) != query.n_params)
croak ("Incorrect number of arguments for emission of signal %s in class %s; need %d but got %d",
name, G_OBJECT_TYPE_NAME (instance),
query.n_params, (gint) items-ARGOFFSET);
/* set up the parameters to g_signal_emitv. this is an array
* of GValues, where [0] is the emission instance, and the rest
* are the query.n_params arguments. */
params = g_new0 (GValue, query.n_params + 1);
g_value_init (¶ms[0], G_OBJECT_TYPE (instance));
g_value_set_object (¶ms[0], instance);
for (i = 0 ; i < query.n_params ; i++) {
g_value_init (¶ms[i+1],
query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE);
if (!gperl_value_from_sv (¶ms[i+1], ST (ARGOFFSET+i)))
croak ("Couldn't convert value %s to type %s for parameter %d of signal %s on a %s",
SvPV_nolen (ST (ARGOFFSET+i)),
g_type_name (G_VALUE_TYPE (¶ms[i+1])),
i, name, G_OBJECT_TYPE_NAME (instance));
}
/* now actually call it. what we do depends on the return type of
* the signal; if the signal returns anything we need to capture it
* and push it onto the return stack. */
if (query.return_type != G_TYPE_NONE) {
/* signal returns a value, woohoo! */
GValue ret = {0,};
g_value_init (&ret, query.return_type);
g_signal_emitv (params, signal_id, detail, &ret);
EXTEND (SP, 1);
SAVED_STACK_PUSHs (sv_2mortal (gperl_sv_from_value (&ret)));
g_value_unset (&ret);
} else {
g_signal_emitv (params, signal_id, detail, NULL);
}
/* clean up */
for (i = 0 ; i < query.n_params + 1 ; i++)
g_value_unset (¶ms[i]);
g_free (params);
#undef ARGOFFSET
##guint g_signal_lookup (const gchar *name,
## GType itype);
##G_CONST_RETURN gchar* g_signal_name (guint signal_id);
##void g_signal_query (guint signal_id, GSignalQuery *query);
=for apidoc
Look up information about the signal I<$name> on the instance type
I<$object_or_class_name>, which may be either a Glib::Object or a package
name.
=for arg data (scalar) data to match, ignored if undef
=cut
=for apidoc
=for arg func (subroutine) function to block
=for arg data (scalar) data to match, ignored if undef
=cut
int
signal_handlers_block_by_func (instance, func, data=NULL)
GObject * instance
SV * func
SV * data
ALIAS:
Glib::Object::signal_handlers_unblock_by_func = 1
Glib::Object::signal_handlers_disconnect_by_func = 2
PREINIT:
sig_match_callback callback = NULL;
CODE:
switch (ix) {
case 0: callback = g_signal_handlers_block_matched; break;
case 1: callback = g_signal_handlers_unblock_matched; break;
case 2: callback = g_signal_handlers_disconnect_matched; break;
default: g_assert_not_reached ();
}
RETVAL = foreach_closure_matched (instance, G_SIGNAL_MATCH_CLOSURE,
0, 0, func, data, callback);
OUTPUT:
RETVAL
##/* --- chaining for language bindings --- */
##void g_signal_override_class_closure (guint signal_id,
## GType instance_type,
## GClosure *class_closure);
##void g_signal_chain_from_overridden (const GValue *instance_and_params,
## GValue *return_value);
=for apidoc
Chain up to an overridden class closure; it is only valid to call this from
a class closure override.
Translation: because of various details in how GObjects are implemented,
the way to override a virtual method on a GObject is to provide a new "class
closure", or default handler for a signal. This happens when a class is
registered with the type system (see Glib::Type::register and
L<Glib::Object::Subclass>). When called from inside such an override, this
method runs the overridden class closure. This is equivalent to calling
$self->SUPER::$method (@_) in normal Perl objects.
=cut
void
g_signal_chain_from_overridden (GObject * instance, ...)
PREINIT:
GSignalInvocationHint * ihint;
GSignalQuery query;
GValue * instance_and_params = NULL,
return_value = {0,};
guint i;
PPCODE:
ihint = g_signal_get_invocation_hint (instance);
if (!ihint)
croak ("could not find signal invocation hint for %s(0x%p)",
G_OBJECT_TYPE_NAME (instance), instance);
g_signal_query (ihint->signal_id, &query);
if ((guint)items != 1 + query.n_params)
croak ("incorrect number of parameters for signal %s, "
"expected %d, got %d",
g_signal_name (ihint->signal_id),
1 + query.n_params,
(gint) items);
instance_and_params = g_new0 (GValue, 1 + query.n_params);
g_value_init (&instance_and_params[0], G_OBJECT_TYPE (instance));
g_value_set_object (&instance_and_params[0], instance);
for (i = 0 ; i < query.n_params ; i++) {
g_value_init (&instance_and_params[i+1],
query.param_types[i]
& ~G_SIGNAL_TYPE_STATIC_SCOPE);
gperl_value_from_sv (&instance_and_params[i+1], ST (i+1));
}
if (query.return_type != G_TYPE_NONE)
g_value_init (&return_value,
query.return_type
& ~G_SIGNAL_TYPE_STATIC_SCOPE);
g_signal_chain_from_overridden (instance_and_params, &return_value);
for (i = 0 ; i < 1 + query.n_params ; i++)
g_value_unset (instance_and_params+i);
g_free (instance_and_params);
if (G_TYPE_NONE != (query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE)) {
SAVED_STACK_XPUSHs (sv_2mortal (gperl_sv_from_value (&return_value)));
g_value_unset (&return_value);
}
( run in 1.096 second using v1.01-cache-2.11-cpan-5511b514fd6 )