gtk_tut.sgml 509 KB
Newer Older
1 2 3 4 5 6 7
<!doctype linuxdoc system>

<!-- This is the tutorial marked up in SGML
     (just to show how to write a comment)
-->

<article>
8 9
<title>GTK v1.1 Tutorial
<author>
10
Tony Gale <tt><htmlurl url="mailto:gale@gtk.org"
11
			      name="&lt;gale@gtk.org&gt;"></tt>
12 13 14
Ian Main <tt><htmlurl url="mailto:imain@gtk.org"
			      name="&lt;imain@gtk.org&gt;"></tt>,
<date>December 6th, 1998
15 16 17 18 19 20

<!-- ***************************************************************** -->
<sect>Introduction
<!-- ***************************************************************** -->
<p>
GTK (GIMP Toolkit) was originally developed as a toolkit for the GIMP
21 22 23 24 25
(General Image Manipulation Program).  GTK is built on top of GDK
(GIMP Drawing Kit) which is basically a wrapper around the Xlib
functions.  It's called the GIMP toolkit because it was originally
written for developing the GIMP, but has now been used in several free
software projects.  The authors are:
26 27 28 29 30 31 32 33 34
<itemize>
<item> Peter Mattis   <tt><htmlurl url="mailto:petm@xcf.berkeley.edu"
			   name="petm@xcf.berkeley.edu"></tt>
<item> Spencer Kimball <tt><htmlurl url="mailto:spencer@xcf.berkeley.edu"
			   name="spencer@xcf.berkeley.edu"></tt>
<item> Josh MacDonald <tt><htmlurl url="mailto:jmacd@xcf.berkeley.edu"
			   name="jmacd@xcf.berkeley.edu"></tt>
</itemize>

35 36 37 38
GTK is essentially an object oriented application programmers
interface (API).  Although written completely in C, it is implemented
using the idea of classes and callback functions (pointers to
functions).
39

40
There is also a third component called glib which contains a few
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
replacements for some standard calls, as well as some additional
functions for handling linked lists etc.  The replacement functions
are used to increase GTK's portability, as some of the functions
implemented here are not available or are nonstandard on other unixes
such as g_strerror().  Some also contain enhancements to the libc
versions, such as g_malloc that has enhanced debugging utilities.

This tutorial is an attempt to document as much as possible of GTK, it
is by no means complete.  This tutorial assumes a good understanding
of C, and how to create C programs.  It would be a great benefit for
the reader to have previous X programming experience, but it shouldn't
be necessary.  If you are learning GTK as your first widget set,
please comment on how you found this tutorial, and what you had
trouble with.  Note that there is also a C++ API for GTK (GTK--) in
the works, so if you prefer to use C++, you should look into this
instead.  There's also an Objective C wrapper, and Guile bindings
available, but I don't follow these.

I would very much like to hear of any problems you have learning GTK
from this document, and would appreciate input as to how it may be
improved. Please see the section on <ref id="sec_Contributing"
name="Contributing"> for further information.
63 64 65 66 67 68

<!-- ***************************************************************** -->
<sect>Getting Started
<!-- ***************************************************************** -->

<p>
69 70 71 72 73 74
The first thing to do of course, is download the GTK source and
install it. You can always get the latest version from ftp.gtk.org in
/pub/gtk. You can also view other sources of GTK information on
http://www.gtk.org/ <htmlurl url="http://www.gtk.org/"
name="http://www.gtk.org/">. GTK uses GNU autoconf for configuration.
Once untar'd, type ./configure --help to see a list of options.
75

76 77 78
Th GTK source distribution also contains the complete source to all of
the examples used in this tutorial, along with Makefiles to aid
compilation.
79

80 81 82
To begin our introduction to GTK, we'll start with the simplest
program possible. This program will create a 200x200 pixel window and
has no way of exiting except to be killed using the shell.
83 84

<tscreen><verb>
85 86
/* example-start base base.c */

87 88
#include <gtk/gtk.h>

89 90
int main( int   argc,
          char *argv[] )
91 92 93 94 95 96
{
    GtkWidget *window;
    
    gtk_init (&amp;argc, &amp;argv);
    
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
97
    gtk_widget_show  (window);
98 99 100
    
    gtk_main ();
    
101
    return(0);
102
}
103 104 105 106 107 108
/* example-end */
</verb></tscreen>

You can compile the above program with gcc using:
<tscreen><verb>
gcc base.c -o base `gtk-config --cflags --libs`
109 110
</verb></tscreen>

111 112
The meaning of the unusual compilation options is explained below.

113
All programs will of course include gtk/gtk.h which declares the
114
variables, functions, structures etc. that will be used in your GTK
115
application.
116

117 118 119 120 121 122 123
The next line:

<tscreen><verb>
gtk_init (&amp;argc, &amp;argv);
</verb></tscreen>

calls the function gtk_init(gint *argc, gchar ***argv) which will be
124
called in all GTK applications. This sets up a few things for us such
125
as the default visual and color map and then proceeds to call
126
gdk_init(gint *argc, gchar ***argv). This function initializes the
127
library for use, sets up default signal handlers, and checks the
128 129
arguments passed to your application on the command line, looking for
one of the following:
130 131

