gtk_tut.sgml 575 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
<title>GTK v1.2 Tutorial
9
<author>
10
Tony Gale <tt><htmlurl url="mailto:gale@gtk.org"
11
			      name="&lt;gale@gtk.org&gt;"></tt>,
12
Ian Main <tt><htmlurl url="mailto:imain@gtk.org"
13 14
			      name="&lt;imain@gtk.org&gt;"></tt>
<date>April 1st, 1999
15 16 17 18 19 20 21 22 23 24
<abstract>
This is a tutorial on how to use GTK (the GIMP Toolkit) through its C
interface.
</abstract>

<!-- Table of contents -->
<!-- Older versions of this tutorial did not have a table of contents,
     but the tutorial is now so large that having one is very useful. -->
<toc>
 
25 26 27 28 29

<!-- ***************************************************************** -->
<sect>Introduction
<!-- ***************************************************************** -->
<p>
30 31 32 33 34 35 36 37 38 39 40
GTK (GIMP Toolkit) is a library for creating graphical user
interfaces. It is licensed using the LGPL license, so you can develop
open software, free software, or even commercial non-free software
using GTK without having to spend anything for licenses or royalties.

It's called the GIMP toolkit because it was originally written for
developing the General Image Manipulation Program (GIMP), but GTK has
now been used in a large number of software projects, including the
GNU Network Object Model Environment (GNOME) project. GTK is built on
top of GDK (GIMP Drawing Kit) which is basically a wrapper around the
low-level functions for accessing the underlying windowing functions
41 42
(Xlib in the case of the X windows system). The primary authors of GTK
are:
43

44 45 46 47 48 49 50 51 52
<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>

53
GTK is essentially an object oriented application programmers
54
interface (API). Although written completely in C, it is implemented
55 56
using the idea of classes and callback functions (pointers to
functions).
57

58
There is also a third component called GLib which contains a few
59
replacements for some standard calls, as well as some additional
60 61
functions for handling linked lists, etc. The replacement functions
are used to increase GTK's portability, as some of the functions
62
implemented here are not available or are nonstandard on other unixes
63
such as g_strerror(). Some also contain enhancements to the libc
64 65
versions, such as g_malloc that has enhanced debugging utilities.

66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
This tutorial describes the C interface to GTK. There are GTK
bindings for many other languages including C++, Guile, Perl, Python,
TOM, Ada95, Objective C, Free Pascal, and Eiffel. If you intend to
use another language's bindings to GTK, look at that binding's
documentation first. In some cases that documentation may describe
some important conventions (which you should know first) and then
refer you back to this tutorial. There are also some cross-platform
APIs (such as wxWindows and V) which use GTK as one of their target
platforms; again, consult their documentation first.

If you're developing your GTK application in C++, a few extra notes
are in order. There's a C++ binding to GTK called GTK--, which
provides a more C++-like interface to GTK; you should probably look
into this instead. If you don't like that approach for whatever
reason, there are two alternatives for using GTK. First, you can use
only the C subset of C++ when interfacing with GTK and then use the C
interface as described in this tutorial. Second, you can use GTK and
C++ together by declaring all callbacks as static functions in C++
classes, and again calling GTK using its C interface. If you choose
this last approach, you can include as the callback's data value a
pointer to the object to be manipulated (the so-called "this" value).
Selecting between these options is simply a matter of preference,
since in all three approaches you get C++ and GTK. None of these
approaches requires the use of a specialized preprocessor, so no
matter what you choose you can use standard C++ with GTK.

This tutorial is an attempt to document as much as possible of GTK,
but 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
98 99
you had trouble with. There are also C++, Objective C, ADA, Guile and
other language bindings available, but I don't follow these.
100

101 102
This document is a "work in progress". Please look for updates on
<htmlurl url="http://www.gtk.org/" name="http://www.gtk.org/">.
103

104 105 106 107
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.
108 109 110 111 112 113

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

<p>
114
The first thing to do, of course, is download the GTK source and
115 116
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
117 118 119
<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.
120

