It's your object's responsibility to emit its signals at
appropriate times. This is very simple; if you've saved
the return value from
gtk_signal_new(), that identifier can be used to
emit the signal. Otherwise, you can emit the signal by
name (with some cost in execution speed, since GTK+ will
have to look up the identifier in a hash table).
Here is code from
gtk/gtkbutton.c which is used to emit the "button_pressed" signal:
void
gtk_button_pressed (GtkButton *button)
{
g_return_if_fail (button != NULL);
g_return_if_fail (GTK_IS_BUTTON (button));
gtk_signal_emit (GTK_OBJECT (button), button_signals[PRESSED]);
}
|
If a signal has arguments (other than the standard two),
you must specify those as a variable argument list:
gtk_signal_emit (GTK_OBJECT (widget), widget_signals[SIZE_REQUEST],
&widget->requisition);
|
If a signal returns a value, you must pass a location for
the returned value as the final argument:
gint return_val;
return_val = FALSE;
gtk_signal_emit (GTK_OBJECT (widget), widget_signals[EVENT], event,
&return_val);
|
Notice that return_val is
initialized to something sane; if there are no signal
handlers, none of them will assign a value to return_val. So you must
initialize the variable. Each signal handler's return
value will be assigned to the same location, so the final
value of return_val is
determined by the last signal handler to run. Note that
certain return values (such as strings) must be freed by
the signal emitter.
gtk_signal_emit_by_name() is
the same as gtk_signal_emit(),
except that the second argument is a signal name rather
than a signal ID number. There are also variants of both
emission functions that take a vector of GtkArg instead of a variable argument
list. These variants expect arrays of n+1GtkArg
structs, where n is the number of
signal arguments and there is an additional GtkArg for the return value. The
GtkArg structs should be
initialized with sane values. If the function returns no
value, the return value
GtkArg will have
GTK_TYPE_NONE.
All four signal emission functions are summarized in Figure 5.
Keep in mind that it is usually inappropriate to simply
emit a signal outside of an object's implementation. Only
GTK_RUN_ACTION signals
are guaranteed to work properly without special setup or
shutdown. Objects often export functions you can use to
emit signals properly; for example, to emit the "size_request" signal, GtkWidget provides this function:
void
gtk_widget_size_request (GtkWidget *widget,
GtkRequisition *requisition)
{
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_WIDGET (widget));
gtk_widget_ref (widget);
gtk_widget_ensure_style (widget);
gtk_signal_emit (GTK_OBJECT (widget), widget_signals[SIZE_REQUEST],
&widget->requisition);
if (requisition)
gtk_widget_get_child_requisition (widget, requisition);
gtk_widget_unref (widget);
}
|
As you can see, particular actions are required before
and after emitting the signal; thus it should only be
emitted via the
gtk_widget_size_request() function.