gtk_tut.sgml 554 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
Ian Main <tt><htmlurl url="mailto:imain@gtk.org"
			      name="&lt;imain@gtk.org&gt;"></tt>,
14
<date>February 1st, 1999
15 16 17 18 19 20

<!-- ***************************************************************** -->
<sect>Introduction
<!-- ***************************************************************** -->
<p>
GTK (GIMP Toolkit) was originally developed as a toolkit for the GIMP
21
(General Image Manipulation Program). GTK is built on top of GDK
22
(GIMP Drawing Kit) which is basically a wrapper around the Xlib
23
functions. It's called the GIMP toolkit because it was originally
24 25
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
GTK is essentially an object oriented application programmers
36
interface (API). Although written completely in C, it is implemented
37 38
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
replacements for some standard calls, as well as some additional
42 43
functions for handling linked lists etc. The replacement functions are
used to increase GTK's portability, as some of the functions
44
implemented here are not available or are nonstandard on other unixes
45
such as g_strerror(). Some also contain enhancements to the libc
46 47 48
versions, such as g_malloc that has enhanced debugging utilities.

This tutorial is an attempt to document as much as possible of GTK, it
49 50 51 52 53 54 55
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
56 57
instead. There are also Objective C, ADA, Guile and other language
bindings available, but I don't follow these.
58

59 60 61 62
This document is a 'work in progress'. Please look for updates on 
http://www.gtk.org/ <htmlurl url="http://www.gtk.org/"
name="http://www.gtk.org/">.

63 64 65 66
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.
67 68 69 70 71 72

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

<p>
73 74 75 76 77 78
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.
79

80 81 82
Th GTK source distribution also contains the complete source to all of
the examples used in this tutorial, along with Makefiles to aid
compilation.
83

84 85 86
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.
87 88

<tscreen><verb>
89 90
/* example-start base base.c */

91 92
#include <gtk/gtk.h>

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

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

115 116
The meaning of the unusual compilation options is explained below.

117
All programs will of course include gtk/gtk.h which declares the
118
variables, functions, structures etc. that will be used in your GTK
119
application.
120

121 122 123 124 125 126 127
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
128
called in all GTK applications. This sets up a few things for us such
129
as the default visual and color map and then proceeds to call
130
gdk_init(gint *argc, gchar ***argv). This function initializes the
131
library for use, sets up default signal handlers, and checks the
132 133
arguments passed to your application on the command line, looking for
one of the following:
134 135

<itemize>
136 137 138 139 140 141
<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/
142 143
<item> <tt/--display/
<item> <tt/--sync/
144
<item> <tt/--no-xshm/
145 146
<item> <tt/--name/
<item> <tt/--class/
147
</itemize>
148

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

153 154 155 156 157 158 159 160 161
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
162 163
window of 0x0 size, a window without children is set to 200x200 by
default so you can still manipulate it.
164

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

168 169 170
The last line enters the GTK main processing loop.

<tscreen><verb>
171
  gtk_main ();
172 173
</verb></tscreen>

174 175 176 177
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.
178 179 180 181

<!-- ----------------------------------------------------------------- -->
<sect1>Hello World in GTK
<p>
182 183
Now for a program with a widget (a button).  It's the classic
hello world a la GTK.
184 185

<tscreen><verb>
186
/* example-start helloworld helloworld.c */
187 188 189

#include <gtk/gtk.h>

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

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

208 209
    g_print ("delete event occurred\n");

210
    /* Change TRUE to FALSE and the main window will be destroyed with
211
     * a "delete_event". */
212

213
    return(TRUE);
214 215
}

216 217 218
/* Another callback */
void destroy( GtkWidget *widget,
              gpointer   data )
219
{
220
    gtk_main_quit();
221 222
}

223 224
int main( int   argc,
          char *argv[] )