<itemize>
132 133 134 135 136 137
<item> <tt/--gtk-module/
<item> <tt/--g-fatal-warnings/
<item> <tt/--gtk-debug/
<item> <tt/--gtk-no-debug/
<item> <tt/--gdk-debug/
<item> <tt/--gdk-no-debug/
138 139
<item> <tt/--display/
<item> <tt/--sync/
140
<item> <tt/--no-xshm/
141 142
<item> <tt/--name/
<item> <tt/--class/
143
</itemize>
144

145 146
It removes these from the argument list, leaving anything it does not
recognize for your application to parse or ignore. This creates a set
147
of standard arguments accepted by all GTK applications.
148

149 150 151 152 153 154 155 156 157
The next two lines of code create and display a window.

<tscreen><verb>
  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_widget_show (window);
</verb></tscreen>

The GTK_WINDOW_TOPLEVEL argument specifies that we want the window to
undergo window manager decoration and placement. Rather than create a
158 159
window of 0x0 size, a window without children is set to 200x200 by
default so you can still manipulate it.
160

161 162
The gtk_widget_show() function lets GTK know that we are done setting
the attributes of this widget, and that it can display it.
163

164 165 166
The last line enters the GTK main processing loop.

<tscreen><verb>
167
  gtk_main ();
168 169
</verb></tscreen>

170 171 172 173
gtk_main() is another call you will see in every GTK application.
When control reaches this point, GTK will sleep waiting for X events
(such as button or key presses), timeouts, or file IO notifications to
occur. In our simple example however, events are ignored.
174 175 176 177

<!-- ----------------------------------------------------------------- -->
<sect1>Hello World in GTK
<p>
178 179
Now for a program with a widget (a button).  It's the classic
hello world a la GTK.
180 181

<tscreen><verb>
182
/* example-start helloworld helloworld.c */
183 184 185

#include <gtk/gtk.h>

186 187 188 189
/* This is a callback function. The data arguments are ignored
 * in this example. More on callbacks below. */
void hello( GtkWidget *widget,
            gpointer   data )
190 191 192 193
{
    g_print ("Hello World\n");
}

194 195 196
gint delete_event( GtkWidget *widget,
                   GdkEvent  *event,
		   gpointer   data )
197
{
198 199
    /* If you return FALSE in the "delete_event" signal handler,
     * GTK will emit the "destroy" signal. Returning TRUE means
200
     * you don't want the window to be destroyed.
201
     * This is useful for popping up 'are you sure you want to quit?'
202
     * type dialogs. */
203

204 205
    g_print ("delete event occurred\n");

206
    /* Change TRUE to FALSE and the main window will be destroyed with
207
     * a "delete_event". */
208

209
    return(TRUE);
210 211
}

212 213 214
/* Another callback */
void destroy( GtkWidget *widget,
              gpointer   data )
215
{
216
    gtk_main_quit();
217 218
}

219 220
int main( int   argc,
          char *argv[] )
221 222 223 224 225
{
    /* GtkWidget is the storage type for widgets */
    GtkWidget *window;
    GtkWidget *button;
    
226 227 228
    /* This is called in all GTK applications. Arguments are parsed
     * from the command line and are returned to the application. */
    gtk_init(&amp;argc, &amp;argv);
229 230 231 232
    
    /* create a new window */
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    
233 234 235 236 237
    /* When the window is given the "delete_event" signal (this is given
     * by the window manager, usually by the 'close' option, or on the
     * titlebar), we ask it to call the delete_event () function
     * as defined above. The data passed to the callback
     * function is NULL and is ignored in the callback function. */
238 239 240
    gtk_signal_connect (GTK_OBJECT (window), "delete_event",
			GTK_SIGNAL_FUNC (delete_event), NULL);
    
241
    /* Here we connect the "destroy" event to a signal handler.  
242
     * This event occurs when we call gtk_widget_destroy() on the window,
243
     * or if we return 'FALSE' in the "delete_event" callback. */
244 245 246
    gtk_signal_connect (GTK_OBJECT (window), "destroy",
			GTK_SIGNAL_FUNC (destroy), NULL);
    
247
    /* Sets the border width of the window. */
248 249
    gtk_container_border_width (GTK_CONTAINER (window), 10);
    
250
    /* Creates a new button with the label "Hello World". */
251 252 253
    button = gtk_button_new_with_label ("Hello World");
    
    /* When the button receives the "clicked" signal, it will call the
254 255
     * function hello() passing it NULL as its argument.  The hello()
     * function is defined above. */
256 257 258 259
    gtk_signal_connect (GTK_OBJECT (button), "clicked",
			GTK_SIGNAL_FUNC (hello), NULL);
    
    /* This will cause the window to be destroyed by calling
260
     * gtk_widget_destroy(window) when "clicked".  Again, the destroy
261 262 263 264 265
     * signal could come from here, or the window manager. */
    gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
			       GTK_SIGNAL_FUNC (gtk_widget_destroy),
			       GTK_OBJECT (window));
    
