]> Pileus Git - ~andy/gtk/blob - docs/faq/gtk-faq.sgml
Start of Section 6.
[~andy/gtk] / docs / faq / gtk-faq.sgml
1 <!doctype book PUBLIC "-//OASIS//DTD DocBook V3.1//EN" []>
2 <book>
3
4   <bookinfo>
5     <date>June 28th 2000</date>
6     <title>GTK+ FAQ</title>
7     <authorgroup>
8       <author>
9         <firstname>Tony</firstname>
10         <surname>Gale</surname>
11       </author>
12       <author>
13         <firstname>Shawn</firstname>
14         <surname>Amundson</surname>
15       </author>
16       <author>
17         <firstname>Emmanuel</firstname>
18         <surname>Deloget</surname>
19       </author>
20     </authorgroup>
21     <abstract>
22       <para> This document is intended to answer questions that are
23       likely to be frequently asked by programmers using GTK+ or
24       people who are just looking at using GTK+. </para>
25     </abstract>
26   </bookinfo>
27
28   <toc></toc>
29
30   <!-- ***************************************************************** -->
31   <chapter>
32     <title>General Information</title>
33     <para>Here's a paragraph of text because it is stylistically poor
34     to start a section right after the chapter title.</para>
35     <sect1>
36       <title></title>
37
38       <!-- ----------------------------------------------------------------- -->
39
40       <sect2>
41         <title>Before anything else: the greetings</title>
42         <para>The FAQ authors want to thank:</para>
43         <itemizedlist spacing=Compact>
44           <listitem>
45             <simpara>Havoc Pennington</simpara>
46           </listitem>
47           <listitem>
48             <simpara>Erik Mouw</simpara>
49           </listitem>
50           <listitem>
51             <simpara>Owen Taylor</simpara>
52           </listitem>
53           <listitem>
54             <simpara>Tim Janik</simpara>
55           </listitem>
56           <listitem>
57             <simpara>Thomas Mailund Jensen</simpara>
58           </listitem>
59           <listitem>
60             <simpara>Joe Pfeiffer</simpara>
61           </listitem>
62           <listitem>
63             <simpara>Andy Kahn</simpara>
64           </listitem>
65           <listitem>
66             <simpara>Federico Mena Quntero</simpara>
67           </listitem>
68           <listitem>
69             <simpara>Damon Chaplin</simpara>
70           </listitem>
71           <listitem>
72             <simpara>and all the members of the GTK+ lists</simpara>
73           </listitem></itemizedlist>
74         <para> If we forgot you, please email us! Thanks again (I know,
75           it's really short :) </para>
76       </sect2>
77       
78       <!-- ----------------------------------------------------------------- -->
79       
80       <sect2>
81         <title>Authors</title>
82         <para>The original authors of GTK+ were:</para>
83         <itemizedlist spacing=Compact>
84           <listitem>
85             <simpara>Peter Mattis</simpara>
86           </listitem>
87           <listitem>
88             <simpara>Spencer Kimball</simpara>
89           </listitem>
90           <listitem>
91             <simpara>Josh MacDonald</simpara>
92           </listitem>
93         </itemizedlist>
94         <para>Since then, much has been added by others. Please see the
95               AUTHORS file in the distribution for the GTK+ Team.</para>
96       </sect2>
97
98       <!-- ----------------------------------------------------------------- -->
99
100       <sect2>
101         <title>What is GTK+?</title>
102         <para>GTK+ is a small and efficient widget set designed with
103         the general look and feel of Motif.  In reality, it looks much
104         better than Motif.  It contains common widgets and some more
105         complex widgets such as a file selection, and color selection
106         widgets.</para>
107         <para>GTK+ provides some unique features. (At least, I know of
108         no other widget library which provides them). For example, a
109         button does not contain a label, it contains a child widget,
110         which in most instances will be a label.  However, the child
111         widget can also be a pixmap, image or any combination possible
112         the programmer desires. This flexibility is adhered to
113         throughout the library.</para>
114       </sect2>
115
116       <!-- ----------------------------------------------------------------- -->
117
118       <sect2>
119         <title>What is the + in GTK+?</title>
120         <para>Peter Mattis informed the gtk mailing list that:</para>
121         <para><quote>I originally wrote gtk which included the three
122         libraries, libglib, libgdk and libgtk. It featured a flat
123         widget hierarchy. That is, you couldn't derive a new widget
124         from an existing one. And it contained a more standard
125         callback mechanism instead of the signal mechanism now present
126         in gtk+. The + was added to distinguish between the original
127         version of gtk and the new version. You can think of it as
128         being an enhancement to the original gtk that adds object
129         oriented features.</quote></para>
130       </sect2>
131
132       <!-- ----------------------------------------------------------------- -->
133
134       <sect2>
135         <title>Does the G in GTK+, GDK and GLib stand for?</title>
136         <para>GTK+ == Gimp Toolkit</para>
137         <para>GDK == GTK+ Drawing Kit</para>
138         <para>GLib == G Libray</para>
139       </sect2>
140
141       <!-- ----------------------------------------------------------------- -->
142
143       <sect2>
144         <title>Where is the documentation for GTK+?</title>
145         <para>In the GTK+ distribution's doc/ directory you will find
146         the reference material for both GTK and GDK, this FAQ and the
147         GTK Tutorial.</para>
148         <para>In addition, you can find links to HTML versions of
149         these documents  by going to <ulink url="http://www.gtk.org/">
150         http://www.gtk.org/</ulink>. A
151         packaged version of the GTK Tutorial, with SGML, HTML,
152         Postscript, DVI and text versions can be found in <ulink
153         url="ftp://ftp.gtk.org/pub/gtk/tutorial">ftp://ftp.gtk.org/pub/gtk/tutorial
154         </ulink></para>
155         <para>There are now a couple of books available that deal with
156         programming GTK+, GDK and GNOME:</para>
157         <itemizedlist>
158           <listitem><simpara>Eric Harlows book entitled "Developing
159           Linux Applications with GTK+ and GDK". The ISBN is 0-7357-0021-4</simpara>
160           </listitem>
161           <listitem><simpara>The example code from Eric's book is
162           available on-line at <ulink
163           url="http://www.bcpl.net/~eharlow/book">
164           http://www.bcpl.net/~eharlow/book</ulink></simpara>
165           </listitem>
166           <listitem><simpara>Havoc Pennington has released a book called
167           "GTK+/GNOME Application Development". The ISBN is 0-7357-0078-8</simpara>
168             <simpara>The free version of the book lives here: <ulink
169           url="http://developer.gnome.org/doc/GGAD/">http://developer.gnome.org/doc/GGAD/
170           </ulink></simpara>
171             <simpara>And Havoc maintains information about it and
172           errata here: <ulink
173           url="http://pobox.com/~hp/gnome-app-devel.html">http://pobox.com/~hp/gnome-app-devel.html
174           </ulink></simpara>
175           </listitem>
176         </itemizedlist>
177       </sect2>
178
179       <!-- ----------------------------------------------------------------- -->
180
181       <sect2>
182         <title>Is there a mailing list (or mailing list archive) for
183         GTK+?</title>
184         <para>Information on mailing lists relating to GTK+ can be
185         found at: <ulink
186         url="http://www.gtk.org/mailinglists.html">http://www.gtk.org/mailinglists.html
187         </ulink></para>
188       </sect2>
189
190       <!-- ----------------------------------------------------------------- -->
191
192       <sect2>
193         <title>How to get help with GTK+</title>
194         <para>First, make sure your question isn't answered in the
195         documentation, this FAQ or the tutorial. Done that? You're
196         sure you've done that, right? In that case, the best place to
197         post questions is to the GTK+ mailing list.</para>
198       </sect2>
199
200       <!-- ----------------------------------------------------------------- -->
201
202       <sect2>
203         <title>How to report bugs in GTK+</title>
204         <para>Bugs should be reported to the GNOME bug tracking system
205         (<ulink
206         url="http://bugs.gnome.org">http://bugs.gnome.org</ulink>). To
207         report a problem about GTK+, send mail to submit@bugs.gnome.org.</para>
208         <para>The subject of the mail should describe your problem. In
209         the body of the mail, you should first include a
210         "pseudo-header" that gives the package and version
211         number. This should be separated by a blank line from the
212         actual headers.</para>
213
214         <para><literallayout><literal>Package: gtk+</literal>
215         <literal>Version: 1.2.0</literal></literallayout></para>
216
217         <para>Substitute 1.2.0 with the version of GTK+ that you have installed.</para>
218         <para>Then describe the bug. Include:</para>
219         
220         <itemizedlist>
221           <listitem><simpara> Information about your system. For instance:</simpara>
222             <itemizedlist spacing=compact>
223               <listitem><simpara> What operating system and version</simpara>
224               </listitem>
225               <listitem><simpara> What version of X</simpara>
226               </listitem>
227               <listitem><simpara> For Linux, what version of the C library</simpara>
228               </listitem>
229             </itemizedlist>
230             <para>And anything else you think is relevant.</para>
231           </listitem>
232           <listitem><simpara> How to reproduce the bug.</simpara>
233             <simpara>If you can reproduce it with the testgtk program
234             that is built in the gtk/ subdirectory, that will be most
235             convenient. Otherwise, please include a short test program
236             that exhibits the behavior. As a last resort, you can also
237             provide a pointer to a larger piece of software that can
238             be downloaded.</simpara>
239             <simpara>(Bugs that can be reproduced within the GIMP are
240             almost as good as bugs that can be reproduced in
241             testgtk. If you are reporting a bug found with the GIMP,
242             please include the version number of the GIMP you are
243             using)</simpara>
244           </listitem>
245           <listitem><simpara> If the bug was a crash, the exact text that was
246           printed out when the crash occured.</simpara>
247           </listitem>
248           <listitem><simpara> Further information such as stack traces
249   may be useful, but are not necessary. If you do send a stack trace,
250   and the error is an X error, it will be more useful if the stacktrace is produced running
251   the test program with the <literal>--sync</literal> command line option.</simpara>
252           </listitem>
253         </itemizedlist>
254       </sect2>
255
256       <!-- ----------------------------------------------------------------- -->
257
258       <sect2>
259         <title>Is there a Windows version of GTK+?</title>
260         <para>There is an on going port of GTK+ to the Windows
261         platform which is making impressive progress.</para>
262         <para>See <ulink
263         url="http://www.iki.fi/tml/gimp/win32">http://www.iki.fi/tml/gimp/win32</ulink>
264         for more information.</para>
265       </sect2>
266
267       <!-- ----------------------------------------------------------------- -->
268
269       <sect2>
270         <title>What applications have been written with GTK+?</title>
271         <para>A list of some GTK+ based application can be found on
272         the GTK+ web server at <ulink
273         url="http://www.gtk.org/apps/">http://www.gtk.org/apps/</ulink>
274         and contains more than 350 applications.</para>
275         <para>Failing that, look for a project to work on for the
276         GNOME project, <ulink
277         url="http://www.gnome.org/">http://www.gnome.org/</ulink>
278         Write a game. Write something that is useful.</para>
279         <para>Some of these are:</para>
280
281         <itemizedlist>
282           <listitem><simpara> GIMP (<ulink
283           url="http://www.gimp.org/">http://www.gimp.org/</ulink>), an
284           image manipulation program</simpara>
285           </listitem>
286           <listitem><simpara> AbiWord (<ulink
287           url="http://www.abisource.com/">http://www.abisource.com/</ulink>),
288           a professional word processor</simpara>
289           </listitem>
290           <listitem><simpara> Gzilla (<ulink
291           url="http://www.levien.com/gzilla/">http://www.levien.com/gzilla/</ulink>),
292           a web browser</simpara>
293           </listitem>
294           <listitem><simpara> XQF (<ulink
295           url="http://www.botik.ru/~roma/quake/">http://www.botik.ru/~roma/quake/</ulink>),
296           a QuakeWorld/Quake2 server browser and launcher</simpara>
297           </listitem>
298           <listitem><simpara> GDK Imlib (<ulink
299           url="http://www.rasterman.com/imlib.html">http://www.rasterman.com/imlib.html</ulink>),
300           a fast image loading and manipulation library for GDK</simpara>
301           </listitem>
302           <listitem><simpara> Glade (<ulink
303           url="http://glade.pn.org/">http://glade.pn.org/</ulink>), a
304           GTK+ based RAD tool which produces GTK+ applications</simpara>
305           </listitem>
306         </itemizedlist>
307        </sect2>
308
309       <!-- ----------------------------------------------------------------- -->
310
311       <sect2>
312         <title>I'm looking for an application to write in GTK+. How
313         about an IRC client?</title>
314         <para>Ask on gtk-list for suggestions. There are at least
315         three IRC clients already under development (probably more in fact. The server at
316         <ulink url="http://www.forcix.cx/irc-clients.html">
317         http://www.forcix.cx/irc-clients.html</ulink> list a bunch of them).</para>
318
319         <itemizedlist spacing=compact>
320           <listitem><simpara> X-Chat.</simpara>
321           </listitem>
322           <listitem><simpara> girc. (Included with GNOME)</simpara>
323           </listitem>
324           <listitem><simpara> gsirc. (In the gnome CVS tree)</simpara>
325           </listitem>
326         </itemizedlist>
327       </sect2>
328     </sect1>
329   </chapter>
330
331   <!-- ***************************************************************** -->
332   <chapter>
333     <title>How to find, configure, install, and troubleshoot GTK+</title>
334     <sect1>
335       <title></title>
336  
337       <!-- ----------------------------------------------------------------- -->
338
339      <sect2>
340         <title>What do I need to run GTK+?</title>
341         <para>To compile GTK+, all you need is a C compiler (gcc) and
342         the X Window System and associated libraries on your system.</para>
343       </sect2>
344  
345       <!-- ----------------------------------------------------------------- -->
346
347      <sect2>
348         <title>Where can I get GTK+?</title>
349         <para>The canonical site is <ulink
350         url="ftp://ftp.gtk.org/pub/gtk">ftp://ftp.gtk.org/pub/gtk</ulink>.</para>
351         <para>This site tends to get busy around the time of a new
352         GTK+ release so try and use one of the mirror sites that are
353         listed in <ulink
354         url="ftp://ftp.gtk.org/etc/mirrors">ftp://ftp.gtk.org/etc/mirrors</ulink></para>
355         <para>Here's a few mirror sites to get you started:</para>
356
357         <itemizedlist spacing=compact>
358           <listitem><simpara> Africa - ftp://ftp.is.co.za/applications/gimp/</simpara>
359           </listitem>
360           <listitem><simpara> Australia - ftp://ftp.au.gimp.org/pub/gimp/</simpara>
361           </listitem>
362           <listitem><simpara> Finland - ftp://ftp.funet.fi/pub/sci/graphics/packages/gimp</simpara>
363           </listitem>
364           <listitem><simpara> Germany - ftp://infosoc.uni-koeln.de/pub/ftp.gimp.org/</simpara>
365           </listitem>
366           <listitem><simpara> Japan - ftp://SunSITE.sut.ac.jp/pub/archives/packages/gimp/</simpara>
367           </listitem>
368           <listitem><simpara> UK - ftp://ftp.flirble.org/pub/X/gimp/</simpara>
369           </listitem>
370           <listitem><simpara> US - ftp://ftp.insync.net/pub/mirrors/ftp.gimp.org/</simpara>
371           </listitem>
372         </itemizedlist>
373       </sect2>
374  
375       <!-- ----------------------------------------------------------------- -->
376
377      <sect2>
378         <title>How do I configure/compile GTK+?</title>
379         <para>Generally, all you will need to do is issue the commands:</para>
380
381         <para><literallayout><literal>./configure</literal>
382         <literal>make</literal></literallayout></para>
383
384         <para>in the gtk+-version/ directory.</para>
385       </sect2>
386
387       <!-- ----------------------------------------------------------------- -->
388
389      <sect2>
390         <title>When compiling GTK+ I get an error like: <literal>make:
391         file `Makefile' line 456: Syntax error</literal></title>
392         <para>Make sure that you are using GNU make (use <literal>make
393         -v</literal>
394         to check). There are many weird and wonderful versions of make
395         out there, and not all of them handle the automatically
396         generated Makefiles.</para>
397       </sect2>
398
399       <!-- ----------------------------------------------------------------- -->
400
401      <sect2>
402         <title>I've compiled and installed GTK+, but I can't get any
403         programs to link with it!</title>
404         <para>This problem is most often encountered when the GTK+
405         libraries can't be  found or are the wrong version. Generally,
406         the compiler will complain about an 'unresolved symbol'.
407         There are two things you need to check:</para>
408
409         <itemizedlist>
410           <listitem><simpara>Make sure that the libraries can be
411  found. You want to edit <filename>/etc/ld.so.conf</filename> to
412  include the directories which contain the GTK libraries,
413  so it looks something like:</simpara>
414         <para><literallayout><literal>/usr/X11R6/lib</literal>
415         <literal>/usr/local/lib</literal></literallayout></para>
416
417             <para>Then you need to run /sbin/ldconfig as root. You can
418             find what directory GTK is in using</para>
419
420         <para><literallayout><literal>gtk-config --libs</literal>
421         </literallayout></para>
422
423             <para>If your system doesn't use ld.so to find libraries
424 (such as Solaris), then you will have to use the LD_LIBRARY_PATH
425 environment variable (or compile the path into your program, which I'm
426 not going to cover here). So, with a Bourne type shell you can do (if
427 your GTK libraries are in /usr/local/lib):</para>
428
429             <para><literallayout><literal>export LD_LIBRARY_PATH=/usr/local/lib</literal></literallayout></para>
430
431             <para>and in a csh, you can do:</para>
432
433             <para><literallayout><literal>setenv LD_LIBRARY_PATH /usr/local/lib</literal></literallayout></para>
434
435           </listitem>
436           <listitem><simpara>Make sure the linker is finding the
437 correct set of libraries. If you have a Linux distribution that
438 installs GTK+ (e.g. RedHat 5.0) then this  older version may be
439 used. Now (assuming you have a RedHat system), issue the
440 command</simpara>
441
442             <para><literallayout><literal>rpm -e gtk gtk-devel</literal></literallayout></para>
443          
444             <para>You may also want to remove the packages that depend
445 on gtk (rpm will tell you which ones they are).  If you don't have a RedHat Linux system, check to make sure
446 that neither <filename>/usr/lib</filename> or <filename>/usr/local/lib</filename> contain any of
447 the libraries libgtk, libgdk, libglib, or libgck.  If they do exist, remove them
448 (and any gtk include files, such as <filename>/usr/include/gtk</filename> and <filename>/usr/include/gdk</filename>) 
449 and reinstall gtk+.</para>
450           </listitem>
451             
452         </itemizedlist>
453       </sect2>
454
455       <!-- ----------------------------------------------------------------- -->
456
457      <sect2>
458         <title>When compiling programs with GTK+, I get compiler error
459         messages about not being able to find
460         <literal>glibconfig.h</literal>.</title>
461         <para>The header file "glibconfig.h" was moved to the
462         directory $exec_prefix/lib/glib/include/. $exec_prefix is the
463         directory that was specified by giving the --exec-prefix flags
464         to ./configure when compiling GTK+. It defaults to  $prefix,
465         (specified with --prefix), which in turn defaults to /usr/local/.</para>
466
467         <para>This was done because "glibconfig.h" includes
468         architecture dependent information, and the rest of the
469         include files are put in $prefix/include, which can be shared
470         between different architectures.</para>
471
472         <para>GTK+ includes a shell script, <literal>/gtk-config/</literal>, that makes it
473         easy to find out the correct include paths. The GTK+ Tutorial
474         includes an example of using <literal>/gtk-config/</literal> for simple
475         compilation from the command line. For information about more
476         complicated configuration, see the file docs/gtk-config.txt in
477         the GTK+ distribution.</para>
478
479         <para>If you are trying to compile an old program, you may be
480         able to work around the problem by configuring it with a
481         command line like:</para>
482
483         <para><literallayout><literal>setenv CPPFLAGS "-I/usr/local/include/glib/include"</literal>
484 <literal>./configure</literal></literallayout></para>
485
486         <para>(Substitute the appropriate value of $exec_prefix for
487         /usr/local.)</para>
488       </sect2>
489
490       <!-- ----------------------------------------------------------------- -->
491
492      <sect2>
493         <title>When installing a GTK+ application, configure reports
494         that it can't find GTK.</title>
495         <para>There are several common reasons for this:</para>
496         <itemizedlist>
497           <listitem><simpara>You have an old version of GTK installed
498           somewhere. RedHat 5.0, for example, installs an older copy of GTK that
499           may not work with the latest applications. You should remove this old
500           copy, but note that in the case of RedHat 5.0 this will
501           break the <literal>control-panel</literal> applications.</simpara>
502           </listitem>
503           <listitem><simpara><literal>gtk-config</literal> (or another
504         component of GTK) isn't in your path, or there is an old
505         version on your system. Type:</simpara>
506         <para><literallayout><literal>gtk-config --version</literal></literallayout></para>
507
508             <para>to check for both of these. If it returns a value
509             different from what you expect, then you have an old
510             version of GTK on your system.</para>
511           </listitem>
512           <listitem><simpara>The ./configure script can't find the GTK
513           libraries. As ./configure compiles various test programs, it needs to
514           be able to find the GTK libraries. See the question above
515           for help on this. </simpara></listitem>
516         </itemizedlist>
517
518         <para>If none of the above help, then have a look in
519         config.log, which is generated by ./configure as it runs. At the
520         bottom will be the last action it took before failing. If it is a
521         section of source code, copy the source code to a file and compile it
522         with the line just above it in config.log. If the compilation is
523         successful, try executing it.</para>
524       </sect2>
525
526     </sect1>
527   </chapter>
528
529   <!-- ***************************************************************** -->
530   <chapter>
531     <title>Development of GTK+</title>
532     <sect1>
533       <title></title>
534  
535       <!-- ----------------------------------------------------------------- -->
536
537      <sect2>
538         <title>Whats this CVS thing that everyone keeps talking about,
539         and how do I access it?</title>
540         <para>CVS is the Concurent Version System and is a very
541         popular means of version control for software projects. It is
542         designed to allow multiple  authors to be able to
543         simultanously operate on the same source tree.  This source
544         tree is centrally maintained, but each developer has a local
545         mirror of this repository that they make there changes to.</para>
546         <para>The GTK+ developers use a CVS repository to store the
547         master copy of the current development version of GTK+. As
548         such, people wishing to contribute patches to GTK+ should
549         generate them against the CVS version. Normal people should
550         use the packaged releases.</para>
551         <para>The CVS toolset is available as RPM packages from the
552         usual RedHat sites. The latest version is available at <ulink
553         url="http://download.cyclic.com/pub/">http://download.cyclic.com/pub/
554         </ulink></para>
555         <para>Anyone can download the latest CVS version of GTK+ by
556         using anonymous access using the following steps:</para>
557         <itemizedlist>
558           <listitem><simpara> In a bourne shell descendant (e.g. bash) type:</simpara>
559         <para><literallayout><literal>CVSROOT=':pserver:anonymous@anoncvs.gnome.org:/cvs/gnome'</literal>
560 <literal>export CVSROOT</literal></literallayout></para>
561           </listitem>
562           <listitem><simpara>Next, the first time the source tree is
563           checked out, a cvs login is needed. </simpara>
564         <para><literallayout><literal>cvs login</literal></literallayout></para>
565             <para>This will ask you for a password. There is no
566           password for cvs.gimp.org, so just enter a carriage return.</para>
567           </listitem>
568           <listitem><simpara>To get the tree and place it in a subdir of your
569           current working directory, issue the command:</simpara>
570         <para><literallayout><literal>cvs -z3 get gtk+</literal></literallayout></para>
571         <para>Note that with the GTK+ 1.1 tree, glib has been moved to
572         a separate CVS module, so if you don't have glib installed you will
573         need to get that as well:</para>
574         <para><literallayout><literal>cvs -z3 get glib</literal></literallayout></para>
575           </listitem>
576         </itemizedlist>
577       </sect2>
578  
579       <!-- ----------------------------------------------------------------- -->
580
581      <sect2>
582         <title>How can I contribute to GTK+?</title>
583         <para>It's simple. If something doesn't work like you think it
584         should in a program, check the documentation to make sure
585         you're not missing something. If it is a true bug or missing
586         feature, track it down in the GTK+ source, change it,  and
587         then generate a patch in the form of a 'context diff'. This
588         can be done using a command such as <literal>diff -ru
589         &lt;oldfile&gt; &lt;newfile&gt;.</literal>  Then upload the patchfile to:</para>
590         <para><literallayout><literal>ftp://ftp.gtk.org/incoming</literal></literallayout></para>
591         <para>along with a README file. Make sure you follow the
592         naming conventions or your patch will just be deleted! The
593         filenames should be of this form:</para>
594         <para><literallayout><literal>gtk&lt;username&gt;-&lt;date yymmdd-n&gt;.patch.gz</literal>
595 <literal>gtk-&lt;username&gt;-&lt;date yymmdd-n&gt;.patch.README</literal></literallayout></para>
596         <para>The "n" in the date indicates a unique number (starting
597         from 0) of patches you uploaded that day.  It should be 0,
598         unless you upload more than one patch in the same day.</para>
599
600         <para>Example:</para>
601         <para><literallayout><literal>gtk-gale-982701-0.patch.gz</literal>
602 <literal>gtk-gale-982701-0.patch.README</literal></literallayout></para>
603         <para>Once you upload <emphasis>anything</emphasis>, send the README to ftp-admin@gtk.org</para>
604       </sect2>
605  
606       <!-- ----------------------------------------------------------------- -->
607
608      <sect2>
609         <title>How do I know if my patch got applied, and if not, why
610         not?</title>
611         <para>Uploaded patches will be moved to
612         <filename>ftp://ftp.gtk.org/pub/gtk/patches</filename> where one of the
613         GTK+ development team will pick them up. If applied, they will
614         be moved to <filename>/pub/gtk/patches/old</filename>.</para>
615         <para>Patches that aren't applied, for whatever reason, are
616         moved to <filename>/pub/gtk/patches/unapplied</filename> or
617         <filename>/pub/gtk/patches/outdated</filename>. At this point you can ask
618         on the <literal>gtk-list</literal> mailing list why your patch wasn't
619         applied. There are many possible reasons why patches may not
620         be applied, ranging from it doesn't apply cleanly, to it isn't
621         right. Don't be put off if your patch didn't make it first
622         time round.</para>
623       </sect2>
624  
625       <!-- ----------------------------------------------------------------- -->
626
627      <sect2>
628         <title>What is the policy on incorporating new widgets into
629         the library?</title>
630         <para>This is up to the authors, so you will have to ask them
631         once you are done with your widget. As a general guideline,
632         widgets that are  generally useful, work, and are not a
633         disgrace to the widget set will gladly be included.</para>
634       </sect2>
635
636       <!-- ----------------------------------------------------------------- -->
637
638      <sect2>
639         <title>Is anyone working on bindings for languages other than
640         C?</title>
641         <para>The GTK+ home page (<ulink
642         url="http://www.gtk.org/">http://www.gtk.org/</ulink>)
643         presents a list of GTK+ bindings.</para>
644         <itemizedlist>
645           <listitem><simpara>There are several C++ wrappers for GTK+.</simpara>
646             <itemizedlist> 
647               <listitem><simpara>the gtk-- package, which is a very small wrapper for GTK+.
648               You can find the home page at <ulink
649               url="http://www.cs.tut.fi/~p150650/gtk/gtk--.html">
650               http://www.cs.tut.fi/~p150650/gtk/gtk--.html</ulink>. The FTP site is 
651               <ulink url="ftp://ftp.gtk.org/pub/gtk/gtk--">
652               ftp://ftp.gtk.org/pub/gtk/gtk--</ulink>.</simpara>
653               </listitem>
654               <listitem><simpara>the VDK package, which was built as
655               the base package of a GTK+ application Borland-like
656               builder. The home page can be found at <ulink
657               url="http://www.guest.net/homepages/mmotta/VDKHome">
658               http://www.guest.net/homepages/mmotta/VDKHome</ulink>.</simpara>
659               </listitem>
660
661               <listitem><simpara>The wxWindows/Gtk package, a free C++ library for cross-platform 
662               GUI development. The home page of this package is
663               <ulink url="http://www.freiburg.linux.de/~wxxt/">
664               http://www.freiburg.linux.de/~wxxt/</ulink>.</simpara>
665               </listitem>
666             </itemizedlist>
667           </listitem>
668           <listitem><simpara>There are three known Objective-c
669           bindings currently in development:</simpara>
670             <itemizedlist> 
671               <listitem><simpara>The <ulink
672           url="http://www.gnome.org/">http://www.gnome.org/</ulink>
673           package of choice is objgtk. Objgtk is based on the Object class and is maintained by
674           <ulink url="mailto:sopwith@cuc.edu">Elliot Lee</ulink>. Apparently,
675           objgtk is being accepted as the `standard' Objective-C binding for GTK+.</simpara>
676               </listitem>
677
678               <listitem><simpara>If you are more inclined towards the 
679               <ulink url="http://www.gnustep.org/">GNUstep project</ulink>,
680               you may want to check out GTKKit by 
681               <ulink url="mailto:helge@mdlink.de">Helge He&szlig;</ulink>.
682               The intention is to setup a GTK+ binding using the FoundationKit. 
683               GTKKit includes nicities like writing a XML-type template file to 
684               construct a GTK+ interface.</simpara>
685               </listitem>
686
687               <listitem><simpara>The GToolKit package, which can be found at
688   <ulink url="ftp://ftp.gtk.org/pub/gtk/objc-gtoolkit/">
689   ftp://ftp.gtk.org/pub/gtk/objc-gtoolkit/</ulink>.</simpara>
690               </listitem>
691             </itemizedlist>
692           </listitem>
693           <listitem><simpara>Perl bindings <ulink
694           url="ftp://ftp.gtk.org/pub/gtk/perl">ftp://ftp.gtk.org/pub/gtk/perl</ulink></simpara>
695           </listitem>
696           <listitem><simpara>Guile bindings. The home page is at
697   <ulink url="http://www.ping.de/sites/zagadka/guile-gtk">http://www.ping.de/sites/zagadka/guile-gtk</ulink>.
698   By the way, Guile is the GNU Project's implemention of R4RS Scheme (the
699   standard). If you like Scheme, you may want to take a look at this.</simpara>
700           </listitem>
701           <listitem><simpara>David Monniaux reports:
702   <quote>I've started a gtk-O'Caml binding system.
703   The basics of the system, including callbacks, work fine.
704
705   The current development is in
706   <ulink url="http://www.ens-lyon.fr/~dmonniau/arcs">http://www.ens-lyon.fr/~dmonniau/arcs</ulink>
707   </quote></simpara>
708           </listitem>
709           <listitem><simpara>Several python bindings have been done:</simpara>
710             <itemizedlist>
711               <listitem><simpara>pygtk is at 
712   <ulink url="http://www.daa.com.au/~james/pygtk">http://www.daa.com.au/~james/pygtk</ulink> and 
713   <ulink url="ftp://ftp.gtk.org/pub/gtk/python">ftp://ftp.gtk.org/pub/gtk/python</ulink></simpara>
714               </listitem>
715
716               <listitem><simpara>python-gtk is at
717   <ulink url="http://www.ucalgary.ca/~nascheme/python-gtk">http://www.ucalgary.ca/~nascheme/python-gtk</ulink></simpara>
718               </listitem>
719             </itemizedlist>
720           </listitem>
721           <listitem><simpara>There's are a couple of OpenGL/Mesa
722           widgets available for GTK+. I suggest you start at
723   <ulink url="http://www.student.oulu.fi/~jlof/gtkglarea/index.html">http://www.student.oulu.fi/~jlof/gtkglarea/index.html</ulink></simpara>
724           </listitem>
725           <listitem><simpara>Last, there are a lot of other language
726           bindings for languages such as Eiffel, TOM, Pascal, Pike, etc.</simpara>
727           </listitem>
728         </itemizedlist>
729       </sect2>
730
731     </sect1>
732   </chapter>
733
734   <!-- ***************************************************************** -->
735   <chapter>
736     <title>Development with GTK+: the begining</title>
737     <sect1>
738       <title></title>
739  
740       <!-- ----------------------------------------------------------------- -->
741
742      <sect2>
743         <title>How do I get started?</title>
744         <para>So, after you have installed GTK+ there are a couple of
745         things that can ease you into developing applications with
746         it. There is the GTK+ Tutorial <ulink
747         url="http://www.gtk.org/tutorial/">
748         http://www.gtk.org/tutorial/</ulink>, which is undergoing
749         development. This will introduce you to writing applications
750         using C.</para>
751
752         <para>The Tutorial doesn't (yet) contain information on all of
753         the widgets that are in GTK+. For example code on how to use
754         the basics of all the GTK+ widgets you should look at the file
755         gtk/testgtk.c (and associated source files) within the GTK+
756         distribution. Looking at these examples will give you a good
757         grounding on what the widgets can do.</para>
758       </sect2>
759  
760       <!-- ----------------------------------------------------------------- -->
761
762      <sect2>
763         <title>I tried to compile a small <command>Hello World</command> of mine,
764         but it failed. Any clue?</title>
765         <para>Since you are good at coding, we will not deal with
766         compile time error here :)</para>
767
768         <para>The classic command line to compile a GTK+ based program is</para>
769         <para><literallayout><literal>gcc -o myprog [c files list] `gtk-config --cflags --libs`</literal></literallayout></para>
770
771         <para>You should notice the backquote character which is used
772         in this command line. A common mistake when you start a GTK+
773         based development is to use quote instead of backquotes. If
774         you do so, the compiler will complain about an unknown file
775         called <filename>gtk-config --cflags --libs</filename>. The
776         text in backquotes is an instruction to your shell to
777         substitute the output of executing this text into the
778         commandline.</para>
779
780         <para>The command line above ensure that:</para>
781         <itemizedlist>
782
783           <listitem><simpara>the correct C compiler flags will be used
784            to compile the program (including the complete C header
785            directory list)</simpara>
786           </listitem>
787
788           <listitem><simpara>your program will be linked with the
789           needed libraries.</simpara>
790           </listitem>
791         </itemizedlist>
792       </sect2>
793  
794       <!-- ----------------------------------------------------------------- -->
795
796      <sect2>
797         <title>What about using the <command>make</command>
798         utility?</title>
799
800         <para>This is a sample makefile which compile a GTK+ based
801         program:</para>
802 <programlisting role="C">
803 # basic GTK+ app makefile
804 SOURCES = myprg.c foo.c bar.c
805 OBJS    = ${SOURCES:.c=.o}
806 CFLAGS  = `gtk-config --cflags`
807 LDADD   = `gtk-config --libs`
808 CC      = gcc
809 PACKAGE = myprg
810
811 all : ${OBJS}
812         ${CC} -o ${PACKAGE} ${OBJS} ${LDADD}
813
814 .c.o:
815         ${CC} ${CFLAGS} -c $<
816
817 # end of file
818 </programlisting>
819
820         <para>For more information about the <command>make</command> utility, you
821         should read either the related man page or the relevant info file.</para>
822       </sect2>
823  
824       <!-- ----------------------------------------------------------------- -->
825
826      <sect2>
827         <title>I use the backquote stuff in my makefiles, but my make
828         process failed.</title>
829
830         <para>The backquote construction seems to not be accepted by
831         some old <command>make</command> utilities. If you use one of these, the
832         make process will probably fail. In order to have the
833         backquote syntax working again, you should use the GNU make
834         utility (get it on the GNU ftp server at <ulink
835         url="ftp://ftp.gnu.org/">ftp://ftp.gnu.org/"</ulink>).</para>
836       </sect2>
837  
838       <!-- ----------------------------------------------------------------- -->
839
840      <sect2>
841         <title>I want to add some configure stuff, how could I do
842         this?</title>
843
844         <para>To use autoconf/automake, you must first install the
845         relevant packages. These are:</para>
846
847         <itemizedlist spacing=Compact>
848           <listitem><simpara>the m4 preprocessor v1.4 or better</simpara>
849           </listitem>
850           <listitem><simpara>autoconf v2.13 or better</simpara>
851           </listitem>
852           <listitem><simpara>automake v1.4 or better</simpara>
853           </listitem>
854         </itemizedlist>
855
856         <para>You'll find these packages on the GNU main ftp server
857         (<ulink url="ftp://ftp.gnu.org/">ftp://ftp.gnu.org/</ulink>)
858         or on any GNU mirror.</para>
859
860         <para>In order to use the powerful autoconf/automake scheme,
861         you must create a configure.in which may look like:</para>
862
863 <programlisting role="C">
864 dnl Process this file with autoconf to produce a configure script.
865 dnl configure.in for a GTK+ based program
866
867 AC_INIT(myprg.c)dnl
868 AM_INIT_AUTOMAKE(mypkgname,0.0.1)dnl
869 AM_CONFIG_HEADER(config.h)dnl
870
871 dnl Checks for programs.
872 AC_PROG_CC dnl check for the c compiler
873 dnl you should add CFLAGS="" here, 'cos it is set to -g by PROG_CC
874
875 dnl Checks for libraries.
876 AM_PATH_GTK(1.2.0,,AC_MSG_ERROR(mypkgname 0.1 needs GTK))dnl
877
878 AC_OUTPUT(
879         Makefile
880 )dnl
881 </programlisting>
882
883         <para>You must add a Makefile.am file:</para>
884
885 <programlisting role="C">
886 bin_PROGRAMS    = myprg
887 myprg_SOURCES   = myprg.c foo.c bar.c
888 INCLUDES        = @GTK_CFLAGS@
889 LDADD           = @GTK_LIBS@
890 CLEANFILES      = *~
891 DISTCLEANFILES  = .deps/*.P
892 </programlisting>
893
894         <para>If your project contains more than one subdirectory,
895         you'll have to create one Makefile.am in each directory plus a
896         master Makefile.am which will look like:</para>
897
898 <programlisting role="C">
899 SUBDIRS         = mydir1 mydir2 mydir3
900 </programlisting>
901
902         <para>then, to use these, simply type the following
903         commands:</para>
904
905 <programlisting role="C">
906 aclocal
907 autoheader
908 autoconf
909 automake --add-missing --include-deps --foreign 
910 </programlisting>
911
912         <para>For further information, you should look at the autoconf
913         and the automake documentation (the shipped info files are
914         really easy to understand, and there are plenty of web
915         resources that deal with autoconf and automake).</para>
916       </sect2>
917  
918       <!-- ----------------------------------------------------------------- -->
919
920      <sect2>
921         <title>I try to debug my GTK+ application with gdb, but it
922         hangs my X server when I hit some breakpoint. Any
923         Idea?</title>
924
925         <para>From Federico Mena Quintero:
926         <quote>X is not locked up.  It is likely that you are hitting a breakpoint
927         inside a callback that is called from a place in Gtk that has a mouse grab.
928
929         Run your program with the <literal>--sync</literal>
930         option; it will make it easier to debug. Also, you may want to
931         use the console for running the debugger, and just let the
932         program run in another console with the X server.</quote></para>
933
934         <para>Eric Mouw had another solution:
935         <quote>An old terminal connected to an otherwise unused serial
936         port is also great for debugging X programs. Old vt100/vt220
937         terminals are dirt cheap but a bit hard to get (here in The
938         Netherlands, YMMV).</quote></para>
939       </sect2>
940     </sect1>
941   </chapter>
942
943   <!-- ***************************************************************** -->
944   <chapter>
945     <title>Development with GTK+: general questions</title>
946     <sect1>
947       <title></title>
948  
949       <!-- ----------------------------------------------------------------- -->
950
951      <sect2>
952         <title>What widgets are in GTK?</title>
953
954         <para>The GTK+ Tutorial lists the following widgets:</para>
955 <programlisting role="C">
956   GtkObject
957    +GtkData
958    | +GtkAdjustment
959    | `GtkTooltips
960    `GtkWidget
961      +GtkContainer
962      | +GtkBin
963      | | +GtkAlignment
964      | | +GtkEventBox
965      | | +GtkFrame
966      | | | `GtkAspectFrame
967      | | +GtkHandleBox
968      | | +GtkItem
969      | | | +GtkListItem
970      | | | +GtkMenuItem
971      | | | | `GtkCheckMenuItem
972      | | | |   `GtkRadioMenuItem
973      | | | `GtkTreeItem
974      | | +GtkViewport
975      | | `GtkWindow
976      | |   +GtkColorSelectionDialog
977      | |   +GtkDialog
978      | |   | `GtkInputDialog
979      | |   `GtkFileSelection
980      | +GtkBox
981      | | +GtkButtonBox
982      | | | +GtkHButtonBox
983      | | | `GtkVButtonBox
984      | | +GtkHBox
985      | | | +GtkCombo
986      | | | `GtkStatusbar
987      | | `GtkVBox
988      | |   +GtkColorSelection
989      | |   `GtkGammaCurve
990      | +GtkButton
991      | | +GtkOptionMenu
992      | | `GtkToggleButton
993      | |   `GtkCheckButton
994      | |     `GtkRadioButton
995      | +GtkCList
996      |   `GtkCTree
997      | +GtkFixed
998      | +GtkList
999      | +GtkMenuShell
1000      | | +GtkMenuBar
1001      | | `GtkMenu
1002      | +GtkNotebook
1003      | +GtkPaned
1004      | | +GtkHPaned
1005      | | `GtkVPaned
1006      | +GtkScrolledWindow
1007      | +GtkTable
1008      | +GtkToolbar
1009      | `GtkTree
1010      +GtkDrawingArea
1011      | `GtkCurve
1012      +GtkEditable
1013      | +GtkEntry
1014      | | `GtkSpinButton
1015      | `GtkText
1016      +GtkMisc
1017      | +GtkArrow
1018      | +GtkImage
1019      | +GtkLabel
1020      | | `GtkTipsQuery
1021      | `GtkPixmap
1022      +GtkPreview
1023      +GtkProgressBar
1024      +GtkRange
1025      | +GtkScale
1026      | | +GtkHScale
1027      | | `GtkVScale
1028      | `GtkScrollbar
1029      |   +GtkHScrollbar
1030      |   `GtkVScrollbar
1031      +GtkRuler
1032      | +GtkHRuler
1033      | `GtkVRuler
1034      `GtkSeparator
1035        +GtkHSeparator
1036        `GtkVSeparator
1037 </programlisting>
1038       </sect2>
1039  
1040       <!-- ----------------------------------------------------------------- -->
1041
1042      <sect2>
1043         <title>Is GTK+ thread safe? How do I write multi-threaded GTK+
1044         applications?</title>
1045
1046         <para>The GLib library can be used in a thread-safe mode by
1047          calling g_thread_init() before making any other GLib
1048          calls. In this mode GLib automatically locks all internal
1049          data structures as needed.  This does not mean that two
1050          threads can simultaneously access, for example, a single hash
1051          table, but they can access two different hash tables
1052          simultaneously. If two different threads need to access the
1053          same hash table, the application is responsible for locking
1054          itself.</para>
1055
1056         <para>When GLib is intialized to be thread-safe, GTK+ is
1057          <emphasis>thread aware</emphasis>. There is a single global
1058          lock that you must acquire with gdk_threads_enter() before
1059          making any GDK calls, and release with gdk_threads_leave()
1060          afterwards.</para>
1061
1062         <para>A minimal main program for a threaded GTK+ application
1063          looks like:</para>
1064
1065 <programlisting role="C">
1066 int
1067 main (int argc, char *argv[])
1068 {
1069   GtkWidget *window;
1070
1071   g_thread_init(NULL);
1072   gtk_init(&amp;argc, &amp;argv);
1073
1074   window = create_window();
1075   gtk_widget_show(window);
1076
1077   gdk_threads_enter();
1078   gtk_main();
1079   gdk_threads_leave();
1080
1081   return(0);
1082 }
1083 </programlisting>
1084
1085         <para>Callbacks require a bit of attention. Callbacks from
1086          GTK+ (signals) are made within the GTK+ lock. However
1087          callbacks from GLib (timeouts, IO callbacks, and idle
1088          functions) are made outside of the GTK+ lock. So, within a
1089          signal handler you do not need to call gdk_threads_enter(),
1090          but within the other types of callbacks, you do.</para>
1091
1092         <para>Erik Mouw contributed the following code example to
1093          illustrate how to use threads within GTK+ programs.</para>
1094
1095 <programlisting role="C">
1096 /*-------------------------------------------------------------------------
1097  * Filename:      gtk-thread.c
1098  * Version:       0.99.1
1099  * Copyright:     Copyright (C) 1999, Erik Mouw
1100  * Author:        Erik Mouw &lt;J.A.K.Mouw@its.tudelft.nl&gt;
1101  * Description:   GTK threads example. 
1102  * Created at:    Sun Oct 17 21:27:09 1999
1103  * Modified by:   Erik Mouw &lt;J.A.K.Mouw@its.tudelft.nl&gt;
1104  * Modified at:   Sun Oct 24 17:21:41 1999
1105  *-----------------------------------------------------------------------*/
1106 /*
1107  * Compile with:
1108  *
1109  * cc -o gtk-thread gtk-thread.c `gtk-config --cflags --libs gthread`
1110  *
1111  * Thanks to Sebastian Wilhelmi and Owen Taylor for pointing out some
1112  * bugs.
1113  *
1114  */
1115
1116 #include &lt;stdio.h&gt;
1117 #include &lt;stdlib.h&gt;
1118 #include &lt;unistd.h&gt;
1119 #include &lt;time.h&gt;
1120 #include &lt;gtk/gtk.h&gt;
1121 #include &lt;glib.h&gt;
1122 #include &lt;pthread.h&gt;
1123
1124 #define YES_IT_IS    (1)
1125 #define NO_IT_IS_NOT (0)
1126
1127 typedef struct 
1128 {
1129   GtkWidget *label;
1130   int what;
1131 } yes_or_no_args;
1132
1133 G_LOCK_DEFINE_STATIC (yes_or_no);
1134 static volatile int yes_or_no = YES_IT_IS;
1135
1136 void destroy(GtkWidget *widget, gpointer data)
1137 {
1138   gtk_main_quit();
1139 }
1140
1141 void *argument_thread(void *args)
1142 {
1143   yes_or_no_args *data = (yes_or_no_args *)args;
1144   gboolean say_something;
1145
1146   for(;;)
1147     {
1148       /* sleep a while */
1149       sleep(rand() / (RAND_MAX / 3) + 1);
1150
1151       /* lock the yes_or_no_variable */
1152       G_LOCK(yes_or_no);
1153
1154       /* do we have to say something? */
1155       say_something = (yes_or_no != data->what);
1156
1157       if(say_something)
1158         {
1159           /* set the variable */
1160           yes_or_no = data->what;
1161         }
1162
1163       /* Unlock the yes_or_no variable */
1164       G_UNLOCK(yes_or_no);
1165
1166       if(say_something)
1167         {
1168           /* get GTK thread lock */
1169           gdk_threads_enter();
1170
1171           /* set label text */
1172           if(data->what == YES_IT_IS)
1173             gtk_label_set_text(GTK_LABEL(data->label), "O yes, it is!");
1174           else
1175             gtk_label_set_text(GTK_LABEL(data->label), "O no, it isn't!");
1176
1177           /* release GTK thread lock */
1178           gdk_threads_leave();
1179         }
1180     }
1181
1182   return(NULL);
1183 }
1184
1185 int main(int argc, char *argv[])
1186 {
1187   GtkWidget *window;
1188   GtkWidget *label;
1189   yes_or_no_args yes_args, no_args;
1190   pthread_t no_tid, yes_tid;
1191
1192   /* init threads */
1193   g_thread_init(NULL);
1194
1195   /* init gtk */
1196   gtk_init(&amp;argc, &amp;argv);
1197
1198   /* init random number generator */
1199   srand((unsigned int)time(NULL));
1200
1201   /* create a window */
1202   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1203
1204   gtk_signal_connect(GTK_OBJECT (window), "destroy",
1205                      GTK_SIGNAL_FUNC(destroy), NULL);
1206
1207   gtk_container_set_border_width(GTK_CONTAINER (window), 10);
1208
1209   /* create a label */
1210   label = gtk_label_new("And now for something completely different ...");
1211   gtk_container_add(GTK_CONTAINER(window), label);
1212   
1213   /* show everything */
1214   gtk_widget_show(label);
1215   gtk_widget_show (window);
1216
1217   /* create the threads */
1218   yes_args.label = label;
1219   yes_args.what = YES_IT_IS;
1220   pthread_create(&amp;yes_tid, NULL, argument_thread, &amp;yes_args);
1221
1222   no_args.label = label;
1223   no_args.what = NO_IT_IS_NOT;
1224   pthread_create(&amp;no_tid, NULL, argument_thread, &amp;no_args);
1225
1226   /* enter the GTK main loop */
1227   gdk_threads_enter();
1228   gtk_main();
1229   gdk_threads_leave();
1230
1231   return(0);
1232 }
1233 </programlisting>
1234       </sect2>
1235  
1236       <!-- ----------------------------------------------------------------- -->
1237
1238      <sect2>
1239         <title>Why does this strange 'x io error' occur when I
1240         <literal>fork()</literal> in my GTK+ app?</title>
1241
1242         <para>This is not really a GTK+ problem, and the problem is
1243          not related to <literal>fork()</literal> either. If the 'x io
1244          error' occurs then you probably use the <literal>exit()</literal> function
1245          in order to exit from the child process.</para>
1246
1247         <para>When GDK opens an X display, it creates a socket file
1248          descriptor. When you use the <literal>exit()</literal>
1249          function, you implicitly close all the open file descriptors,
1250          and the underlying X library really doesn't like this.</para>
1251
1252         <para>The right function to use here is
1253         <literal>_exit()</literal>.</para> 
1254
1255         <para>Erik Mouw contributed the following code example to
1256          illustrate handling fork() and exit().</para>
1257
1258 <programlisting role="C">
1259 /*-------------------------------------------------------------------------
1260  * Filename:      gtk-fork.c
1261  * Version:       0.99.1
1262  * Copyright:     Copyright (C) 1999, Erik Mouw
1263  * Author:        Erik Mouw &lt;J.A.K.Mouw@its.tudelft.nl&gt;
1264  * Description:   GTK+ fork example
1265  * Created at:    Thu Sep 23 21:37:55 1999
1266  * Modified by:   Erik Mouw &lt;J.A.K.Mouw@its.tudelft.nl&gt;
1267  * Modified at:   Thu Sep 23 22:39:39 1999
1268  *-----------------------------------------------------------------------*/
1269 /*
1270  * Compile with:
1271  *
1272  * cc -o gtk-fork gtk-fork.c `gtk-config --cflags --libs`
1273  *
1274  */
1275
1276 #include &lt;stdio.h&gt;
1277 #include &lt;stdlib.h&gt;
1278 #include &lt;signal.h&gt;
1279 #include &lt;sys/types.h&gt;
1280 #include &lt;sys/wait.h&gt;
1281 #include &lt;unistd.h&gt;
1282 #include &lt;gtk/gtk.h&gt;
1283
1284 void sigchld_handler(int num)
1285 {
1286   sigset_t set, oldset;
1287   pid_t pid;
1288   int status, exitstatus;
1289
1290   /* block other incoming SIGCHLD signals */
1291   sigemptyset(&amp;set);
1292   sigaddset(&amp;set, SIGCHLD);
1293   sigprocmask(SIG_BLOCK, &amp;set, &amp;oldset);
1294
1295   /* wait for child */
1296   while((pid = waitpid((pid_t)-1, &amp;status, WNOHANG)) > 0)
1297     {
1298       if(WIFEXITED(status))
1299         {
1300           exitstatus = WEXITSTATUS(status);
1301
1302           fprintf(stderr, 
1303                   "Parent: child exited, pid = %d, exit status = %d\n", 
1304                   (int)pid, exitstatus);
1305         }
1306       else if(WIFSIGNALED(status))
1307         {
1308           exitstatus = WTERMSIG(status);
1309
1310           fprintf(stderr,
1311                   "Parent: child terminated by signal %d, pid = %d\n",
1312                   exitstatus, (int)pid);
1313         }
1314       else if(WIFSTOPPED(status))
1315         {
1316           exitstatus = WSTOPSIG(status);
1317
1318           fprintf(stderr,
1319                   "Parent: child stopped by signal %d, pid = %d\n",
1320                   exitstatus, (int)pid);
1321         }
1322       else
1323         {
1324           fprintf(stderr,
1325                   "Parent: child exited magically, pid = %d\n",
1326                   (int)pid);
1327         }
1328     }
1329
1330   /* re-install the signal handler (some systems need this) */
1331   signal(SIGCHLD, sigchld_handler);
1332   
1333   /* and unblock it */
1334   sigemptyset(&amp;set);
1335   sigaddset(&amp;set, SIGCHLD);
1336   sigprocmask(SIG_UNBLOCK, &amp;set, &amp;oldset);
1337 }
1338
1339 gint delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
1340 {
1341   return(FALSE);
1342 }
1343
1344 void destroy(GtkWidget *widget, gpointer data)
1345 {
1346   gtk_main_quit();
1347 }
1348
1349 void fork_me(GtkWidget *widget, gpointer data)
1350 {
1351   pid_t pid;
1352
1353   pid = fork();
1354
1355   if(pid == -1)
1356     {
1357       /* ouch, fork() failed */
1358       perror("fork");
1359       exit(-1);
1360     }
1361   else if(pid == 0)
1362     {
1363       /* child */
1364       fprintf(stderr, "Child: pid = %d\n", (int)getpid());
1365
1366       execlp("ls", "ls", "-CF", "/", NULL);
1367       
1368       /* if exec() returns, there is something wrong */
1369       perror("execlp");
1370
1371       /* exit child. note the use of _exit() instead of exit() */
1372       _exit(-1);
1373     }
1374   else
1375     {
1376       /* parent */
1377       fprintf(stderr, "Parent: forked a child with pid = %d\n", (int)pid);
1378     }
1379 }
1380
1381 int main(int argc, char *argv[])
1382 {
1383   GtkWidget *window;
1384   GtkWidget *button;
1385
1386   gtk_init(&amp;argc, &amp;argv);
1387
1388   /* the basic stuff: make a window and set callbacks for destroy and
1389    * delete events 
1390    */
1391   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1392
1393   gtk_signal_connect(GTK_OBJECT (window), "delete_event",
1394                      GTK_SIGNAL_FUNC(delete_event), NULL);
1395           
1396   gtk_signal_connect(GTK_OBJECT (window), "destroy",
1397                      GTK_SIGNAL_FUNC(destroy), NULL);
1398
1399 #if (GTK_MAJOR_VERSION == 1) && (GTK_MINOR_VERSION == 0)
1400   gtk_container_border_width(GTK_CONTAINER (window), 10);
1401 #else  
1402   gtk_container_set_border_width(GTK_CONTAINER (window), 10);
1403 #endif
1404
1405   /* add a button to do something usefull */
1406   button = gtk_button_new_with_label("Fork me!");
1407           
1408   gtk_signal_connect(GTK_OBJECT (button), "clicked",
1409                      GTK_SIGNAL_FUNC(fork_me), NULL);
1410
1411   gtk_container_add(GTK_CONTAINER(window), button);
1412           
1413   /* show everything */
1414   gtk_widget_show (button);
1415   gtk_widget_show (window);
1416
1417
1418   /* install a signal handler for SIGCHLD signals */
1419   signal(SIGCHLD, sigchld_handler);
1420
1421   
1422   /* main loop */
1423   gtk_main ();
1424
1425   exit(0);         
1426 }
1427 </programlisting>
1428       </sect2>
1429  
1430       <!-- ----------------------------------------------------------------- -->
1431
1432      <sect2>
1433         <title>Why don't the contents of a button move when the button
1434         is pressed? Here's a patch to make it work that way...</title>
1435
1436         <para>From: Peter Mattis
1437          <quote>The reason buttons don't move their child down and to
1438           the right when they are depressed is because I don't think
1439           that's what is happening visually. My view of buttons is
1440           that you are looking at them straight on. That is, the user
1441           interface lies in a plane and you're above it looking
1442           straight at it. When a button gets pressed it moves directly
1443           away from you. To be absolutely correct I guess the child
1444           should actually shrink a tiny amount. But I don't see why
1445           the child should shift down and to the left. Remember, the
1446           child is supposed to be attached to the buttons surface. Its
1447           not good for it to appear like the child is slipping on the
1448           surface of the button.
1449
1450           On a more practical note, I did implement this at one point
1451           and determined it didn't look good and removed
1452           it.</quote></para>
1453       </sect2>
1454  
1455       <!-- ----------------------------------------------------------------- -->
1456
1457      <sect2>
1458         <title>How to I identifiy a widgets top level window or other
1459         ancestor?</title>
1460
1461         <para>There are a couple of ways to find the top level parent
1462          of a widget. The easier way is to call the
1463          <literal>gtk_widget_top_level()</literal> function that
1464          returns pointer to a GtkWidget that is the top level
1465          window.</para>
1466
1467         <para>A more complicated way to do this (but less limited, as
1468          it allows the user to get the closest ancestor of a known type) is to use
1469          <literal>gtk_widget_get_ancestor()</literal> as in:</para>
1470
1471 <programlisting role="C">
1472       GtkWidget       *widget;
1473       widget = gtk_widget_get_ancestor(w, GTK_TYPE_WINDOW);
1474 </programlisting>
1475
1476         <para>Since virtually all the GTK_TYPEs can be used as the
1477          second parameter of this function, you can get any parent
1478          widget of a particular widget. Suppose you have an hbox which
1479          contains a vbox, which in turn contains some other atomic
1480          widget (entry, label, etc. To find the master hbox using the
1481          <literal>entry</literal> widget simply use:</para>
1482
1483 <programlisting role="C">
1484       GtkWidget       *hbox;
1485       hbox = gtk_widget_get_ancestor(w, GTK_TYPE_HBOX);
1486 </programlisting>
1487       </sect2>
1488  
1489       <!-- ----------------------------------------------------------------- -->
1490
1491      <sect2>
1492         <title>How do I get the Window ID of a GtkWindow?</title>
1493
1494         <para>The actual Gdk/X window will be created when the widget
1495          gets realized. You can get the Window ID with:</para>
1496
1497 <programlisting role="C">
1498 #include &lt;gdk/gdkx.h&gt;
1499
1500 Window xwin = GDK_WINDOW_XWINDOW (GTK_WIDGET (my_window)->window);
1501 </programlisting>
1502       </sect2>
1503  
1504       <!-- ----------------------------------------------------------------- -->
1505
1506      <sect2>
1507         <title>How do I catch a double click event (in a list widget,
1508         for example)?</title>
1509
1510         <para>Tim Janik wrote to gtk-list (slightly modified):</para>
1511
1512         <para>Define a signal handler:</para>
1513
1514 <programlisting role="C">
1515 gint
1516 signal_handler_event(GtkWiget *widget, GdkEvenButton *event, gpointer func_data)
1517 {
1518   if (GTK_IS_LIST_ITEM(widget) &&
1519        (event->type==GDK_2BUTTON_PRESS ||
1520         event->type==GDK_3BUTTON_PRESS) ) {
1521     printf("I feel %s clicked on button %d\",
1522            event->type==GDK_2BUTTON_PRESS ? "double" : "triple",
1523            event->button);
1524   }
1525
1526   return FALSE;
1527 }</programlisting>
1528
1529         <para>And connect the handler to your object:</para>
1530
1531 <programlisting role="C">
1532 {
1533   /* list, list item init stuff */     
1534
1535   gtk_signal_connect(GTK_OBJECT(list_item),
1536                      "button_press_event",
1537                      GTK_SIGNAL_FUNC(signal_handler_event),
1538                      NULL);
1539
1540   /* and/or */
1541
1542   gtk_signal_connect(GTK_OBJECT(list_item),
1543                      "button_release_event",
1544                      GTK_SIGNAL_FUNC(signal_handler_event),
1545                      NULL);
1546
1547   /* something else */
1548 }
1549 </programlisting>
1550
1551         <para>and, Owen Taylor wrote:
1552          <quote>Note that a single button press will be received
1553          beforehand, and if you are doing this for a button, you will
1554          therefore also get a "clicked" signal for the button. (This
1555          is going to be true for any toolkit, since computers aren't
1556          good at reading one's mind.)</quote></para>
1557       </sect2>
1558  
1559       <!-- ----------------------------------------------------------------- -->
1560
1561      <sect2>
1562         <title>By the way, what are the differences between signals
1563         and events?</title>
1564
1565         <para>First of all, Havoc Pennington gives a rather complete
1566          description of the differences between events and signals in
1567          his free book (two chapters can be found at <ulink
1568          url="http://www106.pair.com/rhp/sample_chapters.html">
1569          http://www106.pair.com/rhp/sample_chapters.html</ulink>).</para>
1570
1571         <para>Moreover, Havoc posted this to the <literal>gtk-list</literal>
1572          <quote>Events are a stream of messages received from the X
1573          server. They drive the Gtk main loop; which more or less
1574          amounts to "wait for events, process them" (not exactly, it
1575          is really more general than that and can wait on many
1576          different input streams at once). Events are a Gdk/Xlib
1577          concept.</quote></para>
1578
1579   <para><quote>Signals are a feature of GtkObject and its subclasses. They have
1580   nothing to do with any input stream; really a signal is just a way
1581   to keep a list of callbacks around and invoke them ("emit" the
1582   signal). There are lots of details and extra features of
1583   course. Signals are emitted by object instances, and are entirely
1584   unrelated to the Gtk main loop.  Conventionally, signals are emitted
1585   "when something changes" about the object emitting the signal.</quote></para>
1586
1587   <para><quote>Signals and events only come together because GtkWidget happens to
1588   emit signals when it gets events. This is purely a convenience, so
1589   you can connect callbacks to be invoked when a particular widget
1590   receives a particular event. There is nothing about this that makes
1591   signals and events inherently related concepts, any more than
1592   emitting a signal when you click a button makes button clicking and
1593   signals related concepts.</quote></para>
1594       </sect2>
1595  
1596       <!-- ----------------------------------------------------------------- -->
1597
1598      <sect2>
1599         <title>Data I pass to the <literal>delete_event</literal> (or other event)
1600         handler gets corrupted.</title>
1601
1602         <para>All event handlers take an additional argument which
1603          contains information about the event that triggered the
1604          handler. So, a <literal>delete_event</literal> handler must
1605          be declared as:</para>
1606
1607
1608 <programlisting role="C">
1609 gint delete_event_handler (GtkWidget   *widget,
1610                            GdkEventAny *event,
1611                            gpointer     data);
1612 </programlisting>
1613       </sect2>
1614  
1615       <!-- ----------------------------------------------------------------- -->
1616
1617      <sect2>
1618         <title>I have my signal connected to the the (whatever) event,
1619         but it seems I don't catch it. What's wrong?</title>
1620
1621         <para>There is some special initialisation to do in order to
1622          catch some particular events. In fact, you must set the
1623          correct event mask bit of your widget before getting some
1624          particular events.</para>
1625
1626         <para>For example,</para>
1627
1628 <programlisting role="C">
1629   gtk_widget_add_events(window, GDK_KEY_RELEASE_MASK);
1630 </programlisting>
1631
1632         <para>lets you catch the key release events. If you want to
1633         catch every events, simply us the GDK_ALL_EVENTS_MASK event
1634         mask.</para>
1635
1636         <para>All the event masks are defined in the
1637         <filename>gdktypes.h</filename> file.</para>
1638       </sect2>
1639  
1640       <!-- ----------------------------------------------------------------- -->
1641
1642      <sect2>
1643         <title>I need to add a new signal to a GTK+ widget. Any
1644         idea?</title>
1645
1646         <para>If the signal you want to add may be beneficial for
1647          other GTK+ users, you may want to submit a patch that
1648          presents your changes. Check the tutorial for more
1649          information about adding signals to a widget class.</para>
1650
1651         <para>If you don't think it is the case or if your patch is
1652          not applied you'll have to use the
1653          <literal>gtk_object_class_user_signal_new</literal>
1654          function. <literal>gtk_object_class_user_signal_new</literal> allows you to
1655          add a new signal to a predefined GTK+ widget without any
1656          modification of the GTK+ source code. The new signal can be
1657          emited with <literal>gtk_signal_emit</literal> and can be
1658          handled in the same way as other signals.</para>
1659
1660         <para>Tim Janik posted this code snippet:</para>
1661
1662 <programlisting role="C">
1663 static guint signal_user_action = 0;
1664
1665 signal_user_action =
1666   gtk_object_class_user_signal_new (gtk_type_class (GTK_TYPE_WIDGET),
1667                     "user_action",
1668                     GTK_RUN_LAST | GTK_RUN_ACTION,
1669                     gtk_marshal_NONE__POINTER,
1670                     GTK_TYPE_NONE, 1,
1671                     GTK_TYPE_POINTER);
1672
1673 void
1674 gtk_widget_user_action (GtkWidget *widget,
1675                         gpointer   act_data)
1676 {
1677   g_return_if_fail (GTK_IS_WIDGET (widget));
1678
1679   gtk_signal_emit (GTK_OBJECT (widget), signal_user_action, act_data);
1680 }
1681 </programlisting>
1682
1683         <para>If you want your new signal to have more than the
1684         classical gpointer parameter, you'll have to play with GTK+
1685         marshallers.</para>
1686       </sect2>
1687  
1688       <!-- ----------------------------------------------------------------- -->
1689
1690      <sect2>
1691         <title>Is it possible to get some text displayed which is
1692         truncated to fit inside its allocation?</title>
1693
1694         <para>GTK's behavior (no clipping) is a consequence of its
1695          attempts to conserve X resources. Label widgets (among
1696          others) don't get their own X window - they just draw their
1697          contents on their parent's window. While it might be possible
1698          to have clipping occur by setting the clip mask before
1699          drawing the text, this would probably cause a substantial
1700          performance penalty.</para>
1701
1702         <para>Its possible that, in the long term, the best solution
1703          to such problems might be just to change gtk to give labels X
1704          windows. A short term workaround is to put the label widget
1705          inside another widget that does get its own window - one
1706          possible candidate would be the viewport widget.</para>
1707
1708 <programlisting role="C">
1709 viewport = gtk_viewport (NULL, NULL);
1710 gtk_widget_set_usize (viewport, 50, 25);
1711 gtk_viewport_set_shadow_type (GTK_VIEWPORT(viewport), GTK_SHADOW_NONE);
1712 gtk_widget_show(viewport);
1713
1714 label = gtk_label ("a really long label that won't fit");
1715 gtk_container_add (GTK_CONTAINER(viewport), label);
1716 gtk_widget_show (label);
1717 </programlisting>
1718
1719         <para>If you were doing this for a bunch of widgets, you might
1720          want to copy gtkviewport.c and strip out the adjustment and
1721          shadow functionality (perhaps you could call it
1722          GtkClipper).</para>
1723       </sect2>
1724  
1725       <!-- ----------------------------------------------------------------- -->
1726
1727      <sect2>
1728         <title>How do I make my window modal? / How do I make a single
1729         window active?</title>
1730
1731         <para>After you create your window, do
1732         <literal>gtk_grab_add(my_window)</literal>. And after  closing
1733         the window do
1734         <literal>gtk_grab_remove(my_window)</literal>.</para>
1735       </sect2>
1736  
1737       <!-- ----------------------------------------------------------------- -->
1738
1739      <sect2>
1740         <title>Why doesn't my widget (e.g. progressbar)
1741         update?</title>
1742
1743         <para>You are probably doing all the changes within a function without
1744          returning control to <literal>gtk_main()</literal>. This may
1745          be the case if you do some lengthy calculation in your
1746          code. Most drawing updates are only placed on a queue, which
1747          is processed within <literal>gtk_main()</literal>. You can force the
1748          drawing queue to be processed using something like:</para>
1749
1750
1751 <programlisting role="C">
1752 while (gtk_main_iteration());
1753 </programlisting>
1754
1755         <para>inside you're function that changes the widget.</para>
1756
1757         <para>What the above snippet does is run all pending events
1758          and high priority idle functions, then return immediately
1759          (the drawing is done in a high priority idle function).</para>
1760       </sect2>
1761  
1762       <!-- ----------------------------------------------------------------- -->
1763
1764      <sect2>
1765         <title>How do I attach data to some GTK+ object/widget?</title>
1766
1767         <para>First of all, the attached data is stored in the
1768         object_data field of a GtkObject. The type of this field is
1769         GData, which is defined in glib.h.  So you should read the
1770         gdataset.c file in your glib source directory very
1771         carefully.</para>
1772
1773         <para>There are two (easy) ways to attach some data to a gtk
1774         object.  Using <literal>gtk_object_set_data()</literal> and
1775         <literal>gtk_object_get_data()</literal> seems to be the most
1776         common way to do this, as it provides a powerful interface to
1777         connect objects and data.</para>
1778
1779 <programlisting role="C">
1780 void gtk_object_set_data(GtkObject *object, const gchar *key, gpointer data);
1781
1782 gpointer gtk_object_get_data(GtkObject *object, const gchar *key);
1783 </programlisting>
1784
1785         <para>Since a short example is better than any lengthy speech:</para>
1786
1787 <programlisting role="C">
1788 struct my_struct        p1,p2,*result;
1789 GtkWidget               *w;
1790
1791 gtk_object_set_data(GTK_OBJECT(w),"p1 data",(gpointer)&amp;p1);
1792 gtk_object_set_data(GTK_OBJECT(w),"p2 data",(gpointer)&amp;p2);
1793
1794 result = gtk_object_get_data(GTK_OBJECT(w),"p1 data");
1795 </programlisting>
1796
1797         <para>The <literal>gtk_object_set_user_data()</literal> and
1798         <literal>gtk_object_get_user_data()</literal> functions does
1799         exactly the same thing as the functions above, but does not
1800         let you specify the "key" parameter.Instead, it uses a
1801         standard "user_data" key. Note that the use of these functions
1802         is deprecated in 1.2. They only provide a compatibility mode
1803         with some old gtk packages.</para>
1804       </sect2>
1805  
1806       <!-- ----------------------------------------------------------------- -->
1807
1808      <sect2>
1809         <title>How do I remove the data I have attached to an
1810         object?</title>
1811
1812         <para>When attaching the data to the object, you can use the
1813         <literal>gtk_object_set_data_full()</literal> function. The three
1814         first arguments of the function are the same as in
1815         <literal>gtk_object_set_data()</literal>. The fourth one is a
1816         pointer to a callback function which is called when the data
1817         is destroyed. The data is destroyed when you:</para>
1818
1819         <itemizedlist>
1820           <listitem><simpara> destroy the object</simpara>
1821           </listitem>
1822           <listitem><simpara> replace the data with a new one (with
1823           the same key)</simpara>
1824           </listitem>
1825           <listitem><simpara> replace the data with NULL (with the
1826           same key)</simpara>
1827           </listitem>
1828         </itemizedlist>
1829       </sect2>
1830  
1831       <!-- ----------------------------------------------------------------- -->
1832
1833      <sect2>
1834         <title>How do I reparent a widget?</title>
1835
1836         <para>The normal way to reparent (ie change the owner) of a
1837         widget should be to use the function:</para>
1838
1839 <programlisting role="C">
1840 void gtk_widget_reparent (GtkWidget *widget, 
1841                           GtkWidget *new_parent)
1842 </programlisting>
1843
1844         <para>But this is only a "should be" since this function does
1845         not correctly do its job on some specific widgets. The main
1846         goal of gtk_widget_reparent() is to avoid unrealizing widget
1847         if both widget and new_parent are realized (in this case,
1848         widget->window is successfully reparented). The problem here
1849         is that some widgets in the GTK+ hierarchy have multiple
1850         attached X subwindows and this is notably the case for the
1851         GtkSpinButton widget. For those, gtk_widget_reparent() will
1852         fail by leaving an unrealized child window where it should
1853         not.</para>
1854
1855         <para>To avoid this problem, simply use the following code
1856         snippet:</para>
1857
1858 <programlisting role="C">
1859      gtk_widget_ref(widget);
1860      gtk_container_remove(GTK_CONTAINER(old_parent), widget);
1861      gtk_container_add(GTK_CONTAINER(new_parent), widget);
1862      gtk_widget_unref(widget);
1863 </programlisting>
1864       </sect2>
1865  
1866       <!-- ----------------------------------------------------------------- -->
1867
1868      <sect2>
1869         <title>How could I get any widgets position?</title>
1870
1871         <para>As Tim Janik pointed out, there are different cases, and
1872         each case requires a different solution.</para>
1873
1874         <itemizedlist>
1875           <listitem><simpara> If you want the position of a widget
1876         relative to its parent, you should use
1877         <literal>widget->allocation.x</literal> and
1878         <literal>widget->allocation.y</literal>.</simpara>
1879           </listitem>
1880           <listitem><simpara> If you want the position of a window
1881         relative to the X root window, you should use <literal>gdk_window_get_geometry()</literal>
1882         <literal>gdk_window_get_position()</literal> or
1883         <literal>gdk_window_get_origin()</literal>.</simpara>
1884           </listitem>
1885           <listitem><simpara> If you want to get the position of the
1886         window (including the WM decorations), you should use
1887         <literal>gdk_window_get_root_origin()</literal>.</simpara>
1888           </listitem>
1889           <listitem><simpara> Last but not least, if you want to get a Window Manager frame
1890         position, you should use
1891         <literal>gdk_window_get_deskrelative_origin()</literal>.</simpara>
1892           </listitem>
1893 </itemizedlist>
1894
1895         <para>Your choice of Window Manager will have an effect of the
1896         results of the above functions. You should keep this in mind
1897         when writing your application. This is dependant upon how the
1898         Window Managers manage the decorations that they add around
1899         windows.</para>
1900       </sect2>
1901  
1902       <!-- ----------------------------------------------------------------- -->
1903
1904      <sect2>
1905         <title>How do I set the size of a widget/window? How do I
1906         prevent the user resizing my window?</title>
1907
1908         <para>The <literal>gtk_widget_set_uposition()</literal>
1909         function is used to set the position of any widget.</para>
1910
1911         <para>The <literal>gtk_widget_set_usize()</literal> function
1912         is used to set the size of a widget. In order to use all the
1913         features that are provided by this function when it acts on a
1914         window, you may want to use the
1915         <literal>gtk_window_set_policy</literal> function. The
1916         definition of these functions are:</para>
1917
1918 <programlisting role="C">
1919 void gtk_widget_set_usize (GtkWidget *widget,
1920                            gint width,
1921                            gint height);
1922
1923 void gtk_window_set_policy (GtkWindow *window,
1924                             gint allow_shrink,
1925                             gint allow_grow,
1926                             gint auto_shrink);
1927 </programlisting>
1928
1929         <para><literal>Auto_shrink</literal> will automatically shrink
1930         the window when the requested size of the child widgets goes
1931         below the current size of the
1932         window. <literal>Allow_shrink</literal> will give the user the
1933         authorisation to make the window smaller that it should
1934         normally be. <literal>Allow_grow</literal> will give the user
1935         will have the ability to make the window bigger. The default
1936         values for these parameters are:</para>
1937
1938 <programlisting role="C">
1939 allow_shrink = FALSE
1940 allow_grow   = TRUE
1941 auto_shrink  = FALSE
1942 </programlisting>
1943
1944         <para>The <literal>gtk_widget_set_usize()</literal> functions
1945         is not the easiest way to set a window size since you cannot
1946         decrease this window size with another call to this function
1947         unless you call it twice, as in:</para>
1948
1949 <programlisting role="C">
1950      gtk_widget_set_usize(your_widget, -1, -1);
1951      gtk_widget_set_usize(your_widget, new_x_size, new_y_size);
1952 </programlisting>
1953
1954         <para>Another way to set the size of and/or move a window is to use
1955         the <literal>gdk_window_move_resize()</literal> function which
1956         uses to work fine both to grow or to shrink the window:</para>
1957
1958 <programlisting role="C">
1959      gdk_window_move_resize(window->window, 
1960                             x_pos, y_pos, 
1961                             x_size, y_size);
1962 </programlisting>
1963       </sect2>
1964  
1965       <!-- ----------------------------------------------------------------- -->
1966
1967      <sect2>
1968         <title>How do I add a popup menu to my GTK+
1969         application?</title>
1970
1971         <para>The <literal>menu</literal> example in the examples/menu
1972         directory of the GTK+ distribution implements a popup menu
1973         with this technique:</para>
1974
1975
1976 <programlisting role="C">
1977 static gint button_press (GtkWidget *widget, GdkEvent *event)
1978 {
1979
1980     if (event->type == GDK_BUTTON_PRESS) {
1981         GdkEventButton *bevent = (GdkEventButton *) event; 
1982         gtk_menu_popup (GTK_MENU(widget), NULL, NULL, NULL, NULL,
1983                         bevent->button, bevent->time);
1984         /* Tell calling code that we have handled this event; the buck
1985          * stops here. */
1986         return TRUE;
1987     }
1988
1989     /* Tell calling code that we have not handled this event; pass it on. */
1990     return FALSE;
1991 }
1992 </programlisting>
1993       </sect2>
1994  
1995       <!-- ----------------------------------------------------------------- -->
1996
1997      <sect2>
1998         <title>How do I disable or enable a widget, such as a
1999         button?</title>
2000
2001         <para>To disable (or to enable) a widget, use the
2002         <literal>gtk_widget_set_sensitive()</literal> function. The
2003         first parameter is you widget pointer. The second parameter is
2004         a boolean value: when this value is TRUE, the widget is
2005         enabled.</para>
2006       </sect2>
2007
2008       <!-- ----------------------------------------------------------------- -->
2009
2010      <sect2>
2011         <title>Shouldn't the text argument in the gtk_clist_*
2012         functions be declared const?</title>
2013
2014         <para>For example:</para>
2015
2016 <programlisting role="C">
2017 gint gtk_clist_prepend (GtkCList *clist,
2018                         gchar    *text[]);
2019 </programlisting>
2020
2021         <para>Answer: No, while a type "gchar*" (pointer to char) can
2022         automatically be cast into "const gchar*" (pointer to const
2023         char), this does not apply for "gchar *[]" (array of an
2024         unspecified number of pointers to char) into "const gchar *[]"
2025         (array of an unspecified number of pointers to const char).</para>
2026
2027         <para>The type qualifier "const" may be subject to automatic
2028         casting, but in the array case, it is not the array itself
2029         that needs the (const) qualified cast, but its members, thus
2030         changing the whole type.</para>
2031       </sect2>
2032
2033      <!-- ----------------------------------------------------------------- -->
2034
2035      <sect2>
2036         <title>How do I render pixels (image data) to the
2037         screen?</title>
2038
2039         <para>There are several ways to approach this. The simplest
2040         way is to use GdkRGB, see gdk/gdkrgb.h. You create an RGB
2041         buffer, render to your RGB buffer, then use GdkRGB routines to
2042         copy your RGB buffer to a drawing area or custom widget. The
2043         book "GTK+/Gnome Application Development" gives some details;
2044         GdkRGB is also documented in the GTK+ reference
2045         documentation.</para>
2046
2047         <para>If you're writing a game or other graphics-intensive
2048         application, you might consider a more elaborate
2049         solution. OpenGL is the graphics standard that will let you
2050         access hardware accelaration in future versions of XFree86; so
2051         for maximum speed, you probably want to use OpenGL. A
2052         GtkGLArea widget is available for using OpenGL with GTK+ (but
2053         GtkGLArea does not come with GTK+ itself). There are also
2054         several open source game libraries, such as ClanLib and Loki's
2055         Simple DirectMedia Layer library (SDL).</para>
2056
2057         <para>You do NOT want to use
2058         <literal>gdk_draw_point()</literal>, that will be extremely
2059         slow.</para>
2060       </sect2>
2061
2062      <!-- ----------------------------------------------------------------- -->
2063
2064      <sect2>
2065         <title>How do I create a pixmap without having my window being
2066         realized/shown?</title>
2067
2068         <para>Functions such as
2069         <literal>gdk_pixmap_create_from_xpm()</literal> require a
2070         valid window as a parameter. During the initialisation phase
2071         of an application, a valid window may not be available without
2072         showing a window, which may be inappropriate. In order to
2073         avoid this, a function such as
2074         <literal>gdk_pixmap_colormap_create_from_xpm</literal> can be
2075         used, as in:</para>
2076
2077 <programlisting role="C">
2078   char *pixfile = "foo.xpm";
2079   GtkWidget *top, *box, *pixw;
2080   GdkPixmap *pixmap, *pixmap_mask;
2081
2082   top = gtk_window_new (GKT_WINDOW_TOPLEVEL);
2083   box = gtk_hbox_new (FALSE, 4);
2084   gtk_conainer_add (GTK_CONTAINER(top), box);
2085  
2086   pixmap = gdk_pixmap_colormap_create_from_xpm (
2087                NULL, gtk_widget_get_colormap(top),
2088                &amp;pixmap_mask, NULL, pixfile);
2089   pixw = gtk_pixmap_new (pixmap, pixmap_mask);
2090   gdk_pixmap_unref (pixmap);
2091   gdk_pixmap_unref (pixmap_mask);
2092 </programlisting>
2093       </sect2>
2094     </sect1>
2095   </chapter>
2096
2097   <!-- ***************************************************************** -->
2098   <chapter>
2099     <title>Development with GTK+: widget specific questions</title>
2100     <sect1>
2101       <title></title>
2102  
2103       <!-- ----------------------------------------------------------------- -->
2104
2105      <sect2>
2106         <title>How do I find out about the selection of a GtkList?</title>
2107
2108         <para>Get the selection something like this:</para>
2109
2110 <programlisting role="C">
2111 GList *sel;
2112 sel = GTK_LIST(list)->selection;
2113 </programlisting>
2114
2115         <para>This is how GList is defined (quoting glist.h):</para>
2116
2117 <programlisting role="C">
2118 typedef struct _GList GList;
2119
2120 struct _GList
2121 {
2122   gpointer data;
2123   GList *next;
2124   GList *prev;
2125 };
2126 </programlisting>
2127
2128         <para>A GList structure is just a simple structure for doubly
2129         linked lists. there exist several g_list_*() functions to
2130         modify a linked list in glib.h.  However the
2131         GTK_LIST(MyGtkList)->selection is maintained by the
2132         gtk_list_*() functions and should not be modified.</para>
2133
2134
2135         <para>The selection_mode of the GtkList determines the
2136         selection facilities of a GtkList and therefore the contents
2137         of GTK_LIST(AnyGtkList)->selection:</para>
2138         <informaltable frame="all">
2139           <tgroup cols="2">
2140             <thead>
2141               <row>
2142               <entry><literal>selection_mode</literal></entry>
2143                 <entry><literal> GTK_LIST()->selection</literal>
2144               contents</entry>
2145               </row>
2146             </thead>
2147             <tbody>
2148               <row>
2149                 <entry><literal>GTK_SELECTION_SINGLE</literal></entry>
2150                 <entry>selection is either NULL or contains a GList*
2151                         pointer for a single selected item.</entry>
2152               </row>
2153               <row>
2154                 <entry><literal>GTK_SELECTION_BROWSE</literal></entry>
2155                 <entry>selection is NULL if the list contains no
2156                         widgets, otherwise it contains a GList*
2157                         pointer for one GList structure.</entry>
2158               </row>
2159               <row>
2160                 <entry><literal>GTK_SELECTION_MULTIPLE</literal></entry>
2161                 <entry>selection is NULL if no listitems are selected
2162                         or a a GList* pointer for the first selected
2163                         item. that in turn points to a GList structure
2164                         for the second selected item and so
2165                         on.</entry>
2166               </row>
2167               <row>
2168                 <entry><literal>GTK_SELECTION_EXTENDED</literal></entry>
2169                 <entry>selection is NULL.</entry>
2170               </row>
2171             </tbody>
2172           </tgroup>
2173         </informaltable>
2174
2175         <para>The data field of the GList structure
2176              GTK_LIST(MyGtkList)->selection points to the first
2177              GtkListItem that is selected.  So if you would like to
2178              determine which listitems are selected you should go like
2179              this:</para>
2180
2181 <programlisting role="C">
2182 {
2183         gchar           *list_items[]={
2184                                 "Item0",
2185                                 "Item1",
2186                                 "foo",
2187                                 "last Item",
2188                         };
2189         guint           nlist_items=sizeof(list_items)/sizeof(list_items[0]);
2190         GtkWidget       *list_item;
2191         guint           i;
2192
2193         list=gtk_list_new();
2194         gtk_list_set_selection_mode(GTK_LIST(list), GTK_SELECTION_MULTIPLE);
2195         gtk_container_add(GTK_CONTAINER(AnyGtkContainer), list);
2196         gtk_widget_show (list);
2197
2198         for (i = 0; i < nlist_items; i++)
2199         {
2200                 list_item=gtk_list_item_new_with_label(list_items[i]);
2201                 gtk_object_set_user_data(GTK_OBJECT(list_item), (gpointer)i);
2202                 gtk_container_add(GTK_CONTAINER(list), list_item);
2203                 gtk_widget_show(list_item);
2204         }
2205 }
2206 </programlisting>
2207
2208         <para>To get known about the selection:</para>
2209
2210 <programlisting role="C">
2211 {
2212         GList   *items;
2213
2214         items=GTK_LIST(list)->selection;
2215
2216         printf("Selected Items: ");
2217         while (items) {
2218                 if (GTK_IS_LIST_ITEM(items->data))
2219                         printf("%d ", (guint) 
2220                 gtk_object_get_user_data(items->data));
2221                 items=items->next;
2222         }
2223         printf("\n");
2224 }
2225 </programlisting>
2226
2227       </sect2>
2228  
2229       <!-- ----------------------------------------------------------------- -->
2230
2231      <sect2>
2232         <title>How do I stop the column headings of a GtkCList
2233         disappearing when the list is scrolled?</title>
2234
2235         <para>This happens when a GtkCList is packed into a
2236         GtkScrolledWindow using the function
2237         <literal>gtk_scroll_window_add_with_viewport()</literal>. The prefered
2238         method of adding a CList to a scrolled window is to use the
2239         function <literal>gtk_container_add</literal>, as in:</para>
2240
2241 <programlisting role="C">
2242     GtkWidget *scrolled, *clist;
2243     char *titles[] = { "Title1" , "Title2" };
2244
2245     scrolled = gtk_scrolled_window_new(NULL, NULL);
2246
2247     clist = gtk_clist_new_with_titles(2, titles);
2248     gtk_container_add(GTK_CONTAINER(scrolled), clist);
2249 </programlisting>
2250
2251       </sect2>
2252  
2253       <!-- ----------------------------------------------------------------- -->
2254
2255      <sect2>
2256         <title>I don't want the user of my applications to enter text
2257         into a GtkCombo. Any idea?</title>
2258
2259         <para>A GtkCombo has an associated entry which can be accessed
2260         using the following expression:</para>
2261
2262 <programlisting role="C">
2263       GTK_COMBO(combo_widget)->entry
2264 </programlisting>
2265
2266         <para>If you don't want the user to be able to modify the
2267         content of this entry, you can use the
2268         gtk_entry_set_editable() function:</para>
2269
2270
2271 <programlisting role="C">
2272       void gtk_entry_set_editable(GtkEntry *entry, 
2273                                   gboolean editable);
2274 </programlisting>
2275
2276         <para>Set the editable parameter to FALSE to disable typing
2277         into the entry.</para>
2278       </sect2>
2279  
2280       <!-- ----------------------------------------------------------------- -->
2281
2282      <sect2>
2283         <title>How do I catch a combo box change?</title>
2284
2285         <para>The entry which is associated to your GtkCombo send a
2286         "changed" signal when:</para>
2287
2288         <itemizedlist>
2289           <listitem><simpara>some text is typed in</simpara>
2290           </listitem>
2291           <listitem><simpara>the selection of the combo box is changed</simpara>
2292           </listitem>
2293         </itemizedlist>
2294
2295         <para>To catch any combo box change, simply connect your
2296         signal handler with</para>
2297
2298 <programlisting role="C">
2299       gtk_signal_connect(GTK_COMBO(cb)->entry,
2300                          "changed",
2301                          GTK_SIGNAL_FUNC(my_cb_change_handler),
2302                          NULL);
2303 </programlisting>
2304       </sect2>
2305  
2306       <!-- ----------------------------------------------------------------- -->
2307
2308      <sect2>
2309         <title>How can I define a separation line in a menu?</title>
2310
2311         <para>See the <ulink
2312         url="http://www.gtk.org/tutorial/">Tutorial</ulink> for
2313         information on how to create menus. However, to create a
2314         separation line in a menu, just insert an empty menu item:</para>
2315
2316 <programlisting role="C">
2317 menuitem = gtk_menu_item_new();
2318 gtk_menu_append(GTK_MENU(menu), menuitem);
2319 gtk_widget_show(menuitem);
2320 </programlisting>
2321
2322       </sect2>
2323  
2324       <!-- ----------------------------------------------------------------- -->
2325
2326      <sect2>
2327         <title>How can I right justify a menu, such as Help?</title>
2328
2329         <para>Depending on if you use the MenuFactory or not, there
2330         are two ways to proceed. With the MenuFactory, use something
2331         like the following:</para>
2332
2333 <programlisting role="C">
2334 menu_path = gtk_menu_factory_find (factory,  "&lt;MyApp&gt;/Help");
2335 gtk_menu_item_right_justify(menu_path->widget);
2336 </programlisting>
2337
2338         <para>If you do not use the MenuFactory, you should simply
2339         use:</para>
2340
2341
2342 <programlisting role="C">
2343 gtk_menu_item_right_justify(my_menu_item);
2344 </programlisting>
2345
2346       </sect2>
2347  
2348       <!-- ----------------------------------------------------------------- -->
2349
2350      <sect2>
2351         <title>How do I add some underlined accelerators to menu
2352         items?</title>
2353
2354         <para>Damon Chaplin, the technical force behind the Glade
2355         project, provided the following code sample (this code is an
2356         output from Glade). It creates a small <GUIMenu>File</guimenu> menu item
2357         with only one child (<guimenu>New</guimenu>). The F in <guimenu>File</guimenu> and the N
2358         in <guimenu>New</guimenu> are underlined, and the relevant accelerators are
2359         created.</para>
2360
2361 <programlisting role="C">
2362   menubar1 = gtk_menu_bar_new ();
2363   gtk_object_set_data (GTK_OBJECT (window1), "menubar1", menubar1);
2364   gtk_widget_show (menubar1);
2365   gtk_box_pack_start (GTK_BOX (vbox1), menubar1, FALSE, FALSE, 0);
2366
2367   file1 = gtk_menu_item_new_with_label ("");
2368   tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (file1)->child),
2369                                    _("_File"));
2370   gtk_widget_add_accelerator (file1, "activate_item", accel_group,
2371                               tmp_key, GDK_MOD1_MASK, 0);
2372   gtk_object_set_data (GTK_OBJECT (window1), "file1", file1);
2373   gtk_widget_show (file1);
2374   gtk_container_add (GTK_CONTAINER (menubar1), file1);
2375
2376   file1_menu = gtk_menu_new ();
2377   file1_menu_accels = gtk_menu_ensure_uline_accel_group (GTK_MENU (file1_menu));
2378   gtk_object_set_data (GTK_OBJECT (window1), "file1_menu", file1_menu);
2379   gtk_menu_item_set_submenu (GTK_MENU_ITEM (file1), file1_menu);
2380
2381   new1 = gtk_menu_item_new_with_label ("");
2382   tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (new1)->child),
2383                                    _("_New"));
2384   gtk_widget_add_accelerator (new1, "activate_item", file1_menu_accels,
2385                               tmp_key, 0, 0);
2386   gtk_object_set_data (GTK_OBJECT (window1), "new1", new1);
2387   gtk_widget_show (new1);
2388   gtk_container_add (GTK_CONTAINER (file1_menu), new1);
2389 </programlisting>
2390
2391       </sect2>
2392  
2393       <!-- ----------------------------------------------------------------- -->
2394
2395      <sect2>
2396         <title>How can I retrieve the text from a GtkMenuItem?</title>
2397
2398         <para>You can usually retrieve the label of a specific
2399         GtkMenuItem with:</para>
2400
2401 <programlisting role="C">
2402     if (GTK_BIN (menu_item)->child)
2403     {
2404       GtkWidget *child = GTK_BIN (menu_item)->child;
2405   
2406       /* do stuff with child */
2407       if (GTK_IS_LABEL (child))
2408       {
2409         gchar *text;
2410     
2411         gtk_label_get (GTK_LABEL (child), &amp;text);
2412         g_print ("menu item text: %s\n", text);
2413       }
2414     }
2415 </programlisting>
2416
2417         <para>To get the active menu item from a GtkOptionMenu you can
2418         do:</para>
2419
2420 <programlisting role="C">
2421 if (GTK_OPTION_MENU (option_menu)->menu_item)
2422 {
2423   GtkWidget *menu_item = GTK_OPTION_MENU (option_menu)->menu_item;
2424 }
2425 </programlisting>
2426
2427         <para>But, there's a catch. For this specific case, you can
2428         <emphasis>not</emphasis> get the label widget from
2429         <literal>menu_item</literal> with the above code, because the
2430         option menu reparents the menu_item's child temporarily to
2431         display the currently active contents. So to retrive the child
2432         of the currently active menu_item of an option menu, you'll
2433         have to do:</para>
2434
2435
2436 <programlisting role="C">
2437     if (GTK_BIN (option_menu)->child)
2438     {
2439       GtkWidget *child = GTK_BIN (option_menu)->child;
2440
2441       /* do stuff with child */
2442     }
2443 </programlisting>
2444       </sect2>
2445  
2446       <!-- ----------------------------------------------------------------- -->
2447
2448      <sect2>
2449         <title>How do I right (or otherwise) justify a
2450         GtkLabel?</title>
2451
2452         <para>Are you sure you want to <emphasis>justify</emphasis>
2453         the labels? The label class contains the
2454         <literal>gtk_label_set_justify()</literal> function that is
2455         used to control the justification of a multi-line
2456         label.</para>
2457
2458         <para>What you probably want is to set the <emphasis>alignment</emphasis>
2459         of the label, ie right align it, center it or left align
2460         it. If you want to do this, you should use:</para>
2461
2462 <programlisting role="C">
2463 void gtk_misc_set_alignment (GtkMisc *misc,
2464                              gfloat xalign,
2465                              gfloat yalign);
2466 </programlisting>
2467
2468         <para>where the <literal>xalign</literal> and
2469         <literal>yalign</literal> values are floats in
2470         [0.00;1.00].</para>
2471
2472
2473 <programlisting role="C">
2474 GtkWidget       *label;
2475
2476 /* horizontal : left align, vertical : top */
2477 gtk_misc_set_alignment(GTK_MISK(label), 0.0f, 0.0f);
2478
2479 /* horizontal : centered, vertical : centered */
2480 gtk_misc_set_alignment(GTK_MISK(label), 0.5f, 0.5f);
2481
2482 /* horizontal : right align, vertical : bottom */
2483 gtk_misc_set_alignment(GTK_MISK(label), 1.0f, 1.0f);
2484 </programlisting>
2485       </sect2>
2486  
2487       <!-- ----------------------------------------------------------------- -->
2488
2489      <sect2>
2490         <title>How do I set the background color of a GtkLabel
2491         widget?</title>
2492
2493         <para>The Gtklabel widget is one of a few GTK+ widgets that
2494         don't create their own window to render themselves
2495         into. Instead, they draw themselves directly onto their
2496         parents window.</para>
2497
2498         <para>This means that in order to set the background color for
2499         a GtkLabel widget, you need to change the background color of
2500         its parent, i.e. the object that you pack it into.</para>
2501       </sect2> 
2502
2503     </sect1>
2504   </chapter>
2505
2506   <!-- ----------------------------------------------------------------- -->
2507
2508 </book>