225 226 227 228 229
{
    /* GtkWidget is the storage type for widgets */
    GtkWidget *window;
    GtkWidget *button;
    
230 231 232
    /* 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);
233 234 235 236
    
    /* create a new window */
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    
237 238 239 240 241
    /* 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. */
242 243 244
    gtk_signal_connect (GTK_OBJECT (window), "delete_event",
			GTK_SIGNAL_FUNC (delete_event), NULL);
    
245
    /* Here we connect the "destroy" event to a signal handler.  
246
     * This event occurs when we call gtk_widget_destroy() on the window,
247
     * or if we return 'FALSE' in the "delete_event" callback. */
248 249 250
    gtk_signal_connect (GTK_OBJECT (window), "destroy",
			GTK_SIGNAL_FUNC (destroy), NULL);
    
251
    /* Sets the border width of the window. */
252
    gtk_container_set_border_width (GTK_CONTAINER (window), 10);
253
    
254
    /* Creates a new button with the label "Hello World". */
255 256 257
    button = gtk_button_new_with_label ("Hello World");
    
    /* When the button receives the "clicked" signal, it will call the
258 259
     * function hello() passing it NULL as its argument.  The hello()
     * function is defined above. */
260 261 262 263
    gtk_signal_connect (GTK_OBJECT (button), "clicked",
			GTK_SIGNAL_FUNC (hello), NULL);
    
    /* This will cause the window to be destroyed by calling
264
     * gtk_widget_destroy(window) when "clicked".  Again, the destroy
265 266 267 268 269
     * 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));
    
270
    /* This packs the button into the window (a gtk container). */
271 272
    gtk_container_add (GTK_CONTAINER (window), button);
    
273
    /* The final step is to display this newly created widget. */
274 275 276 277 278
    gtk_widget_show (button);
    
    /* and the window */
    gtk_widget_show (window);
    
279 280 281
    /* 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). */
282 283
    gtk_main ();
    
284
    return(0);
285
}
286
/* example-end */
287 288 289 290 291 292 293 294
</verb></tscreen>

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

<tscreen><verb>
295
gcc -Wall -g helloworld.c -o helloworld `gtk-config --cflags` \
296
    `gtk-config --libs`