266
    /* This packs the button into the window (a gtk container). */
267 268
    gtk_container_add (GTK_CONTAINER (window), button);
    
269
    /* The final step is to display this newly created widget. */
270 271 272 273 274
    gtk_widget_show (button);
    
    /* and the window */
    gtk_widget_show (window);
    
275 276 277
    /* All GTK applications must have a gtk_main(). Control ends here
     * and waits for an event to occur (like a key press or
     * mouse event). */
278 279
    gtk_main ();
    
280
    return(0);
281
}
282
/* example-end */
283 284 285 286 287 288 289 290
</verb></tscreen>

<!-- ----------------------------------------------------------------- -->
<sect1>Compiling Hello World
<p>
To compile use:

<tscreen><verb>
291
gcc -Wall -g helloworld.c -o helloworld `gtk-config --cflags` \
292
    `gtk-config --libs`
293
</verb></tscreen>
294 295 296 297 298 299

This uses the program <tt>gtk-config</>, which comes with gtk. This
program 'knows' what compiler switches are needed to compile programs
that use gtk. <tt>gtk-config --cflags</> will output a list of include
directories for the compiler to look in, and <tt>gtk-config --libs</>
will output the list of libraries for the compiler to link with and
300 301 302
the directories to find them in. In the aboce example they could have
been combined into a single instance, such as
`gtk-config --cflags --libs`.
303

304 305 306
Note that the type of single quote used in the compile command above
is significant.

307
The libraries that are usually linked in are:
308 309 310
<itemize>
<item>The GTK library (-lgtk), the widget library, based on top of GDK.
<item>The GDK library (-lgdk), the Xlib wrapper.
311 312
<item>The gmodule library (-lgmodule), which is used to load run time
extensions.
313
<item>The glib library (-lglib), containing miscellaneous functions, only
314 315 316
g_print() is used in this particular example. GTK is built on top
of glib so you will always require this library. See the section on 
<ref id="sec_glib" name="glib"> for details.
317
<item>The Xlib library (-lX11) which is used by GDK.
318
<item>The Xext library (-lXext). This contains code for shared memory
319
pixmaps and other X extensions.
320
<item>The math library (-lm). This is used by GTK for various purposes.
321 322 323 324 325
</itemize>

<!-- ----------------------------------------------------------------- -->
<sect1>Theory of Signals and Callbacks
<p>
326 327 328 329
Before we look in detail at <em>helloworld</em>, we'll discuss signals
and callbacks. GTK is an event driven toolkit, which means it will
sleep in gtk_main until an event occurs and control is passed to the
appropriate function.
330

331 332 333 334 335
This passing of control is done using the idea of "signals". When an
event occurs, such as the press of a mouse button, the appropriate
signal will be "emitted" by the widget that was pressed.  This is how
GTK does most of its useful work. There are a set of signals that all
widgets inherit, such as "destroy", and there are signals that are
336 337
widget specific, such as "toggled" on a toggle button.

338 339 340
To make a button perform an action, we set up a signal handler to
catch these signals and call the appropriate function. This is done by
using a function such as:
341 342

<tscreen><verb>
343 344 345 346
gint gtk_signal_connect( GtkObject     *object,
                         gchar         *name,
                         GtkSignalFunc  func,
                         gpointer       func_data );
347
</verb></tscreen>
348

349 350 351 352
Where the first argument is the widget which will be emitting the
signal, and the second, the name of the signal you wish to catch. The
third is the function you wish to be called when it is caught, and the
fourth, the data you wish to have passed to this function.
353

354
The function specified in the third argument is called a "callback
355
function", and should generally be of the form:
356 357

<tscreen><verb>
358 359
void callback_func( GtkWidget *widget,
                    gpointer   callback_data );
360
</verb></tscreen>
361

362 363 364
Where the first argument will be a pointer to the widget that emitted
the signal, and the second, a pointer to the data given as the last
argument to the gtk_signal_connect() function as shown above.
365 366

Note that the above form for a signal callback function declaration is
367 368 369
only a general guide, as some widget specific signals generate
different calling parameters. For example, the GtkCList "select_row"
signal provides both row and column parameters.
370

371
Another call used in the <em>helloworld</em> example, is:
372 373

<tscreen><verb>
374 375 376 377
gint gtk_signal_connect_object( GtkObject     *object,
                                gchar         *name,
                                GtkSignalFunc  func,
                                GtkObject     *slot_object );
378
</verb></tscreen>
379

380 381 382
gtk_signal_connect_object() is the same as gtk_signal_connect() except
that the callback function only uses one argument, a pointer to a GTK
object. So when using this function to connect signals, the callback
383
should be of the form:
384 385

<tscreen><verb>
386
void callback_func( GtkObject *object );
387
</verb></tscreen>
388

389 390 391 392
Where the object is usually a widget. We usually don't setup callbacks
for gtk_signal_connect_object however. They are usually used to call a
GTK function that accepts a single widget or object as an argument, as
is the case in our <em>helloworld</em> example.
393

