2.6 Signals


2.6 Signals

Signals are events that can happen to an object during the course of the object's life. Signals serve as a means of communication between objects; when an object gets a signal, it can react in some way. The signal system in GObject is called GSignal.

Note  

In written language, a signal can be the act of sending a message or the message itself. In GObject, a signal is the sender's version of the message. A GObject signal has one source and multiple potential recipients.

A signal handler is a callback function with a prototype that you declare when you initialize a class (for example, media_class_init() from Section 2.4.1). When some other part of a program emits a signal, GSignal calls the handler on the object. You can alter the characteristics of an object with a signal handler. You can specify the order of the handler invocations on a per-signal basis.

Note  

You add signal handlers on a per-object basis. When you add a handler to one object, it does not apply for any other objects in the class.

You can pass parameters along with signals and receive return values from handlers with the marshalling [3] mechanism. Each signal usually has a function pointer in an object's class structure. The function behind this pointer is called the default handler . You can link additional functions into a signal, so that if there is more than one return value per signal emission, the object may process all of the return values back with the help of an accumulator . Otherwise , GSignal returns the value of only the last signal handler.

2.6.1 Defining Signals and Installing Handlers

A signal isn't a data structure; it's just a guint identifier managed by GObject. You should define some names for these identifiers with an enumeration type (for caching purposes later); a good place to do this is somewhere before your class initialization function (for example, media_class_init() ). Here is an example for two signals: one that removes an item from its package, and another that throws out an item.

 /* Signal indices */ enum {   UNPACKED,   THROW_OUT,   LAST_SIGNAL }; 

As you can see, these names correspond to indices. Furthermore, common practice says that you should create a cache array as a static variable. Later, you will set each array element to a GObject signal identifier.

 /* Signal identifier map */ static guint media_signal[LAST_SIGNAL] = {0, 0}; 

Note how LAST_SIGNAL indicates the size of the array.

Now you need to think about the signal handlers. You may recall from Section 2.2.1 that you already provided some infrastructure in the MediaClass class structure for signal handlers: function pointer fields called unpacked and throw_out . The actual functions that correspond to these are media_unpacked() and media_throw_out() , so you need to provide their prototypes :

 /* Prototypes for signal handlers */ static void media_unpacked(Media *media); static void media_throw_out(Media *media, gboolean permanent); 

