1 <!doctype linuxdoc system>
5 <!-- Title information -->
9 <!-- NOTE: Use only one author tag, otherwise sgml2txt barfs - TRG -->
10 <author>Tony Gale, Shawn T. Amundson, Emmanuel Deloget, Nathan Froyd
12 <date>October 30th 1999
14 <abstract> This document is intended to answer questions that are likely to be
15 frequently asked by programmers using GTK+ or people who are just looking at
19 <!-- Table of contents -->
22 <!-- Begin the document -->
24 <!-- ***************************************************************** -->
25 <sect>General Information
27 <!-- ----------------------------------------------------------------- -->
28 <sect1>Before anything else: the greetings
30 The FAQ authors want to thank:
32 <item>Havoc Pennington
36 <item>Thomas Mailund Jensen
39 <item>Federico Mena Quintero
41 <item>and all the members of the GTK+ lists
43 If we forgot you, please email us !
44 Thanks again (I know, it's really short :)
46 <!-- ----------------------------------------------------------------- -->
49 The original authors of GTK+ were:
57 Since then, much has been added by others. Please see the AUTHORS
58 file in the distribution for the GTK+ Team.
60 <!-- ----------------------------------------------------------------- -->
63 GTK+ is a small and efficient widget set designed with the general
64 look and feel of Motif. In reality, it looks much better than Motif.
65 It contains common widgets and some more complex widgets such as a
66 file selection, and color selection widgets.
68 GTK+ provides some unique features. (At least, I know of no other
69 widget library which provides them). For example, a button does not
70 contain a label, it contains a child widget, which in most instances
71 will be a label. However, the child widget can also be a pixmap,
72 image or any combination possible the programmer desires. This
73 flexibility is adhered to throughout the library.
75 <!-- ----------------------------------------------------------------- -->
76 <sect1>What is the + in GTK+?
78 Peter Mattis informed the gtk mailing list that:
80 "I originally wrote gtk which included the three libraries, libglib,
81 libgdk and libgtk. It featured a flat widget hierarchy. That is, you
82 couldn't derive a new widget from an existing one. And it contained
83 a more standard callback mechanism instead of the signal mechanism now
84 present in gtk+. The + was added to distinguish between the original
85 version of gtk and the new version. You can think of it as being an
86 enhancement to the original gtk that adds object oriented features."
89 <!-- ----------------------------------------------------------------- -->
90 <sect1>Does the G in GTK+, GDK and GLib stand for?
94 GDK == Gtk+ Drawing Kit
98 <!-- ----------------------------------------------------------------- -->
99 <sect1>Where is the documentation for GTK+?
101 In the GTK+ distribution's doc/ directory you will find the
102 reference material for both GTK and GDK, this FAQ and the
105 In addition, you can find links to HTML versions of these documents
106 by going to <htmlurl url="http://www.gtk.org/"
107 name="http://www.gtk.org/">. A packaged version of the GTK Tutorial,
108 with SGML, HTML, Postscript, DVI and text versions can be found in
109 <htmlurl url="ftp://ftp.gtk.org/pub/gtk/tutorial"
110 name="ftp://ftp.gtk.org/pub/gtk/tutorial">
112 There are now a couple of books available that deal with programming
115 <item> Eric Harlows book entitled "Developing Linux Applications with
116 GTK+ and GDK". The ISBN is 0-7357-0021-4
118 The example code from Eric's book is available on-line at
119 <htmlurl url="http://www.bcpl.net/~eharlow/book"
120 name="http://www.bcpl.net/~eharlow/book">
122 <item> Havoc Pennington has released a book called "GTK+/GNOME
123 Application Development". The ISBN is 0-7357-0078-8
125 The free version of the book lives here:
126 <htmlurl url="http://developer.gnome.org/doc/GGAD/"
127 name="http://developer.gnome.org/doc/GGAD/">
129 And Havoc maintains information about it and errata here:
130 <htmlurl url="http://pobox.com/~hp/gnome-app-devel.html"
131 name="http://pobox.com/~hp/gnome-app-devel.html">
134 <!-- ----------------------------------------------------------------- -->
135 <sect1>Is there a mailing list (or mailing list archive) for GTK+?
137 Information on mailing lists relating to GTK+ can be found at:
139 <htmlurl url="http://www.gtk.org/mailinglists.html"
140 name="http://www.gtk.org/mailinglists.html">
142 <!-- ----------------------------------------------------------------- -->
143 <sect1>How to get help with GTK+
145 First, make sure your question isn't answered in the documentation,
146 this FAQ or the tutorial. Done that? You're sure you've done that,
147 right? In that case, the best place to post questions is to the GTK+
150 <!-- ----------------------------------------------------------------- -->
151 <sect1>How to report bugs in GTK+
153 Bugs should be reported to the GNOME bug tracking
154 system (<htmlurl url="http://bugs.gnome.org"
155 name="http://bugs.gnome.org">). To report a problem about GTK+, send
156 mail to submit@bugs.gnome.org.
158 The subject of the mail should describe your problem. In the body of
159 the mail, you should first include a "pseudo-header" that gives the
160 package and version number. This should be separated by a blank line
161 from the actual headers.
168 Substitute 1.2.0 with the version of GTK+ that you have installed.
170 Then describe the bug. Include:
173 <item> Information about your system. For instance:
175 <item> What operating system and version
176 <item> What version of X
177 <item> For Linux, what version of the C library
179 And anything else you think is relevant.
181 <item> How to reproduce the bug.
183 If you can reproduce it with the testgtk program that is built in
184 the gtk/ subdirectory, that will be most convenient. Otherwise,
185 please include a short test program that exhibits the behavior. As
186 a last resort, you can also provide a pointer to a larger piece of
187 software that can be downloaded.
189 (Bugs that can be reproduced within the GIMP are almost as good as
190 bugs that can be reproduced in testgtk. If you are reporting a bug
191 found with the GIMP, please include the version number of the GIMP
194 <item> If the bug was a crash, the exact text that was printed out
195 when the crash occured.
197 <item> Further information such as stack traces may be useful, but are
198 not necessary. If you do send a stack trace, and the error is an X
199 error, it will be more useful if the stacktrace is produced running
200 the test program with the <tt/--sync/ command line option.
203 <!-- ----------------------------------------------------------------- -->
204 <sect1>Is there a Windows version of GTK+?
206 There is an on going port of GTK+ to the Windows platform which is
207 making impressive progress.
209 See <htmlurl url="http://www.iki.fi/tml/gimp/win32"
210 name="http://www.iki.fi/tml/gimp/win32"> for more information.
212 <!-- ----------------------------------------------------------------- -->
213 <sect1>What applications have been written with GTK+?
215 A list of some GTK+ based application can be found on the GTK+ web
216 server at <htmlurl url="http://www.gtk.org/apps/"
217 name="http://www.gtk.org/apps/"> and contains more than 350
220 Failing that, look for a project to work on for the GNOME project,
221 <htmlurl url="http://www.gnome.org/" name="http://www.gnome.org/">
222 Write a game. Write something that is useful.
226 <item>GIMP (<htmlurl url="http://www.gimp.org/"
227 name="http://www.gimp.org/">),
228 an image manipulation program
229 <item>AbiWord (<htmlurl url="http://www.abisource.com/"
230 name="http://www.abisource.com/">),
231 a professional word processor
232 <item>GUBI (<htmlurl url="http://www.SoftHome.net/pub/users/timj/gubi/index.htm"
233 name="http://www.SoftHome.net/pub/users/timj/gubi/index.htm">),
234 a user interface builder
235 <item>Gzilla (<htmlurl url="http://www.levien.com/gzilla/"
236 name="http://www.levien.com/gzilla/">),
238 <item>SANE (<htmlurl url="http://www.azstarnet.com/~axplinux/sane/"
239 name="http://www.azstarnet.com/~axplinux/sane/"> ),
240 a universal scanner interface
241 <item>XQF (<htmlurl url="http://www.botik.ru/~roma/quake/"
242 name="http://www.botik.ru/~roma/quake/">),
243 a QuakeWorld/Quake2 server browser and launcher
244 <item>ElectricEyes (<htmlurl url="http://www.labs.redhat.com/ee.shtml"
245 name="http://www.labs.redhat.com/ee.shtml">),
246 an image viewer that aims to be a free replacement for xv
247 <item>GPK - the General Proxy Kit (<htmlurl url="http://www.humanfactor.com/gpk/"
248 name="http://www.humanfactor.com/gpk/">),
249 an add-on library to permit thread-safe access to GTK+
250 <item>GCK - the General Convenience Kit (<htmlurl url="http://www.ii.uib.no/~tomb/gck.html"
251 name="http://www.ii.uib.no/~tomb/gck.html">),
252 miscellaneous functions intended to ease color handling, UI construction,
253 vector operations, and math functions
254 <item>GDK Imlib (<htmlurl url="http://www.labs.redhat.com/imlib/"
255 name="http://www.labs.redhat.com/imlib/">),
256 a fast image loading and manipulation library for GDK
257 <item>Glade (<htmlurl url="http://glade.pn.org/"
258 name="http://glade.pn.org/">),
259 a GTK+ based RAD tool which produces GTK+ applications
262 In addition to the above, the GNOME project (<htmlurl
263 url="http://www.gnome.org" name="http://www.gnome.org">) is using GTK+
264 to build a free desktop for Linux. Many more programs can be found
267 <!-- ----------------------------------------------------------------- -->
268 <sect1>I'm looking for an application to write in GTK+. How about an IRC client?
271 Ask on gtk-list for suggestions. There are at least three IRC clients
272 already under development (probably more in fact. The server at
273 <htmlurl url="http://www.forcix.cx/irc-clients.html"
274 name="http://www.forcix.cx/irc-clients.html"> list a bunch of them).
278 <item>girc. (Included with GNOME)
279 <item>gsirc. (In the gnome CVS tree)
282 <!-- ***************************************************************** -->
283 <sect>How to find, configure, install, and troubleshoot GTK+
285 <!-- ***************************************************************** -->
287 <!-- ----------------------------------------------------------------- -->
288 <sect1>What do I need to run GTK+?
290 To compile GTK+, all you need is a C compiler (gcc) and the X Window System
291 and associated libraries on your system.
293 <!-- ----------------------------------------------------------------- -->
294 <sect1>Where can I get GTK+?
296 The canonical site is:
298 ftp://ftp.gtk.org/pub/gtk
300 This site tends to get busy around the time of a new GTK+ release
301 so try and use one of the mirror sites that are listed in
302 <htmlurl url="ftp://ftp.gtk.org/etc/mirrors"
303 name="ftp://ftp.gtk.org/etc/mirrors">
305 Here's a few mirror sites to get you started:
307 <item>Africa - ftp://ftp.is.co.za/applications/gimp/
308 <item>Australia - ftp://ftp.au.gimp.org/pub/gimp/
309 <item>Finland - ftp://ftp.funet.fi/pub/sci/graphics/packages/gimp
310 <item>Germany - ftp://infosoc.uni-koeln.de/pub/ftp.gimp.org/
311 <item>Japan - ftp://SunSITE.sut.ac.jp/pub/archives/packages/gimp/
312 <item>UK - ftp://ftp.flirble.org/pub/X/gimp/
313 <item>US - ftp://ftp.insync.net/pub/mirrors/ftp.gimp.org/
316 <sect1>How do I configure/compile GTK+?
318 Generally, all you will need to do is issue the commands:
323 in the gtk+-version/ directory.
325 <!-- ----------------------------------------------------------------- -->
326 <sect1>When compiling GTK+ I get an error like:
327 <tt/make: file `Makefile' line 456: Syntax error/
329 Make sure that you are using GNU make (use <tt/make -v/ to check). There are
330 many weird and wonderful versions of make out there, and not all of them
331 handle the automatically generated Makefiles.
333 <!-- ----------------------------------------------------------------- -->
335 <sect1>I've compiled and installed GTK+, but I can't get any programs to link with it!
337 This problem is most often encountered when the GTK+ libraries can't be
338 found or are the wrong version. Generally, the compiler will complain about an
339 'unresolved symbol'. There are two things you need to check:
341 <item>Make sure that the libraries can be found. You want to edit
342 /etc/ld.so.conf to include the directories which contain the GTK libraries,
343 so it looks something like:
348 Then you need to run /sbin/ldconfig as root. You can find what directory
354 If your system doesn't use ld.so to find libraries (such as Solaris), then
355 you will have to use the LD_LIBRARY_PATH environment variable (or compile
356 the path into your program, which I'm not going to cover here). So, with a
357 Bourne type shell you can do (if your GTK libraries are in /usr/local/lib):
359 export LD_LIBRARY_PATH=/usr/local/lib
361 and in a csh, you can do:
363 setenv LD_LIBRARY_PATH /usr/local/lib
366 <item>Make sure the linker is finding the correct set of libraries. If you
367 have a Linux distribution that installs GTK+ (e.g. RedHat 5.0) then this
368 older version may be used. Now (assuming you have a RedHat
369 system), issue the command
373 You may also want to remove the packages that depend on gtk (rpm will tell you
374 which ones they are). If you don't have a RedHat Linux system, check to make sure
375 that neither <verb>/usr/lib</verb> or <verb>/usr/local/lib</verb> contain any of
376 the libraries libgtk, libgdk, libglib, or libgck. If they do exist, remove them
377 (and any gtk include files, such as /usr/include/gtk and /usr/include/gdk)
381 <!-- ----------------------------------------------------------------- -->
382 <sect1>When compiling programs with GTK+, I get compiler error messages about not being able to find <tt/"glibconfig.h"/.
384 The header file "glibconfig.h" was moved to the directory
385 $exec_prefix/lib/glib/include/. $exec_prefix is the
386 directory that was specified by giving the --exec-prefix
387 flags to ./configure when compiling GTK+. It defaults to
388 $prefix, (specified with --prefix), which in turn defaults
391 This was done because "glibconfig.h" includes architecture
392 dependent information, and the rest of the include files
393 are put in $prefix/include, which can be shared between different
396 GTK+ includes a shell script, <tt/gtk-config/, that
397 makes it easy to find out the correct include paths.
398 The GTK+ tutorial includes an example of using <tt/gtk-config/
399 for simple compilation from the command line. For information
400 about more complicated configuration, see the file
401 docs/gtk-config.txt in the GTK+ distribution.
403 If you are trying to compile an old program, you may
404 be able to work around the problem by configuring it
405 with a command line like:
408 CPPFLAGS="-I/usr/local/include/glib/include" ./configure
411 for Bourne-compatible shells like bash, or for csh variants:
414 setenv CPPFLAGS "-I/usr/local/include/glib/include"
418 (Substitute the appropriate value of $exec_prefix for /usr/local.)
420 <!-- ----------------------------------------------------------------- -->
421 <sect1>When installing a GTK+ application, configure reports that it can't find GTK.
423 There are several common reasons for this:
425 <item>You have an old version of GTK installed somewhere. RedHat 5.0, for
426 example, installs an older copy of GTK that may not work with the latest
427 applications. You should remove this old copy, but note that in the case
428 of RedHat 5.0 this will break the <tt/control-panel/ applications.
430 <item><tt/gtk-config/ (or another component of GTK) isn't in your path, or
431 there is an old version on your system. Type:
435 to check for both of these. If it returns a value different from what
436 you expect, then you have an old version of GTK on your system.
438 <item>The ./configure script can't find the GTK libraries. As ./configure
439 compiles various test programs, it needs to be able to find the GTK
440 libraries. See the question above for help on this.
443 If none of the above help, then have a look in config.log, which is
444 generated by ./configure as it runs. At the bottom will be the last
445 action it took before failing. If it is a section of source code, copy
446 the source code to a file and compile it with the line just above it in
447 config.log. If the compilation is successful, try executing it.
449 <!-- ***************************************************************** -->
450 <sect>Development of GTK+
451 <!-- ***************************************************************** -->
453 <!-- ----------------------------------------------------------------- -->
454 <sect1>Whats this CVS thing that everyone keeps talking about, and how do I access it?
456 CVS is the Concurent Version System and is a very popular means of
457 version control for software projects. It is designed to allow multiple
458 authors to be able to simultanously operate on the same source tree.
459 This source tree is centrally maintained, but each developer has a
460 local mirror of this repository that they make there changes to.
462 The GTK+ developers use a CVS repository to store the master copy of
463 the current development version of GTK+. As such, people wishing to
464 contribute patches to GTK+ should generate them against the CVS version.
465 Normal people should use the packaged releases.
467 The CVS toolset is available as RPM packages from the usual RedHat sites.
468 The latest version is available at
469 <htmlurl url="http://download.cyclic.com/pub/"
470 name="<http://download.cyclic.com/pub/>">
472 Anyone can download the latest CVS version of GTK+ by using anonymous access
473 using the following steps:
475 <item> In a bourne shell descendant (e.g. bash) type:
477 CVSROOT=':pserver:anonymous@anoncvs.gnome.org:/cvs/gnome'
480 <item>Next, the first time the source tree is checked out, a cvs login
485 This will ask you for a password. There is no password for cvs.gimp.org,
486 so just enter a carriage return.
487 <item>To get the tree and place it in a subdir of your current working
488 directory, issue the command:
493 Note that with the GTK+ 1.1 tree, glib has been moved to a separate CVS
494 module, so if you don't have glib installed you will need to get that
501 <!-- ----------------------------------------------------------------- -->
502 <sect1>How can I contribute to GTK+?
504 It's simple. If something doesn't work like you think it should in a program,
505 check the documentation to make sure you're not missing something. If it is a
506 true bug or missing feature, track it down in the GTK+ source, change it,
507 and then generate a patch in the form of a 'context diff'. This can be done
508 using a command such as <tt/diff -ru <oldfile> <newfile>/.
509 Then upload the patchfile to:
511 ftp://ftp.gtk.org/incoming
513 along with a README file. Make sure you follow the naming conventions or your
514 patch will just be deleted! The filenames should be of this form:
516 gtk-<username>-<date yymmdd-n>.patch.gz
517 gtk-<username>-<date yymmdd-n>.patch.README
519 The "n" in the date indicates a unique number (starting from 0)
520 of patches you uploaded that day. It should be 0, unless you
521 upload more than one patch in the same day.
525 gtk-gale-982701-0.patch.gz
526 gtk-gale-982701-0.patch.README
528 Once you upload <em>anything</em>, send the README to ftp-admin@gtk.org
530 <!-- ----------------------------------------------------------------- -->
531 <sect1>How do I know if my patch got applied, and if not, why not?
533 Uploaded patches will be moved to <tt>ftp://ftp.gtk.org/pub/gtk/patches</tt>
534 where one of the GTK+ development team will pick them up. If applied, they
535 will be moved to <tt>/pub/gtk/patches/old</tt>.
537 Patches that aren't applied, for whatever reason, are moved to
538 <tt>/pub/gtk/patches/unapplied</tt> or <tt>/pub/gtk/patches/outdated</tt>.
539 At this point you can ask on the <tt/gtk-list/ mailing list why your patch
540 wasn't applied. There are many possible reasons why patches may not be
541 applied, ranging from it doesn't apply cleanly, to it isn't right. Don't
542 be put off if your patch didn't make it first time round.
544 <!-- ----------------------------------------------------------------- -->
545 <sect1>What is the policy on incorporating new widgets into the library?
547 This is up to the authors, so you will have to ask them once you
548 are done with your widget. As a general guideline, widgets that are
549 generally useful, work, and are not a disgrace to the widget set will
552 <!-- ----------------------------------------------------------------- -->
553 <sect1>Is anyone working on bindings for languages other than C?
555 The GTK+ home page (<htmlurl url="http://www.gtk.org/"
556 name="http://www.gtk.org/">) presents a list of GTK+ bindings.
559 <item>There are several C++ wrappers for GTK+.
562 <item>the gtk-- package, which is a very small wrapper for GTK+.
563 You can find the home page at:
564 <htmlurl url="http://www.cs.tut.fi/~p150650/gtk/gtk--.html"
565 name="http://www.cs.tut.fi/~p150650/gtk/gtk--.html">.
567 <htmlurl url="ftp://ftp.gtk.org/pub/gtk/gtk--"
568 name="ftp://ftp.gtk.org/pub/gtk/gtk--">.
570 <item>the VDK package, which was built as the base package of a GTK+
571 application Borland-like builder. The home page can be found at
572 <htmlurl url="www.guest.net/homepages/mmotta/VDKHome"
573 name="www.guest.net/homepages/mmotta/VDKHome">.
575 <item>The wxWindows/Gtk package, a free C++ library for cross-platform
576 GUI development. The home page of this package is
577 <htmlurl url="http://www.freiburg.linux.de/~wxxt/"
578 name="http://www.freiburg.linux.de/~wxxt/">.
583 <item>There are three known Objective-c bindings currently in development:
587 <item>The <htmlurl url="http://www.gnome.org/" name="GNOME project's"> package
588 of choice is objgtk. Objgtk is based on the Object class and is maintained by
589 <htmlurl url="mailto:sopwith@cuc.edu" name="Elliot Lee">. Apparently, objgtk
590 is being accepted as the `standard' Objective-C binding for GTK+.
592 <item>If you are more inclined towards the
593 <htmlurl url="http://www.gnustep.org/" name="GNUstep project">,
594 you may want to check out GTKKit by
595 <htmlurl url="mailto:helge@mdlink.de" name="Helge Heß">.
596 The intention is to setup a GTK+ binding using the FoundationKit.
597 GTKKit includes nicities like writing a XML-type template file to
598 construct a GTK+ interface.
600 <item>The GToolKit package, which can be found at
601 <htmlurl url="ftp://ftp.gtk.org/pub/gtk/objc-gtoolkit/"
602 name="ftp://ftp.gtk.org/pub/gtk/objc-gtoolkit/">.
607 <htmlurl url="ftp://ftp.gtk.org/pub/gtk/perl"
608 name="ftp://ftp.gtk.org/pub/gtk/perl">
610 <item>Guile bindings. The home page is at
611 <htmlurl url="http://www.ping.de/sites/zagadka/guile-gtk"
612 name="http://www.ping.de/sites/zagadka/guile-gtk">.
613 By the way, Guile is the GNU Project's implemention of R4RS Scheme (the
614 standard). If you like Scheme, you may want to take a look at this.
617 <item>David Monniaux reports:
618 <quote>I've started a gtk-O'Caml binding system.
619 The basics of the system, including callbacks, work fine.
621 The current development is in
622 <htmlurl url="http://www.ens-lyon.fr/~dmonniau/arcs"
623 name="http://www.ens-lyon.fr/~dmonniau/arcs">
626 <item> Several python bindings have been done:
630 <htmlurl url="http://www.daa.com.au/~james/pygtk"
631 name="http://www.daa.com.au/~james/pygtk"> and
632 <htmlurl url="ftp://ftp.gtk.org/pub/gtk/python"
633 name="ftp://ftp.gtk.org/pub/gtk/python">
635 <item>python-gtk is at
636 <htmlurl url="http://www.ucalgary.ca/~nascheme/python-gtk"
637 name="http://www.ucalgary.ca/~nascheme/python-gtk">
640 <item>There's are a couple of OpenGL/Mesa widgets available for
641 GTK+. I suggest you start at
642 <htmlurl url="http://www.student.oulu.fi/~jlof/gtkglarea/index.html"
643 name="http://www.student.oulu.fi/~jlof/gtkglarea/index.html">
645 <item>Last, there are a lot of other language bindings for languages such as
646 Eiffel, TOM, Pascal, Pike, etc.
650 <!-- ***************************************************************** -->
651 <sect>Development with GTK+: the begining
652 <!-- ***************************************************************** -->
653 <!-- ----------------------------------------------------------------- -->
654 <sect1>How do I get started?
656 So, after you have installed GTK+ there are a couple of things that can
657 ease you into developing applications with it. There is the
658 GTK+ Tutorial <htmlurl url="http://www.gtk.org/tutorial/"
659 name="<http://www.gtk.org/tutorial/>">, which is undergoing
660 development. This will introduce you to writing applications using C.
662 The Tutorial doesn't (yet) contain information on all of the widgets
663 that are in GTK+. For example code on how to use the basics of all the
664 GTK+ widgets you should look at the file gtk/testgtk.c (and associated
665 source files) within the GTK+ distribution. Looking at these examples will
666 give you a good grounding on what the widgets can do.
668 <!-- ----------------------------------------------------------------- -->
669 <sect1>I tried to compile a small <tt/Hello World/ of mine, but it failed. Any clue?
671 Since you are good at coding, we will not deal with compile time error here :).
673 The classic command line to compile a GTK+ based program is
676 gcc -o myprg [c files list] `gtk-config --cflags --libs`
679 You should notice the backquote character which is used in this command line.
680 A common mistake when you start a GTK+ based development is to use quote
681 instead of backquotes. If you do so, the compiler will complain about an
682 unknown file called 'gtk-config --cflags --libs'. The text in
683 backquotes is an instruction to your shell to substitute the output of
684 executing this text into the command line.
686 The command line above ensure that:
689 <item>the correct C compiler flags will be used to compile the program
690 (including the complete C header directory list)
692 <item>your program will be linked with the needed libraries.
696 <sect1>What about using the <tt/make/ utility?
698 This is a sample makefile which compile a GTK+ based program:
701 # basic GTK+ app makefile
702 SOURCES = myprg.c foo.c bar.c
703 OBJS = ${SOURCES:.c=.o}
704 CFLAGS = `gtk-config --cflags`
705 LDADD = `gtk-config --libs`
710 ${CC} -o ${PACKAGE} ${OBJS} ${LDADD}
713 ${CC} ${CFLAGS} -c $<
718 For more information about the <tt/make/ utility, you should read either the
719 related man page or the relevant info file.
721 <sect1>I use the backquote stuff in my makefiles, but my make process failed.
723 The backquote construction seems to not be accepted by some old <tt/make/
724 utilities. If you use one of these, the make process will probably fail.
725 In order to have the backquote syntax working again, you should use the
726 GNU make utility (get it on the GNU ftp server at
727 <htmlurl url="ftp://ftp.gnu.org/" name="ftp://ftp.gnu.org/">).
729 <!-- ----------------------------------------------------------------- -->
730 <sect1>I want to add some configure stuff, how could I do this?
732 To use autoconf/automake, you must first install the relevant packages. These
736 <item>the m4 preprocessor v1.4 or better
737 <item>autoconf v2.13 or better
738 <item>automake v1.4 or better
741 You'll find these packages on the GNU main ftp server (<htmlurl
742 url="ftp://ftp.gnu.org/" name="ftp://ftp.gnu.org/">) or on any GNU mirror.
744 In order to use the powerfull autoconf/automake scheme, you must create
745 a configure.in which may look like:
748 dnl Process this file with autoconf to produce a configure script.
749 dnl configure.in for a GTK+ based program
752 AM_INIT_AUTOMAKE(mypkbname,0.0.1)dnl
753 AM_CONFIG_HEADER(config.h)dnl
755 dnl Checks for programs.
756 AC_PROG_CC dnl check for the c compiler
757 dnl you should add CFLAGS="" here, 'cos it is set to -g by PROG_CC
759 dnl Checks for libraries.
760 AM_PATH_GTK(1.2.0,,AC_MSG_ERROR(mypkgname 0.1 needs GTK))dnl
767 You must add a Makefile.am file:
771 myprg_SOURCES = myprg.c foo.c bar.c
772 INCLUDES = @GTK_CFLAGS@
775 DISTCLEANFILES = .deps/*.P
778 then, to use these, simply type the following commands:
784 automake --add-missing --include-deps --foreign
787 For further informations, you should look at the autoconf and the automake
788 documentation (the shipped info files are really easy to understand, and there
789 are plenty of web resources that deal with autoconf and/or automake).
791 <!-- ----------------------------------------------------------------- -->
792 <sect1>I try to debug my GTK+ application with gdb, but it hangs my X server when I hit some breakpoint. Any Idea ?
794 From Federico Mena Quintero:
796 X is not locked up. It is likely that you are hitting a breakpoint
797 inside a callback that is called from a place in Gtk that has a mouse
800 Run your program with the "--sync" option; it will make it easier to
801 debug. Also, you may want to use the console for running the
802 debugger, and just let the program run in another console with the X
806 Eric Mouw had another solution:
808 An old terminal connected to an otherwise unused serial port is also great
809 for debugging X programs. Old vt100/vt220 terminals are dirt cheap but a
810 bit hard to get (here in The Netherlands, YMMV).
813 <!-- ***************************************************************** -->
814 <sect>Development with GTK+: general questions
815 <!-- ***************************************************************** -->
816 <!-- ----------------------------------------------------------------- -->
817 <sect1>What widgets are in GTK?
819 The GTK+ Tutorial lists the following widgets:
832 | | | `GtkAspectFrame
837 | | | | `GtkCheckMenuItem
838 | | | | `GtkRadioMenuItem
842 | | +GtkColorSelectionDialog
844 | | | `GtkInputDialog
845 | | `GtkFileSelection
854 | | +GtkColorSelection
905 <!-- ----------------------------------------------------------------- -->
906 <sect1>Is GTK+ thread safe? How do I write multi-threaded GTK+ applications?
908 The GLib library can be used in a thread-safe mode by calling
909 g_thread_init() before making any other GLib calls. In this mode GLib
910 automatically locks all internal data structures as needed. This
911 does not mean that two threads can simultaneously access, for
912 example, a single hash table, but they can access two different hash
913 tables simultaneously. If two different threads need to access the
914 same hash table, the application is responsible for locking
917 When GLib is intialized to be thread-safe, GTK+ is
918 <em>thread aware</em>. There is a single global lock
919 that you must acquire with gdk_threads_enter() before
920 making any GDK calls, and release with gdk_threads_leave()
923 A minimal main program for a threaded GTK+ application
928 main (int argc, char *argv[])
933 gtk_init(&argc, &argv);
935 window = create_window();
936 gtk_widget_show(window);
946 Callbacks require a bit of attention. Callbacks from GTK+
947 (signals) are made within the GTK+ lock. However callbacks
948 from GLib (timeouts, IO callbacks, and idle functions)
949 are made outside of the GTK+ lock. So, within a signal
950 handler you do not need to call gdk_threads_enter(), but
951 within the other types of callbacks, you do.
953 <!-- This is the old answer - TRG
956 Although GTK+, like many X toolkits, isn't thread safe, this does
957 not prohibit the development of multi-threaded applications with
960 Rob Browning (rlb@cs.utexas.edu) describes threading techniques for
961 use with GTK+ (slightly edited):
963 There are basically two main approaches, the first is simple, and the
964 second complicated. In the first, you just make sure that all GTK+ (or
965 X) interactions are handled by one, and
966 only one, thread. Any other thread that wants to draw something has
967 to somehow notify the "GTK+" thread, and let it handle the
970 The second approach allows you to call GTK+ (or X) functions from any
971 thread, but it requires some careful synchronization. The
972 basic idea is that you create an X protection mutex, and no one may
973 make any X calls without first acquiring this mutex.
975 Note that this is a little effort, but it allows you to be
976 potentially more efficient than a completely thread safe GTK+. You
977 get to decide the granularity of the thread locking. You also have to
978 make sure that the thread that calls <tt/gtk_main()/ is holding the lock when
979 it calls <tt/gtk_main()/.
981 The next thing to worry about is that since you were holding the
982 global mutex when you entered <tt/gtk_main()/, all callbacks will also be
983 holding it. This means that the callback must release it if it's
984 going to call any other code that might reacquire it. Otherwise
985 you'll get deadlock. Also, you must be holding the mutex when you
986 finally return from the callback.
988 In order to allow threads other than the one calling <tt/gtk_main/ to
989 get access to the mutex, we also need to register a work function
990 with GTK that allows us to release the mutex periodically.
992 Why can't GTK+ be thread safe by default?
994 Complexity, overhead, and manpower. The proportion of threaded
995 programs is still reasonably small, and getting thread safety right is
996 both quite difficult and takes valuable time away from the main work
997 of getting a good graphics library finished. It would be nice to have
998 GTK+ thread safe "out of the box", but that's not practical right now,
999 and it also might make GTK+ substantially less efficient if not handled
1002 Regardless, it's especially not a priority since relatively good
1003 workarounds exist. -->
1004 <!-- ----------------------------------------------------------------- -->
1005 <sect1>Why do this strange 'x io error' occur when I <tt/fork()/ in my GTK+ app?
1007 This is not really a GTK+ problem, and the problem is not related to <tt/fork()/
1008 either. If the 'x io error' occurs then you probably use the <tt/exit()/ function
1009 in order to exit from the child process.
1011 When GDK opens an X display, it creates a socket file descriptor. When you use
1012 the <tt/exit()/ function, you implicitly close all the open file descriptors,
1013 and the underlying X library really doesn't like this.
1015 The right function to use here is <tt/_exit()/.
1017 Erik Mouw gave the following code example to illustrate handling
1021 /*-------------------------------------------------------------------------
1022 * Filename: gtk-fork.c
1024 * Copyright: Copyright (C) 1999, Erik Mouw
1025 * Author: Erik Mouw <J.A.K.Mouw@its.tudelft.nl>
1026 * Description: GTK+ fork example
1027 * Created at: Thu Sep 23 21:37:55 1999
1028 * Modified by: Erik Mouw <J.A.K.Mouw@its.tudelft.nl>
1029 * Modified at: Thu Sep 23 22:39:39 1999
1030 *-----------------------------------------------------------------------*/
1034 * cc -o gtk-fork gtk-fork.c `gtk-config --cflags --libs`
1041 #include <sys/types.h>
1042 #include <sys/wait.h>
1044 #include <gtk/gtk.h>
1046 void sigchld_handler(int num)
1048 sigset_t set, oldset;
1050 int status, exitstatus;
1052 /* block other incoming SIGCHLD signals */
1053 sigemptyset(&set);
1054 sigaddset(&set, SIGCHLD);
1055 sigprocmask(SIG_BLOCK, &set, &oldset);
1057 /* wait for child */
1058 while((pid = waitpid((pid_t)-1, &status, WNOHANG)) > 0)
1060 if(WIFEXITED(status))
1062 exitstatus = WEXITSTATUS(status);
1065 "Parent: child exited, pid = %d, exit status = %d\n",
1066 (int)pid, exitstatus);
1068 else if(WIFSIGNALED(status))
1070 exitstatus = WTERMSIG(status);
1073 "Parent: child terminated by signal %d, pid = %d\n",
1074 exitstatus, (int)pid);
1076 else if(WIFSTOPPED(status))
1078 exitstatus = WSTOPSIG(status);
1081 "Parent: child stopped by signal %d, pid = %d\n",
1082 exitstatus, (int)pid);
1087 "Parent: child exited magically, pid = %d\n",
1092 /* re-install the signal handler (some systems need this) */
1093 signal(SIGCHLD, sigchld_handler);
1095 /* and unblock it */
1096 sigemptyset(&set);
1097 sigaddset(&set, SIGCHLD);
1098 sigprocmask(SIG_UNBLOCK, &set, &oldset);
1101 gint delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
1106 void destroy(GtkWidget *widget, gpointer data)
1111 void fork_me(GtkWidget *widget, gpointer data)
1119 /* ouch, fork() failed */
1126 fprintf(stderr, "Child: pid = %d\n", (int)getpid());
1128 execlp("ls", "ls", "-CF", "/", NULL);
1130 /* if exec() returns, there is something wrong */
1133 /* exit child. note the use of _exit() instead of exit() */
1139 fprintf(stderr, "Parent: forked a child with pid = %d\n", (int)pid);
1143 int main(int argc, char *argv[])
1148 gtk_init(&argc, &argv);
1150 /* the basic stuff: make a window and set callbacks for destroy and
1153 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1155 gtk_signal_connect(GTK_OBJECT (window), "delete_event",
1156 GTK_SIGNAL_FUNC(delete_event), NULL);
1158 gtk_signal_connect(GTK_OBJECT (window), "destroy",
1159 GTK_SIGNAL_FUNC(destroy), NULL);
1161 #if (GTK_MAJOR_VERSION == 1) && (GTK_MINOR_VERSION == 0)
1162 gtk_container_border_width(GTK_CONTAINER (window), 10);
1164 gtk_container_set_border_width(GTK_CONTAINER (window), 10);
1167 /* add a button to do something usefull */
1168 button = gtk_button_new_with_label("Fork me!");
1170 gtk_signal_connect(GTK_OBJECT (button), "clicked",
1171 GTK_SIGNAL_FUNC(fork_me), NULL);
1173 gtk_container_add(GTK_CONTAINER(window), button);
1175 /* show everything */
1176 gtk_widget_show (button);
1177 gtk_widget_show (window);
1180 /* install a signal handler for SIGCHLD signals */
1181 signal(SIGCHLD, sigchld_handler);
1191 <!-- ----------------------------------------------------------------- -->
1192 <sect1>Why don't the contents of a button move when the button is pressed? Here's a patch to make it work that way...
1197 The reason buttons don't move their child down and to the right when
1198 they are depressed is because I don't think that's what is happening
1199 visually. My view of buttons is that you are looking at them straight
1200 on. That is, the user interface lies in a plane and you're above it
1201 looking straight at it. When a button gets pressed it moves directly
1202 away from you. To be absolutely correct I guess the child should
1203 actually shrink a tiny amount. But I don't see why the child should
1204 shift down and to the left. Remember, the child is supposed to be
1205 attached to the buttons surface. Its not good for it to appear like
1206 the child is slipping on the surface of the button.
1208 On a more practical note, I did implement this at one point and
1209 determined it didn't look good and removed it.
1212 <!-- ----------------------------------------------------------------- -->
1213 <sect1>How to I identifiy a widgets top level window or other ancestor?
1215 There are a couple of ways to find the top level parent of a
1216 widget. The easier way is to call the <tt/gtk_widget_top_level()/
1217 function that returns a pointer to a GtkWidget that is the top level
1220 A more complicated way to do this (but less limited, as it allows
1221 the user to get the closest ancestor of a known type) is to use
1222 <tt/gtk_widget_get_ancestor()/ as in:
1227 widget = gtk_widget_get_ancestor(w, GTK_TYPE_WINDOW);
1230 Since virtually all the GTK_TYPEs can be used as the second parameter of
1231 this function, you can get any parent widget of a particular
1232 widget. Suppose you have an hbox which contains a vbox, which in turn contains
1233 some other atomic widget (entry, label, etc. To find the master hbox
1234 using the <tt/entry/ widget simply use:
1238 hbox = gtk_widget_get_ancestor(w, GTK_TYPE_HBOX);
1241 <!-- ----------------------------------------------------------------- -->
1242 <sect1>How do I get the Window ID of a GtkWindow?
1244 The actual Gdk/X window will be created when the widget gets
1245 realized. You can get the Window ID with:
1248 #include <gdk/gdkx.h>
1250 Window xwin = GDK_WINDOW_XWINDOW (GTK_WIDGET (my_window)->window);
1253 <!-- ----------------------------------------------------------------- -->
1254 <sect1>How do I catch a double click event (in a list widget, for example)?
1256 Tim Janik wrote to gtk-list (slightly modified):
1258 Define a signal handler:
1262 signal_handler_event(GtkWiget *widget, GdkEvenButton *event, gpointer func_data)
1264 if (GTK_IS_LIST_ITEM(widget) &&
1265 (event->type==GDK_2BUTTON_PRESS ||
1266 event->type==GDK_3BUTTON_PRESS) ) {
1267 printf("I feel %s clicked on button %d\",
1268 event->type==GDK_2BUTTON_PRESS ? "double" : "triple",
1276 And connect the handler to your object:
1280 /* list, list item init stuff */
1282 gtk_signal_connect(GTK_OBJECT(list_item),
1283 "button_press_event",
1284 GTK_SIGNAL_FUNC(signal_handler_event),
1289 gtk_signal_connect(GTK_OBJECT(list_item),
1290 "button_release_event",
1291 GTK_SIGNAL_FUNC(signal_handler_event),
1294 /* something else */
1298 and, Owen Taylor wrote:
1300 Note that a single button press will be received beforehand, and
1301 if you are doing this for a button, you will therefore also get a
1302 "clicked" signal for the button. (This is going to be true for
1303 any toolkit, since computers aren't good at reading one's
1306 <!-- ----------------------------------------------------------------- -->
1307 <sect1>By the way, what are the differences between signals and events?
1309 First of all, Havoc Pennington gives a rather complete description of the
1310 differences between events and signals in his free book (two chapters can
1311 be found at <htmlurl url="http://www106.pair.com/rhp/sample_chapters.html"
1312 name="http://www106.pair.com/rhp/sample_chapters.html">).
1314 Moreover, Havoc posted this to the <tt/gtk-list/
1316 Events are a stream of messages received from the X server. They drive the
1317 Gtk main loop; which more or less amounts to "wait for events, process
1318 them" (not exactly, it is really more general than that and can wait on
1319 many different input streams at once). Events are a Gdk/Xlib concept.
1321 Signals are a feature of GtkObject and its subclasses. They have nothing
1322 to do with any input stream; really a signal is just a way to keep a list
1323 of callbacks around and invoke them ("emit" the signal). There are lots of
1324 details and extra features of course. Signals are emitted by object
1325 instances, and are entirely unrelated to the Gtk main loop.
1326 Conventionally, signals are emitted "when something changes" about the
1327 object emitting the signal.
1329 Signals and events only come together because GtkWidget happens to emit
1330 signals when it gets events. This is purely a convenience, so you can
1331 connect callbacks to be invoked when a particular widget receives a
1332 particular event. There is nothing about this that makes signals and
1333 events inherently related concepts, any more than emitting a signal when
1334 you click a button makes button clicking and signals related concepts.
1337 <!-- ----------------------------------------------------------------- -->
1338 <sect1>I have my signal connected to the the (whatever) event, but it seems I don't catch it. What's wrong?
1340 There is some special initialisation to do in order to catch some
1341 particular events. In fact, you must set the correct event mask bit of your
1342 widget before getting some particular events.
1347 gtk_widget_add_events(window, GDK_KEY_RELEASE_MASK);
1350 lets you catch the key release events. If you want to catch every events,
1351 simply us the GDK_ALL_EVENTS_MASK event mask.
1353 All the event masks are defined in the <tt/gdktypes.h/ file.
1355 <!-- ----------------------------------------------------------------- -->
1356 <sect1>Is it possible to get some text displayed which is truncated to fit inside its allocation?
1358 GTK's behavior (no clipping) is a consequence of its attempts to
1359 conserve X resources. Label widgets (among others) don't get their own
1360 X window - they just draw their contents on their parent's window.
1361 While it might be possible to have clipping occur by setting the clip
1362 mask before drawing the text, this would probably cause a substantial
1363 performance penalty.
1365 Its possible that, in the long term, the best solution to such
1366 problems might be just to change gtk to give labels X windows.
1367 A short term workaround is to put the label widget inside another
1368 widget that does get it's own window - one possible candidate would
1369 be the viewport widget.
1372 viewport = gtk_viewport (NULL, NULL);
1373 gtk_widget_set_usize (viewport, 50, 25);
1374 gtk_viewport_set_shadow_type (GTK_VIEWPORT(viewport), GTK_SHADOW_NONE);
1375 gtk_widget_show(viewport);
1377 label = gtk_label ("a really long label that won't fit");
1378 gtk_container_add (GTK_CONTAINER(viewport), label);
1379 gtk_widget_show (label);
1382 If you were doing this for a bunch of widgets, you might want to
1383 copy gtkviewport.c and strip out the adjustment and shadow
1384 functionality (perhaps you could call it GtkClipper).
1386 <!-- ----------------------------------------------------------------- -->
1388 <sect1>How do I make my window modal? / How do I make a single window active?
1390 After you create your window, do <tt/gtk_grab_add(my_window)/. And after
1391 closing the window do <tt/gtk_grab_remove(my_window)/.
1393 <!-- ----------------------------------------------------------------- -->
1394 <sect1>Why doesn't my widget (e.g. progressbar) update?
1397 You are probably doing all the changes within a function
1398 without returning control to <tt/gtk_main()/. This may be the case if you do some
1399 lengthy calculation in your code. Most drawing updates are only
1400 placed on a queue, which is processed within <tt/gtk_main()/. You can
1401 force the drawing queue to be processed using something like:
1404 while (gtk_main_iteration(FALSE));
1407 inside you're function that changes the widget.
1409 What the above snippet does is run all pending events and high priority
1410 idle functions, then return immediately (the drawing is done in a
1411 high priority idle function).
1413 <!-- ----------------------------------------------------------------- -->
1414 <sect1>How do I attach data to some GTK+ object/widget?
1416 First of all, the attached data is stored in the object_data field of a
1417 GtkObject. The type of this field is GData, which is defined in glib.h.
1418 So you should read the gdataset.c file in your glib source directory very
1421 There are two (easy) ways to attach some data to a gtk object.
1422 Using <tt/gtk_object_set_data()/ and <tt/gtk_object_get_data()/ seems to be the
1423 most common way to do this, as it provides a powerfull interface
1424 to connect objects and data.
1427 void gtk_object_set_data(GtkObject *object, const gchar *key, gpointer data);
1428 gpointer gtk_object_get_data(GtkObject *object, const gchar *key);
1431 Since a short example is better than any lengthy speech:
1434 struct my_struct p1,p2,*result;
1437 gtk_object_set_data(GTK_OBJECT(w),"p1 data",(gpointer)&p1);
1438 gtk_object_set_data(GTK_OBJECT(w),"p2 data",(gpointer)&p2);
1440 result = gtk_object_get_data(GTK_OBJECT(w),"p1 data");
1443 The <tt/gtk_object_set_user_data()/ and <tt/gtk_object_get_user_data()/
1444 functions does exactly the same thing
1445 as the functions above, but does not let you specify the "key" parameter.
1446 Instead, it uses a standard "user_data" key. Note that the use of these
1447 functions is deprecated in 1.2. They only provide a compatibility mode
1448 with some old gtk packages.
1450 <!-- ----------------------------------------------------------------- -->
1451 <sect1>How do I remove the data I have attached to an object?
1453 When attaching the data to the object, you can use the
1454 <tt/gtk_object_set_data_full()/
1455 function. The three first arguments of the function are the same as in
1456 <tt/gtk_object_set_data()/. The fourth one is a pointer to a callback function
1457 which is called when the data is destroyed. The data is destroyed when
1461 <item> destroy the object
1462 <item> replace the data with a new one (with the same key)
1463 <item> replace the data with NULL (with the same key)
1466 <!-- ----------------------------------------------------------------- -->
1467 <sect1>How could I get any widgets position?
1469 As Tim Janik pointed out, there are different cases, and each case requires
1470 a different solution.
1473 <item> If you want the position of a widget relative to its parent, you should
1474 use <tt/widget->allocation.x/ and <tt/widget->allocation.y/.
1475 <item> If you want the position of a window relative to the X root window,
1476 you should use <tt/gdk_window_get_geometry()/ or
1477 <tt/gdk_window_get_origin()/.
1478 <item> Last but not least, if you want to get a Window Manager frame position,
1479 you should use <tt/gdk_window_get_deskrelative_origin()/.
1482 <!-- ----------------------------------------------------------------- -->
1483 <sect1>How do I set the size of a widget/window? How do I prevent the user resizing my window?
1485 The <tt/gtk_widget_set_uposition()/ function is used to set the
1486 position of any widget.
1488 The <tt/gtk_widget_set_usize()/ function is used to set the
1489 size of a widget. In order to use all the features that are provided by
1490 this function when it acts on a window, you may want to use the
1491 <tt/gtk_window_set_policy/ function. The definition of these functions
1495 void gtk_widget_set_usize (GtkWidget *widget,
1499 void gtk_window_set_policy (GtkWindow *window,
1505 <tt/Auto_shrink/ will automatically shrink the window when the
1506 requested size of the child widgets goes below the current size of the
1507 window. <tt/Allow_shrink/ will give the user the authorisation to
1508 make the window smaller that it should normally be. <tt/Allow_grow/
1509 will give the user will have the ability to make the window
1510 bigger. The default values for these parameters are:
1513 allow_shrink = FALSE
1518 <!-- ----------------------------------------------------------------- -->
1519 <sect1>How do I add a popup menu to my GTK+ application?
1521 The <tt/menu/ example in the examples/menu directory of the GTK+ distribution
1522 implements a popup menu with this technique :
1525 static gint button_press (GtkWidget *widget, GdkEvent *event)
1528 if (event->type == GDK_BUTTON_PRESS) {
1529 GdkEventButton *bevent = (GdkEventButton *) event;
1530 gtk_menu_popup (GTK_MENU(widget), NULL, NULL, NULL, NULL,
1531 bevent->button, bevent->time);
1532 /* Tell calling code that we have handled this event; the buck
1537 /* Tell calling code that we have not handled this event; pass it on. */
1542 <!-- ----------------------------------------------------------------- -->
1543 <sect1>How do I disable or enable a widget, such as a button?
1545 To disable (or to enable) a widget, use the <tt/gtk_widget_set_sensitive()/
1546 function. The first parameter is you widget pointer. The second parameter
1547 is a boolean value: when this value is TRUE, the widget is enabled.
1549 <!-- ----------------------------------------------------------------- -->
1550 <sect1>Shouldn't the text argument in the gtk_clist_* functions be declared const?
1554 gint gtk_clist_prepend (GtkCList *clist,
1558 Answer: No, while a type "gchar*" (pointer to char) can automatically
1559 be cast into "const gchar*" (pointer to const char), this does not
1560 apply for "gchar *[]" (array of an unspecified number of pointers to
1561 char) into "const gchar *[]" (array of an unspecified number of
1562 pointers to const char).
1564 The type qualifier "const" may be subject to automatic casting, but
1565 in the array case, it is not the array itself that needs the (const)
1566 qualified cast, but its members, thus changing the whole type.
1568 <!-- ----------------------------------------------------------------- -->
1569 <sect1>How do I render pixels (image data) to the screen?
1571 There are several ways to approach this. The simplest way is to use
1572 GdkRGB, see gdk/gdkrgb.h. You create an RGB buffer, render to your RGB
1573 buffer, then use GdkRGB routines to copy your RGB buffer to a drawing
1574 area or custom widget. The book "GTK+/Gnome Application Development"
1575 gives some details; GdkRGB is also documented in the GTK+ reference
1578 If you're writing a game or other graphics-intensive application, you
1579 might consider a more elaborate solution. OpenGL is the graphics
1580 standard that will let you access hardware accelaration in future
1581 versions of XFree86; so for maximum speed, you probably want to use
1582 OpenGL. A GtkGLArea widget is available for using OpenGL with GTK+
1583 (but GtkGLArea does not come with GTK+ itself). There are also several
1584 open source game libraries, such as ClanLib and Loki's Simple
1585 DirectMedia Layer library (SDL).
1587 You do NOT want to use <tt/gdk_draw_point()/, that will be extremely
1590 <!-- ***************************************************************** -->
1591 <sect>Development with GTK+: widget specific questions
1592 <!-- ***************************************************************** -->
1594 <!-- ----------------------------------------------------------------- -->
1595 <sect1>How do I find out about the selection of a GtkList?
1597 Get the selection something like this:
1600 sel = GTK_LIST(list)->selection;
1603 This is how GList is defined (quoting glist.h):
1605 typedef struct _GList GList;
1615 A GList structure is just a simple structure for doubly linked lists.
1616 there exist several g_list_*() functions to modify a linked list in
1617 glib.h. However the GTK_LIST(MyGtkList)->selection is maintained
1618 by the gtk_list_*() functions and should not be modified.
1620 The selection_mode of the GtkList determines the selection
1621 facilities of a GtkList and therefore the contents
1622 of GTK_LIST(AnyGtkList)->selection:
1625 selection_mode GTK_LIST()->selection contents
1626 ------------------------------------------------------
1628 GTK_SELECTION_SINGLE) selection is either NULL
1629 or contains a GList* pointer
1630 for a single selected item.
1632 GTK_SELECTION_BROWSE) selection is NULL if the list
1633 contains no widgets, otherwise
1634 it contains a GList* pointer
1635 for one GList structure.
1636 GTK_SELECTION_MULTIPLE) selection is NULL if no listitems
1637 are selected or a a GList* pointer
1638 for the first selected item. that
1639 in turn points to a GList structure
1640 for the second selected item and so
1643 GTK_SELECTION_EXTENDED) selection is NULL.
1646 The data field of the GList structure GTK_LIST(MyGtkList)->selection points
1647 to the first GtkListItem that is selected. So if you would like to determine
1648 which listitems are selected you should go like this:
1650 Upon Initialization:
1653 gchar *list_items[]={
1659 guint nlist_items=sizeof(list_items)/sizeof(list_items[0]);
1660 GtkWidget *list_item;
1663 list=gtk_list_new();
1664 gtk_list_set_selection_mode(GTK_LIST(list), GTK_SELECTION_MULTIPLE);
1665 gtk_container_add(GTK_CONTAINER(AnyGtkContainer), list);
1666 gtk_widget_show (list);
1668 for (i = 0; i < nlist_items; i++)
1670 list_item=gtk_list_item_new_with_label(list_items[i]);
1671 gtk_object_set_user_data(GTK_OBJECT(list_item), (gpointer)i);
1672 gtk_container_add(GTK_CONTAINER(list), list_item);
1673 gtk_widget_show(list_item);
1678 To get known about the selection:
1683 items=GTK_LIST(list)->selection;
1685 printf("Selected Items: ");
1687 if (GTK_IS_LIST_ITEM(items->data))
1688 printf("%d ", (guint)
1689 gtk_object_get_user_data(items->data));
1696 <!-- ----------------------------------------------------------------- --><p>
1697 <sect1>I don't want the user of my applications to enter text into a GtkCombo. Any idea?
1699 A GtkCombo has an associated entry which can be accessed using the
1700 following expression:
1703 GTK_COMBO(combo_widget)->entry
1706 If you don't want the user to be able to modify the content of this
1707 entry, you can use the gtk_entry_set_editable() function:
1710 void gtk_entry_set_editable(GtkEntry *entry,
1714 Set the editable parameter to FALSE to disable typing into the entry.
1716 <!-- ----------------------------------------------------------------- -->
1717 <sect1>How do I catch a combo box change?
1719 The entry which is associated to your GtkCombo send a "changed" signal when:
1721 <item>some text is typed in
1722 <item>the selection of the combo box is changed
1725 To catch any combo box change, simply connect your signal handler with
1728 gtk_signal_connect(GTK_COMBO(cb)->entry,
1730 GTK_SIGNAL_FUNC(my_cb_change_handler),
1734 <!-- ----------------------------------------------------------------- -->
1735 <sect1>How can I define a separation line in a menu?
1737 See the <htmlurl url="http://www.gtk.org/tutorial/"
1738 name="Tutorial"> for information on how to create menus.
1739 However, to create a separation line in a menu, just insert an
1743 menuitem = gtk_menu_item_new();
1744 gtk_menu_append(GTK_MENU(menu), menuitem);
1745 gtk_widget_show(menuitem);
1748 <!-- ----------------------------------------------------------------- -->
1749 <sect1>How can I right justify a menu, such as Help?
1751 Depending on if you use the MenuFactory or not, there are two ways to proceed.
1752 With the MenuFactory, use something like the following:
1755 menu_path = gtk_menu_factory_find (factory, "<MyApp>/Help");
1756 gtk_menu_item_right_justify(menu_path->widget);
1759 If you do not use the MenuFactory, you should simply use:
1762 gtk_menu_item_right_justify(my_menu_item);
1765 <!-- ----------------------------------------------------------------- -->
1766 <sect1>How do I add some underlined accelerators to menu items?
1768 Damon Chaplin, the technical force behind the Glade project, provided the
1769 following code sample (this code is an output from Glade). It creates a
1770 small <tt/File/ menu item with only one child (<tt/New/). The F in <tt/File/
1771 and the N in <tt/New/ are underlined, and the relevant accelerators are
1775 menubar1 = gtk_menu_bar_new ();
1776 gtk_object_set_data (GTK_OBJECT (window1), "menubar1", menubar1);
1777 gtk_widget_show (menubar1);
1778 gtk_box_pack_start (GTK_BOX (vbox1), menubar1, FALSE, FALSE, 0);
1780 file1 = gtk_menu_item_new_with_label ("");
1781 tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (file1)->child),
1783 gtk_widget_add_accelerator (file1, "activate_item", accel_group,
1784 tmp_key, GDK_MOD1_MASK, 0);
1785 gtk_object_set_data (GTK_OBJECT (window1), "file1", file1);
1786 gtk_widget_show (file1);
1787 gtk_container_add (GTK_CONTAINER (menubar1), file1);
1789 file1_menu = gtk_menu_new ();
1790 file1_menu_accels = gtk_menu_ensure_uline_accel_group (GTK_MENU (file1_menu));
1791 gtk_object_set_data (GTK_OBJECT (window1), "file1_menu", file1_menu);
1792 gtk_menu_item_set_submenu (GTK_MENU_ITEM (file1), file1_menu);
1794 new1 = gtk_menu_item_new_with_label ("");
1795 tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (new1)->child),
1797 gtk_widget_add_accelerator (new1, "activate_item", file1_menu_accels,
1799 gtk_object_set_data (GTK_OBJECT (window1), "new1", new1);
1800 gtk_widget_show (new1);
1801 gtk_container_add (GTK_CONTAINER (file1_menu), new1);
1804 <!-- ----------------------------------------------------------------- -->
1805 <sect1>How do I right (or otherwise) justify a GtkLabel?
1807 Are you sure you want to <em>justify</em> the labels? The label class contains
1808 the <tt/gtk_label_set_justify()/ function that is used to control the
1809 justification of a multi-line label.
1811 What you probably want is to set the <em>alignment</em> of the label, ie right
1812 align it, center it or left align it. If you want to do this, you
1816 void gtk_misc_set_alignment (GtkMisc *misc,
1821 where the <tt/xalign/ and <tt/yalign/ values are floats in [0.00;1.00].
1826 /* horizontal : left align, vertical : top */
1827 gtk_misc_set_alignment(GTK_MISK(label), 0.0f, 0.0f);
1829 /* horizontal : centered, vertical : centered */
1830 gtk_misc_set_alignment(GTK_MISK(label), 0.5f, 0.5f);
1832 /* horizontal : right align, vertical : bottom */
1833 gtk_misc_set_alignment(GTK_MISK(label), 1.0f, 1.0f);
1836 <!-- ----------------------------------------------------------------- -->
1837 <sect1>How do I set the color and font of a GtkLabel using a Resource File?
1839 The widget name path constructed for a Label consists of the widget
1840 names of its object hierarchy as well, e.g.
1843 window (name: humphrey)
1845 label (name: mylabel)
1848 The widget path your pattern needs to match would be:
1849 <tt/humphrey.GtkHBox.mylabel/
1851 The resource file may look something like:
1856 fg[NORMAL] = {1.0, 0.0, 0.0}
1857 font = "-adobe-helvetica-bold-r-normal--*-140-*-*-*-*-*-*"
1859 widget "*mylabel" style "title"
1862 In your program, you would also need to give a name to the Label
1863 widget, which can be done using:
1865 label = gtk_label_new("Some Label Text");
1866 gtk_widget_set_name(label, "mylabel");
1867 gtk_widget_show(label);
1870 <!-- ----------------------------------------------------------------- -->
1871 <sect1>How do I configure Tooltips in a Resource File?
1873 The tooltip's window is named "gtk-tooltips", GtkTooltips in itself is not
1874 a GtkWidget (though a GtkObject) and as such is not attempted to match any
1877 So, you resource file should look something like:
1881 bg[NORMAL] = {1.0, 1.0, 0.0}
1883 widget "gtk-tooltips*" style "postie"
1886 <!-- ----------------------------------------------------------------- -->
1887 <sect1>How do I use horizontal scrollbars with a GtkText widget?
1889 The short answer is that you can't. The current version of the GtkText
1890 widget does not support horizontal scrolling. There is an intention to
1891 completely rewrite the GtkText widget, at which time this limitation
1894 <!-- ----------------------------------------------------------------- -->
1895 <sect1>I can't add more than (something like) 2000 chars in a GtkEntry. What's wrong?
1897 There is now a known problem in the GtkEntry widget. In the
1898 <tt/gtk_entry_insert_text()/ function, the following lines limit
1899 the number of chars in the entry to 2047.
1902 /* The algorithms here will work as long as, the text size (a
1903 * multiple of 2), fits into a guint16 but we specify a shorter
1904 * maximum length so that if the user pastes a very long text, there
1905 * is not a long hang from the slow X_LOCALE functions. */
1907 if (entry->text_max_length == 0)
1910 max_length = MIN (2047, entry->text_max_length);
1913 <!-- ----------------------------------------------------------------- -->
1914 <sect1>How do I change the font of a GtkText widget?
1916 There are a couple of ways of doing this. As GTK+ allows the
1917 appearance of applications to be changed at run time using resources
1918 you can use something like the following in the appropriate
1924 font = "-adobe-helvetica-medium-r-normal--*-100-*-*-*-*-*-*"
1928 Another way to do this is to load a font within your program, and then
1929 use this in the functions for adding text to the text widget. You can
1930 load a font using, for example:
1934 font = gdk_font_load("-adobe-helvetica-medium-r-normal--*-140-*-*-*-*-*-*");
1937 <!-- ----------------------------------------------------------------- -->
1938 <sect1>How do I set the cursor position in a GtkText object?
1940 Notice that the response is valid for any object that inherits from the
1943 Are you sure that you want to move the cursor position? Most of the time,
1944 while the cursor position is good, the insertion point does not match the
1945 cursor position. If this apply to what you really want, then you should use
1946 the <tt/gtk_text_set_point()/ function. If you want to set the insertion point
1947 at the current cursor position, use the following:
1950 gtk_text_set_point(GTK_TEXT(text),
1951 gtk_editable_get_position(GTK_EDITABLE(text)));
1954 If you want the insertion point to follow the cursor at all time, you
1955 should probably catch the button press event, and then move the
1956 insertion point. Be careful : you'll have to catch it after the widget
1957 has changed the cursor position though. Thomas Mailund Jensen proposed the
1962 insert_bar (GtkWidget *text)
1964 /* jump to cursor mark */
1965 gtk_text_set_point (GTK_TEXT (text),
1966 gtk_editable_get_position (GTK_EDITABLE (text)));
1968 gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL,
1969 "bar", strlen ("bar"));
1973 main (int argc, char *argv[])
1975 GtkWidget *window, *text;
1977 gtk_init (&argc, &argv);
1979 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1980 text = gtk_text_new (NULL, NULL);
1981 gtk_text_set_editable (GTK_TEXT (text), TRUE);
1982 gtk_container_add (GTK_CONTAINER (window), text);
1984 /* connect after everything else */
1985 gtk_signal_connect_after (GTK_OBJECT(text), "button_press_event",
1986 GTK_SIGNAL_FUNC (insert_bar), NULL);
1988 gtk_widget_show_all(window);
1995 Now, if you really want to change the cursor position, you should use the
1996 <tt/gtk_editable_set_position()/ function.
1998 <!-- ***************************************************************** -->
2000 <!-- ***************************************************************** -->
2002 <!-- ----------------------------------------------------------------- -->
2005 GDK is basically a wrapper around the standard Xlib function calls. If you are
2006 at all familiar with Xlib, a lot of the functions in GDK will require little
2007 or no getting used to. All functions are written to provide an way
2008 to access Xlib functions in an easier and slightly more intuitive manner.
2009 In addition, since GDK uses GLib (see below), it will be more portable
2010 and safer to use on multiple platforms.
2012 <!-- Examples, anybody? I've been mulling some over. NF -->
2014 <!-- ----------------------------------------------------------------- -->
2015 <sect1>How do I use color allocation?
2017 One of the nice things about GDK is that it's based on top of Xlib; this is
2018 also a problem, especially in the area of color management. If you want
2019 to use color in your program (drawing a rectangle or such, your code
2020 should look something like this:
2031 /* first, create a GC to draw on */
2032 gc = gdk_gc_new(widget->window);
2034 /* find proper dimensions for rectangle */
2035 gdk_window_get_size(widget->window, &width, &height);
2037 /* the color we want to use */
2038 color = (GdkColor *)malloc(sizeof(GdkColor));
2040 /* red, green, and blue are passed values, indicating the RGB triple
2041 * of the color we want to draw. Note that the values of the RGB components
2042 * within the GdkColor are taken from 0 to 65535, not 0 to 255.
2044 color->red = red * (65535/255);
2045 color->green = green * (65535/255);
2046 color->blue = blue * (65535/255);
2048 /* the pixel value indicates the index in the colormap of the color.
2049 * it is simply a combination of the RGB values we set earlier
2051 color->pixel = (gulong)(red*65536 + green*256 + blue);
2053 /* However, the pixel valule is only truly valid on 24-bit (TrueColor)
2054 * displays. Therefore, this call is required so that GDK and X can
2055 * give us the closest color available in the colormap
2057 gdk_color_alloc(gtk_widget_get_colormap(widget), color);
2059 /* set the foreground to our color */
2060 gdk_gc_set_foreground(gc, color);
2062 /* draw the rectangle */
2063 gdk_draw_rectangle(widget->window, gc, 1, 0, 0, width, height);
2070 <!-- ***************************************************************** -->
2072 <!-- ***************************************************************** -->
2074 <!-- ----------------------------------------------------------------- -->
2075 <sect1>What is GLib?
2077 GLib is a library of useful functions and definitions available for use
2078 when creating GDK and GTK applications. It provides replacements for some
2079 standard libc functions, such as malloc, which are buggy on some systems.
2081 It also provides routines for handling:
2083 <item>Doubly Linked Lists
2084 <item>Singly Linked Lists
2086 <item>String Handling
2087 <item>A Lexical Scanner
2088 <item>Error Functions
2091 <!-- ----------------------------------------------------------------- -->
2092 <sect1>How can I use the doubly linked lists?
2094 The GList object is defined as:
2097 typedef struct _GList GList;
2107 To use the GList objects, simply :
2112 gint array[] = { 1, 2, 3, 4, 5, 6 };
2116 /* add data to the list */
2117 for (pos=0;pos < sizeof array; pos++) {
2118 list = g_list_append(list, (gpointer)&array[pos]);
2121 /* run through the list */
2122 listrunner = g_list_first(list);
2123 while (listrunner) {
2124 value = (gint *)listrunner->data;
2125 printf("%d\n", *value);
2126 listrunner = g_list_next(listrunner);
2129 /* removing datas from the list */
2130 listrunner = g_list_first(list);
2131 list = g_list_remove_link(list, listrunner);
2132 list = g_list_remove(list, &array[4]);
2135 The same code is usable with singly linked lists (GSList objects) by replacing
2136 g_list_* functions with the relevant g_slist_* ones (g_slist_append,
2137 g_slist_remove, ...). Just remember that since you can't go backward in a singly
2138 linked list, there is no g_slist_first function - you'll need to keep a
2139 reference on the first node of the list.
2141 <!-- Some Examples might be useful here! NF -->
2142 <!-- I believe it should be better :) ED -->
2143 <!-- Linked lists are pretty standard data structures - don't want to
2144 over do it - TRG -->
2145 <!-- ----------------------------------------------------------------- -->
2146 <sect1>Why use g_print, g_malloc, g_strdup and fellow glib functions?
2148 Thanks to Tim Janik who wrote to gtk-list: (slightly modified)
2150 Regarding g_malloc(), g_free() and siblings, these functions are much safer
2151 than their libc equivalents. For example, g_free() just returns if called
2152 with NULL. Also, if USE_DMALLOC is defined, the definition for these
2153 functions changes (in glib.h) to use MALLOC(), FREE() etc... If MEM_PROFILE
2154 or MEM_CHECK are defined, there are even small statistics made counting
2155 the used block sizes (shown by g_mem_profile() / g_mem_check()).
2157 Considering the fact that glib provides an interface for memory chunks
2158 to save space if you have lots of blocks that are always the same size
2159 and to mark them ALLOC_ONLY if needed, it is just straight forward to
2160 create a small saver (debug able) wrapper around the normal malloc/free
2161 stuff as well - just like gdk covers Xlib. ;)
2163 Using g_error() and g_warning() inside of applications like the GIMP
2164 that fully rely on gtk even gives the opportunity to pop up a window
2165 showing the messages inside of a gtk window with your own handler
2166 (by using g_set_error_handler()) along the lines of <tt/gtk_print()/
2167 (inside of gtkmain.c).
2170 <!-- ----------------------------------------------------------------- -->
2171 <sect1>What's a GScanner and how do I use one?
2173 A GScanner will tokenize your text, that is, it'll return an integer
2174 for every word or number that appears in its input stream, following
2175 certain (customizable) rules to perform this translation.
2176 You still need to write the parsing functions on your own though.
2178 Here's a little test program supplied by Tim Janik that will parse
2181 <SYMBOL> = <OPTIONAL-MINUS> <NUMBER> ;
2184 constructs, while skipping "#\n" and "/**/" style comments.
2189 /* some test text to be fed into the scanner */
2190 static const gchar *test_text =
2192 "/* slide in some \n"
2193 " * comments, just for the\n"
2198 "# the next value is a float\n"
2201 "ping = - 0.5;\n" );
2203 /* define enumeration values to be returned for specific symbols */
2205 SYMBOL_PING = G_TOKEN_LAST + 1,
2206 SYMBOL_PONG = G_TOKEN_LAST + 2,
2207 SYMBOL_ZONK = G_TOKEN_LAST + 3
2211 static const struct {
2215 { "ping", SYMBOL_PING, },
2216 { "pong", SYMBOL_PONG, },
2217 { "zonk", SYMBOL_ZONK, },
2219 }, *symbol_p = symbols;
2221 static gfloat ping = 0;
2222 static gfloat pong = 0;
2223 static gfloat zonk = 0;
2226 parse_symbol (GScanner *scanner)
2229 gboolean negate = FALSE;
2231 /* expect a valid symbol */
2232 g_scanner_get_next_token (scanner);
2233 symbol = scanner->token;
2234 if (symbol < SYMBOL_PING ||
2235 symbol > SYMBOL_ZONK)
2236 return G_TOKEN_SYMBOL;
2239 g_scanner_get_next_token (scanner);
2240 if (scanner->token != '=')
2243 /* feature optional '-' */
2244 g_scanner_peek_next_token (scanner);
2245 if (scanner->next_token == '-')
2247 g_scanner_get_next_token (scanner);
2251 /* expect a float (ints are converted to floats on the fly) */
2252 g_scanner_get_next_token (scanner);
2253 if (scanner->token != G_TOKEN_FLOAT)
2254 return G_TOKEN_FLOAT;
2256 /* make sure the next token is a ';' */
2257 if (g_scanner_peek_next_token (scanner) != ';')
2259 /* not so, eat up the non-semicolon and error out */
2260 g_scanner_get_next_token (scanner);
2264 /* assign value, eat the semicolon and exit successfully */
2268 ping = negate ? - scanner->value.v_float : scanner->value.v_float;
2271 pong = negate ? - scanner->value.v_float : scanner->value.v_float;
2274 zonk = negate ? - scanner->value.v_float : scanner->value.v_float;
2277 g_scanner_get_next_token (scanner);
2279 return G_TOKEN_NONE;
2283 main (int argc, char *argv[])
2286 guint expected_token;
2288 scanner = g_scanner_new (NULL);
2290 /* adjust lexing behaviour to suit our needs
2292 /* convert non-floats (octal values, hex values...) to G_TOKEN_INT */
2293 scanner->config->numbers_2_int = TRUE;
2294 /* convert G_TOKEN_INT to G_TOKEN_FLOAT */
2295 scanner->config->int_2_float = TRUE;
2296 /* don't return G_TOKEN_SYMBOL, but the symbol's value */
2297 scanner->config->symbol_2_token = TRUE;
2299 /* load symbols into the scanner */
2300 while (symbol_p->symbol_name)
2302 g_scanner_add_symbol (scanner,
2303 symbol_p->symbol_name,
2304 GINT_TO_POINTER (symbol_p->symbol_token));
2308 /* feed in the text */
2309 g_scanner_input_text (scanner, test_text, strlen (test_text));
2311 /* give the error handler an idea on how the input is named */
2312 scanner->input_name = "test text";
2314 /* scanning loop, we parse the input untill it's end is reached,
2315 * the scanner encountered a lexing error, or our sub routine came
2316 * across invalid syntax
2320 expected_token = parse_symbol (scanner);
2322 g_scanner_peek_next_token (scanner);
2324 while (expected_token == G_TOKEN_NONE &&
2325 scanner->next_token != G_TOKEN_EOF &&
2326 scanner->next_token != G_TOKEN_ERROR);
2328 /* give an error message upon syntax errors */
2329 if (expected_token != G_TOKEN_NONE)
2330 g_scanner_unexp_token (scanner, expected_token, NULL, "symbol", NULL, NULL, TRUE);
2332 /* finsish parsing */
2333 g_scanner_destroy (scanner);
2336 g_print ("ping: %f\n", ping);
2337 g_print ("pong: %f\n", pong);
2338 g_print ("zonk: %f\n", zonk);
2344 You need to understand that the scanner will parse it's input and
2345 tokenize it, it is up to you to interpret these tokens, not define
2346 their types before they get parsed, e.g. watch gscanner parse a string:
2352 | | v TOKEN_INT, value: 17
2353 | v TOKEN_IDENTIFIER, value: "am"
2354 v TOKEN_CHAR, value: 'i'
2355 TOKEN_IDENTIFIER, value: "hi"
2358 If you configure the scanner with:
2360 scanner->config->int_2_float = TRUE;
2361 scanner->config->char_2_token = TRUE;
2362 scanner->config->scan_symbols = TRUE;
2365 and add "am" as a symbol with
2367 g_scanner_add_symbol (scanner, "am", "symbol value");
2370 GScanner will parse it as
2376 | | v TOKEN_FLOAT, value: 17.0 (automatic int->float conversion)
2377 | | TOKEN_SYMBOL, value: "symbol value" (a successfull hash table lookup
2378 | | turned a TOKEN_IDENTIFIER into a
2379 | | TOKEN_SYMBOL and took over the
2381 v 'i' ('i' can be a valid token as well, as all chars >0 and <256)
2382 TOKEN_IDENTIFIER, value: "hi"
2385 You need to match the token sequence with your code, and if you encounter
2386 something that you don't want, you error out:
2389 /* expect an identifier ("hi") */
2390 g_scanner_get_next_token (scanner);
2391 if (scanner->token != G_TOKEN_IDENTIFIER)
2392 return G_TOKEN_IDENTIFIER;
2393 /* expect a token 'i' */
2394 g_scanner_get_next_token (scanner);
2395 if (scanner->token != 'i')
2397 /* expect a symbol ("am") */
2398 g_scanner_get_next_token (scanner);
2399 if (scanner->token != G_TOKEN_SYMBOL)
2400 return G_TOKEN_SYMBOL;
2401 /* expect a float (17.0) */
2402 g_scanner_get_next_token (scanner);
2403 if (scanner->token != G_TOKEN_FLOAT)
2404 return G_TOKEN_FLOAT;
2407 If you got past here, you have parsed "hi i am 17" and would have
2408 accepted "dooh i am 42" and "bah i am 0.75" as well, but you would
2409 have not accepted "hi 7 am 17" or "hi i hi 17".
2411 <!-- ***************************************************************** -->
2412 <sect>GTK+ FAQ Contributions, Maintainers and Copyright
2414 If you would like to make a contribution to the FAQ, send either one of us
2415 an e-mail message with the exact text you think should be included (question and
2416 answer). With your help, this document can grow and become more useful!
2418 This document is maintained by Nathan Froyd
2419 <htmlurl url="mailto:maestrox@geocities.com"
2420 name="<maestrox@geocities.com>">,
2421 Tony Gale <htmlurl url="mailto:gale@gtk.org"
2422 name="<gale@gtk.org>"> and
2423 Emmanuel Deloget <htmlurl url="mailto:logout@free.fr"
2424 name="<logout@free.fr>">.
2425 This FAQ was created by Shawn T. Amundson
2426 <htmlurl url="mailto:amundson@gimp.org"
2427 name="<amundson@gimp.org>"> who continues to provide support.
2429 The GTK+ FAQ is Copyright (C) 1997,1998, 1999 by Shawn T. Amundson,
2430 Nathan Froyd and Tony Gale, Emmanuel Deloget.
2432 Permission is granted to make and distribute verbatim copies of
2433 this manual provided the copyright notice and this permission notice
2434 are preserved on all copies.
2436 Permission is granted to copy and distribute modified versions of
2437 this document under the conditions for verbatim copying, provided
2438 that this copyright notice is included exactly as in the original,
2439 and that the entire resulting derived work is distributed under
2440 the terms of a permission notice identical to this one.
2442 Permission is granted to copy and distribute translations of
2443 this document into another language, under the above conditions
2444 for modified versions.
2446 If you are intending to incorporate this document into a published work,
2447 please contact one of the maintainers, and we will make an effort to ensure
2448 that you have the most up to date information available.
2450 There is no guarentee that this document lives up to its intended
2451 purpose. This is simply provided as a free resource. As such,
2452 the authors and maintainers of the information provided within can
2453 not make any guarentee that the information is even accurate.