121 122
The GTK source distribution also contains the complete source to all
of the examples used in this tutorial, along with Makefiles to aid
123
compilation.
124

125 126
To begin our introduction to GTK, we'll start with the simplest
program possible. This program will create a 200x200 pixel window and
127
has no way of exiting except to be killed by using the shell.
128 129

<tscreen><verb>
130 131
/* example-start base base.c */

132 133
#include <gtk/gtk.h>

134 135
int main( int   argc,
          char *argv[] )
136 137 138 139 140 141
{
    GtkWidget *window;
    
    gtk_init (&amp;argc, &amp;argv);
    
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
142
    gtk_widget_show  (window);
143 144 145
    
    gtk_main ();
    
146
    return(0);
147
}
148 149 150 151 152 153
/* example-end */
</verb></tscreen>

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

156 157
The meaning of the unusual compilation options is explained below in
<ref id="sec_compiling" name="Compiling Hello World">.
158

159
All programs will of course include gtk/gtk.h which declares the
160
variables, functions, structures, etc. that will be used in your GTK
161
application.
162

163 164 165 166 167 168 169
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
170
called in all GTK applications. This sets up a few things for us such
171
as the default visual and color map and then proceeds to call
172
gdk_init(gint *argc, gchar ***argv). This function initializes the
173
library for use, sets up default signal handlers, and checks the
174 175
arguments passed to your application on the command line, looking for
one of the following:
176 177

<itemize>
178 179 180 181 182 183
<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/
184 185
<item> <tt/--display/
<item> <tt/--sync/
186
<item> <tt/--no-xshm/
187 188
<item> <tt/--name/
<item> <tt/--class/
189
</itemize>
190

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

195 196 197 198 199 200 201
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>

202 203 204 205
The <tt/GTK_WINDOW_TOPLEVEL/ argument specifies that we want the
window to undergo window manager decoration and placement. Rather than
create a window of 0x0 size, a window without children is set to
200x200 by default so you can still manipulate it.
206

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

210 211 212
The last line enters the GTK main processing loop.

<tscreen><verb>
213
  gtk_main ();
214 215
</verb></tscreen>

216 217 218
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
219
occur. In our simple example, however, events are ignored.
220 221 222 223

<!-- ----------------------------------------------------------------- -->
<sect1>Hello World in GTK
<p>
224 225
Now for a program with a widget (a button).  It's the classic
hello world a la GTK.
226 227

<tscreen><verb>
228
/* example-start helloworld helloworld.c */
229 230 231

#include <gtk/gtk.h>

232 233 234 235
/* This is a callback function. The data arguments are ignored
 * in this example. More on callbacks below. */
void hello( GtkWidget *widget,
            gpointer   data )
236 237 238 239
{
    g_print ("Hello World\n");
}

240 241 242
gint delete_event( GtkWidget *widget,
                   GdkEvent  *event,
		   gpointer   data )
243
{
244 245
    /* If you return FALSE in the "delete_event" signal handler,
     * GTK will emit the "destroy" signal. Returning TRUE means
246
     * you don't want the window to be destroyed.
247
     * This is useful for popping up 'are you sure you want to quit?'
248
     * type dialogs. */
249

250 251
    g_print ("delete event occurred\n");

252
    /* Change TRUE to FALSE and the main window will be destroyed with
253
     * a "delete_event". */
254

255
    return(TRUE);
256 257
}

258 259 260
/* Another callback */
void destroy( GtkWidget *widget,
              gpointer   data )
261
{
262
    gtk_main_quit();
263 264
}

265 266
int main( int   argc,
          char *argv[] )