394 395 396 397 398 399
The purpose of having two functions to connect signals is simply to
allow the callbacks to have a different number of arguments. Many
functions in the GTK library accept only a single GtkWidget pointer as
an argument, so you want to use the gtk_signal_connect_object() for
these, whereas for your functions, you may need to have additional
data supplied to the callbacks.
400

401 402 403
<!-- ----------------------------------------------------------------- -->
<sect1>Events
<p>
404 405 406
In addition to the signal mechanism described above, there are a set
of <em>events</em> that reflect the X event mechanism. Callbacks may
also be attached to these events. These events are:
407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439

<itemize>
<item> event
<item> button_press_event
<item> button_release_event
<item> motion_notify_event
<item> delete_event
<item> destroy_event
<item> expose_event
<item> key_press_event
<item> key_release_event
<item> enter_notify_event
<item> leave_notify_event
<item> configure_event
<item> focus_in_event
<item> focus_out_event
<item> map_event
<item> unmap_event
<item> property_notify_event
<item> selection_clear_event
<item> selection_request_event
<item> selection_notify_event
<item> proximity_in_event
<item> proximity_out_event
<item> drag_begin_event
<item> drag_request_event
<item> drag_end_event
<item> drop_enter_event
<item> drop_leave_event
<item> drop_data_available_event
<item> other_event
</itemize>

440 441 442 443 444
In order to connect a callback function to one of these events, you
use the function gtk_signal_connect, as described above, using one of
the above event names as the <tt/name/ parameter. The callback
function for events has a slightly different form than that for
signals:
445 446 447 448 449 450 451

<tscreen><verb>
void callback_func( GtkWidget *widget,
                    GdkEvent  *event,
                    gpointer   callback_data );
</verb></tscreen>

452 453 454 455 456 457
GdkEvent is a C <tt/union/ structure whose type will depend upon which
of the above events has occurred. In order for us to tell which event
has been issued each of the possible alternatives has a <tt/type/
parameter which reflects the event being issued. The other components
of the event structure will depend upon the type of the
event. Possible values for the type are:
458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494

<tscreen><verb>
  GDK_NOTHING
  GDK_DELETE
  GDK_DESTROY
  GDK_EXPOSE
  GDK_MOTION_NOTIFY
  GDK_BUTTON_PRESS
  GDK_2BUTTON_PRESS
  GDK_3BUTTON_PRESS
  GDK_BUTTON_RELEASE
  GDK_KEY_PRESS
  GDK_KEY_RELEASE
  GDK_ENTER_NOTIFY
  GDK_LEAVE_NOTIFY
  GDK_FOCUS_CHANGE
  GDK_CONFIGURE
  GDK_MAP
  GDK_UNMAP
  GDK_PROPERTY_NOTIFY
  GDK_SELECTION_CLEAR
  GDK_SELECTION_REQUEST
  GDK_SELECTION_NOTIFY
  GDK_PROXIMITY_IN
  GDK_PROXIMITY_OUT
  GDK_DRAG_BEGIN
  GDK_DRAG_REQUEST
  GDK_DROP_ENTER
  GDK_DROP_LEAVE
  GDK_DROP_DATA_AVAIL
  GDK_CLIENT_EVENT
  GDK_VISIBILITY_NOTIFY
  GDK_NO_EXPOSE
  GDK_OTHER_EVENT	/* Deprecated, use filters instead */
</verb></tscreen>

So, to connect a callback function to one of these events we would use
495
something like:
496 497 498 499 500 501 502

<tscreen><verb>
gtk_signal_connect( GTK_OBJECT(button), "button_press_event",
                    GTK_SIGNAL_FUNC(button_press_callback), 
		        NULL);
</verb></tscreen>

503 504 505 506
This assumes that <tt/button/ is a GtkButton widget. Now, when the
mouse is over the button and a mouse button is pressed, the function
<tt/button_press_callback/ will be called. This function may be
declared as:
507 508 509 510 511 512 513

<tscreen><verb>
static gint button_press_event (GtkWidget      *widget, 
                                GdkEventButton *event,
                                gpointer        data);
</verb></tscreen>

514 515 516
Note that we can declare the second argument as type
<tt/GdkEventButton/ as we know what type of event will occur for this
function to be called.
517

518 519 520 521 522
The value returned from this function indicates whether the event
should be propagated further by the GTK event handling
mechanism. Returning TRUE indicates that the event has been handled,
and that it should not propagate further. Returning FALSE continues
the normal event handling.  See the section on
523 524 525 526 527 528
<ref id="sec_Adv_Events_and_Signals"
name="Advanced Event and Signal Handling"> for more details on this
propagation process.

For details on the GdkEvent data types, see the appendix entitled
<ref id="sec_GDK_Event_Types" name="GDK Event Types">.
529

530 531 532 533
<!-- ----------------------------------------------------------------- -->
<sect1>Stepping Through Hello World
<p>
Now that we know the theory behind this, lets clarify by walking through 
534
the example <em>helloworld</em> program.
535

