Index

Package: Handlers

Description

package Gtk.Handlers is

The aim of this package is to provide some services to connect a handler to a signal emitted by a Gtk Object. To understand the services provided by this package, some definitions are necessary: Signal: A signal is a kind of message that an object wants to broadcast. All GObjects can emit signals. These messages are associated to certain events happening during the life of an object. For instance, when a user clicks on a button, the "clicked" signal is emitted by the button. Handler (or callback): A handler is a function or procedure that the user "connects" to a signal for a particular object. Connecting a handler to a signal means associating this handler to the signal. When the signal is emitted, all connected handlers are called back. Usually, the role of those callbacks is to do some processing triggered by a user action. For instance, when "clicked" signal is emitted by the "OK" button of a dialog, the connected handler can be used to close the dialog or recompute some value. In GtkAda, the handlers are defined in a form as general as possible. The first argument is always an access to the object it has been connected to. The second object is a table of values (See Glib.Values for more details about this table). It is the responsibility of this handler to extract the values from it, and to convert them to the correct Ada type. Because such handlers are not very convenient to use, this package also provides some services to connect a marshaller instead. It will then do the extraction work before calling the more programmer-friendly handler, as defined in Gtk.Marshallers (see Gtk.Marshallers for more details).

The subdivision of this package is identical to Gtk.Marshallers; it is made of four generic sub-packages, each representing one of the four possible kinds of handlers: they can return a value or not, and they can have some user specific data associated to them or not.

Selecting the right package depends on the profile of the handler.

For example, the handler for the "delete_event" signal of a Gtk_Window has a return value, and has an extra parameter (a Gint).

All handlers also have a user_data field by default, but its usage is optional. To connect a handler to this signal, if the user_data field is not used, the Return_Callback generic should be instantiated. On the other hand, if the user_data field is necessary, then the User_Return_Callback generic should be used.

Note also that the real handler in Gtk+ should expect at least as many arguments as in the marshaller you are using. If your marshaller has one argument, the C handler must have at least one argument too.

The common generic parameter to all sub-packages is the widget type, which is the basic widget manipulated. This can be Glib.Object.GObject_Record type if you want to reduce the number of instantiations, but the conversion to the original type will have to be done inside the handler.

All sub-packages are organized in the same way. First, the type "Handler" is defined. It represents the general form of the callbacks supported by the sub-package. The corresponding sub-package of Gtk.Marshallers is instantiated. A series of "Connect" procedures and functions is given. All cases are covered: the functions return the Handler_Id of the newly created association, while the procedures just connect the handler, dropping the Handler_Id; some services allow the user to connect a Handler while some others allow the usage of Marshallers, which are more convenient. Note that more than one handler may be connected to a signal; the handlers will then be invoked in the order of connection. Some "Connect_Object" services are also provided. Those services never have a user_data. They accept an additional parameter called Slot_Object. When the callback in invoked, the Gtk Object emitting the signal is substituted by this Slot_Object. These callbacks are always automatically disconnected as soon as one of the two widgets involved is destroyed. There are several methods to connect a handler. For each method, although the option of connecting a Handler is provided, the recommended way is to use Marshallers. Each connect service is documented below, in the first sub-package. A series of "To_Marshaller" functions are provided. They return some marshallers for the most commonly used types in order to ease the usage of this package. Most of the time, it will not be necessary to use some other marshallers. For instance, if a signal is documented as receiving a single argument, the widget (for instance the "clicked" signal for a Gtk_Button), you will connect to it with: with Gtkada.Handlers; procedure On_Clicked (Button : access Gtk_Widget_Record'Class); ... Widget_Callback.Connect (Button, "clicked", On_Clicked'Access); The simple form above also applies for most handlers that take one additional argument, for instance the "button_press_event" in gtk-widget.ads. Just declare your subprogram with the appropriate profile and connect it, as in: with Gtkada.Handlers; procedure On_Button (Widget : access Gtk_Widget_Record'Class; Event : Gdk_Event); ... Widget_Callback.Connect (Widget, "button_press_event", On_Button'Access); More complex forms of handlers exists however in GtkAda, for which no predefined marshaller exists. In this case, you have to use the general form of callbacks. For instance, the "select_row" signal of Gtk.Clist. with Gtkada.Handlers; with Gtk.Arguments; procedure On_Select (Clist : access Gtk_Widget_Record'Class; Args : Glib.Values.GValues) is Row : constant Gint := To_Gint (Args, 1); Column : constant Gint := To_Gint (Args, 2); Event : constant Gdk_Event := To_Event (Args, 3); begin ... end On_Select; ... Widget_Callback.Connect (Clist, "select_row", On_Select'Access); As for the "To_Marshaller" functions, a series of "Emit_By_Name" procedures are also provided for the same most common types, to allow the user to easily emit signals. These procedures are mainly intended for people building new GObjects.

