]> Pileus Git - ~andy/gtk/blob - docs/faq/gtkfaq.sgml
3ed17164b6d38125d9682af0ae94c60d372866a5
[~andy/gtk] / docs / faq / gtkfaq.sgml
1 <!doctype linuxdoc system>
2
3 <article>
4
5 <!-- Title information -->
6
7 <title>GTK+ FAQ
8
9 <!-- NOTE: Use only one author tag, otherwise sgml2txt barfs - TRG --> 
10 <author>Tony Gale, Shawn T. Amundson, Emmanuel Deloget, Nathan Froyd
11
12 <date>October 30th 1999
13
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 
16 using GTK+. 
17 </abstract>
18
19 <!-- Table of contents -->
20 <toc>
21
22 <!-- Begin the document -->
23
24 <!-- ***************************************************************** -->
25 <sect>General Information
26
27 <!-- ----------------------------------------------------------------- -->
28 <sect1>Before anything else: the greetings
29 <p>
30 The FAQ authors want to thank:
31 <itemize>
32 <item>Havoc Pennington
33 <item>Erik Mouw
34 <item>Owen Taylor
35 <item>Tim Janik
36 <item>Thomas Mailund Jensen
37 <item>Joe Pfeiffer
38 <item>Andy Kahn
39 <item>Federico Mena Quintero
40 <item>Damon Chaplin
41 <item>and all the members of the GTK+ lists
42 </itemize>
43 If we forgot you, please email us !
44 Thanks again (I know, it's really short :)
45
46 <!-- ----------------------------------------------------------------- -->
47 <sect1>Authors
48 <p>
49 The original authors of GTK+ were:
50
51 <itemize>
52 <item>Peter Mattis
53 <item>Spencer Kimball
54 <item>Josh MacDonald
55 </itemize>
56
57 Since then, much has been added by others. Please see the AUTHORS
58 file in the distribution for the GTK+ Team.
59
60 <!-- ----------------------------------------------------------------- -->
61 <sect1>What is GTK+?
62 <p>
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.
67
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.
74
75 <!-- ----------------------------------------------------------------- -->
76 <sect1>What is the + in GTK+?
77 <P>
78 Peter Mattis informed the gtk mailing list that:
79 <quote>
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."
87 </quote>
88
89 <!-- ----------------------------------------------------------------- -->
90 <sect1>Does the G in GTK+, GDK and GLib stand for?
91 <p>
92 GTK+ == Gimp Toolkit
93
94 GDK == Gtk+ Drawing Kit
95
96 GLib == G Libray
97
98 <!-- ----------------------------------------------------------------- -->
99 <sect1>Where is the documentation for GTK+?
100 <p>
101 In the GTK+ distribution's doc/ directory you will find the
102 reference material for both GTK and GDK, this FAQ and the
103 GTK Tutorial.
104
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">
111
112 There are now a couple of books available that deal with programming
113 GTK+, GDK and GNOME:
114 <itemize>
115 <item> Eric Harlows book entitled "Developing Linux Applications with
116 GTK+ and GDK". The ISBN is 0-7357-0021-4
117 <P>
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">
121
122 <item> Havoc Pennington has released a book called "GTK+/GNOME
123 Application Development". The ISBN is 0-7357-0078-8
124 <P>
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/">
128 <P>
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">
132 </itemize>
133
134 <!-- ----------------------------------------------------------------- -->
135 <sect1>Is there a mailing list (or mailing list archive) for GTK+?
136 <p>
137 Information on mailing lists relating to GTK+ can be found at:
138
139 <htmlurl url="http://www.gtk.org/mailinglists.html"
140 name="http://www.gtk.org/mailinglists.html">
141
142 <!-- ----------------------------------------------------------------- -->
143 <sect1>How to get help with GTK+
144 <p>
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+
148 mailing list.
149
150 <!-- ----------------------------------------------------------------- -->
151 <sect1>How to report bugs in GTK+
152 <p>
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.
157
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.
162
163 <verb>
164  Package: gtk+
165  Version: 1.2.0
166 </verb>
167
168 Substitute 1.2.0 with the version of GTK+ that you have installed.
169
170 Then describe the bug. Include:
171
172 <itemize>
173 <item> Information about your system. For instance:
174    <itemize>
175    <item> What operating system and version
176    <item> What version of X
177    <item> For Linux, what version of the C library
178    </itemize>
179   And anything else you think is relevant.
180
181 <item> How to reproduce the bug. 
182
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.
188
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
192   you are using)
193
194 <item> If the bug was a crash, the exact text that was printed out
195   when the crash occured.
196
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.
201 </itemize>
202
203 <!-- ----------------------------------------------------------------- -->
204 <sect1>Is there a Windows version of GTK+?
205 <p>
206 There is an on going port of GTK+ to the Windows platform which is
207 making impressive progress.
208
209 See <htmlurl url="http://www.iki.fi/tml/gimp/win32"
210 name="http://www.iki.fi/tml/gimp/win32"> for more information.
211
212 <!-- ----------------------------------------------------------------- -->
213 <sect1>What applications have been written with GTK+?
214 <p>
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
218 applications.
219
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.
223
224 Some of these are:
225 <itemize>
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/">),
237         a web browser
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
260 </itemize>
261 <p>
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
265 there.
266
267 <!-- ----------------------------------------------------------------- -->
268 <sect1>I'm looking for an application to write in GTK+. How about an IRC client? 
269 <p> 
270
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).
275
276 <itemize>
277 <item>X-Chat.
278 <item>girc. (Included with GNOME)
279 <item>gsirc. (In the gnome CVS tree)
280 </itemize>
281
282 <!-- ***************************************************************** -->
283 <sect>How to find, configure, install, and troubleshoot GTK+
284
285 <!-- ***************************************************************** -->
286
287 <!-- ----------------------------------------------------------------- -->
288 <sect1>What do I need to run GTK+?
289 <p>
290 To compile GTK+, all you need is a C compiler (gcc) and the X Window System
291 and associated libraries on your system.
292
293 <!-- ----------------------------------------------------------------- -->
294 <sect1>Where can I get GTK+?
295 <p>
296 The canonical site is:
297 <verb>
298 ftp://ftp.gtk.org/pub/gtk
299 </verb>
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">
304
305 Here's a few mirror sites to get you started:
306 <itemize>
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/
314 </itemize>
315
316 <sect1>How do I configure/compile GTK+?
317 <p>
318 Generally, all you will need to do is issue the commands:
319 <verb>
320 ./configure
321 make
322 </verb>
323 in the gtk+-version/ directory.
324
325 <!-- ----------------------------------------------------------------- -->
326 <sect1>When compiling GTK+ I get an error like: 
327 <tt/make: file `Makefile' line 456: Syntax error/
328 <p>
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.
332
333 <!-- ----------------------------------------------------------------- -->
334  
335 <sect1>I've compiled and installed GTK+, but I can't get any programs to link with it!
336 <p>
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:
340 <itemize>
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:
344 <verb>
345 /usr/X11R6/lib
346 /usr/local/lib
347 </verb>
348 Then you need to run /sbin/ldconfig as root. You can find what directory
349 GTK is in using
350 <verb>
351 gtk-config --libs
352 </verb>
353
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):
358 <verb>
359 export LD_LIBRARY_PATH=/usr/local/lib
360 </verb>
361 and in a csh, you can do:
362 <verb>
363 setenv LD_LIBRARY_PATH /usr/local/lib
364 </verb>
365
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
370 <verb>
371 rpm -e gtk gtk-devel
372 </verb>
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) 
378 and reinstall gtk+.
379 </itemize>
380
381 <!-- ----------------------------------------------------------------- -->
382 <sect1>When compiling programs with GTK+, I get compiler error messages about not being able to find <tt/"glibconfig.h"/.
383 <p>
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
389 to /usr/local/.
390
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
394 architectures. 
395
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.
402
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: 
406
407 <tscreen><verb>
408 CPPFLAGS="-I/usr/local/include/glib/include" ./configure
409 </verb></tscreen>
410
411 for Bourne-compatible shells like bash, or for csh variants:
412
413 <tscreen><verb>
414 setenv CPPFLAGS "-I/usr/local/include/glib/include" 
415 ./configure
416 </verb></tscreen>
417
418 (Substitute the appropriate value of $exec_prefix for /usr/local.)
419
420 <!-- ----------------------------------------------------------------- -->
421 <sect1>When installing a GTK+ application, configure reports that it can't find GTK.
422 <p>
423 There are several common reasons for this:
424 <itemize>
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.
429 <P>
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:
432 <verb>
433 gtk-config --version
434 </verb>
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.
437 <P>
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.
441 </itemize>
442 <p>
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.
448
449 <!-- ***************************************************************** -->
450 <sect>Development of GTK+
451 <!-- ***************************************************************** -->
452
453 <!-- ----------------------------------------------------------------- -->
454 <sect1>Whats this CVS thing that everyone keeps talking about, and how do I access it?
455 <p>
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.
461
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.
466
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="&lt;http://download.cyclic.com/pub/&gt;">
471
472 Anyone can download the latest CVS version of GTK+ by using anonymous access
473 using the following steps:
474 <itemize>
475 <item> In a bourne shell descendant (e.g. bash) type:
476 <verb>
477 CVSROOT=':pserver:anonymous@anoncvs.gnome.org:/cvs/gnome'
478 export CVSROOT
479 </verb>
480 <item>Next, the first time the source tree is checked out, a cvs login 
481 is needed. 
482 <verb>
483 cvs login
484 </verb>
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: 
489 <verb>
490 cvs -z3 get gtk+
491 </verb>
492
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
495 as well:
496 <verb>
497 cvs -z3 get glib
498 </verb>
499
500 </itemize>
501 <!-- ----------------------------------------------------------------- -->
502 <sect1>How can I contribute to GTK+?
503 <p>
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 &lt;oldfile&gt; &lt;newfile&gt;/. 
509 Then upload the patchfile to:
510 <verb>
511 ftp://ftp.gtk.org/incoming
512 </verb>
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:
515 <verb>
516 gtk-<username>-<date yymmdd-n>.patch.gz
517 gtk-<username>-<date yymmdd-n>.patch.README
518 </verb>
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.
522
523 Example:
524 <verb>
525 gtk-gale-982701-0.patch.gz
526 gtk-gale-982701-0.patch.README
527 </verb>
528 Once you upload <em>anything</em>, send the README to ftp-admin@gtk.org
529
530 <!-- ----------------------------------------------------------------- -->
531 <sect1>How do I know if my patch got applied, and if not, why not?
532 <p>
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>.
536
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.
543
544 <!-- ----------------------------------------------------------------- -->
545 <sect1>What is the policy on incorporating new widgets into the library?
546 <p>
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 
550 gladly be included.
551
552 <!-- ----------------------------------------------------------------- -->
553 <sect1>Is anyone working on bindings for languages other than C?
554 <p>
555 The GTK+ home page (<htmlurl url="http://www.gtk.org/" 
556 name="http://www.gtk.org/">) presents a list of GTK+ bindings.
557
558 <itemize>
559 <item>There are several C++ wrappers for GTK+.
560   <itemize>
561   
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">. 
566   The FTP site is 
567   <htmlurl url="ftp://ftp.gtk.org/pub/gtk/gtk--"
568   name="ftp://ftp.gtk.org/pub/gtk/gtk--">.
569   
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">.
574
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/">.
579
580   </itemize> 
581 <p>
582
583 <item>There are three known Objective-c bindings currently in development:
584
585   <itemize>
586
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+.
591
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&szlig;">.
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.
599
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/">.
603
604  </itemize> 
605 <p>               
606 <item>Perl bindings
607   <htmlurl url="ftp://ftp.gtk.org/pub/gtk/perl"
608   name="ftp://ftp.gtk.org/pub/gtk/perl">
609 <P>
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.
615 <p>
616
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.
620
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">
624   </quote>
625
626 <item> Several python bindings have been done:
627 <p>
628   <itemize>
629   <item>pygtk is at 
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">
634
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">
638   </itemize>
639 <p>
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">
644 <p>
645 <item>Last, there are a lot of other language bindings for languages such as 
646   Eiffel, TOM, Pascal, Pike, etc.
647
648 </itemize>
649
650 <!-- ***************************************************************** -->
651 <sect>Development with GTK+: the begining
652 <!-- ***************************************************************** -->
653 <!-- ----------------------------------------------------------------- -->
654 <sect1>How do I get started?
655 <p>
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="&lt;http://www.gtk.org/tutorial/&gt;">, which is undergoing 
660 development. This will introduce you to writing applications using C.
661
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.
667
668 <!-- ----------------------------------------------------------------- -->
669 <sect1>I tried to compile a small <tt/Hello World/ of mine, but it failed. Any clue?
670 <p>
671 Since you are good at coding, we will not deal with compile time error here :).
672
673 The classic command line to compile a GTK+ based program is
674
675 <verb>
676 gcc -o myprg [c files list] `gtk-config --cflags --libs`
677 </verb>
678
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.
685
686 The command line above ensure that:
687 <itemize>
688
689   <item>the correct C compiler flags will be used to compile the program
690         (including the complete C header directory list)
691
692   <item>your program will be linked with the needed libraries.
693
694 </itemize>
695
696 <sect1>What about using the <tt/make/ utility?
697 <p>
698 This is a sample makefile which compile a GTK+ based program:
699
700 <tscreen><verb>
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`
706 CC      = gcc
707 PACKAGE = myprg
708
709 all : ${OBJS}
710         ${CC} -o ${PACKAGE} ${OBJS} ${LDADD}
711
712 .c.o:
713         ${CC} ${CFLAGS} -c $<
714
715 # end of file
716 </verb></tscreen>
717
718 For more information about the <tt/make/ utility, you should read either the
719 related man page or the relevant info file.
720
721 <sect1>I use the backquote stuff in my makefiles, but my make process failed.
722 <p>
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/">).
728
729 <!-- ----------------------------------------------------------------- -->
730 <sect1>I want to add some configure stuff, how could I do this?
731 <p>
732 To use autoconf/automake, you must first install the relevant packages. These
733 are:
734
735 <itemize>
736   <item>the m4 preprocessor v1.4 or better
737   <item>autoconf v2.13 or better
738   <item>automake v1.4 or better
739 </itemize>
740
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.
743
744 In order to use the powerfull autoconf/automake scheme, you must create
745 a configure.in which may look like:
746
747 <tscreen><verb>
748 dnl Process this file with autoconf to produce a configure script.
749 dnl configure.in for a GTK+ based program
750
751 AC_INIT(myprg.c)dnl
752 AM_INIT_AUTOMAKE(mypkbname,0.0.1)dnl
753 AM_CONFIG_HEADER(config.h)dnl
754
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
758
759 dnl Checks for libraries.
760 AM_PATH_GTK(1.2.0,,AC_MSG_ERROR(mypkgname 0.1 needs GTK))dnl
761
762 AC_OUTPUT(
763         Makefile
764 )dnl
765 </verb></tscreen>
766
767 You must add a Makefile.am file:
768
769 <tscreen><verb>
770 bin_PROGRAMS    = myprg
771 myprg_SOURCES   = myprg.c foo.c bar.c
772 INCLUDES        = @GTK_CFLAGS@
773 LDADD           = @GTK_LIBS@
774 CLEANFILES      = *~
775 DISTCLEANFILES  = .deps/*.P
776 </verb></tscreen>
777
778 then, to use these, simply type the following commands:
779
780 <verb>
781 aclocal
782 autoheader
783 autoconf
784 automake --add-missing --include-deps --foreign 
785 </verb>
786
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).
790
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 ?
793 <p>
794 From Federico Mena Quintero:
795 <quote>
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
798 grab.
799 <P>
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
803 server.
804 </quote>
805
806 Eric Mouw had another solution:
807 <quote>
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).
811 </quote>
812
813 <!-- ***************************************************************** -->
814 <sect>Development with GTK+: general questions
815 <!-- ***************************************************************** -->
816 <!-- ----------------------------------------------------------------- -->
817 <sect1>What widgets are in GTK?
818 <p>
819 The GTK+ Tutorial lists the following widgets:
820
821 <verb>
822   GtkObject
823    +GtkData
824    | +GtkAdjustment
825    | `GtkTooltips
826    `GtkWidget
827      +GtkContainer
828      | +GtkBin
829      | | +GtkAlignment
830      | | +GtkEventBox
831      | | +GtkFrame
832      | | | `GtkAspectFrame
833      | | +GtkHandleBox
834      | | +GtkItem
835      | | | +GtkListItem
836      | | | +GtkMenuItem
837      | | | | `GtkCheckMenuItem
838      | | | |   `GtkRadioMenuItem
839      | | | `GtkTreeItem
840      | | +GtkViewport
841      | | `GtkWindow
842      | |   +GtkColorSelectionDialog
843      | |   +GtkDialog
844      | |   | `GtkInputDialog
845      | |   `GtkFileSelection
846      | +GtkBox
847      | | +GtkButtonBox
848      | | | +GtkHButtonBox
849      | | | `GtkVButtonBox
850      | | +GtkHBox
851      | | | +GtkCombo
852      | | | `GtkStatusbar
853      | | `GtkVBox
854      | |   +GtkColorSelection
855      | |   `GtkGammaCurve
856      | +GtkButton
857      | | +GtkOptionMenu
858      | | `GtkToggleButton
859      | |   `GtkCheckButton
860      | |     `GtkRadioButton
861      | +GtkCList
862      |   `GtkCTree
863      | +GtkFixed
864      | +GtkList
865      | +GtkMenuShell
866      | | +GtkMenuBar
867      | | `GtkMenu
868      | +GtkNotebook
869      | +GtkPaned
870      | | +GtkHPaned
871      | | `GtkVPaned
872      | +GtkScrolledWindow
873      | +GtkTable
874      | +GtkToolbar
875      | `GtkTree
876      +GtkDrawingArea
877      | `GtkCurve
878      +GtkEditable
879      | +GtkEntry
880      | | `GtkSpinButton
881      | `GtkText
882      +GtkMisc
883      | +GtkArrow
884      | +GtkImage
885      | +GtkLabel
886      | | `GtkTipsQuery
887      | `GtkPixmap
888      +GtkPreview
889      +GtkProgressBar
890      +GtkRange
891      | +GtkScale
892      | | +GtkHScale
893      | | `GtkVScale
894      | `GtkScrollbar
895      |   +GtkHScrollbar
896      |   `GtkVScrollbar
897      +GtkRuler
898      | +GtkHRuler
899      | `GtkVRuler
900      `GtkSeparator
901        +GtkHSeparator
902        `GtkVSeparator
903 </verb>
904
905 <!-- ----------------------------------------------------------------- -->
906 <sect1>Is GTK+ thread safe? How do I write multi-threaded GTK+ applications?
907 <p>
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
915 itself.
916
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()
921 afterwards.
922
923 A minimal main program for a threaded GTK+ application
924 looks like:
925
926 <verb>
927 int
928 main (int argc, char *argv[])
929 {
930   GtkWidget *window;
931
932   g_thread_init(NULL);
933   gtk_init(&amp;argc, &amp;argv);
934
935   window = create_window();
936   gtk_widget_show(window);
937
938   gdk_threads_enter();
939   gtk_main();
940   gdk_threads_leave();
941
942   return(0);
943 }
944 </verb>
945
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.
952
953 <!-- This is the old answer - TRG
954
955
956 Although GTK+, like many X toolkits, isn't thread safe, this does
957 not prohibit the development of multi-threaded applications with
958 GTK+. 
959
960 Rob Browning (rlb@cs.utexas.edu) describes threading techniques for
961 use with GTK+ (slightly edited): 
962
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
968 actual work. 
969
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. 
974
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()/.
980
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. 
987
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.
991
992 Why can't GTK+ be thread safe by default?                           
993
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
1000 carefully.
1001
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?
1006 <p>
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.
1010
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.
1014
1015 The right function to use here is <tt/_exit()/. 
1016
1017 Erik Mouw gave the following code example to illustrate handling
1018 fork() and exit().
1019
1020 <tscreen><verb>
1021 /*-------------------------------------------------------------------------
1022  * Filename:      gtk-fork.c
1023  * Version:       0.99.1
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  *-----------------------------------------------------------------------*/
1031 /*
1032  * Compile with:
1033  *
1034  * cc -o gtk-fork gtk-fork.c `gtk-config --cflags --libs`
1035  *
1036  */
1037
1038 #include <stdio.h>
1039 #include <stdlib.h>
1040 #include <signal.h>
1041 #include <sys/types.h>
1042 #include <sys/wait.h>
1043 #include <unistd.h>
1044 #include <gtk/gtk.h>
1045
1046 void sigchld_handler(int num)
1047 {
1048   sigset_t set, oldset;
1049   pid_t pid;
1050   int status, exitstatus;
1051
1052   /* block other incoming SIGCHLD signals */
1053   sigemptyset(&amp;set);
1054   sigaddset(&amp;set, SIGCHLD);
1055   sigprocmask(SIG_BLOCK, &amp;set, &amp;oldset);
1056
1057   /* wait for child */
1058   while((pid = waitpid((pid_t)-1, &amp;status, WNOHANG)) > 0)
1059     {
1060       if(WIFEXITED(status))
1061         {
1062           exitstatus = WEXITSTATUS(status);
1063
1064           fprintf(stderr, 
1065                   "Parent: child exited, pid = %d, exit status = %d\n", 
1066                   (int)pid, exitstatus);
1067         }
1068       else if(WIFSIGNALED(status))
1069         {
1070           exitstatus = WTERMSIG(status);
1071
1072           fprintf(stderr,
1073                   "Parent: child terminated by signal %d, pid = %d\n",
1074                   exitstatus, (int)pid);
1075         }
1076       else if(WIFSTOPPED(status))
1077         {
1078           exitstatus = WSTOPSIG(status);
1079
1080           fprintf(stderr,
1081                   "Parent: child stopped by signal %d, pid = %d\n",
1082                   exitstatus, (int)pid);
1083         }
1084       else
1085         {
1086           fprintf(stderr,
1087                   "Parent: child exited magically, pid = %d\n",
1088                   (int)pid);
1089         }
1090     }
1091
1092   /* re-install the signal handler (some systems need this) */
1093   signal(SIGCHLD, sigchld_handler);
1094   
1095   /* and unblock it */
1096   sigemptyset(&amp;set);
1097   sigaddset(&amp;set, SIGCHLD);
1098   sigprocmask(SIG_UNBLOCK, &amp;set, &amp;oldset);
1099 }
1100
1101 gint delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
1102 {
1103   return(FALSE);
1104 }
1105
1106 void destroy(GtkWidget *widget, gpointer data)
1107 {
1108   gtk_main_quit();
1109 }
1110
1111 void fork_me(GtkWidget *widget, gpointer data)
1112 {
1113   pid_t pid;
1114
1115   pid = fork();
1116
1117   if(pid == -1)
1118     {
1119       /* ouch, fork() failed */
1120       perror("fork");
1121       exit(-1);
1122     }
1123   else if(pid == 0)
1124     {
1125       /* child */
1126       fprintf(stderr, "Child: pid = %d\n", (int)getpid());
1127
1128       execlp("ls", "ls", "-CF", "/", NULL);
1129       
1130       /* if exec() returns, there is something wrong */
1131       perror("execlp");
1132
1133       /* exit child. note the use of _exit() instead of exit() */
1134       _exit(-1);
1135     }
1136   else
1137     {
1138       /* parent */
1139       fprintf(stderr, "Parent: forked a child with pid = %d\n", (int)pid);
1140     }
1141 }
1142
1143 int main(int argc, char *argv[])
1144 {
1145   GtkWidget *window;
1146   GtkWidget *button;
1147
1148   gtk_init(&amp;argc, &amp;argv);
1149
1150   /* the basic stuff: make a window and set callbacks for destroy and
1151    * delete events 
1152    */
1153   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1154
1155   gtk_signal_connect(GTK_OBJECT (window), "delete_event",
1156                      GTK_SIGNAL_FUNC(delete_event), NULL);
1157           
1158   gtk_signal_connect(GTK_OBJECT (window), "destroy",
1159                      GTK_SIGNAL_FUNC(destroy), NULL);
1160
1161 #if (GTK_MAJOR_VERSION == 1) && (GTK_MINOR_VERSION == 0)
1162   gtk_container_border_width(GTK_CONTAINER (window), 10);
1163 #else  
1164   gtk_container_set_border_width(GTK_CONTAINER (window), 10);
1165 #endif
1166
1167   /* add a button to do something usefull */
1168   button = gtk_button_new_with_label("Fork me!");
1169           
1170   gtk_signal_connect(GTK_OBJECT (button), "clicked",
1171                      GTK_SIGNAL_FUNC(fork_me), NULL);
1172
1173   gtk_container_add(GTK_CONTAINER(window), button);
1174           
1175   /* show everything */
1176   gtk_widget_show (button);
1177   gtk_widget_show (window);
1178
1179
1180   /* install a signal handler for SIGCHLD signals */
1181   signal(SIGCHLD, sigchld_handler);
1182
1183   
1184   /* main loop */
1185   gtk_main ();
1186
1187   exit(0);         
1188 }
1189 </verb></tscreen>
1190
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...
1193 <p>
1194 From: Peter Mattis
1195
1196 <quote>
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.
1207 <P>
1208 On a more practical note, I did implement this at one point and
1209 determined it didn't look good and removed it.
1210 </quote>     
1211
1212 <!-- ----------------------------------------------------------------- -->
1213 <sect1>How to I identifiy a widgets top level window or other ancestor?
1214 <p>
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
1218 window.
1219
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:
1223
1224 <tscreen><verb>
1225       GtkWidget       *widget;
1226       
1227       widget = gtk_widget_get_ancestor(w, GTK_TYPE_WINDOW);
1228 </verb></tscreen>
1229
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:
1235
1236 <tscreen><verb>
1237       GtkWidget       *hbox;
1238       hbox = gtk_widget_get_ancestor(w, GTK_TYPE_HBOX);
1239 </verb></tscreen>
1240
1241 <!-- ----------------------------------------------------------------- -->
1242 <sect1>How do I get the Window ID of a GtkWindow?
1243 <p>
1244 The actual Gdk/X window will be created when the widget gets
1245 realized. You can get the Window ID with:
1246
1247 <verb>
1248 #include <gdk/gdkx.h>
1249
1250 Window xwin = GDK_WINDOW_XWINDOW (GTK_WIDGET (my_window)->window);
1251 </verb>
1252
1253 <!-- ----------------------------------------------------------------- -->
1254 <sect1>How do I catch a double click event (in a list widget, for example)?
1255 <p>
1256 Tim Janik wrote to gtk-list (slightly modified):
1257
1258 Define a signal handler:
1259
1260 <tscreen><verb>
1261 gint
1262 signal_handler_event(GtkWiget *widget, GdkEvenButton *event, gpointer func_data)
1263 {
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",
1269            event->button);
1270   }
1271
1272   return FALSE;
1273 }
1274 </verb></tscreen>
1275
1276 And connect the handler to your object:
1277
1278 <tscreen><verb>
1279 {
1280   /* list, list item init stuff */     
1281
1282   gtk_signal_connect(GTK_OBJECT(list_item),
1283                      "button_press_event",
1284                      GTK_SIGNAL_FUNC(signal_handler_event),
1285                      NULL);
1286
1287   /* and/or */
1288
1289   gtk_signal_connect(GTK_OBJECT(list_item),
1290                      "button_release_event",
1291                      GTK_SIGNAL_FUNC(signal_handler_event),
1292                      NULL);
1293
1294   /* something else */
1295 }
1296 </verb></tscreen>
1297
1298 and, Owen Taylor wrote:
1299
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
1304 mind.)
1305                                        
1306 <!-- ----------------------------------------------------------------- -->
1307 <sect1>By the way, what are the differences between signals and events?
1308 <p>
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">).
1313
1314 Moreover, Havoc posted this to the <tt/gtk-list/
1315 <quote>
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.
1320 <P>
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.
1328 <P>
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.
1335 </quote>
1336
1337 <!-- ----------------------------------------------------------------- -->
1338 <sect1>I have my signal connected to the the (whatever) event, but it seems I don't catch it. What's wrong?
1339 <p>
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.
1343
1344 For example, 
1345
1346 <tscreen><verb>
1347   gtk_widget_add_events(window, GDK_KEY_RELEASE_MASK);
1348 </verb></tscreen>
1349
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.
1352
1353 All the event masks are defined in the <tt/gdktypes.h/ file.
1354
1355 <!-- ----------------------------------------------------------------- -->
1356 <sect1>Is it possible to get some text displayed which is truncated to fit inside its allocation? 
1357 <p>
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.
1364
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.
1370
1371 <tscreen><verb>
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);
1376
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);
1380 </verb></tscreen>
1381
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).
1385
1386 <!-- ----------------------------------------------------------------- -->
1387
1388 <sect1>How do I make my window modal? / How do I make a single window active?
1389 <p>
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)/.
1392
1393 <!-- ----------------------------------------------------------------- -->
1394 <sect1>Why doesn't my widget (e.g. progressbar) update?
1395 <p>
1396
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:
1402
1403 <tscreen><verb>
1404 while (gtk_main_iteration(FALSE));
1405 </verb></tscreen>
1406
1407 inside you're function that changes the widget.
1408
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).
1412
1413 <!-- ----------------------------------------------------------------- -->
1414 <sect1>How do I attach data to some GTK+ object/widget?
1415 <p>
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 
1419 carefully.
1420
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.
1425
1426 <tscreen><verb>
1427 void gtk_object_set_data(GtkObject *object, const gchar *key, gpointer data);
1428 gpointer gtk_object_get_data(GtkObject *object, const gchar *key);
1429 </verb></tscreen>
1430
1431 Since a short example is better than any lengthy speech:
1432
1433 <tscreen><verb>
1434 struct my_struct        p1,p2,*result;
1435 GtkWidget               *w;
1436
1437 gtk_object_set_data(GTK_OBJECT(w),"p1 data",(gpointer)&amp;p1);
1438 gtk_object_set_data(GTK_OBJECT(w),"p2 data",(gpointer)&amp;p2);
1439
1440 result = gtk_object_get_data(GTK_OBJECT(w),"p1 data");
1441 </verb></tscreen>
1442
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.
1449
1450 <!-- ----------------------------------------------------------------- -->
1451 <sect1>How do I remove the data I have attached to an object?
1452 <p>
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
1458 you:
1459
1460 <itemize>
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)
1464 </itemize>
1465
1466 <!-- ----------------------------------------------------------------- -->
1467 <sect1>How could I get any widgets position?
1468 <p>
1469 As Tim Janik pointed out, there are different cases, and each case requires
1470 a different solution.
1471
1472 <itemize>
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()/.
1480 </itemize>
1481
1482 <!-- ----------------------------------------------------------------- -->
1483 <sect1>How do I set the size of a widget/window? How do I prevent the user resizing my window?
1484 <p>
1485 The <tt/gtk_widget_set_uposition()/ function is used to set the
1486 position of any widget.
1487
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
1492 is:
1493
1494 <tscreen><verb>
1495 void        gtk_widget_set_usize (GtkWidget *widget,
1496                                   gint width,
1497                                   gint height);
1498
1499 void        gtk_window_set_policy (GtkWindow *window,
1500                                    gint allow_shrink,
1501                                    gint allow_grow,
1502                                    gint auto_shrink);
1503 </verb></tscreen>
1504
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:
1511
1512 <tscreen><verb>
1513 allow_shrink = FALSE
1514 allow_grow   = TRUE
1515 auto_shrink  = FALSE
1516 </verb></tscreen>
1517
1518 <!-- ----------------------------------------------------------------- -->
1519 <sect1>How do I add a popup menu to my GTK+ application?
1520 <p>
1521 The <tt/menu/ example in the examples/menu directory of the GTK+ distribution
1522 implements a popup menu with this technique :
1523
1524 <tscreen><verb>
1525 static gint button_press (GtkWidget *widget, GdkEvent *event)
1526 {
1527
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
1533          * stops here. */
1534         return TRUE;
1535     }
1536
1537     /* Tell calling code that we have not handled this event; pass it on. */
1538     return FALSE;
1539 }
1540 </verb></tscreen>
1541
1542 <!-- ----------------------------------------------------------------- -->
1543 <sect1>How do I disable or enable a widget, such as a button?
1544 <p>
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.
1548
1549 <!-- ----------------------------------------------------------------- -->
1550 <sect1>Shouldn't the text argument in the gtk_clist_* functions be declared const?
1551 <p>
1552 For example:
1553 <verb>
1554 gint gtk_clist_prepend (GtkCList    *clist,
1555                         gchar       *text[]);
1556 </verb>
1557
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).
1563
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.
1567
1568 <!-- ----------------------------------------------------------------- -->
1569 <sect1>How do I render pixels (image data) to the screen?
1570 <p>
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
1576 documentation.
1577
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).
1586
1587 You do NOT want to use <tt/gdk_draw_point()/, that will be extremely
1588 slow.
1589
1590 <!-- ***************************************************************** -->
1591 <sect>Development with GTK+: widget specific questions 
1592 <!-- ***************************************************************** -->
1593
1594 <!-- ----------------------------------------------------------------- -->
1595 <sect1>How do I find out about the selection of a GtkList?
1596 <p>
1597 Get the selection something like this:
1598 <tscreen><verb>
1599 GList *sel;
1600 sel = GTK_LIST(list)->selection;
1601 </verb></tscreen>
1602
1603 This is how GList is defined (quoting glist.h):
1604 <tscreen><verb>
1605 typedef struct _GList GList;
1606
1607 struct _GList
1608 {
1609   gpointer data;
1610   GList *next;
1611   GList *prev;
1612 };
1613 </verb></tscreen>
1614
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.
1619
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:
1623
1624 <verb>
1625 selection_mode          GTK_LIST()->selection contents
1626 ------------------------------------------------------
1627
1628 GTK_SELECTION_SINGLE)   selection is either NULL
1629                         or contains a GList* pointer
1630                         for a single selected item.
1631
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
1641                         on
1642
1643 GTK_SELECTION_EXTENDED) selection is NULL.
1644 </verb>
1645
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:
1649
1650 Upon Initialization:
1651 <tscreen><verb>
1652 {
1653         gchar           *list_items[]={
1654                                 "Item0",
1655                                 "Item1",
1656                                 "foo",
1657                                 "last Item",
1658                         };
1659         guint           nlist_items=sizeof(list_items)/sizeof(list_items[0]);
1660         GtkWidget       *list_item;
1661         guint           i;
1662
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);
1667
1668         for (i = 0; i < nlist_items; i++)
1669         {
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);
1674         }
1675 }
1676 </verb></tscreen>
1677
1678 To get known about the selection:
1679 <tscreen><verb>
1680 {
1681         GList   *items;
1682
1683         items=GTK_LIST(list)->selection;
1684
1685         printf("Selected Items: ");
1686         while (items) {
1687                 if (GTK_IS_LIST_ITEM(items->data))
1688                         printf("%d ", (guint) 
1689                 gtk_object_get_user_data(items->data));
1690                 items=items->next;
1691         }
1692         printf("\n");
1693 }
1694 </verb></tscreen>
1695
1696 <!-- ----------------------------------------------------------------- --><p>
1697 <sect1>I don't want the user of my applications to enter text into a GtkCombo. Any idea?
1698 <p>
1699 A GtkCombo has an associated entry which can be accessed using the
1700 following expression:
1701
1702 <tscreen><verb>
1703       GTK_COMBO(combo_widget)->entry
1704 </verb></tscreen>
1705
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:
1708
1709 <tscreen><verb>
1710       void gtk_entry_set_editable(GtkEntry *entry, 
1711                                   gboolean editable);
1712 </verb></tscreen>
1713
1714 Set the editable parameter to FALSE to disable typing into the entry.
1715
1716 <!-- ----------------------------------------------------------------- -->
1717 <sect1>How do I catch a combo box change?
1718 <p>
1719 The entry which is associated to your GtkCombo send a "changed" signal when:
1720 <itemize>
1721       <item>some text is typed in
1722       <item>the selection of the combo box is changed
1723 </itemize>
1724
1725 To catch any combo box change, simply connect your signal handler with
1726
1727 <tscreen><verb>
1728       gtk_signal_connect(GTK_COMBO(cb)->entry,
1729                          "changed",
1730                          GTK_SIGNAL_FUNC(my_cb_change_handler),
1731                          NULL);
1732 </verb></tscreen>
1733
1734 <!-- ----------------------------------------------------------------- -->
1735 <sect1>How can I define a separation line in a menu? 
1736 <p>
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
1740 empty menu item:
1741
1742 <tscreen><verb>
1743 menuitem = gtk_menu_item_new();
1744 gtk_menu_append(GTK_MENU(menu), menuitem);
1745 gtk_widget_show(menuitem);
1746 </verb></tscreen>
1747
1748 <!-- ----------------------------------------------------------------- -->
1749 <sect1>How can I right justify a menu, such as Help? 
1750 <p>
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:
1753
1754 <tscreen><verb>
1755 menu_path = gtk_menu_factory_find (factory,  "<MyApp>/Help");
1756 gtk_menu_item_right_justify(menu_path->widget);
1757 </verb></tscreen>
1758
1759 If you do not use the MenuFactory, you should simply use:
1760
1761 <tscreen><verb>
1762 gtk_menu_item_right_justify(my_menu_item);
1763 </verb></tscreen>
1764
1765 <!-- ----------------------------------------------------------------- -->
1766 <sect1>How do I add some underlined accelerators to menu items?
1767 <p>
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 
1772 created.
1773
1774 <tscreen><verb>
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);
1779
1780   file1 = gtk_menu_item_new_with_label ("");
1781   tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (file1)->child),
1782                                    _("_File"));
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);
1788
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);
1793
1794   new1 = gtk_menu_item_new_with_label ("");
1795   tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (new1)->child),
1796                                    _("_New"));
1797   gtk_widget_add_accelerator (new1, "activate_item", file1_menu_accels,
1798                               tmp_key, 0, 0);
1799   gtk_object_set_data (GTK_OBJECT (window1), "new1", new1);
1800   gtk_widget_show (new1);
1801   gtk_container_add (GTK_CONTAINER (file1_menu), new1);
1802 </verb></tscreen>
1803
1804 <!-- ----------------------------------------------------------------- -->
1805 <sect1>How do I right (or otherwise) justify a GtkLabel?
1806 <p>
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.
1810
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 
1813 should use:
1814
1815 <tscreen><verb>
1816 void gtk_misc_set_alignment     (GtkMisc *misc,
1817                                 gfloat xalign,
1818                                 gfloat yalign);
1819 </verb></tscreen>
1820
1821 where the <tt/xalign/ and <tt/yalign/ values are floats in [0.00;1.00].
1822
1823 <tscreen><verb>
1824 GtkWidget       *label;
1825
1826 /* horizontal : left align, vertical : top */
1827 gtk_misc_set_alignment(GTK_MISK(label), 0.0f, 0.0f);
1828
1829 /* horizontal : centered, vertical : centered */
1830 gtk_misc_set_alignment(GTK_MISK(label), 0.5f, 0.5f);
1831
1832 /* horizontal : right align, vertical : bottom */
1833 gtk_misc_set_alignment(GTK_MISK(label), 1.0f, 1.0f);
1834 </verb></tscreen>
1835
1836 <!-- ----------------------------------------------------------------- -->
1837 <sect1>How do I set the color and font of a GtkLabel using a Resource File?
1838 <p>
1839 The widget name path constructed for a Label consists of the widget
1840 names of its object hierarchy as well, e.g.
1841
1842 <verb>
1843 window (name: humphrey)
1844   hbox
1845     label (name: mylabel)
1846 </verb>
1847
1848 The widget path your pattern needs to match would be:
1849 <tt/humphrey.GtkHBox.mylabel/
1850
1851 The resource file may look something like:
1852
1853 <verb>
1854 style "title"
1855 {
1856       fg[NORMAL] = {1.0, 0.0, 0.0}
1857       font = "-adobe-helvetica-bold-r-normal--*-140-*-*-*-*-*-*"
1858 }
1859 widget "*mylabel" style "title"
1860 </verb>
1861
1862 In your program, you would also need to give a name to the Label
1863 widget, which can be done using:
1864 <verb>
1865   label = gtk_label_new("Some Label Text");
1866   gtk_widget_set_name(label, "mylabel");
1867   gtk_widget_show(label);
1868 </verb>
1869
1870 <!-- ----------------------------------------------------------------- -->
1871 <sect1>How do I configure Tooltips in a Resource File?
1872 <p>
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
1875 widget styles.
1876
1877 So, you resource file should look something like:
1878 <verb> 
1879 style "postie"
1880 {
1881       bg[NORMAL] = {1.0, 1.0, 0.0}
1882 }
1883 widget "gtk-tooltips*" style "postie"
1884 </verb>
1885
1886 <!-- ----------------------------------------------------------------- -->
1887 <sect1>How do I use horizontal scrollbars with a GtkText widget?
1888 <p>
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
1892 will be removed.
1893
1894 <!-- ----------------------------------------------------------------- -->
1895 <sect1>I can't add more than (something like) 2000 chars in a GtkEntry. What's wrong?
1896 <p>
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.
1900
1901 <tscreen><verb>
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.  */
1906
1907   if (entry->text_max_length == 0)
1908     max_length = 2047;
1909   else
1910     max_length = MIN (2047, entry->text_max_length);
1911 </verb></tscreen>
1912
1913 <!-- ----------------------------------------------------------------- -->
1914 <sect1>How do I change the font of a GtkText widget?
1915 <p>
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
1919 file:
1920
1921 <tscreen><verb>
1922 style "text"
1923 {
1924   font = "-adobe-helvetica-medium-r-normal--*-100-*-*-*-*-*-*"
1925 }
1926 </verb></tscreen>
1927
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:
1931
1932 <tscreen><verb>
1933   GdkFont *font;
1934   font = gdk_font_load("-adobe-helvetica-medium-r-normal--*-140-*-*-*-*-*-*");
1935 </verb></tscreen>
1936
1937 <!-- ----------------------------------------------------------------- -->
1938 <sect1>How do I set the cursor position in a GtkText object?
1939 <p>
1940 Notice that the response is valid for any object that inherits from the 
1941 GtkEditable class.
1942
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:
1948
1949 <tscreen><verb>
1950   gtk_text_set_point(GTK_TEXT(text),
1951       gtk_editable_get_position(GTK_EDITABLE(text)));
1952 </verb></tscreen>
1953
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
1958 following code:
1959
1960 <tscreen><verb>
1961 static void
1962 insert_bar (GtkWidget *text)
1963 {
1964   /* jump to cursor mark */
1965   gtk_text_set_point (GTK_TEXT (text),
1966       gtk_editable_get_position (GTK_EDITABLE  (text)));
1967
1968   gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL,
1969      "bar", strlen ("bar"));
1970 }
1971
1972 int
1973 main (int argc, char *argv[])
1974 {
1975   GtkWidget *window, *text;
1976
1977   gtk_init (&amp;argc, &amp;argv);
1978
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);
1983
1984   /* connect after everything else */
1985   gtk_signal_connect_after (GTK_OBJECT(text), "button_press_event",
1986     GTK_SIGNAL_FUNC (insert_bar), NULL);
1987
1988   gtk_widget_show_all(window);
1989   gtk_main();
1990
1991   return 0;
1992 }
1993 </verb></tscreen>
1994
1995 Now, if you really want to change the cursor position, you should use the
1996 <tt/gtk_editable_set_position()/ function.
1997
1998 <!-- ***************************************************************** -->
1999 <sect>About gdk
2000 <!-- ***************************************************************** -->
2001
2002 <!-- ----------------------------------------------------------------- -->
2003 <sect1>What is GDK?
2004 <p>
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.
2011
2012 <!-- Examples, anybody? I've been mulling some over. NF -->
2013    
2014 <!-- ----------------------------------------------------------------- -->
2015 <sect1>How do I use color allocation?
2016 <p>
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:
2021 <tscreen>
2022 <verb>
2023 {
2024   GdkColor *color;
2025   int width, height;
2026   GtkWidget *widget;
2027   GdkGC *gc;
2028
2029   ...
2030   
2031   /* first, create a GC to draw on */
2032   gc = gdk_gc_new(widget->window);
2033
2034   /* find proper dimensions for rectangle */
2035   gdk_window_get_size(widget->window, &amp;width, &amp;height);
2036
2037   /* the color we want to use */
2038   color = (GdkColor *)malloc(sizeof(GdkColor));
2039   
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.
2043    */
2044   color->red = red * (65535/255);
2045   color->green = green * (65535/255);
2046   color->blue = blue * (65535/255);
2047   
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
2050    */
2051   color->pixel = (gulong)(red*65536 + green*256 + blue);
2052
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
2056    */
2057   gdk_color_alloc(gtk_widget_get_colormap(widget), color);
2058
2059   /* set the foreground to our color */
2060   gdk_gc_set_foreground(gc, color);
2061   
2062   /* draw the rectangle */
2063   gdk_draw_rectangle(widget->window, gc, 1, 0, 0, width, height);
2064
2065   ...
2066 }
2067 </verb>
2068 </tscreen>
2069
2070 <!-- ***************************************************************** -->
2071 <sect>About GLib
2072 <!-- ***************************************************************** -->
2073
2074 <!-- ----------------------------------------------------------------- -->
2075 <sect1>What is GLib?
2076 <p>
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.
2080 <p>
2081 It also provides routines for handling:
2082 <itemize>
2083 <item>Doubly Linked Lists
2084 <item>Singly Linked Lists
2085 <item>Timers
2086 <item>String Handling
2087 <item>A Lexical Scanner
2088 <item>Error Functions
2089 </itemize>
2090
2091 <!-- ----------------------------------------------------------------- -->
2092 <sect1>How can I use the doubly linked lists?
2093 <p>
2094 The GList object is defined as:
2095
2096 <tscreen><verb>
2097 typedef struct _GList GList;
2098
2099 struct _GList
2100 {
2101   gpointer data;
2102   GList *next;
2103   GList *prev;
2104 };
2105 </verb></tscreen>
2106
2107 To use the GList objects, simply :
2108
2109 <tscreen><verb>
2110 GList   *list = NULL;
2111 GList   *listrunner;
2112 gint    array[] = { 1, 2, 3, 4, 5, 6 };
2113 gint    pos;
2114 gint    *value;
2115
2116 /* add data to the list */
2117 for (pos=0;pos < sizeof array; pos++) {
2118   list = g_list_append(list, (gpointer)&amp;array[pos]);
2119 }
2120
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);
2127 }
2128
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, &amp;array[4]);
2133 </verb></tscreen>
2134
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.
2140
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?  
2147 <p>
2148 Thanks to Tim Janik who wrote to gtk-list: (slightly modified)
2149 <quote>
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()).
2156 <P>
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. ;)
2162 <P>
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).
2168 </quote>
2169
2170 <!-- ----------------------------------------------------------------- -->
2171 <sect1>What's a GScanner and how do I use one?  
2172 <p>
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.
2177
2178 Here's a little test program supplied by Tim Janik that will parse
2179
2180 <verb>
2181 <SYMBOL> = <OPTIONAL-MINUS> <NUMBER> ;
2182 </verb>
2183
2184 constructs, while skipping "#\n" and "/**/" style comments.
2185
2186 <verb>
2187 #include <glib.h>
2188
2189 /* some test text to be fed into the scanner */
2190 static const gchar *test_text =
2191 ( "ping = 5;\n"
2192   "/* slide in some \n"
2193   " * comments, just for the\n"
2194   " * fun of it \n"
2195   " */\n"
2196   "pong = -6; \n"
2197   "\n"
2198   "# the next value is a float\n"
2199   "zonk = 0.7;\n"
2200   "# redefine ping\n"
2201   "ping = - 0.5;\n" );
2202
2203 /* define enumeration values to be returned for specific symbols */
2204 enum {
2205   SYMBOL_PING = G_TOKEN_LAST + 1,
2206   SYMBOL_PONG = G_TOKEN_LAST + 2,
2207   SYMBOL_ZONK = G_TOKEN_LAST + 3
2208 };
2209
2210 /* symbol array */
2211 static const struct {
2212   gchar *symbol_name;
2213   guint  symbol_token;
2214 } symbols[] = {
2215   { "ping", SYMBOL_PING, },
2216   { "pong", SYMBOL_PONG, },
2217   { "zonk", SYMBOL_ZONK, },
2218   { NULL, 0, },
2219 }, *symbol_p = symbols;
2220
2221 static gfloat ping = 0;
2222 static gfloat pong = 0;
2223 static gfloat zonk = 0;
2224
2225 static guint
2226 parse_symbol (GScanner *scanner)
2227 {
2228   guint symbol;
2229   gboolean negate = FALSE;
2230
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;
2237
2238   /* expect '=' */
2239   g_scanner_get_next_token (scanner);
2240   if (scanner->token != '=')
2241     return '=';
2242
2243   /* feature optional '-' */
2244   g_scanner_peek_next_token (scanner);
2245   if (scanner->next_token == '-')
2246     {
2247       g_scanner_get_next_token (scanner);
2248       negate = !negate;
2249     }
2250
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;
2255
2256   /* make sure the next token is a ';' */
2257   if (g_scanner_peek_next_token (scanner) != ';')
2258     {
2259       /* not so, eat up the non-semicolon and error out */
2260       g_scanner_get_next_token (scanner);
2261       return ';';
2262     }
2263
2264   /* assign value, eat the semicolon and exit successfully */
2265   switch (symbol)
2266     {
2267     case SYMBOL_PING:
2268       ping = negate ? - scanner->value.v_float : scanner->value.v_float;
2269       break;
2270     case SYMBOL_PONG:
2271       pong = negate ? - scanner->value.v_float : scanner->value.v_float;
2272       break;
2273     case SYMBOL_ZONK:
2274       zonk = negate ? - scanner->value.v_float : scanner->value.v_float;
2275       break;
2276     }
2277   g_scanner_get_next_token (scanner);
2278
2279   return G_TOKEN_NONE;
2280 }
2281
2282 int
2283 main (int argc, char *argv[])
2284 {
2285   GScanner *scanner;
2286   guint expected_token;
2287
2288   scanner = g_scanner_new (NULL);
2289
2290   /* adjust lexing behaviour to suit our needs
2291    */
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;
2298
2299   /* load symbols into the scanner */
2300   while (symbol_p->symbol_name)
2301     {
2302       g_scanner_add_symbol (scanner,
2303                             symbol_p->symbol_name,
2304                             GINT_TO_POINTER (symbol_p->symbol_token));
2305       symbol_p++;
2306     }
2307
2308   /* feed in the text */
2309   g_scanner_input_text (scanner, test_text, strlen (test_text));
2310
2311   /* give the error handler an idea on how the input is named */
2312   scanner->input_name = "test text";
2313
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
2317    */
2318   do
2319     {
2320       expected_token = parse_symbol (scanner);
2321       
2322       g_scanner_peek_next_token (scanner);
2323     }
2324   while (expected_token == G_TOKEN_NONE &&
2325          scanner->next_token != G_TOKEN_EOF &&
2326          scanner->next_token != G_TOKEN_ERROR);
2327
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);
2331
2332   /* finsish parsing */
2333   g_scanner_destroy (scanner);
2334
2335   /* print results */
2336   g_print ("ping: %f\n", ping);
2337   g_print ("pong: %f\n", pong);
2338   g_print ("zonk: %f\n", zonk);
2339   
2340   return 0;
2341 }
2342 </verb>
2343
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:
2347  
2348 <verb>
2349 "hi i am 17"
2350  |  | |  |
2351  |  | |  v
2352  |  | v  TOKEN_INT, value: 17
2353  |  v TOKEN_IDENTIFIER, value: "am"
2354  v  TOKEN_CHAR, value: 'i'
2355 TOKEN_IDENTIFIER, value: "hi"
2356 </verb>
2357
2358 If you configure the scanner with:
2359 <verb>
2360 scanner->config->int_2_float = TRUE;
2361 scanner->config->char_2_token = TRUE;
2362 scanner->config->scan_symbols = TRUE;
2363 </verb>
2364
2365 and add "am" as a symbol with
2366 <verb>
2367 g_scanner_add_symbol (scanner, "am", "symbol value");
2368 </verb>
2369
2370 GScanner will parse it as
2371
2372 <verb>
2373 "hi i am 17"
2374  |  | |  |
2375  |  | |  v
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
2380  |  v                                       symbol's value)
2381  v  'i'  ('i' can be a valid token as well, as all chars >0 and <256)
2382 TOKEN_IDENTIFIER, value: "hi"
2383 </verb>
2384
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:
2387
2388 <verb>
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')
2396   return '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;
2405 </verb>
2406
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".
2410
2411 <!-- ***************************************************************** -->
2412 <sect>GTK+ FAQ Contributions, Maintainers and Copyright
2413 <p>
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!
2417
2418 This document is maintained by Nathan Froyd 
2419 <htmlurl url="mailto:maestrox@geocities.com" 
2420 name="&lt;maestrox@geocities.com&gt;">,
2421 Tony Gale <htmlurl url="mailto:gale@gtk.org" 
2422 name="&lt;gale@gtk.org&gt;"> and 
2423 Emmanuel Deloget <htmlurl url="mailto:logout@free.fr"
2424 name="&lt;logout@free.fr&gt;">.
2425 This FAQ was created by Shawn T. Amundson 
2426 <htmlurl url="mailto:amundson@gimp.org" 
2427 name="&lt;amundson@gimp.org&gt;"> who continues to provide support.
2428
2429 The GTK+ FAQ is Copyright (C) 1997,1998, 1999 by Shawn T. Amundson, 
2430 Nathan Froyd and Tony Gale, Emmanuel Deloget.
2431
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.
2435
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.
2441
2442 Permission is granted to copy and distribute translations of 
2443 this document into another language,  under the above conditions 
2444 for modified versions.
2445
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.
2449
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.
2454
2455 </article>