536
Here is the callback function that will be called when the button is
537 538 539
"clicked". We ignore both the widget and the data in this example, but
it is not hard to do things with them. The next example will use the
data argument to tell us which button was pressed.
540 541

<tscreen><verb>
542 543
void hello( GtkWidget *widget,
            gpointer   data )
544 545 546 547 548
{
    g_print ("Hello World\n");
}
</verb></tscreen>

549 550 551 552
The next callback is a bit special. The "delete_event" occurs when the
window manager sends this event to the application. We have a choice
here as to what to do about these events. We can ignore them, make
some sort of response, or simply quit the application.
553

554 555 556 557 558
The value you return in this callback lets GTK know what action to
take.  By returning TRUE, we let it know that we don't want to have
the "destroy" signal emitted, keeping our application running. By
returning FALSE, we ask that "destroy" is emitted, which in turn will
call our "destroy" signal handler.
559 560

<tscreen><verb>
561 562 563
gint delete_event( GtkWidget *widget,
                   GdkEvent  *event,
		   gpointer   data )
564
{
565
    g_print ("delete event occurred\n");
566

567
    return (TRUE); 
568 569 570
}
</verb></tscreen>

571 572 573
Here is another callback function which causes the program to quit by
calling gtk_main_quit(). This function tells GTK that it is to exit
from gtk_main when control is returned to it.
574

575
<tscreen><verb>
576 577
void destroy( GtkWidget *widget,
              gpointer   data )
578 579 580 581
{
    gtk_main_quit ();
}
</verb></tscreen>
582

583 584
I assume you know about the main() function... yes, as with other
applications, all GTK applications will also have one of these.
585

586
<tscreen><verb>
587 588
int main( int   argc,
          char *argv[] )
589 590
{
</verb></tscreen>
591

592 593
This next part, declares a pointer to a structure of type
GtkWidget. These are used below to create a window and a button.
594

595 596 597 598
<tscreen><verb>
    GtkWidget *window;
    GtkWidget *button;
</verb></tscreen>
599

600 601 602 603 604
Here is our gtk_init again. As before, this initializes the toolkit,
and parses the arguments found on the command line. Any argument it
recognizes from the command line, it removes from the list, and
modifies argc and argv to make it look like they never existed,
allowing your application to parse the remaining arguments.
605

606 607 608
<tscreen><verb>
    gtk_init (&amp;argc, &amp;argv);
</verb></tscreen>
609

610 611 612 613
Create a new window. This is fairly straight forward. Memory is
allocated for the GtkWidget *window structure so it now points to a
valid structure. It sets up a new window, but it is not displayed
until we call gtk_widget_show(window) near the end of our program.
614

615 616 617
<tscreen><verb>
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
</verb></tscreen>
618 619

Here is an example of connecting a signal handler to an object, in
620 621 622 623 624 625 626
this case, the window. Here, the "destroy" signal is caught. This is
emitted when we use the window manager to kill the window (and we
return TRUE in the "delete_event" handler), or when we use the
gtk_widget_destroy() call passing in the window widget as the object
to destroy. By setting this up, we handle both cases with a single
call.  Here, it just calls the destroy() function defined above with a
NULL argument, which quits GTK for us.
627

628 629 630
The GTK_OBJECT and GTK_SIGNAL_FUNC are macros that perform type
casting and checking for us, as well as aid the readability of the
code.
631

632 633
<tscreen><verb>
    gtk_signal_connect (GTK_OBJECT (window), "destroy",
634
                        GTK_SIGNAL_FUNC (destroy), NULL);
635
</verb></tscreen>
636

637 638 639 640
This next function is used to set an attribute of a container object.
This just sets the window so it has a blank area along the inside of
it 10 pixels wide where no widgets will go. There are other similar
functions which we will look at in the section on
641
<ref id="sec_setting_widget_attributes" name="Setting Widget Attributes">
642

643
And again, GTK_CONTAINER is a macro to perform type casting.
644

645 646 647
<tscreen><verb>
    gtk_container_border_width (GTK_CONTAINER (window), 10);
</verb></tscreen>
648

649 650 651 652
This call creates a new button. It allocates space for a new GtkWidget
structure in memory, initializes it, and makes the button pointer
point to it. It will have the label "Hello World" on it when
displayed.
653

654 655 656
<tscreen><verb>
    button = gtk_button_new_with_label ("Hello World");
</verb></tscreen>
657

658 659 660 661 662
Here, we take this button, and make it do something useful. We attach
a signal handler to it so when it emits the "clicked" signal, our
hello() function is called. The data is ignored, so we simply pass in
NULL to the hello() callback function. Obviously, the "clicked" signal
is emitted when we click the button with our mouse pointer.
663 664 665

<tscreen><verb>
    gtk_signal_connect (GTK_OBJECT (button), "clicked",
666
                        GTK_SIGNAL_FUNC (hello), NULL);
667
</verb></tscreen>
668

669 670 671 672 673 674 675 676 677 678
We are also going to use this button to exit our program. This will
illustrate how the "destroy" signal may come from either the window
manager, or our program. When the button is "clicked", same as above,
it calls the first hello() callback function, and then this one in the
order they are set up. You may have as many callback functions as you
need, and all will be executed in the order you connected
them. Because the gtk_widget_destroy() function accepts only a
GtkWidget *widget as an argument, we use the
gtk_signal_connect_object() function here instead of straight
gtk_signal_connect().
679 680

<tscreen><verb>
681 682 683
    gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
                               GTK_SIGNAL_FUNC (gtk_widget_destroy),
                               GTK_OBJECT (window));