With this, you are close to completing the media_class_init() function first started in Section 2.4.1. Continue by setting the function pointers in the class structure to the actual signal handlers as shown on the next page:

 /* Initialize the Media class */ static void media_class_init(MediaClass *class) {   GObjectClass *g_object_class;   << parameter/property code >>   /* set signal handlers */   class->unpacked = media_unpacked;   class->throw_out = media_throw_out; 

Then install the unpacked signal and its default handler with g_signal_new() :

 /* install signals and default handlers */   media_signal[UNPACKED] =      g_signal_new("unpacked",                     /* name */                   TYPE_MEDIA,                     /* class type identifier */                   G_SIGNAL_RUN_LASTG_SIGNAL_DETAILED, /* options */                   G_STRUCT_OFFSET(MediaClass, unpacked), /* handler offset */                   NULL,                           /* accumulator function */                   NULL,                           /* accumulator data */                   g_cclosure_marshal_VOID__VOID,  /* marshaller */                   G_TYPE_NONE,                    /* type of return value */                   0); 

That's a mouthful, to say the least, so here's how the code breaks down:

  • The return value of g_signal_new() is GObject's identifier. You should store it in the mapping array from earlier.

  • The name is a short string to identify the signal.

  • The type identifier is the GObject class type identifier macro.

  • Options may include one or more of the following as a bitwise OR:

    • G_SIGNAL_DETAILED : The signal supports details (see Section 2.6.6).

    • G_SIGNAL_NO_HOOKS : You may not use emission hooks with the signal (see Section 2.6.7).

    • G_SIGNAL_NO_RECURSE : If GSignal gets another signal emission for this signal handler when the handler is still active, the signal handler restarts ” it does not call the signal handler from within the signal handler.

    • G_SIGNAL_RUN_FIRST : Signal emission has several stages. This flag indicates that the handler should run in the first stage (see Section 2.6.2).

    • G_SIGNAL_RUN_LAST : The signal handler runs in the third stage (use this if you're not sure what to do).

    • G_SIGNAL_RUN_CLEANUP : The signal handler runs in the last stage.

    • G_SIGNAL_ACTION : If some code emits an action signal , it doesn't need to do any extra housecleaning around the target object. You can use this to interconnect code from different sources.

  • The offset is an ugly way to tell g_signal_new() where the class signal handler function is. It is an offset from the memory location of the class structure, and luckily, you have the G_STRUCT_OFFSET macro to do the work for you.

  • The accumulator is a callback function that collects various return values (see Section 2.6.4).

  • The accumulator data is where to put the accumulator's data.

  • The C Marshaller for the signal is described in Section 2.6.3.

  • The return value is the return value of the marshaller.

  • The number of parameters specifies how many extra parameters to pass along with the marshaller. If this number is greater than zero, you must specify the GValue types (see the throw_out example that follows ).

Having learned all of this, you can install the signal and default handler for throw_out (the difference is that throw_out takes a gboolean parameter) and finally put media_class_init() to rest.

 media_signal[THROW_OUT] =      g_signal_new("throw_out",                   TYPE_MEDIA,                   G_SIGNAL_RUN_LASTG_SIGNAL_DETAILED,                   G_STRUCT_OFFSET(MediaClass, throw_out),                   NULL, NULL,                   g_cclosure_marshal_VOID__BOOLEAN,                   G_TYPE_NONE,                   1,                   G_TYPE_BOOLEAN); 

The signal handlers are fairly simple:

 /* unpacked signal handler */ static void media_unpacked(Media *media) {   if (media->orig_package)   {      g_object_set(media, "orig-package", FALSE, NULL);      g_print("Media unpacked.\n");   } else {      g_print("Media already unpacked.\n");   } } /* throw_out signal handler */ static void media_throw_out(Media *media, gboolean permanent) {   if (permanent)   {      g_print("Trashing media.\n");   } else {      g_print("Media not in the dumpster quite yet.\n");   } } 

Notice the additional parameter to media_throw_out() , and that these functions have no return values.

2.6.2 Emitting Signals

One way to emit a signal is with

 g_signal_emit_by_name(  object  ,  name  [,  parms  ..] [,  return  ]) 

The arguments are as follows:

  • object ( gpointer ): The target object.

  • name ( const gchar * ): The signal identifier (for example, "unpacked" ).

  • parms : Signal handler parameters (if any).

  • return : Location of return value (if any).

Therefore, if you have a signal with a signature of VOID:VOID , you need only two parameters; otherwise, you need at least three. Here are some examples with the signals defined in Section 2.6.1:

 g_signal_emit_by_name(media, "unpacked"); /* expect "Media unpacked." */ g_signal_emit_by_name(media, "unpacked"); /* expect "Media already unpacked." */ g_signal_emit_by_name(media, "throw-out", TRUE); /* expect "Trashing media." */ 

Many programmers prefer to emit signals based on the numeric signal identifier to avoid a lookup on a string. This function is the manual equivalent of g_signal_emit_by_name() :

 g_signal_emit(gpointer  object  , guint  signal_id  , GQuark  detail  , ...) 

You should use this function in conjunction with cached signal identifiers. Recall from Section 2.6.1 that media_signal[] holds the cache for the ongoing media example. Therefore, this example sends the unpacked signal to media :

 g_signal_emit(media, media_signal[UNPACKED], 0); 
Note  

This book primarily uses g_signal_emit_by_name() because it requires less coding baggage. However, if you continuously emit signals, you should consider caching the signal identifiers as described above.

If you set the throw-out handlers to return gboolean , the following code would retrieve that value and place it into a return_val variable:

 gboolean return_val;   << ... >> g_signal_emit_by_name(media, "throw-out", TRUE, &return_val); if (return_val) {    g_print("Signal (throw-out): returned TRUE.\n"); } else {    g_print("Signal (throw-out): returned FALSE.\n"); } 

When you emit a signal, the GSignal runs through the following stages of handler calls:

  1. Default handlers installed with the G_SIGNAL_RUN_FIRST option

  2. Emission hooks (see Section 2.6.7)

  3. User -defined handlers installed without the after option (see Section 2.6.5)

  4. Default handlers installed with the G_SIGNAL_RUN_LAST option

  5. User-defined handlers installed with the after option

  6. Default handlers installed with the G_SIGNAL_RUN_CLEANUP option

Here are a few additional functions for emitting signals:

  • g_signal_emitv(const GValue object_and_parms , guint signal_id , GQuark detail , GValue * result )

    To use this function, you must store the target object and signal parameters in a GValue array object_and_parms and provide a place for the return value at result .

  • g_signal_emit_valist(gpointer object , guint signal_id , GQuark detail , va_list va_args )

    This function works just like g_signal_emit , but with a previously prepared variable argument list va_list for the handler arguments and return value. With this call, you can create your own signal emission functions that take variable arguments.

2.6.3 Marshallers

When some code emits a signal, GSignal uses a marshaller to transport a list of parameters to the signal handler and to collect and propagate any return values.

Marshallers have names that reflect the parameter types and return values. The format is:

  prefix_RETURNTYPE__PARM1TYPE[_PARM2TYPE_...]  

For example, the marshaller for media_unpacked() was g_cclosure_marshal_VOID__VOID because this handler takes no parameters other than the object and returns nothing.

GObject comes with a number of marshallers for one parameter and no return value, as shown in the table on the next page.

Marshaller

Parameter Type

g_cclosure_marshal_VOID__BOOLEAN

gboolean

g_cclosure_marshal_VOID__BOXED

GBoxed*

g_cclosure_marshal_VOID__CHAR

gchar

g_cclosure_marshal_VOID__DOUBLE

gdouble

g_cclosure_marshal_VOID__ENUM

gint (enumeration types)

g_cclosure_marshal_VOID__FLAGS

guint (options)

g_cclosure_marshal_VOID__FLOAT

gfloat

g_cclosure_marshal_VOID__INT

gint

g_cclosure_marshal_VOID__LONG

glong

g_cclosure_marshal_VOID__OBJECT

GObject*

g_cclosure_marshal_VOID__PARAM

GParamSpec* or derived

g_cclosure_marshal_VOID__POINTER

gpointer

g_cclosure_marshal_VOID__STRING

gchar* or gchararray

g_cclosure_marshal_VOID__UCHAR

guchar

g_cclosure_marshal_VOID__ULONG

gulong

g_cclosure_marshal_VOID__UINT

guint

g_cclosure_marshal_VOID__VOID

void (no parameters)

Warning  

Using the wrong marshaller will probably cause your program to crash.

If you don't see the marshaller you need in the preceding list (that is, your signal handler returns a value and/or takes more than a single parameter), you have to provide your own. Your marshaller names should resemble the following:

 _my_marshal_INT__VOID _my_marshal_VOID__OBJECT_INT _my_marshal_UINT__BOOLEAN_BOOLEAN 

where _my_marshal is your prefix.

Thankfully, you don't have to actually write the marshaller code; there's a utility called glib-genmarshal to do the dirty work for you. For example, to create the marshallers above, put the following in a file called my_marshaller.list :

 INT:VOID VOID:OBJECT,INT UINT:BOOLEAN 

The file format is fairly obvious; each line is a signature defining a new marshaller, starting with the return type. After a colon , you list the parameter types. You should be able to determine the valid types from the table earlier in this section.

To create the actual code, run these two commands:

 glib-genmarshal --prefix _my_marshal --header my_marshaller.list > my_marshaller.h glib-genmarshal --prefix _my_marshal --body my_marshaller.list > my_marshaller.c 

You now have a new source file, my_marshaller.c , and a my_marshaller.h header file.

Warning  

You don't have to supply a prefix. The default is g_cclosure_user_marshal , but if you choose to accept this, be aware that you risk duplicate symbols at link time, especially if you are combining several different pieces of code.

You must include my_marshaller.h in the source file that includes your class initialization function (or any other place where you install signal handlers). The my_marshaller.h file should look something like this:

 #ifndef ___my_marshal_MARSHAL_H__ #define ___my_marshal_MARSHAL_H__ #include <glib-object.h> G_BEGIN_DECLS /* INT:VOID (my_marshaller.list:1) */ extern void _my_marshal_INT__VOID     (GClosure     *closure,      GValue       *return_value,      guint         n_param_values,      const GValue *param_values,      gpointer      invocation_hint,      gpointer      marshal_data); /* VOID:OBJECT,INT (my_marshaller.list:2) */ extern void _my_marshal_VOID__OBJECT_INT     (GClosure     *closure,      GValue       *return_value,      guint         n_param_values,      const GValue *param_values,      gpointer      invocation_hint,      gpointer      marshal_data); /* UINT:BOOLEAN (my_marshaller.list:3) */ extern void _my_marshal_UINT__BOOLEAN     (GClosure     *closure,      GValue       *return_value,      guint         n_param_values,      const GValue *param_values,      gpointer      invocation_hint,      gpointer      marshal_data); G_END_DECLS #endif /* ___my_marshal_MARSHAL_H__ */ 

If you're building a Makefile, rules for creating the marshallers would look something like this:

 my_marshaller.h: my_marshaller.list         glib-genmarshal --prefix _my_marshal --header \         my_marshaller.list > my_marshaller.h my_marshaller.c: my_marshaller.list         glib-genmarshal --prefix _my_marshal --body \         my_marshaller.list > my_marshaller.c 
Note  

Remember that the whitespace in the preceding listing actually consists of tabs.

You may also want to add a dependency for glib-genmarshal , but this is probably best done with the help of GNU autoconf (see Chapter 6).

2.6.4 Signal Accumulators

If GSignal runs several signal handlers for one signal, the handler calls run in succession, and the marshaller propagates the return value from the last handler back to the code that emitted the signal.

In rare cases, though, you may want to know what all of the handlers returned. You can define an accumulator to collect and process all of the return values.

To install an accumulator along with a signal, supply a GSignalAccumulator callback function as the fifth argument to g_signal_new() . Here is the callback type definition:

 typedef struct _GSignalInvocationHint GSignalInvocationHint;   << ... >> typedef gboolean (*GSignalAccumulator)      (GSignalInvocationHint *ihint,       GValue                *return_accu,       const GValue          *handler_return,       gpointer               data);   << ... >> struct _GSignalInvocationHint {   guint         signal_id;   GQuark        detail;   GSignalFlags  run_type; }; 

GSignal calls your accumulator right after it runs each signal handler. As you can see from the preceding code, accumulator functions have four arguments:

  • ihint ( GSignalInvocationHint * ): A structure containing the signal identifier signal_id , a detail (see Section 2.6.6) and the signal options from g_signal_new() .

  • return_accu ( GValue * ): The accumulator that GSignal eventually returns to the code that emitted the signal. You can do anything you like with this container.

  • handler_return ( const GValue * ): Contains the return value from the last signal handler.

  • data ( gpointer ): Any accumulator data that you set up with g_signal_new() .

Your accumulator should return TRUE if you want GSignal to continue calling signal handlers for this particular signal emission, or FALSE if it should stop.

An accumulator typically may be used to look over Boolean values that signal handlers return. As soon as one of the handlers returns TRUE , the accumulator propagates TRUE as a return value and stops the emission process.

This book doesn't have an example of an accumulator (there's only so much space), but it's easy enough to find one: Unpack the GTK+ source code, change to the distribution's top-level directory, and run this command:

 grep GSignalInvocationHint */* 

This command prints lines from the source files that have accumulators.

2.6.5 Attaching Handlers to Signals

As you will see with widget objects in Chapter 3, you want to be able attach different signal handlers to the same kind of object (for example, if you have two button objects, you don't want the buttons to do the exact same thing).

This code attaches a new handler called meep_meep() to the unpacked signal on media , using g_signal_connect() :

 static void meep_meep(Media *media) {   guint nr;   g_object_get(media, "inventory-id", &nr, NULL);   g_print("Meep-meep! (Inventory number: \%d)\n", nr); }   << ... >> gulong handler_id; /* connect new handler */ handler_id = g_signal_connect(media,                               "unpacked",                               (GCallback) meep_meep,                               NULL); /* test the new handler */ g_signal_emit_by_name(media, "unpacked"); /* expect "meep-meep" message, plus output of other handler(s) */ 

In this example, GSignal calls meep_meep() before the default signal handler, because the default was not installed with G_SIGNAL_RUN_FIRST .

The most common way to attach a handler is to use

 gulong  handler_id  ;  handler_id  = g_signal_connect(  object  ,  name  ,  function  ,  data  ); 
  • object ( gpointer ): The target object.

  • name ( const gchar * ): The signal name.

  • function ( GCallback * ): The new signal handler. This callback function must have the same prototype as in the instance structure, but you may need to cast to get a fit as an argument.

  • data ( gpointer ): Optional data for the signal handler.

You'll see plenty of uses for the optional data pointer later in this book, such as the one described in Section 3.3. Normally, GSignal attempts to pass the data to the signal handler as the last argument. However, if you want to use a handler that takes a data pointer as its first parameter, use

 g_signal_connect_swapped(  object  ,  name  ,  function  ,  data  ) 

You might want to do this if your handler is a library function that takes only one argument. An example is in Section 3.6.10.

 g_signal_connect_after(  object  ,  name  ,  function  ,  data  ) 

is nearly identical to g_signal_connect() , except that function runs in stage 5 listed in Section 2.6.2 rather than in stage 3. The idea is that you can make the handler run after the default handler, but as you can see from that section, you can also override that behavior when you install the default handler.

All g_signal_connect*() calls return an identifier for the handler binding. If you store the identifier as handler_id , you can check the status of a binding with

 g_signal_handler_is_connected(  object  ,  handler_id  ) 

To remove a binding, invoke

 g_signal_handler_disconnect(  object  ,  handler_id  ) 

Here are some examples:

 /* test and disconnect handlers */ if (g_signal_handler_is_connected(media, handler_id)) {    g_print("meepmeep is connected to media. Detaching...\n"); } g_signal_handler_disconnect(media, handler_id); if (!g_signal_handler_is_connected(media, handler_id)) {   g_print("meepmeep no longer connected:\n");   g_signal_emit_by_name(media, "unpacked"); } 
Note  

Remember that any handlers that you connect to an object are on a per-object basis and do not apply for the rest of the class. You can also connect, disconnect, and block signal handlers during emission.

2.6.6 Details

Signal details are further subdivisions of signals. To specify a detail in a signal name, append two colons and the detail name (for example, unpacked::ding ).

You can add detail information when you connect a handler or emit a signal. When you emit a signal with a detail, GSignal calls the handlers with that detail and those completely without details. GSignal does not call a handler with a detail that does not match the given emission. In addition, if you emit a signal without a detail, GSignal will not call any handler connected with a detail. You should get the idea from the following example:

 static void ding(Media *media) {   g_print("Ding.\n"); } static void dong(Media *media) {   g_print("Dong.\n"); }   << ... >> /* connect handlers with ding and dong details */ g_signal_connect(media, "unpacked::ding", (GCallback)ding, NULL); g_signal_connect(media, "unpacked::dong", (GCallback)dong, NULL); g_signal_emit_by_name(media, "unpacked::ding"); /* expect "Ding," then "Media ... unpacked" */ g_signal_emit_by_name(media, "unpacked::dong"); /* expect "Dong," then "Media ... unpacked" */ g_signal_emit_by_name(media, "unpacked"); /* expect only "Media ... unpacked" */ 
Note  

Signal details work only when you install a signal with the G_SIGNAL_DETAILED option (see Section 2.6.1).

2.6.7 Emission Hooks

User-defined signal handlers connect only to single objects. However, you can also define emission hooks that apply to a GSignal identifier instead of an object. When you emit a signal that has a hook, GSignal calls the hook regardless of the target object. Therefore, you can make user-defined hooks at run time that apply to all objects in a class rather than just one object. You can attach details to hooks, just as you did with regular signals and their handlers.

Hook functions have the GSignalEmissionHook type and look a bit different than normal signal handlers. Here is the function type definition:

 typedef gboolean (*GSignalEmissionHook) (GSignalInvocationHint *ihint,                                          guint n_param_values,                                          const GValue *param_values,                                          gpointer data); 

As with the accumulators in Section 2.6.4, each hook receives a GSignalInvocationHint structure and a user-defined untyped data pointer. The other parameters are as follows:

  • n_param_values is the number of signal emission parameters.

  • param_values is an array of GValues, each containing the parameters from the signal emission. The first parameter is the target object. To get to the others, you need to do some pointer arithmetic (as the example in this section will imply).

  • data is a pointer to any user-defined data.

Hooks return gboolean . If a hook returns FALSE , GSignal removes the hook from the signal emission sequence. Make sure to return TRUE if you want your hook to run more than once.

The following example is a little difficult to read at first, but it does very little. Essentially, the hook verifies that its parameter is a Media object and prints the inventory number. After GSignal calls the hook for the third time, the hook returns FALSE and therefore requests removal from the signal.

 static gboolean my_hook(GSignalInvocationHint *ihint,                         guint n_param_values,                         const GValue *param_values,                         gpointer *data) {   static gint n = 0;   guint inv_nr;   Media *m;   GObject *obj;   g_print("my_hook(): ");   /* check for a valid Media object */   if (n_param_values > 0)   {      obj = g_value_get_object(param_values + 0);      if (IS_MEDIA(obj))      {         m = MEDIA(obj);         g_object_get(m, "inventory-id", &inv_nr, NULL);         g_print("inventory number = %d.\n", inv_nr);      } else {         g_print("called with invalid object\n");      }   } else {       g_print("called with invalid parameters\n");   }   n++;   g_print("my_hook(): invocation #%d", n);   if (n == 3)   {      g_print(" (last time)\n");      return(FALSE);   } else {      g_print("\n");      return(TRUE);   } }   << ... >> gulong hook_id; Media *m2, *m3;   << create one more media object, m2 >> /* add an emission hook */   hook_id = g_signal_add_emission_hook(media_signal[UNPACKED],                                        0,                                        (GSignalEmissionHook)my_hook,                                        NULL, NULL); /* test the hook on three different objects */ g_signal_emit_by_name(media, "unpacked"); g_signal_emit_by_name(m2, "unpacked"); g_signal_emit_by_name(media, "unpacked"); /* this time, the hook should no longer be active */ g_signal_emit_by_name(media, "unpacked"); 

Notice that g_signal_add_emission_hook() uses the signal identifier map from Section 2.6.1.

To remove a hook, run g_signal_hook_remove() on the hook identifier that g_signal_add_emission_hook() returns.

Note  

You won't find too much use for hooks in common practice. Before you install a hook into a class, you might ask yourself if it's really necessary.

2.6.8 More Signal Utilities

A number of tools are available to monitor and control signals and their emissions. For example, you can get the options specified at installation, the after flag, and handler bindings. In addition, you can block signal handlers and interrupt a signal emission.

Blocking Signal Handlers

  • g_signal_handler_block(gpointer object , gulong handler_id ) Disables a signal handler temporarily. GSignal will not call the handler for object until further notice.

  • g_signal_handler_unblock(gpointer object , gulong handler_id ) Enables a signal handler.

Note  

You can disable a signal handler as many times as you like; the effect is like putting an extra latch on a door. Therefore, if you block a handler three times in succession, you must enable it three times to get it working again.

Aborting Signal Emissions

  • g_signal_stop_emission_by_name(gpointer object , const gchar * signame ) Ends the current signal emission. Note that signame is the signal's name, including any detail. If there is no such signal emission, this function prints a warning message.

  • g_signal_stop_emission(gpointer object , guint signal_id , GQuark detail ) Same as the preceding function, but uses a signal identifier and a separate detail name.

Identifier Functions

To help you manage signals, names, and identifiers, GSignal provides the following:

  • guint g_signal_lookup(gchar * name , GType class ) returns the signal identifier corresponding to name for the class class type identifier.

  • gchar *g_signal_name(guint signal_id ) returns the signal name for signal_id .

  • guint *g_signal_list_ids(GType class , guint * num_sigs ) returns an array of signal IDs for class , writing the number of signals in num_sigs . You must deallocate this memory by yourself.

Here is a small demonstration:

 guint i, nr, *sigs; sigs = g_signal_list_ids(TYPE_MEDIA, &nr); g_print("ID    Name\n"); g_print("----  -------------\n"); i = 0; while (i < nr) {   g_print("%-4d %s\n", *sigs, g_signal_name(*sigs));   i++;   sigs++; } g_print("\nTotal signals: %d\n", nr); g_free(sigs); 

Miscellaneous Functions

Here are several more functions that work with signals that you might find useful. Refer to the online API documentation for a detailed list of the parameters.

  • g_signal_newv() is like g_signal_new() , except that here you supply the handler parameter types in an array.

  • g_signal_valist() wants a va_list of the handler parameter types. This function is suitable for building your own signal installers .

  • g_signal_connect_data() is the full-blown function for installing signal handlers. The rest of the g_signal_connect functions in this chapter are macros based on this function.

  • g_signal_query() asks for detailed information about a signal and fills a GSignalQuery structure with the information. If the utilities in the previous subsection weren't enough for you, check out this one.

  • g_signal_handlers_block_matched() blocks all signal handlers that match criteria in a given GSignalMatchType structure.

  • g_signal_handlers_unblock_matched() is like the preceding function, but it enables the signal handlers.

  • g_signal_handlers_disconnect_matched() is like the preceding function, but it removes the signal handlers from their objects.

  • g_signal_handler_find() looks for a signal that matches the criteria in a GSignalMatchType structure.

  • g_signal_handlers_block_by_func() disables signal handlers based on a pointer to the handler function.

  • g_signal_handlers_unblock_by_func() is the opposite of the preceding function.

  • g_signal_handlers_disconnect_by_func() is like the preceding function, but removes the handler.

[3] There are two spellings of this word: marshaling and marshalling . The text in this book uses the double-l variants, but you may see files and API elements with a single l .




The Official GNOME 2 Developers Guide
The Official GNOME 2 Developers Guide
ISBN: 1593270305
EAN: 2147483647
Year: 2004
Pages: 108

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net