267 268 269 270 271
{
    /* GtkWidget is the storage type for widgets */
    GtkWidget *window;
    GtkWidget *button;
    
272 273 274
    /* 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);
275 276 277 278
    
    /* create a new window */
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    
279
    /* When the window is given the "delete_event" signal (this is given
280
     * by the window manager, usually by the "close" option, or on the
281 282 283
     * 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. */
284 285 286
    gtk_signal_connect (GTK_OBJECT (window), "delete_event",
			GTK_SIGNAL_FUNC (delete_event), NULL);
    
287
    /* Here we connect the "destroy" event to a signal handler.  
288
     * This event occurs when we call gtk_widget_destroy() on the window,
289
     * or if we return FALSE in the "delete_event" callback. */
290 291 292
    gtk_signal_connect (GTK_OBJECT (window), "destroy",
			GTK_SIGNAL_FUNC (destroy), NULL);
    
293
    /* Sets the border width of the window. */
294
    gtk_container_set_border_width (GTK_CONTAINER (window), 10);
295
    
296
    /* Creates a new button with the label "Hello World". */
297 298 299
    button = gtk_button_new_with_label ("Hello World");
    
    /* When the button receives the "clicked" signal, it will call the
300 301
     * function hello() passing it NULL as its argument.  The hello()
     * function is defined above. */
302 303 304 305
    gtk_signal_connect (GTK_OBJECT (button), "clicked",
			GTK_SIGNAL_FUNC (hello), NULL);
    
    /* This will cause the window to be destroyed by calling
306
     * gtk_widget_destroy(window) when "clicked".  Again, the destroy
307 308 309 310 311
     * 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));
    
312
    /* This packs the button into the window (a gtk container). */
313 314
    gtk_container_add (GTK_CONTAINER (window), button);
    
315
    /* The final step is to display this newly created widget. */
316 317 318 319 320
    gtk_widget_show (button);
    
    /* and the window */
    gtk_widget_show (window);
    
321 322 323
    /* 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). */
324 325
    gtk_main ();
    
326
    return(0);
327
}
328
/* example-end */
329 330 331
</verb></tscreen>

<!-- ----------------------------------------------------------------- -->
332
<sect1>Compiling Hello World <label id="sec_compiling">
333 334 335 336
<p>
To compile use:

<tscreen><verb>
337
gcc -Wall -g helloworld.c -o helloworld `gtk-config --cflags` \
338
    `gtk-config --libs`
339
</verb></tscreen>
340

341 342 343
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
344 345
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
346 347
the directories to find them in. In the aboce example they could have
been combined into a single instance, such as
348
<tt/`gtk-config --cflags --libs`/.
349

350 351 352
Note that the type of single quote used in the compile command above
is significant.

353
The libraries that are usually linked in are:
354 355 356
<itemize>
<item>The GTK library (-lgtk), the widget library, based on top of GDK.
<item>The GDK library (-lgdk), the Xlib wrapper.
357 358
<item>The gmodule library (-lgmodule), which is used to load run time
extensions.
359 360 361 362
<item>The GLib library (-lglib), containing miscellaneous functions;
only 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.
363
<item>The Xlib library (-lX11) which is used by GDK.
364
<item>The Xext library (-lXext). This contains code for shared memory
365
pixmaps and other X extensions.
366
<item>The math library (-lm). This is used by GTK for various purposes.
367 368 369 370 371
</itemize>

<!-- ----------------------------------------------------------------- -->
<sect1>Theory of Signals and Callbacks
<p>
372 373 374 375
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.
376

377 378 379 380 381 382 383 384 385
This passing of control is done using the idea of "signals". (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.) 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
signals that all widgets inherit, such as "destroy", and there are
signals that are widget specific, such as "toggled" on a toggle
button.
386

387 388 389
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:
390 391

<tscreen><verb>
392 393 394 395
gint gtk_signal_connect( GtkObject     *object,
                         gchar         *name,
                         GtkSignalFunc  func,
                         gpointer       func_data );
396
</verb></tscreen>
397

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

403
The function specified in the third argument is called a "callback
404
function", and should generally be of the form
405 406

<tscreen><verb>
407 408
void callback_func( GtkWidget *widget,
                    gpointer   callback_data );
409
</verb></tscreen>
410

411 412
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
413
argument to the gtk_signal_connect() function as shown above.
414 415

Note that the above form for a signal callback function declaration is
416
only a general guide, as some widget specific signals generate
417
different calling parameters. For example, the CList "select_row"
418
signal provides both row and column parameters.
419

420
Another call used in the <em>helloworld</em> example, is:
421 422