684
</verb></tscreen>
685

686 687 688 689 690 691
This is a packing call, which will be explained in depth later on. But
it is fairly easy to understand. It simply tells GTK that the button
is to be placed in the window where it will be displayed. Note that a
GTK container can only contain one widget. There are other widgets,
that are described later, which are designed to layout multiple
widgets in various ways.
692
 
693 694 695
<tscreen><verb>
    gtk_container_add (GTK_CONTAINER (window), button);
</verb></tscreen>
696

697
Now we have everything set up the way we want it to be. With all the
698
signal handlers in place, and the button placed in the window where it
699 700 701 702
should be, we ask GTK to "show" the widgets on the screen. The window
widget is shown last so the whole window will pop up at once rather
than seeing the window pop up, and then the button form inside of
it. Although with such a simple example, you'd never notice.
703

704 705 706 707 708
<tscreen><verb>
    gtk_widget_show (button);

    gtk_widget_show (window);
</verb></tscreen>
709

710 711 712
And of course, we call gtk_main() which waits for events to come from
the X server and will call on the widgets to emit signals when these
events come.
713

714 715 716
<tscreen><verb>
    gtk_main ();
</verb></tscreen>
717

718
And the final return. Control returns here after gtk_quit() is called.
719

720 721 722
<tscreen><verb>
    return 0;
</verb></tscreen>
723

724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744
Now, when we click the mouse button on a GTK button, the widget emits
a "clicked" signal. In order for us to use this information, our
program sets up a signal handler to catch that signal, which
dispatches the function of our choice. In our example, when the button
we created is "clicked", the hello() function is called with a NULL
argument, and then the next handler for this signal is called. This
calls the gtk_widget_destroy() function, passing it the window widget
as its argument, destroying the window widget. This causes the window
to emit the "destroy" signal, which is caught, and calls our destroy()
callback function, which simply exits GTK.

Another course of events, is to use the window manager to kill the
window. This will cause the "delete_event" to be emitted. This will
call our "delete_event" handler. If we return TRUE here, the window
will be left as is and nothing will happen. Returning FALSE will cause
GTK to emit the "destroy" signal which of course, calls the "destroy"
callback, exiting GTK.

Note that these signals are not the same as the Unix system signals,
and are not implemented using them, although the terminology is almost
identical.
745 746 747 748 749 750 751 752

<!-- ***************************************************************** -->
<sect>Moving On
<!-- ***************************************************************** -->

<!-- ----------------------------------------------------------------- -->
<sect1>Data Types
<p>
753 754 755 756
There are a few things you probably noticed in the previous examples
that need explaining. The gint, gchar etc. that you see are typedefs
to int and char respectively. This is done to get around that nasty
dependency on the size of simple data types when doing calculations.
757

758 759 760 761
A good example is "gint32" which will be typedef'd to a 32 bit integer
for any given platform, whether it be the 64 bit alpha, or the 32 bit
i386. The typedefs are very straight forward and intuitive. They are
all defined in glib/glib.h (which gets included from gtk.h).
762

763 764 765
You'll also notice the ability to use GtkWidget when the function
calls for a GtkObject. GTK is an object oriented design, and a widget
is an object.
766 767 768 769 770 771 772

<!-- ----------------------------------------------------------------- -->
<sect1>More on Signal Handlers
<p>
Lets take another look at the gtk_signal_connect declaration.

<tscreen><verb>
773 774 775 776
gint gtk_signal_connect( GtkObject *object,
                         gchar *name,
                         GtkSignalFunc func,
                         gpointer func_data );
777 778
</verb></tscreen>

779 780 781 782
Notice the gint return value? This is a tag that identifies your
callback function. As stated above, you may have as many callbacks per
signal and per object as you need, and each will be executed in turn,
in the order they were attached.
783

784
This tag allows you to remove this callback from the list by using:
785

786
<tscreen><verb>
787 788
void gtk_signal_disconnect( GtkObject *object,
                            gint id );
789
</verb></tscreen>
790

791 792
So, by passing in the widget you wish to remove the handler from, and
the tag returned by one of the signal_connect functions, you can
793
disconnect a signal handler.
794

795
Another function to remove all the signal handers from an object is:
796

797
<tscreen><verb>
798
void gtk_signal_handlers_destroy( GtkObject *object );
799
</verb></tscreen>
800

801 802 803
This call is fairly self explanatory. It simply removes all the
current signal handlers from the object passed in as the first
argument.
804 805 806 807

