Commit 337bdee2 authored by GMT 1998  Tony Gale's avatar GMT 1998 Tony Gale Committed by Tony Gale
Browse files

Start mass update for GTK 1.1 Look for the best version of awk Fix FD leak

Mon Dec  7 15:15:06 GMT 1998  Tony Gale <gale@gtk.org>

        * docs/gtk_tut.sgml: Start mass update for GTK 1.1
        * examples/extract.sh: Look for the best version of awk
        * examples/extract.awk: Fix FD leak
        * example/base: minimal example from Tutorial
parent 621beb8a
Mon Dec 7 15:15:06 GMT 1998 Tony Gale <gale@gtk.org>
* docs/gtk_tut.sgml: Start mass update for GTK 1.1
* examples/extract.sh: Look for the best version of awk
* examples/extract.awk: Fix FD leak
* example/base: minimal example from Tutorial
Mon Dec 7 01:29:27 1998 Owen Taylor <otaylor@gtk.org>
* gtk/gtkwindow.c: New functions
......
Mon Dec 7 15:15:06 GMT 1998 Tony Gale <gale@gtk.org>
* docs/gtk_tut.sgml: Start mass update for GTK 1.1
* examples/extract.sh: Look for the best version of awk
* examples/extract.awk: Fix FD leak
* example/base: minimal example from Tutorial
Mon Dec 7 01:29:27 1998 Owen Taylor <otaylor@gtk.org>
* gtk/gtkwindow.c: New functions
......
Mon Dec 7 15:15:06 GMT 1998 Tony Gale <gale@gtk.org>
* docs/gtk_tut.sgml: Start mass update for GTK 1.1
* examples/extract.sh: Look for the best version of awk
* examples/extract.awk: Fix FD leak
* example/base: minimal example from Tutorial
Mon Dec 7 01:29:27 1998 Owen Taylor <otaylor@gtk.org>
* gtk/gtkwindow.c: New functions
......
Mon Dec 7 15:15:06 GMT 1998 Tony Gale <gale@gtk.org>
* docs/gtk_tut.sgml: Start mass update for GTK 1.1
* examples/extract.sh: Look for the best version of awk
* examples/extract.awk: Fix FD leak
* example/base: minimal example from Tutorial
Mon Dec 7 01:29:27 1998 Owen Taylor <otaylor@gtk.org>
* gtk/gtkwindow.c: New functions
......
Mon Dec 7 15:15:06 GMT 1998 Tony Gale <gale@gtk.org>
* docs/gtk_tut.sgml: Start mass update for GTK 1.1
* examples/extract.sh: Look for the best version of awk
* examples/extract.awk: Fix FD leak
* example/base: minimal example from Tutorial
Mon Dec 7 01:29:27 1998 Owen Taylor <otaylor@gtk.org>
* gtk/gtkwindow.c: New functions
......
Mon Dec 7 15:15:06 GMT 1998 Tony Gale <gale@gtk.org>
* docs/gtk_tut.sgml: Start mass update for GTK 1.1
* examples/extract.sh: Look for the best version of awk
* examples/extract.awk: Fix FD leak
* example/base: minimal example from Tutorial
Mon Dec 7 01:29:27 1998 Owen Taylor <otaylor@gtk.org>
* gtk/gtkwindow.c: New functions
......
Mon Dec 7 15:15:06 GMT 1998 Tony Gale <gale@gtk.org>
* docs/gtk_tut.sgml: Start mass update for GTK 1.1
* examples/extract.sh: Look for the best version of awk
* examples/extract.awk: Fix FD leak
* example/base: minimal example from Tutorial
Mon Dec 7 01:29:27 1998 Owen Taylor <otaylor@gtk.org>
* gtk/gtkwindow.c: New functions
......
......@@ -5,23 +5,24 @@
-->
<article>
<title>GTK Tutorial
<author>Ian Main <tt><htmlurl url="mailto:imain@gtk.org"
name="&lt;imain@gtk.org&gt;"></tt>,
<title>GTK v1.1 Tutorial
<author>
Tony Gale <tt><htmlurl url="mailto:gale@gtk.org"
name="&lt;gale@gtk.org&gt;"></tt>
<date>September 2nd, 1998
Ian Main <tt><htmlurl url="mailto:imain@gtk.org"
name="&lt;imain@gtk.org&gt;"></tt>,
<date>December 6th, 1998
<!-- ***************************************************************** -->
<sect>Introduction
<!-- ***************************************************************** -->
<p>
GTK (GIMP Toolkit) was originally developed as a toolkit for the GIMP
(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
(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:
<itemize>
<item> Peter Mattis <tt><htmlurl url="mailto:petm@xcf.berkeley.edu"
name="petm@xcf.berkeley.edu"></tt>
......@@ -31,73 +32,86 @@ authors are
name="jmacd@xcf.berkeley.edu"></tt>
</itemize>
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).
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).
There is also a third component called glib which contains a few
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 unicies 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.
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.
<!-- ***************************************************************** -->
<sect>Getting Started
<!-- ***************************************************************** -->
<p>
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.
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.
Th GTK source distribution also contains the complete source to all of the
examples used in this tutorial, along with Makefiles to aid compilation.
Th GTK source distribution also contains the complete source to all of
the examples used in this tutorial, along with Makefiles to aid
compilation.
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.
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.
<tscreen><verb>
/* example-start base base.c */
#include <gtk/gtk.h>
int main (int argc, char *argv[])
int main( int argc,
char *argv[] )
{
GtkWidget *window;
gtk_init (&amp;argc, &amp;argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_widget_show (window);
gtk_widget_show (window);
gtk_main ();
return 0;
return(0);
}
/* example-end */
</verb></tscreen>
You can compile the above program with gcc using:
<tscreen><verb>
gcc base.c -o base `gtk-config --cflags --libs`
</verb></tscreen>
The meaning of the unusual compilation options is explained below.
All programs will of course include gtk/gtk.h which declares the
variables, functions, structures etc. that will be used in your GTK
variables, functions, structures etc. that will be used in your GTK
application.
The next line:
......@@ -107,26 +121,29 @@ gtk_init (&amp;argc, &amp;argv);
</verb></tscreen>
calls the function gtk_init(gint *argc, gchar ***argv) which will be
called in all GTK applications. This sets up a few things for us such
called in all GTK applications. This sets up a few things for us such
as the default visual and color map and then proceeds to call
gdk_init(gint *argc, gchar ***argv). This function initializes the
gdk_init(gint *argc, gchar ***argv). This function initializes the
library for use, sets up default signal handlers, and checks the
arguments passed to your application on the command line, looking for one
of the following:
arguments passed to your application on the command line, looking for
one of the following:
<itemize>
<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/
<item> <tt/--display/
<item> <tt/--debug-level/
<item> <tt/--no-xshm/
<item> <tt/--sync/
<item> <tt/--show-events/
<item> <tt/--no-show-events/
<item> <tt/--no-xshm/
<item> <tt/--name/
<item> <tt/--class/
</itemize>
It removes these from the argument list, leaving anything it does
not recognize for your application to parse or ignore. This creates a set
It removes these from the argument list, leaving anything it does not
recognize for your application to parse or ignore. This creates a set
of standard arguments accepted by all GTK applications.
The next two lines of code create and display a window.
......@@ -138,98 +155,104 @@ The next two lines of code create and display a window.
The 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.
window of 0x0 size, a window without children is set to 200x200 by
default so you can still manipulate it.
The gtk_widget_show() function lets GTK know that we are done setting the
attributes of this widget, and that it can display it.
The gtk_widget_show() function lets GTK know that we are done setting
the attributes of this widget, and that it can display it.
The last line enters the GTK main processing loop.
<tscreen><verb>
gtk_main ();
gtk_main ();
</verb></tscreen>
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.
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.
<!-- ----------------------------------------------------------------- -->
<sect1>Hello World in GTK
<p>
OK, now for a program with a widget (a button). It's the classic hello
world ala GTK.
Now for a program with a widget (a button). It's the classic
hello world a la GTK.
<tscreen><verb>
/* example-start helloworld helloworld.c */
#include <gtk/gtk.h>
/* this is a callback function. the data arguments are ignored in this example..
* More on callbacks below. */
void hello (GtkWidget *widget, gpointer data)
/* This is a callback function. The data arguments are ignored
* in this example. More on callbacks below. */
void hello( GtkWidget *widget,
gpointer data )
{
g_print ("Hello World\n");
}
gint delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
gint delete_event( GtkWidget *widget,
GdkEvent *event,
gpointer data )
{
g_print ("delete event occurred\n");
/* if you return FALSE in the "delete_event" signal handler,
* GTK will emit the "destroy" signal. Returning TRUE means
/* If you return FALSE in the "delete_event" signal handler,
* GTK will emit the "destroy" signal. Returning TRUE means
* you don't want the window to be destroyed.
* This is useful for popping up 'are you sure you want to quit ?'
* This is useful for popping up 'are you sure you want to quit?'
* type dialogs. */
g_print ("delete event occurred\n");
/* Change TRUE to FALSE and the main window will be destroyed with
* a "delete_event". */
return (TRUE);
return(TRUE);
}
/* another callback */
void destroy (GtkWidget *widget, gpointer data)
/* Another callback */
void destroy( GtkWidget *widget,
gpointer data )
{
gtk_main_quit ();
gtk_main_quit();
}
int main (int argc, char *argv[])
int main( int argc,
char *argv[] )
{
/* GtkWidget is the storage type for widgets */
GtkWidget *window;
GtkWidget *button;
/* 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);
/* 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);
/* create a new window */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
/* 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. */
/* 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. */
gtk_signal_connect (GTK_OBJECT (window), "delete_event",
GTK_SIGNAL_FUNC (delete_event), NULL);
/* here we connect the "destroy" event to a signal handler.
/* Here we connect the "destroy" event to a signal handler.
* This event occurs when we call gtk_widget_destroy() on the window,
* or if we return 'FALSE' in the "delete_event" callback. */
gtk_signal_connect (GTK_OBJECT (window), "destroy",
GTK_SIGNAL_FUNC (destroy), NULL);
/* sets the border width of the window. */
/* Sets the border width of the window. */
gtk_container_border_width (GTK_CONTAINER (window), 10);
/* creates a new button with the label "Hello World". */
/* Creates a new button with the label "Hello World". */
button = gtk_button_new_with_label ("Hello World");
/* When the button receives the "clicked" signal, it will call the
* function hello() passing it NULL as its argument. The hello() function is
* defined above. */
* function hello() passing it NULL as its argument. The hello()
* function is defined above. */
gtk_signal_connect (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC (hello), NULL);
......@@ -240,20 +263,21 @@ int main (int argc, char *argv[])
GTK_SIGNAL_FUNC (gtk_widget_destroy),
GTK_OBJECT (window));
/* this packs the button into the window (a gtk container). */
/* This packs the button into the window (a gtk container). */
gtk_container_add (GTK_CONTAINER (window), button);
/* the final step is to display this newly created widget... */
/* The final step is to display this newly created widget. */
gtk_widget_show (button);
/* and the window */
gtk_widget_show (window);
/* 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). */
/* 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). */
gtk_main ();
return 0;
return(0);
}
/* example-end */
</verb></tscreen>
......@@ -264,7 +288,7 @@ int main (int argc, char *argv[])
To compile use:
<tscreen><verb>
gcc -Wall -g helloworld.c -o hello_world `gtk-config --cflags` \
gcc -Wall -g helloworld.c -o helloworld `gtk-config --cflags` \
`gtk-config --libs`
</verb></tscreen>
......@@ -273,7 +297,9 @@ 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
the directories to find them in.
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`.
Note that the type of single quote used in the compile command above
is significant.
......@@ -282,34 +308,36 @@ The libraries that are usually linked in are:
<itemize>
<item>The GTK library (-lgtk), the widget library, based on top of GDK.
<item>The GDK library (-lgdk), the Xlib wrapper.
<item>The gmodule library (-lgmodule), which is used to load run time
extensions.
<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.
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.
<item>The Xlib library (-lX11) which is used by GDK.
<item>The Xext library (-lXext). This contains code for shared memory
<item>The Xext library (-lXext). This contains code for shared memory
pixmaps and other X extensions.
<item>The math library (-lm). This is used by GTK for various purposes.
<item>The math library (-lm). This is used by GTK for various purposes.
</itemize>
<!-- ----------------------------------------------------------------- -->
<sect1>Theory of Signals and Callbacks
<p>
Before we look in detail at hello world, 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.
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.
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
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
widget specific, such as "toggled" on a toggle button.
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:
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:
<tscreen><verb>
gint gtk_signal_connect( GtkObject *object,
......@@ -318,10 +346,10 @@ gint gtk_signal_connect( GtkObject *object,
gpointer func_data );
</verb></tscreen>
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.
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.
The function specified in the third argument is called a "callback
function", and should generally be of the form:
......@@ -331,16 +359,16 @@ void callback_func( GtkWidget *widget,
gpointer callback_data );
</verb></tscreen>
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.
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.
Note that the above form for a signal callback function declaration is
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.
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.
Another call used in the hello world example, is:
Another call used in the <em>helloworld</em> example, is:
<tscreen><verb>
gint gtk_signal_connect_object( GtkObject *object,
......@@ -349,32 +377,33 @@ gint gtk_signal_connect_object( GtkObject *object,
GtkObject *slot_object );
</verb></tscreen>
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
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
should be of the form:
<tscreen><verb>
void callback_func( GtkObject *object );
</verb></tscreen>
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 hello world example.
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.
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.
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.
<!-- ----------------------------------------------------------------- -->
<sect1>Events
<p>
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:
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:
<itemize>
<item> event
......@@ -408,10 +437,11 @@ attached to these events. These events are:
<item> other_event
</itemize>
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:
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:
<tscreen><verb>
void callback_func( GtkWidget *widget,
......@@ -419,11 +449,12 @@ void callback_func( GtkWidget *widget,
gpointer callback_data );
</verb></tscreen>
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:
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:
<tscreen><verb>
GDK_NOTHING
......@@ -461,7 +492,7 @@ upon the type of the event. Possible values for the type are:
</verb></tscreen>
So, to connect a callback function to one of these events we would use
something like
something like:
<tscreen><verb>
gtk_signal_connect( GTK_OBJECT(button), "button_press_event",
......@@ -469,9 +500,10 @@ gtk_signal_connect( GTK_OBJECT(button), "button_press_event",
NULL);
</verb></tscreen>