<tscreen><verb>
423 424 425 426
gint gtk_signal_connect_object( GtkObject     *object,
                                gchar         *name,
                                GtkSignalFunc  func,
                                GtkObject     *slot_object );
427
</verb></tscreen>
428

429 430 431
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
432
should be of the form
433 434

<tscreen><verb>
435
void callback_func( GtkObject *object );
436
</verb></tscreen>
437

438
where the object is usually a widget. We usually don't setup callbacks
439 440 441
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.
442

443 444 445 446 447 448
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.
449

450 451 452
<!-- ----------------------------------------------------------------- -->
<sect1>Events
<p>
453
In addition to the signal mechanism described above, there is a set
454 455
of <em>events</em> that reflect the X event mechanism. Callbacks may
also be attached to these events. These events are:
456 457 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

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

489 490 491 492 493
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:
494 495 496 497 498 499 500

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

501 502 503 504 505 506
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:
507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543

<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
544
something like:
545 546 547 548

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

552
This assumes that <tt/button/ is a Button widget. Now, when the
553 554 555
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:
556 557

<tscreen><verb>
558 559 560
static gint button_press_callback( GtkWidget      *widget, 
                                   GdkEventButton *event,
                                   gpointer        data );
561 562
</verb></tscreen>

563 564 565
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.
566

567 568 569 570 571
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
572 573 574 575 576 577
<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">.
578

579 580 581
<!-- ----------------------------------------------------------------- -->
<sect1>Stepping Through Hello World
<p>
582 583
Now that we know the theory behind this, let's clarify by walking
through the example <em>helloworld</em> program.
584

585
Here is the callback function that will be called when the button is
586 587 588
"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.
589 590

<tscreen><verb>
591 592
void hello( GtkWidget *widget,
            gpointer   data )
593 594 595 596 597
{
    g_print ("Hello World\n");
}
</verb></tscreen>

598 599 600 601
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.
602

603 604 605
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
606
returning FALSE, we ask that "destroy" be emitted, which in turn will
607
call our "destroy" signal handler.
608 609

<tscreen><verb>
610 611 612
gint delete_event( GtkWidget *widget,
                   GdkEvent  *event,
		   gpointer   data )
613
{
614
    g_print ("delete event occurred\n");
615

616
    return (TRUE); 
617 618 619
}
</verb></tscreen>

620 621 622
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.
623

624
<tscreen><verb>
625 626
void destroy( GtkWidget *widget,
              gpointer   data )
627 628 629 630
{
    gtk_main_quit ();
}
</verb></tscreen>
631

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

635
<tscreen><verb>
636 637
int main( int   argc,
          char *argv[] )
638 639
{
</verb></tscreen>
640

641
This next part declares pointers to a structure of type
642
GtkWidget. These are used below to create a window and a button.
643

644 645 646 647
<tscreen><verb>
    GtkWidget *window;
    GtkWidget *button;
</verb></tscreen>
648

649 650 651 652 653
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.
654

655 656 657
<tscreen><verb>
    gtk_init (&amp;argc, &amp;argv);
</verb></tscreen>
658

659
Create a new window. This is fairly straightforward. Memory is
660 661 662
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.
663

664 665 666
<tscreen><verb>
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
</verb></tscreen>
667

668 669 670 671 672 673 674 675 676 677
Here are two examples of connecting a signal handler to an object, in
this case, the window. Here, the "delete_event" and "destroy" signals
are caught. The first is emitted when we use the window manager to
kill the window, or when we use the gtk_widget_destroy() call passing
in the window widget as the object to destroy. The second is emitted
when, in the "delete_event" handler, we return FALSE.
 
The <tt/GTK_OBJECT/ and <tt/GTK_SIGNAL_FUNC/ are macros that perform
type casting and checking for us, as well as aid the readability of
the code.
678

679
<tscreen><verb>
680 681
    gtk_signal_connect (GTK_OBJECT (window), "delete_event",
                        GTK_SIGNAL_FUNC (delete_event), NULL);
682
    gtk_signal_connect (GTK_OBJECT (window), "destroy",
683
                        GTK_SIGNAL_FUNC (destroy), NULL);
684
</verb></tscreen>
685

686 687 688 689
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
690
<ref id="sec_setting_widget_attributes" name="Setting Widget Attributes">
691

692
And again, <tt/GTK_CONTAINER/ is a macro to perform type casting.
693

694
<tscreen><verb>
695
    gtk_container_set_border_width (GTK_CONTAINER (window), 10);
696
</verb></tscreen>
697

698 699 700 701
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.
702

703 704 705
<tscreen><verb>
    button = gtk_button_new_with_label ("Hello World");
</verb></tscreen>
706

707 708 709 710 711
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.
712 713 714

<tscreen><verb>
    gtk_signal_connect (GTK_OBJECT (button), "clicked",
715
                        GTK_SIGNAL_FUNC (hello), NULL);
716
</verb></tscreen>
717

718 719 720 721 722 723 724 725 726 727
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().
728 729

<tscreen><verb>
730 731 732
    gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
                               GTK_SIGNAL_FUNC (gtk_widget_destroy),
                               GTK_OBJECT (window));