<!-- ----------------------------------------------------------------- -->
<sect1>An Upgraded Hello World
<p>
808 809 810
Let's take a look at a slightly improved <em>helloworld</em> with
better examples of callbacks. This will also introduce us to our next
topic, packing widgets.
811 812

<tscreen><verb>
813
/* example-start helloworld2 helloworld2.c */
814 815 816

#include <gtk/gtk.h>

817 818 819 820
/* Our new improved callback.  The data passed to this function
 * is printed to stdout. */
void callback( GtkWidget *widget,
               gpointer   data )
821 822 823 824 825
{
    g_print ("Hello again - %s was pressed\n", (char *) data);
}

/* another callback */
826 827 828
void delete_event( GtkWidget *widget,
                   GdkEvent  *event,
		   gpointer   data )
829 830 831 832
{
    gtk_main_quit ();
}

833 834
int main( int   argc,
          char *argv[] )
835 836 837 838 839 840
{
    /* GtkWidget is the storage type for widgets */
    GtkWidget *window;
    GtkWidget *button;
    GtkWidget *box1;

841 842
    /* This is called in all GTK applications. Arguments are parsed
     * from the command line and are returned to the application. */
843 844
    gtk_init (&amp;argc, &amp;argv);

845
    /* Create a new window */
846 847
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

848
    /* This is a new call, this just sets the title of our
849 850 851 852 853 854 855 856
     * new window to "Hello Buttons!" */
    gtk_window_set_title (GTK_WINDOW (window), "Hello Buttons!");

    /* Here we just set a handler for delete_event that immediately
     * exits GTK. */
    gtk_signal_connect (GTK_OBJECT (window), "delete_event",
			GTK_SIGNAL_FUNC (delete_event), NULL);

857
    /* Sets the border width of the window. */
858 859
    gtk_container_border_width (GTK_CONTAINER (window), 10);

860 861
    /* We create a box to pack widgets into.  This is described in detail
     * in the "packing" section. The box is not really visible, it
862 863 864
     * is just used as a tool to arrange widgets. */
    box1 = gtk_hbox_new(FALSE, 0);

865
    /* Put the box into the main window. */
866 867
    gtk_container_add (GTK_CONTAINER (window), box1);

868
    /* Creates a new button with the label "Button 1". */
869 870 871
    button = gtk_button_new_with_label ("Button 1");

    /* Now when the button is clicked, we call the "callback" function
872
     * with a pointer to "button 1" as its argument */
873 874 875
    gtk_signal_connect (GTK_OBJECT (button), "clicked",
			GTK_SIGNAL_FUNC (callback), (gpointer) "button 1");

876
    /* Instead of gtk_container_add, we pack this button into the invisible
877 878 879
     * box, which has been packed into the window. */
    gtk_box_pack_start(GTK_BOX(box1), button, TRUE, TRUE, 0);

880 881
    /* Always remember this step, this tells GTK that our preparation for
     * this button is complete, and it can now be displayed. */
882 883
    gtk_widget_show(button);

884
    /* Do these same steps again to create a second button */
885 886
    button = gtk_button_new_with_label ("Button 2");

887
    /* Call the same callback function with a different argument,
888 889 890 891 892 893 894 895 896 897 898 899 900 901
     * passing a pointer to "button 2" instead. */
    gtk_signal_connect (GTK_OBJECT (button), "clicked",
			GTK_SIGNAL_FUNC (callback), (gpointer) "button 2");

    gtk_box_pack_start(GTK_BOX(box1), button, TRUE, TRUE, 0);

    /* The order in which we show the buttons is not really important, but I
     * recommend showing the window last, so it all pops up at once. */
    gtk_widget_show(button);

    gtk_widget_show(box1);

    gtk_widget_show (window);

902
    /* Rest in gtk_main and wait for the fun to begin! */
903 904
    gtk_main ();

905
    return(0);
906
}
907
/* example-end */
908
</verb></tscreen>
909

910 911 912 913 914 915 916
Compile this program using the same linking arguments as our first
example.  You'll notice this time there is no easy way to exit the
program, you have to use your window manager or command line to kill
it. A good exercise for the reader would be to insert a third "Quit"
button that will exit the program. You may also wish to play with the
options to gtk_box_pack_start() while reading the next section.  Try
resizing the window, and observe the behavior.
917

918 919 920
Just as a side note, there is another useful define for
gtk_window_new() - GTK_WINDOW_DIALOG. This interacts with the window
manager a little differently and should be used for transient windows.
921 922 923 924 925

<!-- ***************************************************************** -->
<sect>Packing Widgets
<!-- ***************************************************************** -->
<p>
926
When creating an application, you'll want to put more than one widget
927 928 929 930 931
inside a window. Our first <em>helloworld</em> example only used one
widget so we could simply use a gtk_container_add call to "pack" the
widget into the window. But when you want to put more than one widget
into a window, how do you control where that widget is positioned?
This is where packing comes in.
932 933 934 935

