FAQ Update: - Minor cleanups (Emmanuel, me) - New questions: I need to add

Thu Mar  9 22:10:56 GMT 2000  Tony Gale <gale@gtk.org>

        * docs/gtkfaq.sgml: FAQ Update:
          - Minor cleanups (Emmanuel, me)
          - New questions:
                I need to add a new signal to a GTK+ widget. Any idea? (timj)
                How can I retrieve the text from a GtkMenuItem? (timj)
                How do I validate/limit/filter the input to a GtkEntry? (me)
                Memory does not seem to be released when I free the list
                        nodes I've allocated (timj)
This commit is contained in:
GMT 2000 Tony Gale 2000-03-09 22:17:20 +00:00 committed by Tony Gale
parent 407a379189
commit e99b78cdea
9 changed files with 843 additions and 290 deletions

View File

@ -1,3 +1,14 @@
Thu Mar 9 22:10:56 GMT 2000 Tony Gale <gale@gtk.org>
* docs/gtkfaq.sgml: FAQ Update:
- Minor cleanups (Emmanuel, me)
- New questions:
I need to add a new signal to a GTK+ widget. Any idea? (timj)
How can I retrieve the text from a GtkMenuItem? (timj)
How do I validate/limit/filter the input to a GtkEntry? (me)
Memory does not seem to be released when I free the list
nodes I've allocated (timj)
2000-03-07 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkmain-win32.c: Internal GDK error reporting changes:

View File

@ -1,3 +1,14 @@
Thu Mar 9 22:10:56 GMT 2000 Tony Gale <gale@gtk.org>
* docs/gtkfaq.sgml: FAQ Update:
- Minor cleanups (Emmanuel, me)
- New questions:
I need to add a new signal to a GTK+ widget. Any idea? (timj)
How can I retrieve the text from a GtkMenuItem? (timj)
How do I validate/limit/filter the input to a GtkEntry? (me)
Memory does not seem to be released when I free the list
nodes I've allocated (timj)
2000-03-07 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkmain-win32.c: Internal GDK error reporting changes:

View File

@ -1,3 +1,14 @@
Thu Mar 9 22:10:56 GMT 2000 Tony Gale <gale@gtk.org>
* docs/gtkfaq.sgml: FAQ Update:
- Minor cleanups (Emmanuel, me)
- New questions:
I need to add a new signal to a GTK+ widget. Any idea? (timj)
How can I retrieve the text from a GtkMenuItem? (timj)
How do I validate/limit/filter the input to a GtkEntry? (me)
Memory does not seem to be released when I free the list
nodes I've allocated (timj)
2000-03-07 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkmain-win32.c: Internal GDK error reporting changes:

View File

@ -1,3 +1,14 @@
Thu Mar 9 22:10:56 GMT 2000 Tony Gale <gale@gtk.org>
* docs/gtkfaq.sgml: FAQ Update:
- Minor cleanups (Emmanuel, me)
- New questions:
I need to add a new signal to a GTK+ widget. Any idea? (timj)
How can I retrieve the text from a GtkMenuItem? (timj)
How do I validate/limit/filter the input to a GtkEntry? (me)
Memory does not seem to be released when I free the list
nodes I've allocated (timj)
2000-03-07 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkmain-win32.c: Internal GDK error reporting changes:

View File

@ -1,3 +1,14 @@
Thu Mar 9 22:10:56 GMT 2000 Tony Gale <gale@gtk.org>
* docs/gtkfaq.sgml: FAQ Update:
- Minor cleanups (Emmanuel, me)
- New questions:
I need to add a new signal to a GTK+ widget. Any idea? (timj)
How can I retrieve the text from a GtkMenuItem? (timj)
How do I validate/limit/filter the input to a GtkEntry? (me)
Memory does not seem to be released when I free the list
nodes I've allocated (timj)
2000-03-07 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkmain-win32.c: Internal GDK error reporting changes:

View File

@ -1,3 +1,14 @@
Thu Mar 9 22:10:56 GMT 2000 Tony Gale <gale@gtk.org>
* docs/gtkfaq.sgml: FAQ Update:
- Minor cleanups (Emmanuel, me)
- New questions:
I need to add a new signal to a GTK+ widget. Any idea? (timj)
How can I retrieve the text from a GtkMenuItem? (timj)
How do I validate/limit/filter the input to a GtkEntry? (me)
Memory does not seem to be released when I free the list
nodes I've allocated (timj)
2000-03-07 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkmain-win32.c: Internal GDK error reporting changes:

View File

@ -1,3 +1,14 @@
Thu Mar 9 22:10:56 GMT 2000 Tony Gale <gale@gtk.org>
* docs/gtkfaq.sgml: FAQ Update:
- Minor cleanups (Emmanuel, me)
- New questions:
I need to add a new signal to a GTK+ widget. Any idea? (timj)
How can I retrieve the text from a GtkMenuItem? (timj)
How do I validate/limit/filter the input to a GtkEntry? (me)
Memory does not seem to be released when I free the list
nodes I've allocated (timj)
2000-03-07 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkmain-win32.c: Internal GDK error reporting changes:

View File

