This is gtkada_ug.info, produced by makeinfo version 4.5 from gtkada_ug.texi. INFO-DIR-SECTION User Interface Toolkit START-INFO-DIR-ENTRY * GtkAda_Ug: (gtkada_ug). Ada95 graphical tookit based on GTK+ (User's Guide) END-INFO-DIR-ENTRY  File: gtkada_ug.info, Node: General description of the tagged types, Next: Using tagged types to extend Gtk widgets, Up: Object-oriented features General description of the tagged types ======================================= Why should I use object-oriented programing ? --------------------------------------------- Every widget in GtkAda is a tagged type and has a number of primitive subprograms which all its children inherit. This means that most of the time, as opposed to what you see in C code, you don't have to explicitly cast types and, even when you have to, Ada always makes sure that the conversion is valid. Thus your programs are much safer and most errors are found at compile time, as usual with Ada. For instance, if you create a table, put some widgets in it, and then, later in your program, try to access those widgets, then you do not need to know beforehand what their type is, when and by whom they were created, ... You simply ask for the children of the table, and you get in return a tagged type that contains all the information you need. You can even use dynamic dispatching without ever having to cast to a known type. This makes GtkAda a very powerful tool for designing graphical interfaces. If you think one of the standard widgets is nice, but would be even better if it was drawing itself in a slighlty different way, or if it could contain some other data that you need in your application, there is a very simple way to do it: just create a new type that extends the current one (see the section *Note Using tagged types to extend Gtk widgets:: below. Maybe you want to create your own brand new widget, that knows how to draw itself, how to react to events, ... and you want to be able to reuse it anytime you need ? Once again, using the standard Ada features, you can simply create a new tagged type and teach it how to interact with the user. See the section *Note Creating new widgets in Ada:: below. Type conversions from C to Ada widgets -------------------------------------- There are basically three kinds of widgets that you can use with GtkAda: * Ada widgets: These are widgets that are written directly in Ada, using the object oriented features of GtkAda * Standard widgets: These are the widgets that are part of the standard gtk+ and GtkAda distributions. This include all the basic widgets you need to build advanced interfaces. * third party C widgets These are widgets that were created in C, and for which you (or someone else) created an Ada binding. This is most probably the kind of widgets you will have if you want to use third party widgets. GtkAda will always be able to find and/or create a valid tagged type in the first case, no matter if you explicitly created the widget or if it was created automatically by gtk+. For instance, if you created a widget in Ada, put it in a table, and later on extracted it from the table, then you will still have the same widget. There are two issues: if the widget was explictly created by you, or at least by GtkAda, then it will always be and remain associated with a correct Ada type. If the widget was created implicitly (for instance every time you create a Gtk_Button, a Gtk_Label is also created for the text displayed), then GtkAda will only be able to create the corresponding type by default for the following widgets: Gtk_Label, Gtk_Button, Gtk_Item, Gtk_List_Item, Gtk_Menu_Item, Gtk_Check_Menu_Item, Gtk_Radio_Menu_Item, Gtk_Tearoff_Menu_Item, Gtk_Tree_Item and Gtk_Entry. For other widgets, it will instead create a Gtk_Widget, and you will have to either call Gtk.Unchecked_Cast to convert it back to the type you expect, or use Gtk.Type_Conversion as described below. Here is an example of use of Gtk.Unchecked_Cast: declare Stub : Gtk_Window_Record; begin Window := Gtk.Unchecked_Cast (Widget, Stub); end; In the third case (third party C widgets), GtkAda is not, by default, able to create the corresponding Ada type. The solution we suggest to solve the first issue is to 'with' the Gtk.Type_Conversion unit. In that case, every standard widget, no matter who created them, will always be correctly converted to an appropriate Ada type. So, basically, if you put the following in your main unit: with Gtk.Type_Conversion; begin Gtk.Main.Init; ... end then you can safely get the children of any widget (table, boxes, ...) and be sure you have the right Ada type. You won't need to explictly convert your widget to something else. However, 'with'ing this unit means that your application will depend on every package of GtkAda, which is a little bit heavier, and explains why this is not the default. We do recommend you use it if it is not extremely important whether your application depends on all the packages of GtkAda. The case of third party C widgets is a little bit trickier. Since GtkAda does not know anything about them when it is built, it can't magically convert the C widgets to Ada widgets. This is your job to teach GtkAda how to do the conversion. We thus provide a 'hook' function which you need to modify. This function is defined in the package Gtk.Type_Conversion. This function takes a string with the name of the C widget (ex/ "GtkButton"), and should return a newly allocated pointer. If you don't know this type either, simply return null.  File: gtkada_ug.info, Node: Using tagged types to extend Gtk widgets, Next: Creating new widgets in Ada, Prev: General description of the tagged types, Up: Object-oriented features Using tagged types to extend Gtk widgets ======================================== Since version 0.6 of this toolkit, it is possible to associate your own data with existing widgets simply by creating new types. This section will show you a simple example, but you should rather read the source code in testgtk/ where we used this feature instead of using `user_data' as is used in the C version. type My_Button_Record is new Gtk_Button_Record with record -- whatever data you want to associate with your button end record; type My_Button is access all My_Button_Record'Class; With the above statements, your new type is defined. Every function available for `Gtk_Button' is also available for `My_Button'. Of course, as with every tagged type in Ada, you can create your own primitive functions with the following prototype: procedure My_Primitive_Func (Myb : access My_Button_Record); To instanciate an object of type `My_Button' in your application, do the following: declare Myb : My_Button; begin Myb := new My_Button_Record; Initialize (Myb); -- from Gtk.Button end; The first line creates the Ada type, whereas the `Initialize' call actually creates the C widget and associates it with the Ada type.  File: gtkada_ug.info, Node: Creating new widgets in Ada, Prev: Using tagged types to extend Gtk widgets, Up: Object-oriented features Creating new widgets in Ada =========================== With GtkAda, you can now create widgets directly in Ada. These new widgets can be used directly, as if they were part of gtk itself. Creating new widgets is a way to create reuseable components. You can apply to them the same functions as would for any other widget, such as Show, Hide, ... This section will explain how to create two types of widgets: composite widgets and widgets created from scratch. Two examples are provided with GtkAda, in the directories `examples/composite_widget' and `examples/base_widget'. Please also refer to the gtk+ tutorial, which describes the basic mechanisms that you need to know to create a widget (even if the Ada code is really different from the C code...) * Menu: * Creating composite widgets:: * Creating widgets from scratch::  File: gtkada_ug.info, Node: Creating composite widgets, Next: Creating widgets from scratch, Up: Creating new widgets in Ada Creating composite widgets -------------------------- A composite widget is a widget that does not do much by itself. Rather, this is a collection of subwidgets grouped into a more general entity. For instance, among the standard widgets, `Gtk_File_Selection' and `Gtk_Font_Selection' belong to this category. The good news is that there is nothing special to know. Just create a new tagged type, extending one of the standard widgets (or even another of your own widgets), provide a `Gtk_New' function that allocates memory for this widget, and call the `Initialize' function that does the actual creation of the widget and the subwidgets. There is only one thing to do: `Initialize' should call the parent class's `Initialize' function, to create the underlying C widget. The example directory `examples/composite_widget' reimplements the `Gtk_Dialog' widget as written in C by the creators of gtk+.  File: gtkada_ug.info, Node: Creating widgets from scratch, Prev: Creating composite widgets, Up: Creating new widgets in Ada Creating widgets from scratch ----------------------------- First, an important note: please do not read this if this is your first time using GtkAda or if you don't really understand the signal mechanism. Creating a nice and working widget really takes a lot of messing with the low level signals. Creating a widget from scratch is what you want to do if your widget should be drawn in a special way, should create and emit new signals, ... The example we give in `examples/base_widget' is a small target on which the user can click, and that sends one of two signals "bullseye" or "missed", depending on where the user has clicked. See also the example in `examples/tutorial/gtkdial' for a more complex widget, that implements a gauge where the user can move the arrow to select a new value. Once again, the only two functions that you must create are `Gtk_New' and `Initialize'. This time, `Initialize' has to do two things: Parent_Package.Initialize (Widget); -- The above line calls the Initialize function from the parent. -- This creates the underlying C widget, which we are going to -- modify with the following call: Gtk.Object.Initialize_Class_Record (Widget, Signals, Class_Record); -- This initializes the "class record" for the widget and -- creates the signals. In the above example, the new part is the second call. It takes three or four arguments: * `Widget' This is the widget that you want to initialize * `Signals' This is an array of string access containing the name of the signals you want to create. For instance, you could create Signals with Signals : Gtkada.Types.Chars_Ptr_Array := "bullseye" + "missed"; This will create two signals, named "bullseye" and "missed", whose callbacks' arguments can be specified with the fourth parameter. * `Class_Record' Every widget in C is associated with two records. The first one, which exists only once per widget type, is the "class record". It contains the list of signals that are known by this widget type, the list of default callbacks for the signals, ...; the second record is an "instance record", which contains data specific to a particular instance. In GtkAda, the "instance record" is simply your tagged type and its fields. The call to `Initialize_Class_Record' is provided to initialize the "class record". As we said, there should be only one such record per widget type. This parameter "Class_Record" will point to this records, once it is created, and will be reused for every instanciation of the widget. * `Parameters' This fourth argument is in fact optional, and is used to specify which kind of parameters each new signal is expecting. By default (ie if you don't give any value for this parameter), all the signals won't expect any argument, except of course a possible user_data. However, you can decide for instance that the first signal ("bullseye") should in fact take a second argument (say a Gint), and that "missed" will take two parameters (two Gints). `Parameters' should thus contain a value of (1 => (1 => Gtk_Type_Int, 2 => Gtk_Type_None), 2 => (1 => Gtk_Type_Int, 2 => Gtk_Type_Int)); Due to the way arrays are handled in Ada, each component must have the same number of signals. However, if you specify a type of `Gtk_Type_None', this will in fact be considered as no argument. Thus, the first signal above has only one parameter. Note also that to be able to emit a signal such a the second one, ie with multiple arguments, you will have to extend the packages defined in Gtk.Handlers. By default, the provided packages can only emit up to one argument (and only for a few specific types). Creating your own `Emit_By_Name' subprograms should not be hard if you look at what is done in `gtk-marshallers.adb'. Basically, something like: procedure Emit_With_Two_Ints (Object : access Widget_Type'Class; Name : String; Arg1 : Gint; Arg2 : Gint); pragma Import (C, Emit_With_Two_Ints, "gtk_signal_emit_by_name"); Emit_With_Two_Ints (Gtk.Get_Object (Your_Widget), "missed" & ASCII.NUL, 1, 2); will emit the "missed" signal with the two parameters 1 and 2. Then of course `Initialize' should set up some signal handlers for the functions you want to redefine. Three signals are especially useful: * "size_request" This callback is passed one parameter, as in : procedure Size_Request (Widget : access My_Widget_Record; Requisition : in out Gtk.Widget.Gtk_Requisition); This function should modify Requisition to specify the widget's ideal size. This might not be the exact size that will be set, since some containers might decide to enlarge or to shrink it. * "size_allocate" This callback is called every time the widget is moved in its parent window, or it is resized. It is passed one paramater, as in : procedure Size_Allocate (Widget : access My_Widget_Record; Allocation : in out Gtk.Widget.Gtk_Allocation) This function should take the responsability to move the widget, using for instance `Gdk.Window.Move_Resize'. * "expose_event" This callback is called every time the widget needs to be redrawn. It is passed one parameter, the area to be redrawn (to speed things up, you don't need to redraw the whole widget, just this area).  File: gtkada_ug.info, Node: Support for Glade the Gtk GUI builder, Next: Binding new widgets, Prev: Object-oriented features, Up: Top Support for Glade, the Gtk GUI builder ************************************** Introduction ============ GtkAda now comes with support for the GUI builder Glade (this is not the glade released with Gnat for distributed systems). Using Glade itself is straightforward: it is an intuitive point and click GUI builder. The main difference from other builders is that, since GtkAda builds a UI with blocks by default, you will not be asked to set the size and position of your windows by default. If you are looking for this kind of interaction you should consider using the Gtk_Fixed container. However, please read the GtkAda reference manual before considering using Gtk_Fixed. Using Glade =========== Note that we only recommend using version 2.0.0 of Glade, as previous versions are not compatible. Using this version you can directly create Ada files from Glade by selecting Ada95 as the language under project options. Glade saves your interface in a project file whose syntax is XML based. In the following sections, we will refer to this file as either `the XML file' or `the project file' interchangeably. Taking advantage of Glade's options ----------------------------------- In this XML file, Glade will save various options that Gate can take advantage of. In particular, going to the project options window, some General Options in the `C Options' section will also be used by Gate: Gettext support, if enabled, will generate an additional package called _intl that will use Gtkada.Intl; The `Set Widget Names' option is also recognized and will generate additional calls to Set_Name for each widget. Associating icons with buttons ------------------------------ Up to now, the only way to specify an icon for a button was to associate a pixmap file to it. As an alternative, if the name specified in the `Icon' field does not contain any dots, Gate will consider the name as a variable rather than a file name. It is up to you to provide the necessary definitions in order to compile properly the generated code. Note for GNU/Linux users ------------------------ Some GNU/Linux systems come with a precompiled version of Glade that will usually have support for Gnome. Gate currently does not provide support for Gnome, which means that you should not enable Gnome support in Glade. Gate ==== Invoking Gate ------------- Gate is a program that is delivered with GtkAda. Gate takes the Glade XML file as an argument and generates a set of Ada files. When compiled, these files will recreate the interface you just designed with Glade. Gate is generally invoked through the `Write source code' button in Glade's menu bar. In addition, you can also invoke it from the command line by providing a Glade project file. This will generate Ada files in the directory set as the `Source Directory' project option, or otherwise in the current working directory. Structure of the generated files -------------------------------- The main file ............. The main file is the name of the program name specified in the XML Glade file: `.adb'. It contains initialization and creation code for each top level widget contained in the XML file. This is intended as a convenient default to visualize your GUI, but you will usually want to modify this initialization. Top level widget files ...................... For each top level widget, Gate will generate a package `_Pkg' in the files `_pkg.ads' and `.adb'. These packages contain all the GtkAda calls needed to create the widgets you designed within Glade. You will usually not need to modify these files yourself. Main handler file ................. This file, called `callbacks_.ads' contains all the Handler package instantiations needed by your application. You will usually not need to modify it. Top level widget signal files ............................. These are the most important files created by Gate. Each is called `_pkg-callbacks.adb'. They contain stubs for all the callbacks related to a top level widget you declared in Glade. With the main file, this the only files you should modify yourself. Note that it is recommended that you structure your application such that the real code is put in separate packages (i.e not generated files) as much as possible, to avoid potential merging problems when your interface is significantly changed within Glade. See next section for more details. Currently, Gate will generate callback stub procedures that can handle the expected number of arguments for each signal. This is done using a relatively low level mechanism explained in the reference manual (package Gtk.Handlers). Basically, callbacks expecting arguments will take a Gtk_Argument as their only parameter, and Gate will generate the appropriate variable declaration and conversion calls to provide the expected GtkAda arguments. You should not modify this code by hand unless you know what you are doing. For example, given a signal `delete_event', Gate will generate the following procedure body, giving access to the arguments of this callback: a `Gtk_Window_Record' (Object) and a `Gdk_Event' (Arg1) function On_Main_Window_Delete_Event (Object : access Gtk_Window_Record'Class; Params : Gtk.Arguments.Gtk_Args) return Boolean is Arg1 : Gdk_Event := To_Event (Params, 1); begin return False; end On_Main_Window_Delete_Event; Modifying generated files ------------------------- Note that you can easily go back to Glade any time, modify your interface, and have Gate re-generate a set of files. All your modifications will be kept in the new files. For that, Gate creates a directory `.gate' in the current directory. Please do not delete it if you want Gate to be able to keep your changes from one version to the next. Also note that to keep track of your modifications, gate relies on either `merge', or `patch' and `diff' being available on your system. If you don't have a working set of `diff/patch', `configure' will simply replace them by null operations, which means that regenerated files will override the previous ones. Under Win32 based systems, Gate will not attempt to merge changes. Instead, it will always regenerate and overwrite every file. In some cases, due to major changes in the project file, Gate may not be able to merge all the changes. In this case, it will notify you so, and will either keep the old and new sections in the files (if you are using `merge'), or files with a `.rej' extension will be generated to help you do the merge manually. Adding Gate support for new widgets ----------------------------------- This section is intended for developpers that wish to add support for new GtkAda widgets in Gate. Note that this section is not complete yet. Implementing the `Generate' procedure ..................................... To provide support for a new widget, you first need to write a `Generate' procedure that will take care of generating the piece of code related to the widget's properties. Note that the parents properties do not have to be handled by this function. * Glib.Glade API The Glib.Glade package contains a self documented API that will help you automate most of the work for common widgets. * Most common mapping * Gen_New * Gen_Set * Gen_Call_Child * example * Registering `Generate' functions Gtk.Glade.Register_Generate (Widget, Func) This procedure associates a given Generate procedure with a given widget C name. Dynamic loading of XML files ============================ Introduction to Libglade ------------------------ Libglade is an external library provided by default on some systems (e.g GNU/Linux, Gnome) that supports dynamic loading of XML files and creation of widgets at run time. The advantage of using libglade is that you do not need to recompile your application to change your user interface. On the other hand, everything is done at run time, meaning less compile checks, and also the inability to take advantage of the object oriented features of GtkAda and Ada such as deriving from a widget creating using the GUI builder, to add fields and properties. See packages Glade and Glade.XML for more information. Limitations =========== Gate currently support all Gtk+ widgets and properties available under Glade. But, to help you identify widgets that may not be supported (e.g Gnome widgets), Gate will generate a warning on the standard error: $ gate warning.glade Generating Ada files... GtkAda-WARNING **: Unsupported widget GnomeCanvas (canvas1) The following files have been created/updated in src: [...] and add a comment in the `_pkg.adb' file that looks like: -- WARNING: Unsupported widget GnomeCanvas (canvas1) This means that while generating the file Gate detected an unsupported widget (in this case GnomeCanvas) whose name is canvas1. If you get such a warning your file may or may not compile properly, but you won't get the complete widget hierarchy at run time. Feel free to send us (see *Note How to report bugs::) the XML file that causes this problem. We don't guarantee a rapid fix for each particular problem but receiving real examples of missing functionnalities will certainly help implementing them faster.  File: gtkada_ug.info, Node: Binding new widgets, Next: Debugging GtkAda applications, Prev: Support for Glade the Gtk GUI builder, Up: Top Binding new widgets ******************* GtkAda comes with a Perl script to help you create a binding to a C widget (this is the script we have used ourselves). This will not fully automate the process, although it should really speed things up. You will probably need less than 15 min to create a new binding once you will get used to the way GtkAda works. Note that your C file should have the same format as is used by Gtk+ itself. Here are the steps to create a new binding : * Give the 'generate.pl' script the C header file * The perl script should ask you for every field in the C structure if you want to create a function to make it accessible from Ada. Answer y or n (the default value is n, just press ENTER). $ generate.pl ../include/gtk/gtkbutton.h > temporary Create a function for the field child (of type GtkWidget*) [n]? Create a function for the field in_button (of type guint) [n]? Create a function for the field button_down (of type guint) [n]? * If you answered yes to at least one of the above questions, create a new C file, and move the C part of the temporary file created by generate.pl to this C file. * Do a gnatchop on the temporary file created by generate.pl $ gnatchop temporary This should create two Ada files (spec and body) * Edit these two files if needed (generally to change some parameters from Gint to Boolean for instance). It can be a little bit tricky when one of your functions returns a GList* or a GSList*. Please have a look at `gtk-combo.ads' for examples how to do this.  File: gtkada_ug.info, Node: Debugging GtkAda applications, Next: How to report bugs, Prev: Binding new widgets, Up: Top Debugging GtkAda applications ***************************** This chapter presents a number of technics that can be used when debugging GtkAda applications. First, the standard tools to debug Ada applications can be used: *Compile with -g You should almost always include debugging information when compiling and linking your code. This gives you the possibility to use the debugger. See below the variable GDK_DEBUG for how to disable grabs. *bind with -E Using this argument on the `gnatbind' or `gnatmake' command line will force the compiler to include backtraces when an exception is raised. These backtraces can be converted to symbolic backtraces by using the `addr2line' tool. *Link with -lgmem Using this switch gives access to the `gnatmem' tool, that helps you to detect memory leaks or doubly-deallocated memory. The latter often results in hard-to-fix Storage_Error exceptions. See the GNAT User's guide for more information. There are also a number of technics specific to GtkAda or gtk+ applications. For most of them, you might need to recompile these libraries with the appropriate switches to get access to the extended debugging features. *Use the `--sync' switch All applications compiled with gtk+ automatically support this switch, which forces events to be processed synchronously, thus making it easier to detect problems as soon as they happen. *break on g_log In the debugger, it is often useful to put a breakpoint on the glib function `g_log'. When gtk+ is linked dynamically, you will need to first start your application with `begin', then put the breakpoint and continue the application with `cont'. This helps understand internal errors or warnings reported by gtk+ and glib *compile glib with `--disable-mem-pools' Glib, the underlying layer that provides system-independent services to gtk+, has an extensive and optimized system for memory allocation. Bigger chunks of Memory are allocated initially, and then subdivided by glib itself. Although this is extremely performant, this also make the debugging of memory-related problems (storage_error) more difficult. Compiling with the above switch forces glib to use the standard malloc() and free() system calls. On GNU/Linux systems, it might be useful to set the variable `MALLOC_CHECK_' to 1 to use error-detecting algorithms (see the man page for malloc()). *compile glib and gtk+ with `--enable-debug=yes' It is recommended that you always compile these two libraries by specifying this switch on the `configure' command line. In addition to giving access to the debugger, this also provides a number of environment variables that can be set to visualize events, object creation,... For these three variables, the possible values are given below. These are lists of colon-separated keywords. You can choose to remove any of these value from the variable -`GOBJECT_DEBUG=objects:signals' This sets up the debugging output for glib. The value `objects' is probably the most useful, and displays, on exit of the application, the list of unfreed objects. This helps detect memory leaks. The second value `signals' will display all the signals emitted by the objects. Note that this results in a significant amount of output. -`GDK_DEBUG=updates:nograbs:events:dnd:misc: xim:colormap:gdkrgb:gc:pixmap:image:input:cursor' This sets up the debugging output for gdk. The most useful value is `nograbs', which prevents the application from ever grabbing the mouse or keyboards. If you don't set this, it might happen that the debugger becomes unusable, since you don't have access to the mouse when the debugger stops on a breakpoint. Another simpler solution is to debug remotely from another machine, in which case the grabs won't affect the terminal on which the debugger is running. -`GTK_DEBUG=misc:plugsocket:text:tree:updates:keybindings' This sets up the debugging output for gtk. Almost all of these values are mostly for internal use by gtk+ developpers, although `keybindings' might prove useful sometimes. *Import the C function ada_gtk_debug_get_ref_count This function has the following Ada profile: function Ref_Count (Add : System.Address) return Guint; pragma Import (C, Ref_Count, "ada_gtk_debug_get_ref_count"); and should be called in a manner similar to declare Widget : Gtk_Widget; Count : Guint; begin Count := Ref_Count (Get_Object (Widget)); end; and returns the internal reference counter for the widget. When this counter reaches 0, the memory allocated for the widget is automatically freed. This is mostly a debugging aid for people writting their own containers, and shouldn't generally be needed. You shouldn't rely on the internal reference counter in your actual code, which is why it isn't exported by default in GtkAda.  File: gtkada_ug.info, Node: How to report bugs, Next: Bibliography, Prev: Debugging GtkAda applications, Up: Top How to report bugs ****************** GtkAda is becoming more and more stable due to its increasing use, but you may still find bugs while using it. We have tried to test it as much as possible, essentially by converting the testgtk.c file found in the gtk distribution, as well as with generating a significant enumber of interfaces using the GUI builder and Gate. We strongly suggest that you have a look at testgtk, which gives a lot of examples of how to use this toolkit. There are two kinds of problems you can encounter: * If the gtk library itself was compiled with warnings turned on, you may get some warnings messages, mainly because of types problems. These warnings should not appear, as we have tried to be as type safe as possible in this package. To know exactly where the problem is, compile your program with debug information, run gdb, and set a breakpoint on the function `g_log'. Then run your program as usual, using the `run' command. Then send us the result of the `where' command. Here is a summary: $ gnatmake -f -g `gtkada-config` $ gdb (gdb) break main (gdb) run (gdb) break g_log (gdb) continue .... (gdb) where * In some (hopefully) rare cases, you can even get a segmentation fault within gtk. That means there is definitly something wrong either in your program or in the toolkit. Please check your program carefully and, if you think this is a problem in GtkAda itself, send us an e-mail. If you are a supported user of GNAT, send mail to `mailto:report@gnat.com' to report errors, otherwise send mail to the authors (`mailto:gtkada@ada.eu.org') explaining exactly what your are doing, what is the expected result and what you actually get. Please include the required sources to reproduce the problem, in a format usable by `gnatchop' (basically, insert all the required sources at the end of the mail). Please try to provide as small as possible a subset of your sources. Of course, we will welcome any patch you can provide, so that this toolkit may be as useful as possible.  File: gtkada_ug.info, Node: Bibliography, Prev: How to report bugs, Up: Top Bibliography ************ We recommand the following documents. Most of them were written with C in mind, but should be easily adapted after you've read the rest of this document. * [1] "Gtk+/Gome Application Development" - Havoc Pennington This book, by one of the main authors of the the GNOME environment, describes in detail some of the inner mechanisms of gtk+, including signal handling, and a complete description of all the widgets and all the events found in `Gdk.Event'. It is worth noting that this book has been published under the Open Publication License. You can get an electronic copy of it at .