At the end of this package, some general services related to the management of signals and handlers are also provided. Each one of them is documented individually below.

IMPORTANT NOTE: These packages must be instantiated at library-level

Binding from C File version 2.8.17

Packages

Return_Callback (generic)

User_Return_Callback (generic)

User_Return_Callback_With_Setup (generic)

Callback (generic)

User_Callback (generic)

User_Callback_With_Setup (generic)

Types

Handler_Id

type Handler_Id is record
      Id      : Gulong := Null_Handler_Id;
      Closure : GClosure;
   end record;
This uniquely identifies a connection widget<->signal. Closure is an internal data, that you should not use.

Constants & Global variables

Null_Handler_Id (Glib.Gulong)

Null_Handler_Id : constant Gulong := 0;

Subprograms & Entries

To_Address

function To_Address 
(Path: Gtk.Tree_Model.Gtk_Tree_Path) return System.Address;

Set_On_Exception

procedure Set_On_Exception 
(Handler: Gtkada.Bindings.Exception_Handler) renames Gtkada.Bindings.Set_On_Exception;
Set the handler that catch all exceptions occurring in a a callback. An exception should never be propagated to C to avoid undefined behavior. By default, unhandled exceptions are printed to stderr. This function can be used to provide your own global exception handler, which presumably will simply log the exception in application-specific manner.

Add_Watch

procedure Add_Watch 
(Id: Handler_Id;
Object: access Glib.Object.GObject_Record'Class);
Make sure that when Object is destroyed, the handler Id is also destroyed. This function should mostly be used in cases where you use a User_Data that is Object. If you don't destroy the callback at the same time, then the next time the callback is called it will try to access some invalid memory (Object being destroyed), and you will likely get a Storage_Error.

Disconnect

procedure Disconnect 
(Object: access Glib.Object.GObject_Record'Class;
Id: in out Handler_Id);
Disconnect the handler identified by the given Handler_Id.

Emit_Stop_By_Name

procedure Emit_Stop_By_Name 
(Object: access Glib.Object.GObject_Record'Class;
Name: Glib.Signal_Name);
During a signal emission, invoking this procedure will halt the emission.

Handler_Block

procedure Handler_Block 
(Obj: access Glib.Object.GObject_Record'Class;
Id: Handler_Id);
Blocks temporily the signal. For each call to this procedure, a call to Handler_Unblock must be performed in order to really unblock the signal.

Handlers_Destroy

procedure Handlers_Destroy 
(Obj: access Glib.Object.GObject_Record'Class);
Destroys all the handlers associated to the given object.

Handler_Unblock

procedure Handler_Unblock 
(Obj: access Glib.Object.GObject_Record'Class;
Id: Handler_Id);

Do_Signal_Connect

function Do_Signal_Connect 
(Object: Glib.Object.GObject;
Name: Glib.Signal_Name;
Marshaller: C_Marshaller;
Handler: System.Address;
Func_Data: System.Address;
Destroy: System.Address;
After: Boolean;
Slot_Object: System.Address := System.Null_Address;
Expect_Return_Value: Boolean) return Handler_Id;
Internal function used to connect the signal. * Object is the object that will emit the signal. * Marshaller is the C convention subprogram that will be called directly by gtk+, and is in charge of translating the arguments into a form suitable for calling the user's Handler callback. This subprogram does not check the profile of the Handler and whether the Marshaller will call it with the proper format, so is potentially dangerous. * Func_Data is an extra parameter passed to Handler by the Marshaller. It might be ignored, depending on the Marshaller. * Destroy is called when the handler is destroyed, for instance because the object itself is destroyed. * After indicates whether the handler is called after or before the default handler set by gtk+ for this signal. * Slot_Object is the object passed to the handler, if any. When this object is destroyed, the handler should be automatically disconnected. This object is not automatically connected to the handler, only the watch to destroy the handler is set in place. * Expect_Return_Value should be true if the user is connecting a function to the signal, False if he is connecting a procedure. This is used to check that the user has used the proper form of handler.