@ -9,7 +9,7 @@
<!-- NOTE: Use only one author tag, otherwise sgml2txt barfs - TRG -->
<author>Tony Gale, Shawn T. Amundson, Emmanuel Deloget, Nathan Froyd
<date>February 22nd 2000
<date>March 9th 2000
<abstract> This document is intended to answer questions that are likely to be
frequently asked by programmers using GTK+ or people who are just looking at
@ -91,7 +91,7 @@ enhancement to the original gtk that adds object oriented features."
<p>
GTK+ == Gimp Toolkit
GDK == Gtk+ Drawing Kit
GDK == GTK+ Drawing Kit
GLib == G Libray
@ -281,7 +281,6 @@ name="http://www.forcix.cx/irc-clients.html"> list a bunch of them).
<!-- ***************************************************************** -->
<sect>How to find, configure, install, and troubleshoot GTK+
<!-- ***************************************************************** -->
<!-- ----------------------------------------------------------------- -->
@ -313,6 +312,7 @@ Here's a few mirror sites to get you started:
<item>US - ftp://ftp.insync.net/pub/mirrors/ftp.gimp.org/
</itemize>
<!-- ----------------------------------------------------------------- -->
<sect1>How do I configure/compile GTK+?
<p>
Generally, all you will need to do is issue the commands:
@ -326,21 +326,22 @@ in the gtk+-version/ directory.
<sect1>When compiling GTK+ I get an error like:
<tt/make: file `Makefile' line 456: Syntax error/
<p>
Make sure that you are using GNU make (use <tt/make -v/ to check). There are
many weird and wonderful versions of make out there, and not all of them
handle the automatically generated Makefiles.
Make sure that you are using GNU make (use <tt/make -v/ to
check). There are many weird and wonderful versions of make out there,
and not all of them handle the automatically generated Makefiles.
<!-- ----------------------------------------------------------------- -->
<sect1>I've compiled and installed GTK+, but I can't get any programs to link with it!
<p>
This problem is most often encountered when the GTK+ libraries can't be
found or are the wrong version. Generally, the compiler will complain about an
'unresolved symbol'. There are two things you need to check:
This problem is most often encountered when the GTK+ libraries can't
be found or are the wrong version. Generally, the compiler will
complain about an 'unresolved symbol'. There are two things you need
to check:
<itemize>
<item>Make sure that the libraries can be found. You want to edit
/etc/ld.so.conf to include the directories which contain the GTK libraries,
so it looks something like:
<item>Make sure that the libraries can be found. You want to edit
/etc/ld.so.conf to include the directories which contain the GTK
libraries, so it looks something like:
<verb>
/usr/X11R6/lib
/usr/local/lib
@ -370,13 +371,13 @@ system), issue the command
<verb>
rpm -e gtk gtk-devel
</verb>
You may also want to remove the packages that depend on gtk (rpm will tell you
which ones they are). If you don't have a RedHat Linux system, check to make sure
that neither <verb>/usr/lib</verb> or <verb>/usr/local/lib</verb> contain any of
the libraries libgtk, libgdk, libglib, or libgck. If they do exist, remove them
(and any gtk include files, such as /usr/include/gtk and /usr/include/gdk)
and reinstall gtk+.
</itemize>
You may also want to remove the packages that depend on gtk (rpm will
tell you which ones they are). If you don't have a RedHat Linux
system, check to make sure that neither <verb>/usr/lib</verb> or
<verb>/usr/local/lib</verb> contain any of the libraries libgtk,
libgdk, libglib, or libgck. If they do exist, remove them (and any
gtk include files, such as /usr/include/gtk and /usr/include/gdk) and
reinstall gtk+. </itemize>
<!-- ----------------------------------------------------------------- -->
<sect1>When compiling programs with GTK+, I get compiler error messages about not being able to find <tt/"glibconfig.h"/.
@ -467,7 +468,7 @@ Normal people should use the packaged releases.
The CVS toolset is available as RPM packages from the usual RedHat sites.
The latest version is available at
<htmlurl url="http://download.cyclic.com/pub/"
name="&lt;http://download.cyclic.com/pub/&gt;">
name="http://download.cyclic.com/pub/">
Anyone can download the latest CVS version of GTK+ by using anonymous access
using the following steps:
@ -496,8 +497,8 @@ as well:
<verb>
cvs -z3 get glib
</verb>
</itemize>
<!-- ----------------------------------------------------------------- -->
<sect1>How can I contribute to GTK+?
<p>
@ -552,7 +553,7 @@ gladly be included.
<!-- ----------------------------------------------------------------- -->
<sect1>Is anyone working on bindings for languages other than C?
<p>
The GTK+ home page (<htmlurl url="http://www.gtk.org/"
The GTK+ home page (<htmlurl url="http://www.gtk.org/"
name="http://www.gtk.org/">) presents a list of GTK+ bindings.
<itemize>
@ -650,13 +651,15 @@ GTK+. I suggest you start at
<!-- ***************************************************************** -->
<sect>Development with GTK+: the begining
<!-- ***************************************************************** -->
<!-- ----------------------------------------------------------------- -->
<sect1>How do I get started?
<p>
So, after you have installed GTK+ there are a couple of things that can
ease you into developing applications with it. There is the
GTK+ Tutorial <htmlurl url="http://www.gtk.org/tutorial/"
name="&lt;http://www.gtk.org/tutorial/&gt;">, which is undergoing
name="http://www.gtk.org/tutorial/">, which is undergoing
development. This will introduce you to writing applications using C.
The Tutorial doesn't (yet) contain information on all of the widgets
@ -693,6 +696,7 @@ The command line above ensure that:
</itemize>
<!-- ----------------------------------------------------------------- -->
<sect1>What about using the <tt/make/ utility?
<p>
This is a sample makefile which compile a GTK+ based program:
@ -749,7 +753,7 @@ dnl Process this file with autoconf to produce a configure script.
dnl configure.in for a GTK+ based program
AC_INIT(myprg.c)dnl
AM_INIT_AUTOMAKE(mypkbname,0.0.1)dnl
AM_INIT_AUTOMAKE(mypkgname,0.0.1)dnl
AM_CONFIG_HEADER(config.h)dnl
dnl Checks for programs.
@ -775,6 +779,14 @@ CLEANFILES = *~
DISTCLEANFILES = .deps/*.P
</verb></tscreen>
If your project contains more than one subdirectory, you'll have to
create one Makefile.am in each directory plus a master Makefile.am
which will look like:
<tscreen><verb>
SUBDIRS = mydir1 mydir2 mydir3
</verb></tscreen>
then, to use these, simply type the following commands:
<verb>
@ -784,9 +796,10 @@ autoconf
automake --add-missing --include-deps --foreign
</verb>
For further informations, you should look at the autoconf and the automake
documentation (the shipped info files are really easy to understand, and there
are plenty of web resources that deal with autoconf and/or automake).
For further information, you should look at the autoconf and the
automake documentation (the shipped info files are really easy to
understand, and there are plenty of web resources that deal with
autoconf and automake).
<!-- ----------------------------------------------------------------- -->
<sect1>I try to debug my GTK+ application with gdb, but it hangs my X server when I hit some breakpoint. Any Idea ?
@ -813,6 +826,7 @@ bit hard to get (here in The Netherlands, YMMV).
<!-- ***************************************************************** -->
<sect>Development with GTK+: general questions
<!-- ***************************************************************** -->
<!-- ----------------------------------------------------------------- -->
<sect1>What widgets are in GTK?
<p>
@ -1095,7 +1109,6 @@ int main(int argc, char *argv[])
<!-- This is the old answer - TRG
Although GTK+, like many X toolkits, isn't thread safe, this does
not prohibit the development of multi-threaded applications with
GTK+.
@ -1143,22 +1156,25 @@ and it also might make GTK+ substantially less efficient if not handled
carefully.
Regardless, it's especially not a priority since relatively good
workarounds exist. -->
workarounds exist.
-->
<!-- ----------------------------------------------------------------- -->
<sect1>Why does this strange 'x io error' occur when I <tt/fork()/ in my GTK+ app?
<p>
This is not really a GTK+ problem, and the problem is not related to <tt/fork()/
either. If the 'x io error' occurs then you probably use the <tt/exit()/ function
in order to exit from the child process.
This is not really a GTK+ problem, and the problem is not related to
<tt/fork()/ either. If the 'x io error' occurs then you probably use
the <tt/exit()/ function in order to exit from the child process.
When GDK opens an X display, it creates a socket file descriptor. When you use
the <tt/exit()/ function, you implicitly close all the open file descriptors,
and the underlying X library really doesn't like this.
When GDK opens an X display, it creates a socket file descriptor. When
you use the <tt/exit()/ function, you implicitly close all the open
file descriptors, and the underlying X library really doesn't like
this.
The right function to use here is <tt/_exit()/.
Erik Mouw contributed the following code example to illustrate handling
fork() and exit().
Erik Mouw contributed the following code example to illustrate
handling fork() and exit().
<tscreen><verb>
/*-------------------------------------------------------------------------
@ -1370,11 +1386,11 @@ the user to get the closest ancestor of a known type) is to use
widget = gtk_widget_get_ancestor(w, GTK_TYPE_WINDOW);
</verb></tscreen>
Since virtually all the GTK_TYPEs can be used as the second parameter of
this function, you can get any parent widget of a particular
widget. Suppose you have an hbox which contains a vbox, which in turn contains
some other atomic widget (entry, label, etc. To find the master hbox
using the <tt/entry/ widget simply use:
Since virtually all the GTK_TYPEs can be used as the second parameter
of this function, you can get any parent widget of a particular
widget. Suppose you have an hbox which contains a vbox, which in turn
contains some other atomic widget (entry, label, etc. To find the
master hbox using the <tt/entry/ widget simply use:
<tscreen><verb>
GtkWidget *hbox;
@ -1449,32 +1465,35 @@ mind.)
<!-- ----------------------------------------------------------------- -->
<sect1>By the way, what are the differences between signals and events?
<p>
First of all, Havoc Pennington gives a rather complete description of the
differences between events and signals in his free book (two chapters can
be found at <htmlurl url="http://www106.pair.com/rhp/sample_chapters.html"
First of all, Havoc Pennington gives a rather complete description of
the differences between events and signals in his free book (two
chapters can be found at <htmlurl
url="http://www106.pair.com/rhp/sample_chapters.html"
name="http://www106.pair.com/rhp/sample_chapters.html">).
Moreover, Havoc posted this to the <tt/gtk-list/
<quote>
Events are a stream of messages received from the X server. They drive the
Gtk main loop; which more or less amounts to "wait for events, process
them" (not exactly, it is really more general than that and can wait on
many different input streams at once). Events are a Gdk/Xlib concept.
Events are a stream of messages received from the X server. They
drive the Gtk main loop; which more or less amounts to "wait for
events, process them" (not exactly, it is really more general than
that and can wait on many different input streams at once). Events
are a Gdk/Xlib concept.
<P>
Signals are a feature of GtkObject and its subclasses. They have nothing
to do with any input stream; really a signal is just a way to keep a list
of callbacks around and invoke them ("emit" the signal). There are lots of
details and extra features of course. Signals are emitted by object
instances, and are entirely unrelated to the Gtk main loop.
Conventionally, signals are emitted "when something changes" about the
object emitting the signal.
Signals are a feature of GtkObject and its subclasses. They have
nothing to do with any input stream; really a signal is just a way
to keep a list of callbacks around and invoke them ("emit" the
signal). There are lots of details and extra features of
course. Signals are emitted by object instances, and are entirely
unrelated to the Gtk main loop. Conventionally, signals are emitted
"when something changes" about the object emitting the signal.
<P>
Signals and events only come together because GtkWidget happens to emit
signals when it gets events. This is purely a convenience, so you can
connect callbacks to be invoked when a particular widget receives a
particular event. There is nothing about this that makes signals and
events inherently related concepts, any more than emitting a signal when
you click a button makes button clicking and signals related concepts.
Signals and events only come together because GtkWidget happens to
emit signals when it gets events. This is purely a convenience, so
you can connect callbacks to be invoked when a particular widget
receives a particular event. There is nothing about this that makes
signals and events inherently related concepts, any more than
emitting a signal when you click a button makes button clicking and
signals related concepts.
</quote>
<!-- ----------------------------------------------------------------- -->
@ -1493,9 +1512,9 @@ gint delete_event_handler (GtkWidget *widget,
<!-- ----------------------------------------------------------------- -->
<sect1>I have my signal connected to the the (whatever) event, but it seems I don't catch it. What's wrong?
<p>
There is some special initialisation to do in order to catch some
particular events. In fact, you must set the correct event mask bit of your
widget before getting some particular events.
There is some special initialisation to do in order to catch some
particular events. In fact, you must set the correct event mask bit of
your widget before getting some particular events.
For example,
@ -1508,6 +1527,47 @@ simply us the GDK_ALL_EVENTS_MASK event mask.
All the event masks are defined in the <tt/gdktypes.h/ file.
<!-- ----------------------------------------------------------------- -->
<sect1>I need to add a new signal to a GTK+ widget. Any idea?
<p>
If the signal you want to add may be beneficial for other GTK+ users,
you may want to submit a patch that presents your changes. Check the
tutorial for more information about adding signals to a widget class.
If you don't think it is the case or if your patch is not applied
you'll have to use the <tt/gtk_object_class_user_signal_new/
function. <tt/gtk_object_class_user_signal_new/ allows you to add a
new signal to a predefined GTK+ widget without any modification of the
GTK+ source code. The new signal can be emited with
<tt/gtk_signal_emit/ and can be handled in the same way as other
signals.
Tim Janik posted this code snippet:
<tscreen><verb>
static guint signal_user_action = 0;
signal_user_action =
gtk_object_class_user_signal_new (gtk_type_class (GTK_TYPE_WIDGET),
"user_action",
GTK_RUN_LAST | GTK_RUN_ACTION,
gtk_marshal_NONE__POINTER,
GTK_TYPE_NONE, 1,
GTK_TYPE_POINTER);
void
gtk_widget_user_action (GtkWidget *widget,
gpointer act_data)
{
g_return_if_fail (GTK_IS_WIDGET (widget));
gtk_signal_emit (GTK_OBJECT (widget), signal_user_action, act_data);
}
</verb></tscreen>
If you want your new signal to have more than the classical gpointer
parameter, you'll have to play with GTK+ marshallers.
<!-- ----------------------------------------------------------------- -->
<sect1>Is it possible to get some text displayed which is truncated to fit inside its allocation?
<p>
@ -1550,9 +1610,9 @@ closing the window do <tt/gtk_grab_remove(my_window)/.
<sect1>Why doesn't my widget (e.g. progressbar) update?
<p>
You are probably doing all the changes within a function
without returning control to <tt/gtk_main()/. This may be the case if you do some
lengthy calculation in your code. Most drawing updates are only
You are probably doing all the changes within a function without
returning control to <tt/gtk_main()/. This may be the case if you do
some lengthy calculation in your code. Most drawing updates are only
placed on a queue, which is processed within <tt/gtk_main()/. You can
force the drawing queue to be processed using something like:
@ -1569,18 +1629,19 @@ high priority idle function).
<!-- ----------------------------------------------------------------- -->
<sect1>How do I attach data to some GTK+ object/widget?
<p>
First of all, the attached data is stored in the object_data field of a
GtkObject. The type of this field is GData, which is defined in glib.h.
So you should read the gdataset.c file in your glib source directory very
carefully.
First of all, the attached data is stored in the object_data field of
a GtkObject. The type of this field is GData, which is defined in
glib.h. So you should read the gdataset.c file in your glib source
directory very carefully.
There are two (easy) ways to attach some data to a gtk object.
Using <tt/gtk_object_set_data()/ and <tt/gtk_object_get_data()/ seems to be the
most common way to do this, as it provides a powerful interface
to connect objects and data.
There are two (easy) ways to attach some data to a gtk object. Using
<tt/gtk_object_set_data()/ and <tt/gtk_object_get_data()/ seems to be
the most common way to do this, as it provides a powerful interface to
connect objects and data.
<tscreen><verb>
void gtk_object_set_data(GtkObject *object, const gchar *key, gpointer data);
gpointer gtk_object_get_data(GtkObject *object, const gchar *key);
</verb></tscreen>
@ -1606,12 +1667,11 @@ with some old gtk packages.
<!-- ----------------------------------------------------------------- -->
<sect1>How do I remove the data I have attached to an object?
<p>
When attaching the data to the object, you can use the
<tt/gtk_object_set_data_full()/
function. The three first arguments of the function are the same as in
<tt/gtk_object_set_data()/. The fourth one is a pointer to a callback function
which is called when the data is destroyed. The data is destroyed when
you:
When attaching the data to the object, you can use the
<tt/gtk_object_set_data_full()/ function. The three first arguments of
the function are the same as in <tt/gtk_object_set_data()/. The fourth
one is a pointer to a callback function which is called when the data
is destroyed. The data is destroyed when you:
<itemize>
<item> destroy the object
@ -1652,8 +1712,8 @@ To avoid this problem, simply use the following code snippet:
<!-- ----------------------------------------------------------------- -->
<sect1>How could I get any widgets position?
<p>
As Tim Janik pointed out, there are different cases, and each case requires
a different solution.
As Tim Janik pointed out, there are different cases, and each case
requires a different solution.
<itemize>
<item> If you want the position of a widget relative to its parent,
@ -1682,9 +1742,9 @@ decorations that they add around windows.
The <tt/gtk_widget_set_uposition()/ function is used to set the
position of any widget.
The <tt/gtk_widget_set_usize()/ function is used to set the
size of a widget. In order to use all the features that are provided by
this function when it acts on a window, you may want to use the
The <tt/gtk_widget_set_usize()/ function is used to set the size of a
widget. In order to use all the features that are provided by this
function when it acts on a window, you may want to use the
<tt/gtk_window_set_policy/ function. The definition of these functions
are:
@ -1701,10 +1761,10 @@ void gtk_window_set_policy (GtkWindow *window,
<tt/Auto_shrink/ will automatically shrink the window when the
requested size of the child widgets goes below the current size of the
window. <tt/Allow_shrink/ will give the user the authorisation to
make the window smaller that it should normally be. <tt/Allow_grow/
will give the user will have the ability to make the window
bigger. The default values for these parameters are:
window. <tt/Allow_shrink/ will give the user the authorisation to make
the window smaller that it should normally be. <tt/Allow_grow/ will
give the user will have the ability to make the window bigger. The
default values for these parameters are:
<tscreen><verb>
allow_shrink = FALSE
@ -1716,16 +1776,21 @@ The <tt/gtk_widget_set_usize()/ functions is not the easiest way to
set a window size since you cannot decrease this window size with
another call to this function unless you call it twice, as in:
<tscreen><verb>
gtk_widget_set_usize(your_widget, -1, -1);
gtk_widget_set_usize(your_widget, new_x_size, new_y_size);
</verb></tscreen>
Another way to set the size of and/or move a window is to use the
<tt/gdk_window_move_resize()/ function which uses to work fine both to
grow or to shrink the window:
<tscreen><verb>
gdk_window_move_resize(window->window,
x_pos, y_pos,
x_size, y_size);
</verb></tscreen>
<!-- ----------------------------------------------------------------- -->
<sect1>How do I add a popup menu to my GTK+ application?
<p>
@ -1753,9 +1818,10 @@ static gint button_press (GtkWidget *widget, GdkEvent *event)
<!-- ----------------------------------------------------------------- -->
<sect1>How do I disable or enable a widget, such as a button?
<p>
To disable (or to enable) a widget, use the <tt/gtk_widget_set_sensitive()/
function. The first parameter is you widget pointer. The second parameter
is a boolean value: when this value is TRUE, the widget is enabled.
To disable (or to enable) a widget, use the
<tt/gtk_widget_set_sensitive()/ function. The first parameter is you
widget pointer. The second parameter is a boolean value: when this
value is TRUE, the widget is enabled.
<!-- ----------------------------------------------------------------- -->
<sect1>Shouldn't the text argument in the gtk_clist_* functions be declared const?
@ -1772,8 +1838,8 @@ apply for "gchar *[]" (array of an unspecified number of pointers to
char) into "const gchar *[]" (array of an unspecified number of
pointers to const char).
The type qualifier "const" may be subject to automatic casting, but
in the array case, it is not the array itself that needs the (const)
The type qualifier "const" may be subject to automatic casting, but in
the array case, it is not the array itself that needs the (const)
qualified cast, but its members, thus changing the whole type.
<!-- ----------------------------------------------------------------- -->
@ -1864,22 +1930,23 @@ of GTK_LIST(AnyGtkList)->selection:
selection_mode GTK_LIST()->selection contents
------------------------------------------------------
GTK_SELECTION_SINGLE) selection is either NULL
GTK_SELECTION_SINGLE selection is either NULL
or contains a GList* pointer
for a single selected item.
GTK_SELECTION_BROWSE) selection is NULL if the list
GTK_SELECTION_BROWSE selection is NULL if the list
contains no widgets, otherwise
it contains a GList* pointer
for one GList structure.
GTK_SELECTION_MULTIPLE) selection is NULL if no listitems
GTK_SELECTION_MULTIPLE selection is NULL if no listitems
are selected or a a GList* pointer
for the first selected item. that
in turn points to a GList structure
for the second selected item and so
on
on.
GTK_SELECTION_EXTENDED) selection is NULL.
GTK_SELECTION_EXTENDED selection is NULL.
</verb>
The data field of the GList structure GTK_LIST(MyGtkList)->selection points
@ -1974,7 +2041,8 @@ Set the editable parameter to FALSE to disable typing into the entry.
<!-- ----------------------------------------------------------------- -->
<sect1>How do I catch a combo box change?
<p>
The entry which is associated to your GtkCombo send a "changed" signal when:
The entry which is associated to your GtkCombo send a "changed" signal
when:
<itemize>
<item>some text is typed in
<item>the selection of the combo box is changed
@ -2006,8 +2074,8 @@ gtk_widget_show(menuitem);
<!-- ----------------------------------------------------------------- -->
<sect1>How can I right justify a menu, such as Help?
<p>
Depending on if you use the MenuFactory or not, there are two ways to proceed.
With the MenuFactory, use something like the following:
Depending on if you use the MenuFactory or not, there are two ways to
proceed. With the MenuFactory, use something like the following:
<tscreen><verb>
menu_path = gtk_menu_factory_find (factory, "<MyApp>/Help");
@ -2023,11 +2091,11 @@ gtk_menu_item_right_justify(my_menu_item);
<!-- ----------------------------------------------------------------- -->
<sect1>How do I add some underlined accelerators to menu items?
<p>
Damon Chaplin, the technical force behind the Glade project, provided the
following code sample (this code is an output from Glade). It creates a
small <tt/File/ menu item with only one child (<tt/New/). The F in <tt/File/
and the N in <tt/New/ are underlined, and the relevant accelerators are
created.
Damon Chaplin, the technical force behind the Glade project, provided
the following code sample (this code is an output from Glade). It
creates a small <tt/File/ menu item with only one child
(<tt/New/). The F in <tt/File/ and the N in <tt/New/ are underlined,
and the relevant accelerators are created.
<tscreen><verb>
menubar1 = gtk_menu_bar_new ();
@ -2059,16 +2127,60 @@ created.
gtk_container_add (GTK_CONTAINER (file1_menu), new1);
</verb></tscreen>
<!-- ----------------------------------------------------------------- -->
<sect1>How can I retrieve the text from a GtkMenuItem?
<p>
You can usually retrieve the label of a specific GtkMenuItem with:
<tscreen><verb>
if (GTK_BIN (menu_item)->child)
{
GtkWidget *child = GTK_BIN (menu_item)->child;
/* do stuff with child */
if (GTK_IS_LABEL (child))
{
gchar *text;
gtk_label_get (GTK_LABEL (child), &amp;text);
g_print ("menu item text: %s\n", text);
}
}
</verb></tscreen>
To get the active menu item from a GtkOptionMenu you can do:
<tscreen><verb>
if (GTK_OPTION_MENU (option_menu)->menu_item)
{
GtkWidget *menu_item = GTK_OPTION_MENU (option_menu)->menu_item;
}
</verb></tscreen>
But, there's a catch. For this specific case, you can <bf>not</bf> get
the label widget from <tt/menu_item/ with the above code, because the
option menu reparents the menu_item's child temporarily to display the
currently active contents. So to retrive the child of the currently
active menu_item of an option menu, you'll have to do:
<tscreen><verb>
if (GTK_BIN (option_menu)->child)
{
GtkWidget *child = GTK_BIN (option_menu)->child;
/* do stuff with child */
}
</verb></tscreen>
<!-- ----------------------------------------------------------------- -->
<sect1>How do I right (or otherwise) justify a GtkLabel?
<p>
Are you sure you want to <em>justify</em> the labels? The label class contains
the <tt/gtk_label_set_justify()/ function that is used to control the
justification of a multi-line label.
Are you sure you want to <em>justify</em> the labels? The label class
contains the <tt/gtk_label_set_justify()/ function that is used to
control the justification of a multi-line label.
What you probably want is to set the <em>alignment</em> of the label, ie right
align it, center it or left align it. If you want to do this, you
should use:
What you probably want is to set the <em>alignment</em> of the label,
ie right align it, center it or left align it. If you want to do this,
you should use:
<tscreen><verb>
void gtk_misc_set_alignment (GtkMisc *misc,
@ -2139,9 +2251,9 @@ widget, which can be done using:
<!-- ----------------------------------------------------------------- -->
<sect1>How do I configure Tooltips in a Resource File?
<p>
The tooltip's window is named "gtk-tooltips", GtkTooltips in itself is not
a GtkWidget (though a GtkObject) and as such is not attempted to match any
widget styles.
The tooltip's window is named "gtk-tooltips", GtkTooltips in itself is
not a GtkWidget (though a GtkObject) and as such is not attempted to
match any widget styles.
So, you resource file should look something like:
<verb>
@ -2185,6 +2297,78 @@ want to do. Typical code would be:
NULL);
</verb></tscreen>
<!-- ----------------------------------------------------------------- -->
<sect1>How do I validate/limit/filter the input to a GtkEntry?
<p>
If you want to validate the text that a user enters into a GtkEntry
widget you can attach to the "insert_text" signal of the entry, and
modify the text within the callback function. The example below forces
all characters to uppercase, and limits the range of characters to
A-Z. Note that the entry is cast to an object of type GtkEditable,
from which GtkEntry is derived.
<tscreen><verb>
#include <ctype.h>
#include <gtk/gtk.h>
void insert_text_handler (GtkEntry *entry,
const gchar *text,
gint length,
gint *position,
gpointer data)
{
GtkEditable *editable = GTK_EDITABLE(entry);
int i, count=0;
gchar *result = g_new (gchar, length);
for (i=0; i < length; i++) {
if (!isalpha(text[i]))
continue;
result[count++] = islower(text[i]) ? toupper(text[i]) : text[i];
}
if (count > 0) {
gtk_signal_handler_block_by_func (GTK_OBJECT (editable),
GTK_SIGNAL_FUNC (insert_text_handler),
data);
gtk_editable_insert_text (editable, result, count, position);
gtk_signal_handler_unblock_by_func (GTK_OBJECT (editable),
GTK_SIGNAL_FUNC (insert_text_handler),
data);
}
gtk_signal_emit_stop_by_name (GTK_OBJECT (editable), "insert_text");
g_free (result);
}
int main (int argc,
char *argv[])
{
GtkWidget *window;
GtkWidget *entry;
gtk_init (&amp;argc, &amp;argv);
/* create a new window */
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW (window), "GTK Entry");
gtk_signal_connect(GTK_OBJECT (window), "delete_event",
(GtkSignalFunc) gtk_exit, NULL);
entry = gtk_entry_new();
gtk_signal_connect(GTK_OBJECT(entry), "insert_text",
GTK_SIGNAL_FUNC(insert_text_handler),
NULL);
gtk_container_add(GTK_CONTAINER (window), entry);
gtk_widget_show(entry);
gtk_widget_show(window);
gtk_main();
return(0);
}
</verb></tscreen>
<!-- ----------------------------------------------------------------- -->
<sect1>How do I use horizontal scrollbars with a GtkText widget?
<p>
@ -2223,22 +2407,23 @@ load a font using, for example:
Notice that the response is valid for any object that inherits from the
GtkEditable class.
Are you sure that you want to move the cursor position? Most of the time,
while the cursor position is good, the insertion point does not match the
cursor position. If this apply to what you really want, then you should use
the <tt/gtk_text_set_point()/ function. If you want to set the insertion point
at the current cursor position, use the following:
Are you sure that you want to move the cursor position? Most of the
time, while the cursor position is good, the insertion point does not
match the cursor position. If this apply to what you really want, then
you should use the <tt/gtk_text_set_point()/ function. If you want to
set the insertion point at the current cursor position, use the
following:
<tscreen><verb>
gtk_text_set_point(GTK_TEXT(text),
gtk_editable_get_position(GTK_EDITABLE(text)));
gtk_editable_get_position(GTK_EDITABLE(text)));
</verb></tscreen>
If you want the insertion point to follow the cursor at all time, you
should probably catch the button press event, and then move the
insertion point. Be careful : you'll have to catch it after the widget
has changed the cursor position though. Thomas Mailund Jensen proposed the
following code:
insertion point. Be careful : you'll have to catch it after the widget
has changed the cursor position though. Thomas Mailund Jensen proposed
the following code:
<tscreen><verb>
static void
@ -2246,7 +2431,7 @@ insert_bar (GtkWidget *text)
{
/* jump to cursor mark */
gtk_text_set_point (GTK_TEXT (text),
gtk_editable_get_position (GTK_EDITABLE (text)));
gtk_editable_get_position (GTK_EDITABLE (text)));
gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL,
"bar", strlen ("bar"));
@ -2285,12 +2470,12 @@ Now, if you really want to change the cursor position, you should use the
<!-- ----------------------------------------------------------------- -->
<sect1>What is GDK?
<p>
GDK is basically a wrapper around the standard Xlib function calls. If you are
at all familiar with Xlib, a lot of the functions in GDK will require little
or no getting used to. All functions are written to provide an way
to access Xlib functions in an easier and slightly more intuitive manner.
In addition, since GDK uses GLib (see below), it will be more portable
and safer to use on multiple platforms.
GDK is basically a wrapper around the standard Xlib function calls. If
you are at all familiar with Xlib, a lot of the functions in GDK will
require little or no getting used to. All functions are written to
provide an way to access Xlib functions in an easier and slightly more
intuitive manner. In addition, since GDK uses GLib (see below), it
will be more portable and safer to use on multiple platforms.
<!-- Examples, anybody? I've been mulling some over. NF -->
@ -2425,24 +2610,76 @@ reference on the first node of the list.
<!-- I believe it should be better :) ED -->
<!-- Linked lists are pretty standard data structures - don't want to
over do it - TRG -->
<!-- ----------------------------------------------------------------- -->
<sect1>Memory does not seem to be released when I free the list nodes I've allocated
<p>
GLib tries to be "intelligent" on this special issue: it assumes that
you are likely to reuse the objects, so caches the allocated memory.
If you do not want to use this behavior, you'll probably want to set
up a special allocator.
To quote Tim Janik:
<quote>
If you have a certain portion of code that uses *lots* of GLists or
GNodes, and you know you'd better want to release all of them after a
short while, you'd want to use a GAllocator. Pushing an allocator into
g_list will make all subsequent glist operations private to that
allocator's memory pool (and thus you have to take care to pop the
allocator again, before making any external calls):
</quote>
<tscreen><verb>
GAllocator *allocator;
GList *list = NULL;
guint i;
/* set a new allocation pool for GList nodes */
allocator = g_allocator_new ("list heap", 1024);
g_list_push_allocator (allocator);
/* do some list operations */
for (i = 0; i < 4096; i++)
list = g_list_prepend (list, NULL);
list = g_list_reverse (list);
/* beware to pop allocator befor calling external functions */
g_list_pop_allocator ();
gtk_label_set_text (GTK_LABEL (some_label), "some text");
/* and set our private glist pool again */
g_list_push_allocator (allocator);
/* do some list operations */
g_list_free (list);
list = NULL;
for (i = 0; i < 4096; i++)
list = g_list_prepend (list, NULL);
/* and back out (while freeing all of the list nodes in our pool) */
g_list_pop_allocator ();
g_allocator_free (allocator);
</verb></tscreen>
<!-- ----------------------------------------------------------------- -->
<sect1>Why use g_print, g_malloc, g_strdup and fellow glib functions?
<p>
Thanks to Tim Janik who wrote to gtk-list: (slightly modified)
<quote>
Regarding g_malloc(), g_free() and siblings, these functions are much safer
than their libc equivalents. For example, g_free() just returns if called
with NULL. Also, if USE_DMALLOC is defined, the definition for these
functions changes (in glib.h) to use MALLOC(), FREE() etc... If MEM_PROFILE
or MEM_CHECK are defined, there are even small statistics made counting
the used block sizes (shown by g_mem_profile() / g_mem_check()).
<P>
Regarding g_malloc(), g_free() and siblings, these functions are much
safer than their libc equivalents. For example, g_free() just returns
if called with NULL. Also, if USE_DMALLOC is defined, the definition
for these functions changes (in glib.h) to use MALLOC(), FREE() etc...
If MEM_PROFILE or MEM_CHECK are defined, there are even small
statistics made counting the used block sizes (shown by
g_mem_profile() / g_mem_check()).
<p>
Considering the fact that glib provides an interface for memory chunks
to save space if you have lots of blocks that are always the same size
and to mark them ALLOC_ONLY if needed, it is just straight forward to
create a small saver (debug able) wrapper around the normal malloc/free
stuff as well - just like gdk covers Xlib. ;)
<P>
<p>
Using g_error() and g_warning() inside of applications like the GIMP
that fully rely on gtk even gives the opportunity to pop up a window
showing the messages inside of a gtk window with your own handler
@ -2626,7 +2863,8 @@ main (int argc, char *argv[])
You need to understand that the scanner will parse its input and
tokenize it, it is up to you to interpret these tokens, not define
their types before they get parsed, e.g. watch gscanner parse a string:
their types before they get parsed, e.g. watch gscanner parse a
string:
<verb>
"hi i am 17"
@ -2711,8 +2949,8 @@ This FAQ was created by Shawn T. Amundson
<htmlurl url="mailto:amundson@gimp.org"
name="&lt;amundson@gimp.org&gt;"> who continues to provide support.
Contributions should be sent to Tony Gale <htmlurl url="mailto:gale@gtk.org"
name="&lt;gale@gtk.org&gt;">
Contributions should be sent to Tony Gale <htmlurl
url="mailto:gale@gtk.org" name="&lt;gale@gtk.org&gt;">
The GTK+ FAQ is Copyright (C) 1997-2000 by Shawn T. Amundson,
Tony Gale, Emmanuel Deloget and Nathan Froyd.

View File

@ -9,7 +9,7 @@
<!-- NOTE: Use only one author tag, otherwise sgml2txt barfs - TRG -->
<author>Tony Gale, Shawn T. Amundson, Emmanuel Deloget, Nathan Froyd
<date>February 22nd 2000
<date>March 9th 2000
<abstract> This document is intended to answer questions that are likely to be
frequently asked by programmers using GTK+ or people who are just looking at
@ -91,7 +91,7 @@ enhancement to the original gtk that adds object oriented features."
<p>
GTK+ == Gimp Toolkit
GDK == Gtk+ Drawing Kit
GDK == GTK+ Drawing Kit
GLib == G Libray
@ -281,7 +281,6 @@ name="http://www.forcix.cx/irc-clients.html"> list a bunch of them).
<!-- ***************************************************************** -->
<sect>How to find, configure, install, and troubleshoot GTK+
<!-- ***************************************************************** -->
<!-- ----------------------------------------------------------------- -->
@ -313,6 +312,7 @@ Here's a few mirror sites to get you started:
<item>US - ftp://ftp.insync.net/pub/mirrors/ftp.gimp.org/
</itemize>
<!-- ----------------------------------------------------------------- -->
<sect1>How do I configure/compile GTK+?
<p>
Generally, all you will need to do is issue the commands:
@ -326,21 +326,22 @@ in the gtk+-version/ directory.
<sect1>When compiling GTK+ I get an error like:
<tt/make: file `Makefile' line 456: Syntax error/
<p>
Make sure that you are using GNU make (use <tt/make -v/ to check). There are
many weird and wonderful versions of make out there, and not all of them
handle the automatically generated Makefiles.
Make sure that you are using GNU make (use <tt/make -v/ to
check). There are many weird and wonderful versions of make out there,
and not all of them handle the automatically generated Makefiles.
<!-- ----------------------------------------------------------------- -->
<sect1>I've compiled and installed GTK+, but I can't get any programs to link with it!
<p>
This problem is most often encountered when the GTK+ libraries can't be
found or are the wrong version. Generally, the compiler will complain about an
'unresolved symbol'. There are two things you need to check:
This problem is most often encountered when the GTK+ libraries can't
be found or are the wrong version. Generally, the compiler will
complain about an 'unresolved symbol'. There are two things you need
to check:
<itemize>
<item>Make sure that the libraries can be found. You want to edit
/etc/ld.so.conf to include the directories which contain the GTK libraries,
so it looks something like:
<item>Make sure that the libraries can be found. You want to edit
/etc/ld.so.conf to include the directories which contain the GTK
libraries, so it looks something like:
<verb>
/usr/X11R6/lib
/usr/local/lib
@ -370,13 +371,13 @@ system), issue the command
<verb>
rpm -e gtk gtk-devel
</verb>
You may also want to remove the packages that depend on gtk (rpm will tell you
which ones they are). If you don't have a RedHat Linux system, check to make sure
that neither <verb>/usr/lib</verb> or <verb>/usr/local/lib</verb> contain any of
the libraries libgtk, libgdk, libglib, or libgck. If they do exist, remove them
(and any gtk include files, such as /usr/include/gtk and /usr/include/gdk)
and reinstall gtk+.
</itemize>
You may also want to remove the packages that depend on gtk (rpm will
tell you which ones they are). If you don't have a RedHat Linux
system, check to make sure that neither <verb>/usr/lib</verb> or
<verb>/usr/local/lib</verb> contain any of the libraries libgtk,
libgdk, libglib, or libgck. If they do exist, remove them (and any
gtk include files, such as /usr/include/gtk and /usr/include/gdk) and
reinstall gtk+. </itemize>
<!-- ----------------------------------------------------------------- -->
<sect1>When compiling programs with GTK+, I get compiler error messages about not being able to find <tt/"glibconfig.h"/.
@ -467,7 +468,7 @@ Normal people should use the packaged releases.
The CVS toolset is available as RPM packages from the usual RedHat sites.
The latest version is available at
<htmlurl url="http://download.cyclic.com/pub/"
name="&lt;http://download.cyclic.com/pub/&gt;">
name="http://download.cyclic.com/pub/">
Anyone can download the latest CVS version of GTK+ by using anonymous access
using the following steps:
@ -496,8 +497,8 @@ as well:
<verb>
cvs -z3 get glib
</verb>
</itemize>
<!-- ----------------------------------------------------------------- -->
<sect1>How can I contribute to GTK+?
<p>
@ -552,7 +553,7 @@ gladly be included.
<!-- ----------------------------------------------------------------- -->
<sect1>Is anyone working on bindings for languages other than C?
<p>
The GTK+ home page (<htmlurl url="http://www.gtk.org/"
The GTK+ home page (<htmlurl url="http://www.gtk.org/"
name="http://www.gtk.org/">) presents a list of GTK+ bindings.
<itemize>
@ -650,13 +651,15 @@ GTK+. I suggest you start at
<!-- ***************************************************************** -->
<sect>Development with GTK+: the begining
<!-- ***************************************************************** -->
<!-- ----------------------------------------------------------------- -->
<sect1>How do I get started?
<p>
So, after you have installed GTK+ there are a couple of things that can
ease you into developing applications with it. There is the
GTK+ Tutorial <htmlurl url="http://www.gtk.org/tutorial/"
name="&lt;http://www.gtk.org/tutorial/&gt;">, which is undergoing
name="http://www.gtk.org/tutorial/">, which is undergoing
development. This will introduce you to writing applications using C.
The Tutorial doesn't (yet) contain information on all of the widgets
@ -693,6 +696,7 @@ The command line above ensure that:
</itemize>
<!-- ----------------------------------------------------------------- -->
<sect1>What about using the <tt/make/ utility?
<p>
This is a sample makefile which compile a GTK+ based program:
@ -749,7 +753,7 @@ dnl Process this file with autoconf to produce a configure script.
dnl configure.in for a GTK+ based program
AC_INIT(myprg.c)dnl
AM_INIT_AUTOMAKE(mypkbname,0.0.1)dnl
AM_INIT_AUTOMAKE(mypkgname,0.0.1)dnl
AM_CONFIG_HEADER(config.h)dnl
dnl Checks for programs.
@ -775,6 +779,14 @@ CLEANFILES = *~
DISTCLEANFILES = .deps/*.P
</verb></tscreen>
If your project contains more than one subdirectory, you'll have to
create one Makefile.am in each directory plus a master Makefile.am
which will look like:
<tscreen><verb>
SUBDIRS = mydir1 mydir2 mydir3
</verb></tscreen>
then, to use these, simply type the following commands:
<verb>
@ -784,9 +796,10 @@ autoconf
automake --add-missing --include-deps --foreign
</verb>
For further informations, you should look at the autoconf and the automake
documentation (the shipped info files are really easy to understand, and there
are plenty of web resources that deal with autoconf and/or automake).
For further information, you should look at the autoconf and the
automake documentation (the shipped info files are really easy to
understand, and there are plenty of web resources that deal with
autoconf and automake).
<!-- ----------------------------------------------------------------- -->
<sect1>I try to debug my GTK+ application with gdb, but it hangs my X server when I hit some breakpoint. Any Idea ?
@ -813,6 +826,7 @@ bit hard to get (here in The Netherlands, YMMV).
<!-- ***************************************************************** -->
<sect>Development with GTK+: general questions
<!-- ***************************************************************** -->
<!-- ----------------------------------------------------------------- -->
<sect1>What widgets are in GTK?
<p>
@ -1095,7 +1109,6 @@ int main(int argc, char *argv[])
<!-- This is the old answer - TRG
Although GTK+, like many X toolkits, isn't thread safe, this does
not prohibit the development of multi-threaded applications with
GTK+.
@ -1143,22 +1156,25 @@ and it also might make GTK+ substantially less efficient if not handled
carefully.
Regardless, it's especially not a priority since relatively good
workarounds exist. -->
workarounds exist.
-->
<!-- ----------------------------------------------------------------- -->
<sect1>Why does this strange 'x io error' occur when I <tt/fork()/ in my GTK+ app?
<p>
This is not really a GTK+ problem, and the problem is not related to <tt/fork()/
either. If the 'x io error' occurs then you probably use the <tt/exit()/ function
in order to exit from the child process.
This is not really a GTK+ problem, and the problem is not related to
<tt/fork()/ either. If the 'x io error' occurs then you probably use
the <tt/exit()/ function in order to exit from the child process.
When GDK opens an X display, it creates a socket file descriptor. When you use
the <tt/exit()/ function, you implicitly close all the open file descriptors,
and the underlying X library really doesn't like this.
When GDK opens an X display, it creates a socket file descriptor. When
you use the <tt/exit()/ function, you implicitly close all the open
file descriptors, and the underlying X library really doesn't like
this.
The right function to use here is <tt/_exit()/.
Erik Mouw contributed the following code example to illustrate handling
fork() and exit().
Erik Mouw contributed the following code example to illustrate
handling fork() and exit().
<tscreen><verb>
/*-------------------------------------------------------------------------
@ -1370,11 +1386,11 @@ the user to get the closest ancestor of a known type) is to use
widget = gtk_widget_get_ancestor(w, GTK_TYPE_WINDOW);
</verb></tscreen>
Since virtually all the GTK_TYPEs can be used as the second parameter of
this function, you can get any parent widget of a particular
widget. Suppose you have an hbox which contains a vbox, which in turn contains
some other atomic widget (entry, label, etc. To find the master hbox
using the <tt/entry/ widget simply use:
Since virtually all the GTK_TYPEs can be used as the second parameter
of this function, you can get any parent widget of a particular
widget. Suppose you have an hbox which contains a vbox, which in turn
contains some other atomic widget (entry, label, etc. To find the
master hbox using the <tt/entry/ widget simply use:
<tscreen><verb>
GtkWidget *hbox;
@ -1449,32 +1465,35 @@ mind.)
<!-- ----------------------------------------------------------------- -->
<sect1>By the way, what are the differences between signals and events?
<p>
First of all, Havoc Pennington gives a rather complete description of the
differences between events and signals in his free book (two chapters can
be found at <htmlurl url="http://www106.pair.com/rhp/sample_chapters.html"
First of all, Havoc Pennington gives a rather complete description of
the differences between events and signals in his free book (two
chapters can be found at <htmlurl
url="http://www106.pair.com/rhp/sample_chapters.html"
name="http://www106.pair.com/rhp/sample_chapters.html">).
Moreover, Havoc posted this to the <tt/gtk-list/
<quote>
Events are a stream of messages received from the X server. They drive the
Gtk main loop; which more or less amounts to "wait for events, process
them" (not exactly, it is really more general than that and can wait on
many different input streams at once). Events are a Gdk/Xlib concept.
Events are a stream of messages received from the X server. They
drive the Gtk main loop; which more or less amounts to "wait for
events, process them" (not exactly, it is really more general than
that and can wait on many different input streams at once). Events
are a Gdk/Xlib concept.
<P>
Signals are a feature of GtkObject and its subclasses. They have nothing
to do with any input stream; really a signal is just a way to keep a list
of callbacks around and invoke them ("emit" the signal). There are lots of
details and extra features of course. Signals are emitted by object
instances, and are entirely unrelated to the Gtk main loop.
Conventionally, signals are emitted "when something changes" about the
object emitting the signal.
Signals are a feature of GtkObject and its subclasses. They have
nothing to do with any input stream; really a signal is just a way
to keep a list of callbacks around and invoke them ("emit" the
signal). There are lots of details and extra features of
course. Signals are emitted by object instances, and are entirely
unrelated to the Gtk main loop. Conventionally, signals are emitted
"when something changes" about the object emitting the signal.
<P>
Signals and events only come together because GtkWidget happens to emit
signals when it gets events. This is purely a convenience, so you can
connect callbacks to be invoked when a particular widget receives a
particular event. There is nothing about this that makes signals and
events inherently related concepts, any more than emitting a signal when
you click a button makes button clicking and signals related concepts.
Signals and events only come together because GtkWidget happens to
emit signals when it gets events. This is purely a convenience, so
you can connect callbacks to be invoked when a particular widget
receives a particular event. There is nothing about this that makes
signals and events inherently related concepts, any more than
emitting a signal when you click a button makes button clicking and
signals related concepts.
</quote>
<!-- ----------------------------------------------------------------- -->
@ -1493,9 +1512,9 @@ gint delete_event_handler (GtkWidget *widget,
<!-- ----------------------------------------------------------------- -->
<sect1>I have my signal connected to the the (whatever) event, but it seems I don't catch it. What's wrong?
<p>
There is some special initialisation to do in order to catch some
particular events. In fact, you must set the correct event mask bit of your
widget before getting some particular events.
There is some special initialisation to do in order to catch some
particular events. In fact, you must set the correct event mask bit of
your widget before getting some particular events.
For example,
@ -1508,6 +1527,47 @@ simply us the GDK_ALL_EVENTS_MASK event mask.
All the event masks are defined in the <tt/gdktypes.h/ file.
<!-- ----------------------------------------------------------------- -->
<sect1>I need to add a new signal to a GTK+ widget. Any idea?
<p>
If the signal you want to add may be beneficial for other GTK+ users,
you may want to submit a patch that presents your changes. Check the
tutorial for more information about adding signals to a widget class.
If you don't think it is the case or if your patch is not applied
you'll have to use the <tt/gtk_object_class_user_signal_new/
function. <tt/gtk_object_class_user_signal_new/ allows you to add a
new signal to a predefined GTK+ widget without any modification of the
GTK+ source code. The new signal can be emited with
<tt/gtk_signal_emit/ and can be handled in the same way as other
signals.
Tim Janik posted this code snippet:
<tscreen><verb>
static guint signal_user_action = 0;
signal_user_action =
gtk_object_class_user_signal_new (gtk_type_class (GTK_TYPE_WIDGET),
"user_action",
GTK_RUN_LAST | GTK_RUN_ACTION,
gtk_marshal_NONE__POINTER,
GTK_TYPE_NONE, 1,
GTK_TYPE_POINTER);
void
gtk_widget_user_action (GtkWidget *widget,
gpointer act_data)
{
g_return_if_fail (GTK_IS_WIDGET (widget));
gtk_signal_emit (GTK_OBJECT (widget), signal_user_action, act_data);
}
</verb></tscreen>
If you want your new signal to have more than the classical gpointer
parameter, you'll have to play with GTK+ marshallers.
<!-- ----------------------------------------------------------------- -->
<sect1>Is it possible to get some text displayed which is truncated to fit inside its allocation?
<p>
@ -1550,9 +1610,9 @@ closing the window do <tt/gtk_grab_remove(my_window)/.
<sect1>Why doesn't my widget (e.g. progressbar) update?
<p>
You are probably doing all the changes within a function
without returning control to <tt/gtk_main()/. This may be the case if you do some
lengthy calculation in your code. Most drawing updates are only
You are probably doing all the changes within a function without
returning control to <tt/gtk_main()/. This may be the case if you do
some lengthy calculation in your code. Most drawing updates are only
placed on a queue, which is processed within <tt/gtk_main()/. You can
force the drawing queue to be processed using something like:
@ -1569,18 +1629,19 @@ high priority idle function).
<!-- ----------------------------------------------------------------- -->
<sect1>How do I attach data to some GTK+ object/widget?
<p>
First of all, the attached data is stored in the object_data field of a
GtkObject. The type of this field is GData, which is defined in glib.h.
So you should read the gdataset.c file in your glib source directory very
carefully.
First of all, the attached data is stored in the object_data field of
a GtkObject. The type of this field is GData, which is defined in
glib.h. So you should read the gdataset.c file in your glib source
directory very carefully.
There are two (easy) ways to attach some data to a gtk object.
Using <tt/gtk_object_set_data()/ and <tt/gtk_object_get_data()/ seems to be the
most common way to do this, as it provides a powerful interface
to connect objects and data.
There are two (easy) ways to attach some data to a gtk object. Using
<tt/gtk_object_set_data()/ and <tt/gtk_object_get_data()/ seems to be
the most common way to do this, as it provides a powerful interface to
connect objects and data.
<tscreen><verb>
void gtk_object_set_data(GtkObject *object, const gchar *key, gpointer data);
gpointer gtk_object_get_data(GtkObject *object, const gchar *key);
</verb></tscreen>
@ -1606,12 +1667,11 @@ with some old gtk packages.
<!-- ----------------------------------------------------------------- -->
<sect1>How do I remove the data I have attached to an object?
<p>
When attaching the data to the object, you can use the
<tt/gtk_object_set_data_full()/
function. The three first arguments of the function are the same as in
<tt/gtk_object_set_data()/. The fourth one is a pointer to a callback function
which is called when the data is destroyed. The data is destroyed when
you:
When attaching the data to the object, you can use the
<tt/gtk_object_set_data_full()/ function. The three first arguments of
the function are the same as in <tt/gtk_object_set_data()/. The fourth
one is a pointer to a callback function which is called when the data
is destroyed. The data is destroyed when you:
<itemize>
<item> destroy the object
@ -1652,8 +1712,8 @@ To avoid this problem, simply use the following code snippet:
<!-- ----------------------------------------------------------------- -->
<sect1>How could I get any widgets position?
<p>
As Tim Janik pointed out, there are different cases, and each case requires
a different solution.
As Tim Janik pointed out, there are different cases, and each case
requires a different solution.
<itemize>
<item> If you want the position of a widget relative to its parent,
@ -1682,9 +1742,9 @@ decorations that they add around windows.
The <tt/gtk_widget_set_uposition()/ function is used to set the
position of any widget.
The <tt/gtk_widget_set_usize()/ function is used to set the
size of a widget. In order to use all the features that are provided by
this function when it acts on a window, you may want to use the
The <tt/gtk_widget_set_usize()/ function is used to set the size of a
widget. In order to use all the features that are provided by this
function when it acts on a window, you may want to use the
<tt/gtk_window_set_policy/ function. The definition of these functions
are:
@ -1701,10 +1761,10 @@ void gtk_window_set_policy (GtkWindow *window,
<tt/Auto_shrink/ will automatically shrink the window when the
requested size of the child widgets goes below the current size of the
window. <tt/Allow_shrink/ will give the user the authorisation to
make the window smaller that it should normally be. <tt/Allow_grow/
will give the user will have the ability to make the window
bigger. The default values for these parameters are:
window. <tt/Allow_shrink/ will give the user the authorisation to make
the window smaller that it should normally be. <tt/Allow_grow/ will
give the user will have the ability to make the window bigger. The
default values for these parameters are:
<tscreen><verb>
allow_shrink = FALSE
@ -1716,16 +1776,21 @@ The <tt/gtk_widget_set_usize()/ functions is not the easiest way to
set a window size since you cannot decrease this window size with
another call to this function unless you call it twice, as in:
<tscreen><verb>
gtk_widget_set_usize(your_widget, -1, -1);
gtk_widget_set_usize(your_widget, new_x_size, new_y_size);
</verb></tscreen>
Another way to set the size of and/or move a window is to use the
<tt/gdk_window_move_resize()/ function which uses to work fine both to
grow or to shrink the window:
<tscreen><verb>
gdk_window_move_resize(window->window,
x_pos, y_pos,
x_size, y_size);
</verb></tscreen>
<!-- ----------------------------------------------------------------- -->
<sect1>How do I add a popup menu to my GTK+ application?
<p>
@ -1753,9 +1818,10 @@ static gint button_press (GtkWidget *widget, GdkEvent *event)
<!-- ----------------------------------------------------------------- -->
<sect1>How do I disable or enable a widget, such as a button?
<p>
To disable (or to enable) a widget, use the <tt/gtk_widget_set_sensitive()/
function. The first parameter is you widget pointer. The second parameter
is a boolean value: when this value is TRUE, the widget is enabled.
To disable (or to enable) a widget, use the
<tt/gtk_widget_set_sensitive()/ function. The first parameter is you
widget pointer. The second parameter is a boolean value: when this
value is TRUE, the widget is enabled.
<!-- ----------------------------------------------------------------- -->
<sect1>Shouldn't the text argument in the gtk_clist_* functions be declared const?
@ -1772,8 +1838,8 @@ apply for "gchar *[]" (array of an unspecified number of pointers to
char) into "const gchar *[]" (array of an unspecified number of
pointers to const char).
The type qualifier "const" may be subject to automatic casting, but
in the array case, it is not the array itself that needs the (const)
The type qualifier "const" may be subject to automatic casting, but in
the array case, it is not the array itself that needs the (const)
qualified cast, but its members, thus changing the whole type.
<!-- ----------------------------------------------------------------- -->
@ -1864,22 +1930,23 @@ of GTK_LIST(AnyGtkList)->selection:
selection_mode GTK_LIST()->selection contents
------------------------------------------------------
GTK_SELECTION_SINGLE) selection is either NULL
GTK_SELECTION_SINGLE selection is either NULL
or contains a GList* pointer
for a single selected item.
GTK_SELECTION_BROWSE) selection is NULL if the list
GTK_SELECTION_BROWSE selection is NULL if the list
contains no widgets, otherwise
it contains a GList* pointer
for one GList structure.
GTK_SELECTION_MULTIPLE) selection is NULL if no listitems
GTK_SELECTION_MULTIPLE selection is NULL if no listitems
are selected or a a GList* pointer
for the first selected item. that
in turn points to a GList structure
for the second selected item and so
on
on.
GTK_SELECTION_EXTENDED) selection is NULL.
GTK_SELECTION_EXTENDED selection is NULL.
</verb>
The data field of the GList structure GTK_LIST(MyGtkList)->selection points
@ -1974,7 +2041,8 @@ Set the editable parameter to FALSE to disable typing into the entry.
<!-- ----------------------------------------------------------------- -->
<sect1>How do I catch a combo box change?
<p>
The entry which is associated to your GtkCombo send a "changed" signal when:
The entry which is associated to your GtkCombo send a "changed" signal
when:
<itemize>
<item>some text is typed in
<item>the selection of the combo box is changed
@ -2006,8 +2074,8 @@ gtk_widget_show(menuitem);
<!-- ----------------------------------------------------------------- -->
<sect1>How can I right justify a menu, such as Help?
<p>
Depending on if you use the MenuFactory or not, there are two ways to proceed.
With the MenuFactory, use something like the following:
Depending on if you use the MenuFactory or not, there are two ways to
proceed. With the MenuFactory, use something like the following:
<tscreen><verb>
menu_path = gtk_menu_factory_find (factory, "<MyApp>/Help");
@ -2023,11 +2091,11 @@ gtk_menu_item_right_justify(my_menu_item);
<!-- ----------------------------------------------------------------- -->
<sect1>How do I add some underlined accelerators to menu items?
<p>
Damon Chaplin, the technical force behind the Glade project, provided the
following code sample (this code is an output from Glade). It creates a
small <tt/File/ menu item with only one child (<tt/New/). The F in <tt/File/
and the N in <tt/New/ are underlined, and the relevant accelerators are
created.
Damon Chaplin, the technical force behind the Glade project, provided
the following code sample (this code is an output from Glade). It
creates a small <tt/File/ menu item with only one child
(<tt/New/). The F in <tt/File/ and the N in <tt/New/ are underlined,
and the relevant accelerators are created.
<tscreen><verb>
menubar1 = gtk_menu_bar_new ();
@ -2059,16 +2127,60 @@ created.
gtk_container_add (GTK_CONTAINER (file1_menu), new1);
</verb></tscreen>
<!-- ----------------------------------------------------------------- -->
<sect1>How can I retrieve the text from a GtkMenuItem?
<p>
You can usually retrieve the label of a specific GtkMenuItem with:
<tscreen><verb>
if (GTK_BIN (menu_item)->child)
{
GtkWidget *child = GTK_BIN (menu_item)->child;
/* do stuff with child */
if (GTK_IS_LABEL (child))
{
gchar *text;
gtk_label_get (GTK_LABEL (child), &amp;text);
g_print ("menu item text: %s\n", text);
}
}
</verb></tscreen>
To get the active menu item from a GtkOptionMenu you can do:
<tscreen><verb>
if (GTK_OPTION_MENU (option_menu)->menu_item)
{
GtkWidget *menu_item = GTK_OPTION_MENU (option_menu)->menu_item;
}
</verb></tscreen>
But, there's a catch. For this specific case, you can <bf>not</bf> get
the label widget from <tt/menu_item/ with the above code, because the
option menu reparents the menu_item's child temporarily to display the
currently active contents. So to retrive the child of the currently
active menu_item of an option menu, you'll have to do:
<tscreen><verb>
if (GTK_BIN (option_menu)->child)
{
GtkWidget *child = GTK_BIN (option_menu)->child;
/* do stuff with child */
}
</verb></tscreen>
<!-- ----------------------------------------------------------------- -->
<sect1>How do I right (or otherwise) justify a GtkLabel?
<p>
Are you sure you want to <em>justify</em> the labels? The label class contains
the <tt/gtk_label_set_justify()/ function that is used to control the
justification of a multi-line label.
Are you sure you want to <em>justify</em> the labels? The label class
contains the <tt/gtk_label_set_justify()/ function that is used to
control the justification of a multi-line label.
What you probably want is to set the <em>alignment</em> of the label, ie right
align it, center it or left align it. If you want to do this, you
should use:
What you probably want is to set the <em>alignment</em> of the label,
ie right align it, center it or left align it. If you want to do this,
you should use:
<tscreen><verb>
void gtk_misc_set_alignment (GtkMisc *misc,
@ -2139,9 +2251,9 @@ widget, which can be done using:
<!-- ----------------------------------------------------------------- -->
<sect1>How do I configure Tooltips in a Resource File?
<p>
The tooltip's window is named "gtk-tooltips", GtkTooltips in itself is not
a GtkWidget (though a GtkObject) and as such is not attempted to match any
widget styles.
The tooltip's window is named "gtk-tooltips", GtkTooltips in itself is
not a GtkWidget (though a GtkObject) and as such is not attempted to
match any widget styles.
So, you resource file should look something like:
<verb>
@ -2185,6 +2297,78 @@ want to do. Typical code would be:
NULL);
</verb></tscreen>
<!-- ----------------------------------------------------------------- -->
<sect1>How do I validate/limit/filter the input to a GtkEntry?
<p>
If you want to validate the text that a user enters into a GtkEntry
widget you can attach to the "insert_text" signal of the entry, and
modify the text within the callback function. The example below forces
all characters to uppercase, and limits the range of characters to
A-Z. Note that the entry is cast to an object of type GtkEditable,
from which GtkEntry is derived.
<tscreen><verb>
#include <ctype.h>
#include <gtk/gtk.h>
void insert_text_handler (GtkEntry *entry,
const gchar *text,
gint length,
gint *position,
gpointer data)
{
GtkEditable *editable = GTK_EDITABLE(entry);
int i, count=0;
gchar *result = g_new (gchar, length);
for (i=0; i < length; i++) {
if (!isalpha(text[i]))
continue;
result[count++] = islower(text[i]) ? toupper(text[i]) : text[i];
}
if (count > 0) {
gtk_signal_handler_block_by_func (GTK_OBJECT (editable),
GTK_SIGNAL_FUNC (insert_text_handler),
data);
gtk_editable_insert_text (editable, result, count, position);
gtk_signal_handler_unblock_by_func (GTK_OBJECT (editable),
GTK_SIGNAL_FUNC (insert_text_handler),
data);
}
gtk_signal_emit_stop_by_name (GTK_OBJECT (editable), "insert_text");
g_free (result);
}
int main (int argc,
char *argv[])
{
GtkWidget *window;
GtkWidget *entry;
gtk_init (&amp;argc, &amp;argv);
/* create a new window */
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW (window), "GTK Entry");
gtk_signal_connect(GTK_OBJECT (window), "delete_event",
(GtkSignalFunc) gtk_exit, NULL);
entry = gtk_entry_new();
gtk_signal_connect(GTK_OBJECT(entry), "insert_text",
GTK_SIGNAL_FUNC(insert_text_handler),
NULL);
gtk_container_add(GTK_CONTAINER (window), entry);
gtk_widget_show(entry);
gtk_widget_show(window);
gtk_main();
return(0);
}
</verb></tscreen>
<!-- ----------------------------------------------------------------- -->
<sect1>How do I use horizontal scrollbars with a GtkText widget?
<p>
@ -2223,22 +2407,23 @@ load a font using, for example:
Notice that the response is valid for any object that inherits from the
GtkEditable class.
Are you sure that you want to move the cursor position? Most of the time,
while the cursor position is good, the insertion point does not match the
cursor position. If this apply to what you really want, then you should use
the <tt/gtk_text_set_point()/ function. If you want to set the insertion point
at the current cursor position, use the following:
Are you sure that you want to move the cursor position? Most of the
time, while the cursor position is good, the insertion point does not
match the cursor position. If this apply to what you really want, then
you should use the <tt/gtk_text_set_point()/ function. If you want to
set the insertion point at the current cursor position, use the
following:
<tscreen><verb>
gtk_text_set_point(GTK_TEXT(text),
gtk_editable_get_position(GTK_EDITABLE(text)));
gtk_editable_get_position(GTK_EDITABLE(text)));
</verb></tscreen>
If you want the insertion point to follow the cursor at all time, you
should probably catch the button press event, and then move the
insertion point. Be careful : you'll have to catch it after the widget
has changed the cursor position though. Thomas Mailund Jensen proposed the
following code:
insertion point. Be careful : you'll have to catch it after the widget
has changed the cursor position though. Thomas Mailund Jensen proposed
the following code:
<tscreen><verb>
static void
@ -2246,7 +2431,7 @@ insert_bar (GtkWidget *text)
{
/* jump to cursor mark */
gtk_text_set_point (GTK_TEXT (text),
gtk_editable_get_position (GTK_EDITABLE (text)));
gtk_editable_get_position (GTK_EDITABLE (text)));
gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL,
"bar", strlen ("bar"));
@ -2285,12 +2470,12 @@ Now, if you really want to change the cursor position, you should use the
<!-- ----------------------------------------------------------------- -->
<sect1>What is GDK?
<p>
GDK is basically a wrapper around the standard Xlib function calls. If you are
at all familiar with Xlib, a lot of the functions in GDK will require little
or no getting used to. All functions are written to provide an way
to access Xlib functions in an easier and slightly more intuitive manner.
In addition, since GDK uses GLib (see below), it will be more portable
and safer to use on multiple platforms.
GDK is basically a wrapper around the standard Xlib function calls. If
you are at all familiar with Xlib, a lot of the functions in GDK will
require little or no getting used to. All functions are written to
provide an way to access Xlib functions in an easier and slightly more
intuitive manner. In addition, since GDK uses GLib (see below), it
will be more portable and safer to use on multiple platforms.
<!-- Examples, anybody? I've been mulling some over. NF -->
@ -2425,24 +2610,76 @@ reference on the first node of the list.
<!-- I believe it should be better :) ED -->
<!-- Linked lists are pretty standard data structures - don't want to
over do it - TRG -->
<!-- ----------------------------------------------------------------- -->
<sect1>Memory does not seem to be released when I free the list nodes I've allocated
<p>
GLib tries to be "intelligent" on this special issue: it assumes that
you are likely to reuse the objects, so caches the allocated memory.
If you do not want to use this behavior, you'll probably want to set
up a special allocator.
To quote Tim Janik:
<quote>
If you have a certain portion of code that uses *lots* of GLists or
GNodes, and you know you'd better want to release all of them after a
short while, you'd want to use a GAllocator. Pushing an allocator into
g_list will make all subsequent glist operations private to that
allocator's memory pool (and thus you have to take care to pop the
allocator again, before making any external calls):
</quote>
<tscreen><verb>
GAllocator *allocator;
GList *list = NULL;
guint i;
/* set a new allocation pool for GList nodes */
allocator = g_allocator_new ("list heap", 1024);
g_list_push_allocator (allocator);
/* do some list operations */
for (i = 0; i < 4096; i++)
list = g_list_prepend (list, NULL);
list = g_list_reverse (list);
/* beware to pop allocator befor calling external functions */
g_list_pop_allocator ();
gtk_label_set_text (GTK_LABEL (some_label), "some text");
/* and set our private glist pool again */
g_list_push_allocator (allocator);
/* do some list operations */
g_list_free (list);
list = NULL;
for (i = 0; i < 4096; i++)
list = g_list_prepend (list, NULL);
/* and back out (while freeing all of the list nodes in our pool) */
g_list_pop_allocator ();
g_allocator_free (allocator);
</verb></tscreen>
<!-- ----------------------------------------------------------------- -->
<sect1>Why use g_print, g_malloc, g_strdup and fellow glib functions?
<p>
Thanks to Tim Janik who wrote to gtk-list: (slightly modified)
<quote>
Regarding g_malloc(), g_free() and siblings, these functions are much safer
than their libc equivalents. For example, g_free() just returns if called
with NULL. Also, if USE_DMALLOC is defined, the definition for these
functions changes (in glib.h) to use MALLOC(), FREE() etc... If MEM_PROFILE
or MEM_CHECK are defined, there are even small statistics made counting
the used block sizes (shown by g_mem_profile() / g_mem_check()).
<P>
Regarding g_malloc(), g_free() and siblings, these functions are much
safer than their libc equivalents. For example, g_free() just returns
if called with NULL. Also, if USE_DMALLOC is defined, the definition
for these functions changes (in glib.h) to use MALLOC(), FREE() etc...
If MEM_PROFILE or MEM_CHECK are defined, there are even small
statistics made counting the used block sizes (shown by
g_mem_profile() / g_mem_check()).
<p>
Considering the fact that glib provides an interface for memory chunks
to save space if you have lots of blocks that are always the same size
and to mark them ALLOC_ONLY if needed, it is just straight forward to
create a small saver (debug able) wrapper around the normal malloc/free
stuff as well - just like gdk covers Xlib. ;)
<P>
<p>
Using g_error() and g_warning() inside of applications like the GIMP
that fully rely on gtk even gives the opportunity to pop up a window
showing the messages inside of a gtk window with your own handler
@ -2626,7 +2863,8 @@ main (int argc, char *argv[])
You need to understand that the scanner will parse its input and
tokenize it, it is up to you to interpret these tokens, not define
their types before they get parsed, e.g. watch gscanner parse a string:
their types before they get parsed, e.g. watch gscanner parse a
string:
<verb>
"hi i am 17"
@ -2711,8 +2949,8 @@ This FAQ was created by Shawn T. Amundson
<htmlurl url="mailto:amundson@gimp.org"
name="&lt;amundson@gimp.org&gt;"> who continues to provide support.
Contributions should be sent to Tony Gale <htmlurl url="mailto:gale@gtk.org"
name="&lt;gale@gtk.org&gt;">
Contributions should be sent to Tony Gale <htmlurl
url="mailto:gale@gtk.org" name="&lt;gale@gtk.org&gt;">
The GTK+ FAQ is Copyright (C) 1997-2000 by Shawn T. Amundson,
Tony Gale, Emmanuel Deloget and Nathan Froyd.