297
</verb></tscreen>
298 299 300 301 302 303

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
304 305 306
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`.
307

308 309 310
Note that the type of single quote used in the compile command above
is significant.

311
The libraries that are usually linked in are:
312 313 314
<itemize>
<item>The GTK library (-lgtk), the widget library, based on top of GDK.
<item>The GDK library (-lgdk), the Xlib wrapper.
315 316
<item>The gmodule library (-lgmodule), which is used to load run time
extensions.
317
<item>The glib library (-lglib), containing miscellaneous functions, only
318 319 320
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.
321
<item>The Xlib library (-lX11) which is used by GDK.
322
<item>The Xext library (-lXext). This contains code for shared memory
323
pixmaps and other X extensions.
324
<item>The math library (-lm). This is used by GTK for various purposes.
325 326 327 328 329
</itemize>

<!-- ----------------------------------------------------------------- -->
<sect1>Theory of Signals and Callbacks
<p>
330 331 332 333
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.
334

335 336 337 338 339
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
340 341
widget specific, such as "toggled" on a toggle button.

342 343 344
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:
345 346

<tscreen><verb>
347 348 349 350
gint gtk_signal_connect( GtkObject     *object,
                         gchar         *name,
                         GtkSignalFunc  func,
                         gpointer       func_data );
351
</verb></tscreen>
352

353 354 355 356
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.
357

358
The function specified in the third argument is called a "callback
359
function", and should generally be of the form:
360 361

<tscreen><verb>
362 363
void callback_func( GtkWidget *widget,
                    gpointer   callback_data );
364
</verb></tscreen>
365

366 367 368
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.
369 370

Note that the above form for a signal callback function declaration is
371 372 373
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.
374

375
Another call used in the <em>helloworld</em> example, is:
376 377

<tscreen><verb>
378 379 380 381
gint gtk_signal_connect_object( GtkObject     *object,
                                gchar         *name,
                                GtkSignalFunc  func,
                                GtkObject     *slot_object );
382
</verb></tscreen>
383

384 385 386
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
387
should be of the form:
388 389

<tscreen><verb>
390
void callback_func( GtkObject *object );
391
</verb></tscreen>
392

393 394 395 396
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.
397

398 399 400 401 402 403
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.
404

405 406 407
<!-- ----------------------------------------------------------------- -->
<sect1>Events
<p>
408 409 410
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:
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 440 441 442 443

<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>

444 445 446 447 448
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:
449 450 451 452 453 454 455

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

456 457 458 459 460 461
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:
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 495 496 497 498

<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
499
something like:
500 501 502 503 504 505 506

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

507 508 509 510
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:
511 512 513 514 515 516 517

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

518 519 520
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.
521

522 523 524 525 526
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
527 528 529 530 531 532
<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">.
533

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

540
Here is the callback function that will be called when the button is
541 542 543
"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.
544 545

<tscreen><verb>
546 547
void hello( GtkWidget *widget,
            gpointer   data )
548 549 550 551 552
{
    g_print ("Hello World\n");
}
</verb></tscreen>

553 554 555 556
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.
557

558 559 560 561 562
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.
563 564

<tscreen><verb>
565 566 567
gint delete_event( GtkWidget *widget,
                   GdkEvent  *event,
		   gpointer   data )
568
{
569
    g_print ("delete event occurred\n");
570

571
    return (TRUE); 
572 573 574
}
</verb></tscreen>

575 576 577
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.
578

579
<tscreen><verb>
580 581
void destroy( GtkWidget *widget,
              gpointer   data )
582 583 584 585
{
    gtk_main_quit ();
}
</verb></tscreen>
586

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

590
<tscreen><verb>
591 592
int main( int   argc,
          char *argv[] )
593 594
{
</verb></tscreen>
595

596 597
This next part, declares a pointer to a structure of type
GtkWidget. These are used below to create a window and a button.
598

599 600 601 602
<tscreen><verb>
    GtkWidget *window;
    GtkWidget *button;
</verb></tscreen>
603

604 605 606 607 608
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.
609

610 611 612
<tscreen><verb>
    gtk_init (&amp;argc, &amp;argv);
</verb></tscreen>
613

614 615 616 617
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.
618

619 620 621
<tscreen><verb>
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
</verb></tscreen>
622 623

Here is an example of connecting a signal handler to an object, in
624 625
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
626
return FALSE in the "delete_event" handler), or when we use the
627 628
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
629
call. Here, it just calls the destroy() function defined above with a
630
NULL argument, which quits GTK for us.
631

632 633 634
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.
635

636 637
<tscreen><verb>
    gtk_signal_connect (GTK_OBJECT (window), "destroy",
638
                        GTK_SIGNAL_FUNC (destroy), NULL);
639
</verb></tscreen>
640

641 642 643 644
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
645
<ref id="sec_setting_widget_attributes" name="Setting Widget Attributes">
646

647
And again, GTK_CONTAINER is a macro to perform type casting.
648

649
<tscreen><verb>
650
    gtk_container_set_border_width (GTK_CONTAINER (window), 10);
651
</verb></tscreen>
652

653 654 655 656
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.
657

658 659 660
<tscreen><verb>
    button = gtk_button_new_with_label ("Hello World");
</verb></tscreen>
661

662 663 664 665 666
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.
667 668 669

<tscreen><verb>
    gtk_signal_connect (GTK_OBJECT (button), "clicked",
670
                        GTK_SIGNAL_FUNC (hello), NULL);
671
</verb></tscreen>
672

673 674 675 676 677 678 679 680 681 682
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().
683 684

<tscreen><verb>
685 686 687
    gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
                               GTK_SIGNAL_FUNC (gtk_widget_destroy),
                               GTK_OBJECT (window));
688
</verb></tscreen>
689

690 691 692 693 694 695
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.
696
 
697 698 699
<tscreen><verb>
    gtk_container_add (GTK_CONTAINER (window), button);
</verb></tscreen>
700

701
Now we have everything set up the way we want it to be. With all the
702
signal handlers in place, and the button placed in the window where it
703 704 705 706
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.
707

708 709 710 711 712
<tscreen><verb>
    gtk_widget_show (button);

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

714 715 716
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.
717

718 719 720
<tscreen><verb>
    gtk_main ();
</verb></tscreen>
721

722
And the final return. Control returns here after gtk_quit() is called.
723

724 725 726
<tscreen><verb>
    return 0;
</verb></tscreen>
727

728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748
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.
749 750 751 752 753 754 755 756

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

<!-- ----------------------------------------------------------------- -->
<sect1>Data Types
<p>
757 758 759 760
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.
761

762 763 764 765
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).
766

767 768 769
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.
770 771 772 773 774 775 776

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

<tscreen><verb>
777 778 779 780
gint gtk_signal_connect( GtkObject *object,
                         gchar *name,
                         GtkSignalFunc func,
                         gpointer func_data );
781 782
</verb></tscreen>

783 784 785 786
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.
787

788
This tag allows you to remove this callback from the list by using:
789

790
<tscreen><verb>
791 792
void gtk_signal_disconnect( GtkObject *object,
                            gint id );
793
</verb></tscreen>
794

795 796
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
797
disconnect a signal handler.
798

799
Another function to remove all the signal handers from an object is:
800

801
<tscreen><verb>
802
void gtk_signal_handlers_destroy( GtkObject *object );
803
</verb></tscreen>
804

805 806 807
This call is fairly self explanatory. It simply removes all the
current signal handlers from the object passed in as the first
argument.
808 809 810 811

<!-- ----------------------------------------------------------------- -->
<sect1>An Upgraded Hello World
<p>
812 813 814
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.
815 816

<tscreen><verb>
817
/* example-start helloworld2 helloworld2.c */
818 819 820

#include <gtk/gtk.h>

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

/* another callback */
830 831 832
void delete_event( GtkWidget *widget,
                   GdkEvent  *event,
		   gpointer   data )
833 834 835 836
{
    gtk_main_quit ();
}

837 838
int main( int   argc,
          char *argv[] )
839 840 841 842 843 844
{
    /* GtkWidget is the storage type for widgets */
    GtkWidget *window;
    GtkWidget *button;
    GtkWidget *box1;

845 846
    /* This is called in all GTK applications. Arguments are parsed
     * from the command line and are returned to the application. */
847 848
    gtk_init (&amp;argc, &amp;argv);

849
    /* Create a new window */
850 851
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

852
    /* This is a new call, this just sets the title of our
853 854 855 856 857 858 859 860
     * 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);

861
    /* Sets the border width of the window. */
862
    gtk_container_set_border_width (GTK_CONTAINER (window), 10);
863

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

869
    /* Put the box into the main window. */
870 871
    gtk_container_add (GTK_CONTAINER (window), box1);

872
    /* Creates a new button with the label "Button 1". */
873 874 875
    button = gtk_button_new_with_label ("Button 1");

    /* Now when the button is clicked, we call the "callback" function
876
     * with a pointer to "button 1" as its argument */
877 878 879
    gtk_signal_connect (GTK_OBJECT (button), "clicked",
			GTK_SIGNAL_FUNC (callback), (gpointer) "button 1");

880
    /* Instead of gtk_container_add, we pack this button into the invisible
881 882 883
     * box, which has been packed into the window. */
    gtk_box_pack_start(GTK_BOX(box1), button, TRUE, TRUE, 0);

884 885
    /* Always remember this step, this tells GTK that our preparation for
     * this button is complete, and it can now be displayed. */
886 887
    gtk_widget_show(button);

888
    /* Do these same steps again to create a second button */
889 890
    button = gtk_button_new_with_label ("Button 2");

891
    /* Call the same callback function with a different argument,
892 893 894 895 896 897 898 899 900 901 902 903 904 905
     * 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);

906
    /* Rest in gtk_main and wait for the fun to begin! */
907 908
    gtk_main ();

909
    return(0);
910
}
911
/* example-end */
912
</verb></tscreen>
913

914 915 916 917 918 919 920
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.
921

922 923 924
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.
925 926 927 928 929

<!-- ***************************************************************** -->
<sect>Packing Widgets
<!-- ***************************************************************** -->
<p>
930
When creating an application, you'll want to put more than one widget
931 932 933 934 935
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.
936 937 938 939

<!-- ----------------------------------------------------------------- -->
<sect1>Theory of Packing Boxes
<p>
940 941 942 943 944 945 946 947 948 949 950
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
951
gtk_box_pack_end() functions are used to place objects inside of these
952 953 954 955 956 957 958 959 960 961 962 963 964 965 966
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.
967 968 969 970 971 972

<!-- ----------------------------------------------------------------- -->
<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
973
they all fit together. In the end however, there are basically five
974
different styles.
975 976 977

<? <CENTER> >
<?
978 979
<IMG SRC="gtk_tut_packbox1.gif" VSPACE="15" HSPACE="10" WIDTH="528"
HEIGHT="235" ALT="Box Packing Example Image">
980 981 982 983
>
<? </CENTER> >

Each line contains one horizontal box (hbox) with several buttons. The
984 985 986
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).
987

988 989 990
This is the declaration of the gtk_box_pack_start function.

<tscreen><verb>
991 992 993 994 995
void gtk_box_pack_start( GtkBox    *box,
                         GtkWidget *child,
                         gint       expand,
                         gint       fill,
                         gint       padding );
996 997
</verb></tscreen>

998 999 1000
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.
1001

1002 1003 1004 1005 1006 1007 1008 1009
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.
1010

1011 1012 1013 1014
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.
1015

1016 1017 1018
When creating a new box, the function looks like this:

<tscreen><verb>
1019 1020
GtkWidget *gtk_hbox_new (gint homogeneous,
                         gint spacing);
1021 1022
</verb></tscreen>