733
</verb></tscreen>
734

735 736 737 738 739 740 741
This is a packing call, which will be explained in depth later on in
<ref id="sec_packing_widgets" name="Packing Widgets">. 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.
742
 
743 744 745
<tscreen><verb>
    gtk_container_add (GTK_CONTAINER (window), button);
</verb></tscreen>
746

747
Now we have everything set up the way we want it to be. With all the
748
signal handlers in place, and the button placed in the window where it
749 750 751 752
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.
753

754 755 756 757 758
<tscreen><verb>
    gtk_widget_show (button);

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

760 761 762
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.
763

764 765 766
<tscreen><verb>
    gtk_main ();
</verb></tscreen>
767

768
And the final return. Control returns here after gtk_quit() is called.
769

770
<tscreen><verb>
771
    return (0;
772
</verb></tscreen>
773

774 775 776 777 778 779 780 781 782 783 784
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.

785 786
Another course of events is to use the window manager to kill the
window, which will cause the "delete_event" to be emitted. This will
787 788
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
789
GTK to emit the "destroy" signal which of course calls the "destroy"
790 791
callback, exiting GTK.

792 793 794 795 796 797 798
<!-- ***************************************************************** -->
<sect>Moving On
<!-- ***************************************************************** -->

<!-- ----------------------------------------------------------------- -->
<sect1>Data Types
<p>
799
There are a few things you probably noticed in the previous examples
800 801 802 803
that need explaining. The gint, gchar, etc. that you see are typedefs
to int and char, respectively, that are part of the GLlib system. This
is done to get around that nasty dependency on the size of simple data
types when doing calculations.
804

805 806
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
807
i386. The typedefs are very straightforward and intuitive. They are
808
all defined in glib/glib.h (which gets included from gtk.h).
809

810 811
You'll also notice GTK's ability to use GtkWidget when the function
calls for an Object. GTK is an object oriented design, and a widget
812
is an object.
813 814 815 816 817 818 819

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

<tscreen><verb>
820 821 822 823
gint gtk_signal_connect( GtkObject *object,
                         gchar *name,
                         GtkSignalFunc func,
                         gpointer func_data );
824 825
</verb></tscreen>

826 827 828 829
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.
830

831
This tag allows you to remove this callback from the list by using:
832

833
<tscreen><verb>
834 835
void gtk_signal_disconnect( GtkObject *object,
                            gint id );
836
</verb></tscreen>
837

838 839
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
840
disconnect a signal handler.
841

842
Another function to remove all the signal handers from an object is:
843

844
<tscreen><verb>
845
void gtk_signal_handlers_destroy( GtkObject *object );
846
</verb></tscreen>
847

848 849 850
This call is fairly self explanatory. It simply removes all the
current signal handlers from the object passed in as the first
argument.
851 852 853 854

<!-- ----------------------------------------------------------------- -->
<sect1>An Upgraded Hello World
<p>
855 856 857
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.
858 859

<tscreen><verb>
860
/* example-start helloworld2 helloworld2.c */
861 862 863

#include <gtk/gtk.h>

864 865 866 867
/* Our new improved callback.  The data passed to this function
 * is printed to stdout. */
void callback( GtkWidget *widget,
               gpointer   data )
868 869 870 871 872
{
    g_print ("Hello again - %s was pressed\n", (char *) data);
}

/* another callback */
873 874 875
void delete_event( GtkWidget *widget,
                   GdkEvent  *event,
		   gpointer   data )
876 877 878 879
{
    gtk_main_quit ();
}

880 881
int main( int   argc,
          char *argv[] )
882 883 884 885 886 887
{
    /* GtkWidget is the storage type for widgets */
    GtkWidget *window;
    GtkWidget *button;
    GtkWidget *box1;

888 889
    /* This is called in all GTK applications. Arguments are parsed
     * from the command line and are returned to the application. */
890 891
    gtk_init (&amp;argc, &amp;argv);

892
    /* Create a new window */
893 894
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

895
    /* This is a new call, which just sets the title of our
896 897 898 899 900 901 902 903
     * 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);

904
    /* Sets the border width of the window. */
905
    gtk_container_set_border_width (GTK_CONTAINER (window), 10);
906

907 908
    /* We create a box to pack widgets into.  This is described in detail
     * in the "packing" section. The box is not really visible, it
909 910 911
     * is just used as a tool to arrange widgets. */
    box1 = gtk_hbox_new(FALSE, 0);

912
    /* Put the box into the main window. */
913 914
    gtk_container_add (GTK_CONTAINER (window), box1);

915
    /* Creates a new button with the label "Button 1". */
916 917 918
    button = gtk_button_new_with_label ("Button 1");

    /* Now when the button is clicked, we call the "callback" function
919
     * with a pointer to "button 1" as its argument */
920 921 922
    gtk_signal_connect (GTK_OBJECT (button), "clicked",
			GTK_SIGNAL_FUNC (callback), (gpointer) "button 1");

923
    /* Instead of gtk_container_add, we pack this button into the invisible
924 925 926
     * box, which has been packed into the window. */
    gtk_box_pack_start(GTK_BOX(box1), button, TRUE, TRUE, 0);

927 928
    /* Always remember this step, this tells GTK that our preparation for
     * this button is complete, and it can now be displayed. */
929 930
    gtk_widget_show(button);

931
    /* Do these same steps again to create a second button */
932 933
    button = gtk_button_new_with_label ("Button 2");

934
    /* Call the same callback function with a different argument,
935 936 937 938 939 940 941 942 943 944 945 946 947 948
     * 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);

949
    /* Rest in gtk_main and wait for the fun to begin! */
950 951
    gtk_main ();

952
    return(0);
953
}
954
/* example-end */
955
</verb></tscreen>
956

957 958 959 960 961 962 963
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.
964

965
Just as a side note, there is another useful define for
966 967 968
gtk_window_new() - <tt/GTK_WINDOW_DIALOG/. This interacts with the
window manager a little differently and should be used for transient
windows.
969 970

<!-- ***************************************************************** -->
971
<sect>Packing Widgets <label id="sec_packing_widgets">
972 973
<!-- ***************************************************************** -->
<p>
974
When creating an application, you'll want to put more than one widget
975 976 977 978 979
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.
980 981 982 983

<!-- ----------------------------------------------------------------- -->
<sect1>Theory of Packing Boxes
<p>
984 985 986 987 988 989 990 991 992 993
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
994
for vertical boxes, gtk_vbox_new(). The gtk_box_pack_start() and
995
gtk_box_pack_end() functions are used to place objects inside of these
996 997 998
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
999
a vbox, and right to left in an hbox. Using these functions allows us
1000 1001 1002 1003 1004 1005 1006
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
1007 1008 1009
so it can do automatic resizing and other nifty things. There are 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
1010
placing and creating widgets.
1011 1012 1013 1014 1015 1016

<!-- ----------------------------------------------------------------- -->
<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
1017
they all fit together. In the end, however, there are basically five
1018
different styles.
1019 1020 1021

<? <CENTER> >
<?