<!-- ----------------------------------------------------------------- -->
<sect1>Theory of Packing Boxes
<p>
936 937 938 939 940 941 942 943 944 945 946
Most packing is done by creating boxes as in the example above. These
are invisible widget containers that we can pack our widgets into
which come in two forms, a horizontal box, and a vertical box. When
packing widgets into a horizontal box, the objects are inserted
horizontally from left to right or right to left depending on the call
used. In a vertical box, widgets are packed from top to bottom or vice
versa. You may use any combination of boxes inside or beside other
boxes to create the desired effect.

To create a new horizontal box, we use a call to gtk_hbox_new(), and
for vertical boxes, gtk_vbox_new().The gtk_box_pack_start() and
947
gtk_box_pack_end() functions are used to place objects inside of these
948 949 950 951 952 953 954 955 956 957 958 959 960 961 962
containers. The gtk_box_pack_start() function will start at the top
and work its way down in a vbox, and pack left to right in an hbox.
gtk_box_pack_end() will do the opposite, packing from bottom to top in
a vbox, and right to left in an hbox. Using these functions allow us
to right justify or left justify our widgets and may be mixed in any
way to achieve the desired effect. We will use gtk_box_pack_start() in
most of our examples. An object may be another container or a
widget. In fact, many widgets are actually containers themselves,
including the button, but we usually only use a label inside a button.

By using these calls, GTK knows where you want to place your widgets
so it can do automatic resizing and other nifty things. There's also a
number of options as to how your widgets should be packed. As you can
imagine, this method gives us a quite a bit of flexibility when
placing and creating widgets.
963 964 965 966 967 968

<!-- ----------------------------------------------------------------- -->
<sect1>Details of Boxes
<p>
Because of this flexibility, packing boxes in GTK can be confusing at
first. There are a lot of options, and it's not immediately obvious how
969
they all fit together. In the end however, there are basically five
970
different styles.
971 972 973

<? <CENTER> >
<?
974 975
<IMG SRC="gtk_tut_packbox1.gif" VSPACE="15" HSPACE="10" WIDTH="528"
HEIGHT="235" ALT="Box Packing Example Image">
976 977 978 979
>
<? </CENTER> >

Each line contains one horizontal box (hbox) with several buttons. The
980 981 982
call to gtk_box_pack is shorthand for the call to pack each of the
buttons into the hbox. Each of the buttons is packed into the hbox the
same way (i.e. same arguments to the gtk_box_pack_start() function).
983

984 985 986
This is the declaration of the gtk_box_pack_start function.

<tscreen><verb>
987 988 989 990 991
void gtk_box_pack_start( GtkBox    *box,
                         GtkWidget *child,
                         gint       expand,
                         gint       fill,
                         gint       padding );
992 993
</verb></tscreen>

994 995 996
The first argument is the box you are packing the object into, the
second is the object. The objects will all be buttons for now, so
we'll be packing buttons into boxes.
997

998 999 1000 1001 1002 1003 1004 1005
The expand argument to gtk_box_pack_start() and gtk_box_pack_end()
controls whether the widgets are laid out in the box to fill in all
the extra space in the box so the box is expanded to fill the area
alloted to it (TRUE).  Or the box is shrunk to just fit the widgets
(FALSE). Setting expand to FALSE will allow you to do right and left
justification of your widgets.  Otherwise, they will all expand to fit
into the box, and the same effect could be achieved by using only one
of gtk_box_pack_start or gtk_box_pack_end.
1006

1007 1008 1009 1010
The fill argument to the gtk_box_pack functions control whether the
extra space is allocated to the objects themselves (TRUE), or as extra
padding in the box around these objects (FALSE). It only has an effect
if the expand argument is also TRUE.
1011

1012 1013 1014
When creating a new box, the function looks like this:

<tscreen><verb>
1015 1016
GtkWidget *gtk_hbox_new (gint homogeneous,
                         gint spacing);
1017 1018
</verb></tscreen>

1019 1020 1021 1022 1023
The homogeneous argument to gtk_hbox_new (and the same for
gtk_vbox_new) controls whether each object in the box has the same
size (i.e. the same width in an hbox, or the same height in a
vbox). If it is set, the expand argument to the gtk_box_pack routines
is always turned on.
1024

1025 1026 1027 1028
What's the difference between spacing (set when the box is created)
and padding (set when elements are packed)? Spacing is added between
objects, and padding is added on either side of an object. The
following figure should make it clearer:
1029 1030 1031

<? <CENTER> >
<?
1032 1033 1034
<IMG ALIGN="center" SRC="gtk_tut_packbox2.gif" WIDTH="509"
HEIGHT="213" VSPACE="15" HSPACE="10"
ALT="Box Packing Example Image">
1035 1036 1037
>
<? </CENTER> >

1038 1039 1040
Here is the code used to create the above images. I've commented it
fairly heavily so hopefully you won't have any problems following
it. Compile it yourself and play with it.
1041 1042 1043 1044 1045

<!-- ----------------------------------------------------------------- -->
<sect1>Packing Demonstration Program
<p>
<tscreen><verb>
1046
/* example-start packbox packbox.c */
1047