gtkfaq.sgml 91.7 KB
Newer Older
1 2 3 4 5 6 7
<!doctype linuxdoc system>

<article>

<!-- Title information -->

<title>GTK+ FAQ
Tony Gale's avatar
Tony Gale committed
8 9

<!-- NOTE: Use only one author tag, otherwise sgml2txt barfs - TRG --> 
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
10
<author>Tony Gale, Shawn T. Amundson, Emmanuel Deloget, Nathan Froyd
BST 1998  Tony Gale's avatar
BST 1998 Tony Gale committed
11

12
<date>February 22nd 2000
BST 1998  Tony Gale's avatar
BST 1998 Tony Gale committed
13

BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
14 15 16
<abstract> This document is intended to answer questions that are likely to be 
frequently asked by programmers using GTK+ or people who are just looking at 
using GTK+. 
17 18 19 20 21 22 23 24 25 26
</abstract>

<!-- Table of contents -->
<toc>

<!-- Begin the document -->

<!-- ***************************************************************** -->
<sect>General Information

BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
27 28 29 30 31 32
<!-- ----------------------------------------------------------------- -->
<sect1>Before anything else: the greetings
<p>
The FAQ authors want to thank:
<itemize>
<item>Havoc Pennington
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
33
<item>Erik Mouw
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
34 35 36 37 38 39 40 41 42 43 44 45
<item>Owen Taylor
<item>Tim Janik
<item>Thomas Mailund Jensen
<item>Joe Pfeiffer
<item>Andy Kahn
<item>Federico Mena Quintero
<item>Damon Chaplin
<item>and all the members of the GTK+ lists
</itemize>
If we forgot you, please email us !
Thanks again (I know, it's really short :)

46
<!-- ----------------------------------------------------------------- -->
Shawn Amundson's avatar
Shawn Amundson committed
47
<sect1>Authors
48
<p>
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
49
The original authors of GTK+ were:
50

Shawn Amundson's avatar
Shawn Amundson committed
51
<itemize>
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
52 53 54
<item>Peter Mattis
<item>Spencer Kimball
<item>Josh MacDonald
Shawn Amundson's avatar
Shawn Amundson committed
55
</itemize>
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
56 57 58

Since then, much has been added by others. Please see the AUTHORS
file in the distribution for the GTK+ Team.
59 60

<!-- ----------------------------------------------------------------- -->
Shawn Amundson's avatar
Shawn Amundson committed
61
<sect1>What is GTK+?
62
<p>
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
63 64 65 66
GTK+ is a small and efficient widget set designed with the general
look and feel of Motif.  In reality, it looks much better than Motif.
It contains common widgets and some more complex widgets such as a
file selection, and color selection widgets.
67

BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
68 69 70 71 72 73
GTK+ provides some unique features. (At least, I know of no other
widget library which provides them). For example, a button does not
contain a label, it contains a child widget, which in most instances
will be a label.  However, the child widget can also be a pixmap,
image or any combination possible the programmer desires.  This
flexibility is adhered to throughout the library.
Shawn Amundson's avatar
Shawn Amundson committed
74

75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
<!-- ----------------------------------------------------------------- -->
<sect1>What is the + in GTK+?
<P>
Peter Mattis informed the gtk mailing list that:
<quote>
"I originally wrote gtk which included the three libraries, libglib,
libgdk and libgtk. It featured a flat widget hierarchy. That is, you
couldn't derive a new widget from an existing one. And it contained
a more standard callback mechanism instead of the signal mechanism now
present in gtk+. The + was added to distinguish between the original
version of gtk and the new version. You can think of it as being an
enhancement to the original gtk that adds object oriented features."
</quote>

<!-- ----------------------------------------------------------------- -->
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
90
<sect1>Does the G in GTK+, GDK and GLib stand for?
91
<p>
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
92 93 94 95
GTK+ == Gimp Toolkit

GDK == Gtk+ Drawing Kit

BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
96
GLib == G Libray
97

Shawn Amundson's avatar
Shawn Amundson committed
98 99 100 101
<!-- ----------------------------------------------------------------- -->
<sect1>Where is the documentation for GTK+?
<p>
In the GTK+ distribution's doc/ directory you will find the
102 103
reference material for both GTK and GDK, this FAQ and the
GTK Tutorial.
Shawn Amundson's avatar
Shawn Amundson committed
104

105
In addition, you can find links to HTML versions of these documents 
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
106 107 108 109 110
by going to <htmlurl url="http://www.gtk.org/" 
name="http://www.gtk.org/">. A packaged version of the GTK Tutorial,
with SGML, HTML, Postscript, DVI and text versions can be found in
<htmlurl url="ftp://ftp.gtk.org/pub/gtk/tutorial"
name="ftp://ftp.gtk.org/pub/gtk/tutorial">
Shawn Amundson's avatar
Shawn Amundson committed
111

BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
112 113 114 115 116 117
There are now a couple of books available that deal with programming
GTK+, GDK and GNOME:
<itemize>
<item> Eric Harlows book entitled "Developing Linux Applications with
GTK+ and GDK". The ISBN is 0-7357-0021-4
<P>
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
118 119 120
The example code from Eric's book is available on-line at
<htmlurl url="http://www.bcpl.net/~eharlow/book"
name="http://www.bcpl.net/~eharlow/book">
Shawn Amundson's avatar
Shawn Amundson committed
121

BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
122 123 124 125 126 127 128 129 130 131 132 133
<item> Havoc Pennington has released a book called "GTK+/GNOME
Application Development". The ISBN is 0-7357-0078-8
<P>
The free version of the book lives here:
<htmlurl url="http://developer.gnome.org/doc/GGAD/"
name="http://developer.gnome.org/doc/GGAD/">
<P>
And Havoc maintains information about it and errata here:
<htmlurl url="http://pobox.com/~hp/gnome-app-devel.html"
name="http://pobox.com/~hp/gnome-app-devel.html">
</itemize>

Shawn Amundson's avatar
Shawn Amundson committed
134 135 136
<!-- ----------------------------------------------------------------- -->
<sect1>Is there a mailing list (or mailing list archive) for GTK+?
<p>
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
137 138 139 140
Information on mailing lists relating to GTK+ can be found at:

<htmlurl url="http://www.gtk.org/mailinglists.html"
name="http://www.gtk.org/mailinglists.html">
Shawn Amundson's avatar
Shawn Amundson committed
141 142 143 144

<!-- ----------------------------------------------------------------- -->
<sect1>How to get help with GTK+
<p>
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
145 146 147 148
First, make sure your question isn't answered in the documentation,
this FAQ or the tutorial. Done that? You're sure you've done that,
right? In that case, the best place to post questions is to the GTK+
mailing list.
Shawn Amundson's avatar
Shawn Amundson committed
149 150 151 152

<!-- ----------------------------------------------------------------- -->
<sect1>How to report bugs in GTK+
<p>
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
Bugs should be reported to the GNOME bug tracking
system (<htmlurl url="http://bugs.gnome.org"
name="http://bugs.gnome.org">). To report a problem about GTK+, send
mail to submit@bugs.gnome.org.

The subject of the mail should describe your problem. In the body of
the mail, you should first include a "pseudo-header" that gives the
package and version number. This should be separated by a blank line
from the actual headers.

<verb>
 Package: gtk+
 Version: 1.2.0
</verb>

Substitute 1.2.0 with the version of GTK+ that you have installed.

Then describe the bug. Include:

<itemize>
<item> Information about your system. For instance:
   <itemize>
   <item> What operating system and version
   <item> What version of X
   <item> For Linux, what version of the C library
   </itemize>
  And anything else you think is relevant.

<item> How to reproduce the bug. 

BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
183 184 185 186 187
  If you can reproduce it with the testgtk program that is built in
  the gtk/ subdirectory, that will be most convenient. Otherwise,
  please include a short test program that exhibits the behavior. As
  a last resort, you can also provide a pointer to a larger piece of
  software that can be downloaded.
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
188

BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
189 190 191
  (Bugs that can be reproduced within the GIMP are almost as good as
  bugs that can be reproduced in testgtk. If you are reporting a bug
  found with the GIMP, please include the version number of the GIMP
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
192 193 194 195 196
  you are using)

<item> If the bug was a crash, the exact text that was printed out
  when the crash occured.

BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
197 198 199 200
<item> Further information such as stack traces may be useful, but are
  not necessary. If you do send a stack trace, and the error is an X
  error, it will be more useful if the stacktrace is produced running
  the test program with the <tt/--sync/ command line option.
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
201
</itemize>
Shawn Amundson's avatar
Shawn Amundson committed
202

BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
203 204 205 206 207 208 209 210 211
<!-- ----------------------------------------------------------------- -->
<sect1>Is there a Windows version of GTK+?
<p>
There is an on going port of GTK+ to the Windows platform which is
making impressive progress.

See <htmlurl url="http://www.iki.fi/tml/gimp/win32"
name="http://www.iki.fi/tml/gimp/win32"> for more information.

212 213 214
<!-- ----------------------------------------------------------------- -->
<sect1>What applications have been written with GTK+?
<p>
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
215
A list of some GTK+ based application can be found on the GTK+ web
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
216 217 218 219 220 221 222
server at <htmlurl url="http://www.gtk.org/apps/"
name="http://www.gtk.org/apps/"> and contains more than 350
applications.

Failing that, look for a project to work on for the GNOME project,
<htmlurl url="http://www.gnome.org/" name="http://www.gnome.org/">
Write a game. Write something that is useful.
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
223 224

Some of these are:
225
<itemize>
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
226 227 228 229 230 231
<item>GIMP (<htmlurl url="http://www.gimp.org/" 
                  name="http://www.gimp.org/">), 
        an image manipulation program
<item>AbiWord (<htmlurl url="http://www.abisource.com/" 
        name="http://www.abisource.com/">),
        a professional word processor
Tony Gale's avatar
Tony Gale committed
232 233
<item>GUBI (<htmlurl url="http://www.SoftHome.net/pub/users/timj/gubi/index.htm"
            name="http://www.SoftHome.net/pub/users/timj/gubi/index.htm">),
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259
        a user interface builder
<item>Gzilla (<htmlurl url="http://www.levien.com/gzilla/" 
        name="http://www.levien.com/gzilla/">),
        a web browser
<item>SANE (<htmlurl url="http://www.azstarnet.com/~axplinux/sane/" 
        name="http://www.azstarnet.com/~axplinux/sane/"> ),
        a universal scanner interface
<item>XQF (<htmlurl url="http://www.botik.ru/~roma/quake/" 
        name="http://www.botik.ru/~roma/quake/">),
        a QuakeWorld/Quake2 server browser and launcher
<item>ElectricEyes (<htmlurl url="http://www.labs.redhat.com/ee.shtml" 
        name="http://www.labs.redhat.com/ee.shtml">),
        an image viewer that aims to be a free replacement for xv
<item>GPK - the General Proxy Kit (<htmlurl url="http://www.humanfactor.com/gpk/" 
        name="http://www.humanfactor.com/gpk/">),
        an add-on library to permit thread-safe access to GTK+
<item>GCK - the General Convenience Kit (<htmlurl url="http://www.ii.uib.no/~tomb/gck.html" 
        name="http://www.ii.uib.no/~tomb/gck.html">),
        miscellaneous functions intended to ease color handling, UI construction,
        vector operations, and math functions
<item>GDK Imlib (<htmlurl url="http://www.labs.redhat.com/imlib/" 
        name="http://www.labs.redhat.com/imlib/">),
        a fast image loading and manipulation library for GDK
<item>Glade (<htmlurl url="http://glade.pn.org/"
        name="http://glade.pn.org/">),
        a GTK+ based RAD tool which produces GTK+ applications
260
</itemize>
Tony Gale's avatar
Tony Gale committed
261
<p>
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
262 263 264
In addition to the above, the GNOME project (<htmlurl
url="http://www.gnome.org" name="http://www.gnome.org">) is using GTK+
to build a free desktop for Linux. Many more programs can be found
Tony Gale's avatar
Tony Gale committed
265
there.
266

Owen Taylor's avatar
Owen Taylor committed
267
<!-- ----------------------------------------------------------------- -->
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
268
<sect1>I'm looking for an application to write in GTK+. How about an IRC client? 
Owen Taylor's avatar
Owen Taylor committed
269 270
<p> 

BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
271 272
Ask on gtk-list for suggestions. There are at least three IRC clients
already under development (probably more in fact. The server at
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
273 274
<htmlurl url="http://www.forcix.cx/irc-clients.html"
name="http://www.forcix.cx/irc-clients.html"> list a bunch of them).
Owen Taylor's avatar
Owen Taylor committed
275 276

<itemize>
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
277
<item>X-Chat.
Owen Taylor's avatar
Owen Taylor committed
278
<item>girc. (Included with GNOME)
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
279
<item>gsirc. (In the gnome CVS tree)
Owen Taylor's avatar
Owen Taylor committed
280 281
</itemize>

282 283 284 285
<!-- ***************************************************************** -->
<sect>How to find, configure, install, and troubleshoot GTK+

<!-- ***************************************************************** -->
286 287

<!-- ----------------------------------------------------------------- -->
288 289 290 291 292
<sect1>What do I need to run GTK+?
<p>
To compile GTK+, all you need is a C compiler (gcc) and the X Window System
and associated libraries on your system.

293
<!-- ----------------------------------------------------------------- -->
294 295 296 297
<sect1>Where can I get GTK+?
<p>
The canonical site is:
<verb>
298
ftp://ftp.gtk.org/pub/gtk
299
</verb>
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
This site tends to get busy around the time of a new GTK+ release
so try and use one of the mirror sites that are listed in
<htmlurl url="ftp://ftp.gtk.org/etc/mirrors"
name="ftp://ftp.gtk.org/etc/mirrors">

Here's a few mirror sites to get you started:
<itemize>
<item>Africa - ftp://ftp.is.co.za/applications/gimp/
<item>Australia - ftp://ftp.au.gimp.org/pub/gimp/
<item>Finland - ftp://ftp.funet.fi/pub/sci/graphics/packages/gimp
<item>Germany - ftp://infosoc.uni-koeln.de/pub/ftp.gimp.org/
<item>Japan - ftp://SunSITE.sut.ac.jp/pub/archives/packages/gimp/
<item>UK - ftp://ftp.flirble.org/pub/X/gimp/
<item>US - ftp://ftp.insync.net/pub/mirrors/ftp.gimp.org/
</itemize>
315 316 317 318 319 320 321 322 323 324

<sect1>How do I configure/compile GTK+?
<p>
Generally, all you will need to do is issue the commands:
<verb>
./configure
make
</verb>
in the gtk+-version/ directory.

325 326 327 328 329 330 331 332 333 334
<!-- ----------------------------------------------------------------- -->
<sect1>When compiling GTK+ I get an error like: 
<tt/make: file `Makefile' line 456: Syntax error/
<p>
Make sure that you are using GNU make (use <tt/make -v/ to check). There are
many weird and wonderful versions of make out there, and not all of them
handle the automatically generated Makefiles.

<!-- ----------------------------------------------------------------- -->
 
Owen Taylor's avatar
Owen Taylor committed
335
<sect1>I've compiled and installed GTK+, but I can't get any programs to link with it!
336
<p>
Shawn Amundson's avatar
Shawn Amundson committed
337 338 339 340 341
This problem is most often encountered when the GTK+ libraries can't be 
found or are the wrong version. Generally, the compiler will complain about an
'unresolved symbol'.  There are two things you need to check:
<itemize>
<item>Make sure that the libraries can be found. You want to edit 
342
/etc/ld.so.conf to include the directories which contain the GTK libraries,
Shawn Amundson's avatar
Shawn Amundson committed
343
 so it looks something like:
344 345 346 347
<verb>
/usr/X11R6/lib
/usr/local/lib
</verb>
348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
Then you need to run /sbin/ldconfig as root. You can find what directory
GTK is in using
<verb>
gtk-config --libs
</verb>

If your system doesn't use ld.so to find libraries (such as Solaris), then
you will have to use the LD_LIBRARY_PATH environment variable (or compile
the path into your program, which I'm not going to cover here). So, with a
Bourne type shell you can do (if your GTK libraries are in /usr/local/lib):
<verb>
export LD_LIBRARY_PATH=/usr/local/lib
</verb>
and in a csh, you can do:
<verb>
setenv LD_LIBRARY_PATH /usr/local/lib
</verb>

Shawn Amundson's avatar
Shawn Amundson committed
366 367 368
<item>Make sure the linker is finding the correct set of libraries. If you
have a Linux distribution that installs GTK+ (e.g. RedHat 5.0) then this 
older version may be used. Now (assuming you have a RedHat
369 370 371 372 373 374 375 376
system), issue the command
<verb>
rpm -e gtk gtk-devel
</verb>
You may also want to remove the packages that depend on gtk (rpm will tell you
which ones they are).  If you don't have a RedHat Linux system, check to make sure
that neither <verb>/usr/lib</verb> or <verb>/usr/local/lib</verb> contain any of
the libraries libgtk, libgdk, libglib, or libgck.  If they do exist, remove them
Shawn Amundson's avatar
Shawn Amundson committed
377
(and any gtk include files, such as /usr/include/gtk and /usr/include/gdk) 
378
and reinstall gtk+.
Shawn Amundson's avatar
Shawn Amundson committed
379
</itemize>
380

Owen Taylor's avatar
Owen Taylor committed
381 382
<!-- ----------------------------------------------------------------- -->
<sect1>When compiling programs with GTK+, I get compiler error messages about not being able to find <tt/"glibconfig.h"/.
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
383 384
<p>
The header file "glibconfig.h" was moved to the directory
Owen Taylor's avatar
Owen Taylor committed
385 386 387 388 389 390
$exec_prefix/lib/glib/include/. $exec_prefix is the
directory that was specified by giving the --exec-prefix
flags to ./configure when compiling GTK+. It defaults to 
$prefix, (specified with --prefix), which in turn defaults
to /usr/local/.

391
This was done because "glibconfig.h" includes architecture
Owen Taylor's avatar
Owen Taylor committed
392 393 394 395
dependent information, and the rest of the include files
are put in $prefix/include, which can be shared between different
architectures. 

396
GTK+ includes a shell script, <tt/gtk-config/, that
Owen Taylor's avatar
Owen Taylor committed
397 398 399 400 401 402
makes it easy to find out the correct include paths.
The GTK+ tutorial includes an example of using <tt/gtk-config/
for simple compilation from the command line. For information
about more complicated configuration, see the file
docs/gtk-config.txt in the GTK+ distribution.

403
If you are trying to compile an old program, you may
Owen Taylor's avatar
Owen Taylor committed
404 405 406 407
be able to work around the problem by configuring it
with a command line like: 

<tscreen><verb>
408
CPPFLAGS="-I/usr/local/include/glib/include" ./configure
Owen Taylor's avatar
Owen Taylor committed
409 410 411 412 413
</verb></tscreen>

for Bourne-compatible shells like bash, or for csh variants:

<tscreen><verb>
414
setenv CPPFLAGS "-I/usr/local/include/glib/include" 
Owen Taylor's avatar
Owen Taylor committed
415 416 417 418 419
./configure
</verb></tscreen>

(Substitute the appropriate value of $exec_prefix for /usr/local.)

420
<!-- ----------------------------------------------------------------- -->
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
421
<sect1>When installing a GTK+ application, configure reports that it can't find GTK.
422
<p>
423
There are several common reasons for this:
424 425
<itemize>
<item>You have an old version of GTK installed somewhere. RedHat 5.0, for 
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
426 427
example, installs an older copy of GTK that may not work with the latest 
applications. You should remove this old copy, but note that in the case
428 429 430 431 432 433 434
of RedHat 5.0 this will break the <tt/control-panel/ applications.
<P>
<item><tt/gtk-config/ (or another component of GTK) isn't in your path, or
there is an old version on your system. Type:
<verb>
gtk-config --version
</verb>
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
435 436
to check for both of these. If it returns a value different from what
you expect, then you have an old version of GTK on your system.
437 438 439 440
<P>
<item>The ./configure script can't find the GTK libraries. As ./configure
compiles various test programs, it needs to be able to find the GTK
libraries. See the question above for help on this.
441
</itemize>
442 443 444 445 446 447
<p>
If none of the above help, then have a look in config.log, which is
generated by ./configure as it runs. At the bottom will be the last
action it took before failing. If it is a section of source code, copy
the source code to a file and compile it with the line just above it in
config.log. If the compilation is successful, try executing it.
448

449 450
<!-- ***************************************************************** -->
<sect>Development of GTK+
Shawn Amundson's avatar
Shawn Amundson committed
451
<!-- ***************************************************************** -->
452

453 454 455
<!-- ----------------------------------------------------------------- -->
<sect1>Whats this CVS thing that everyone keeps talking about, and how do I access it?
<p>
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
456
CVS is the Concurent Version System and is a very popular means of 
457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476
version control for software projects. It is designed to allow multiple 
authors to be able to simultanously operate on the same source tree. 
This source tree is centrally maintained, but each developer has a
local mirror of this repository that they make there changes to.

The GTK+ developers use a CVS repository to store the master copy of
the current development version of GTK+. As such, people wishing to
contribute patches to GTK+ should generate them against the CVS version.
Normal people should use the packaged releases.

The CVS toolset is available as RPM packages from the usual RedHat sites.
The latest version is available at 
<htmlurl url="http://download.cyclic.com/pub/" 
name="&lt;http://download.cyclic.com/pub/&gt;">

Anyone can download the latest CVS version of GTK+ by using anonymous access
using the following steps:
<itemize>
<item> In a bourne shell descendant (e.g. bash) type:
<verb>
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
477 478
CVSROOT=':pserver:anonymous@anoncvs.gnome.org:/cvs/gnome'
export CVSROOT
479 480 481 482 483 484 485 486
</verb>
<item>Next, the first time the source tree is checked out, a cvs login 
is needed. 
<verb>
cvs login
</verb>
This will ask you for a password. There is no password for cvs.gimp.org, 
so just enter a carriage return. 
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
487 488
<item>To get the tree and place it in a subdir of your current working
directory, issue the command: 
489
<verb>
BST 1998  Tony Gale's avatar
BST 1998 Tony Gale committed
490 491 492 493 494 495 496 497
cvs -z3 get gtk+
</verb>

Note that with the GTK+ 1.1 tree, glib has been moved to a separate CVS
module, so if you don't have glib installed you will need to get that
as well:
<verb>
cvs -z3 get glib
498
</verb>
BST 1998  Tony Gale's avatar
BST 1998 Tony Gale committed
499

500
</itemize>
Shawn Amundson's avatar
Shawn Amundson committed
501
<!-- ----------------------------------------------------------------- -->
502 503
<sect1>How can I contribute to GTK+?
<p>
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
504 505
It's simple. If something doesn't work like you think it should in a program,
check the documentation to make sure you're not missing something. If it is a
506 507 508 509
true bug or missing feature, track it down in the GTK+ source, change it, 
and then generate a patch in the form of a 'context diff'. This can be done
using a command such as <tt/diff -ru &lt;oldfile&gt; &lt;newfile&gt;/. 
Then upload the patchfile to:
510
<verb>
511
ftp://ftp.gtk.org/incoming
512
</verb>
Shawn Amundson's avatar
Shawn Amundson committed
513
along with a README file.  Make sure you follow the naming conventions or your
514
patch will just be deleted! The filenames should be of this form:
Shawn Amundson's avatar
Shawn Amundson committed
515 516 517 518 519 520 521 522 523 524 525 526 527
<verb>
gtk-<username>-<date yymmdd-n>.patch.gz
gtk-<username>-<date yymmdd-n>.patch.README
</verb>
The "n" in the date indicates a unique number (starting from 0)
of patches you uploaded that day.  It should be 0, unless you
upload more than one patch in the same day.

Example:
<verb>
gtk-gale-982701-0.patch.gz
gtk-gale-982701-0.patch.README
</verb>
528
Once you upload <em>anything</em>, send the README to ftp-admin@gtk.org
529

530 531 532
<!-- ----------------------------------------------------------------- -->
<sect1>How do I know if my patch got applied, and if not, why not?
<p>
533
Uploaded patches will be moved to <tt>ftp://ftp.gtk.org/pub/gtk/patches</tt>
534 535 536 537 538 539 540 541 542 543
where one of the GTK+ development team will pick them up. If applied, they
will be moved to <tt>/pub/gtk/patches/old</tt>.

Patches that aren't applied, for whatever reason, are moved to 
<tt>/pub/gtk/patches/unapplied</tt> or <tt>/pub/gtk/patches/outdated</tt>.
At this point you can ask on the <tt/gtk-list/ mailing list why your patch
wasn't applied. There are many possible reasons why patches may not be
applied, ranging from it doesn't apply cleanly, to it isn't right. Don't
be put off if your patch didn't make it first time round.

Shawn Amundson's avatar
Shawn Amundson committed
544
<!-- ----------------------------------------------------------------- -->
545 546 547
<sect1>What is the policy on incorporating new widgets into the library?
<p>
This is up to the authors, so you will have to ask them once you
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
548
are done with your widget. As a general guideline, widgets that are 
549 550
generally useful, work, and are not a disgrace to the widget set will 
gladly be included.
551

552
<!-- ----------------------------------------------------------------- -->
Shawn Amundson's avatar
Shawn Amundson committed
553
<sect1>Is anyone working on bindings for languages other than C?
554
<p>
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
555 556 557
The GTK+ home page (<htmlurl url="http://www.gtk.org/" 
name="http://www.gtk.org/">) presents a list of GTK+ bindings.

Shawn Amundson's avatar
Shawn Amundson committed
558
<itemize>
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580
<item>There are several C++ wrappers for GTK+.
  <itemize>
  
  <item>the gtk-- package, which is a very small wrapper for GTK+.
  You can find the home page at:
  <htmlurl url="http://www.cs.tut.fi/~p150650/gtk/gtk--.html"
  name="http://www.cs.tut.fi/~p150650/gtk/gtk--.html">. 
  The FTP site is 
  <htmlurl url="ftp://ftp.gtk.org/pub/gtk/gtk--"
  name="ftp://ftp.gtk.org/pub/gtk/gtk--">.
  
  <item>the VDK package, which was built as the base package of a GTK+
  application Borland-like builder. The home page can be found at
  <htmlurl url="www.guest.net/homepages/mmotta/VDKHome" 
  name="www.guest.net/homepages/mmotta/VDKHome">.

  <item>The wxWindows/Gtk package, a free C++ library for cross-platform 
  GUI development. The home page of this package is
  <htmlurl url="http://www.freiburg.linux.de/~wxxt/"
  name="http://www.freiburg.linux.de/~wxxt/">.

  </itemize> 
581
<p>
Shawn Amundson's avatar
Shawn Amundson committed
582

BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
583
<item>There are three known Objective-c bindings currently in development:
584

BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
585
  <itemize>
586

BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
587 588 589 590
  <item>The <htmlurl url="http://www.gnome.org/" name="GNOME project's"> package
  of choice is objgtk. Objgtk is based on the Object class and is maintained by
  <htmlurl url="mailto:sopwith@cuc.edu" name="Elliot Lee">. Apparently, objgtk
  is being accepted as the `standard' Objective-C binding for GTK+.
591

BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
592 593 594 595 596 597 598 599 600 601 602
  <item>If you are more inclined towards the 
  <htmlurl url="http://www.gnustep.org/" name="GNUstep project">,
  you may want to check out GTKKit by 
  <htmlurl url="mailto:helge@mdlink.de" name="Helge He&szlig;">.
  The intention is to setup a GTK+ binding using the FoundationKit. 
  GTKKit includes nicities like writing a XML-type template file to 
  construct a GTK+ interface.

  <item>The GToolKit package, which can be found at
  <htmlurl url="ftp://ftp.gtk.org/pub/gtk/objc-gtoolkit/" 
  name="ftp://ftp.gtk.org/pub/gtk/objc-gtoolkit/">.
603 604 605

 </itemize> 
<p>               
606
<item>Perl bindings
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
607 608
  <htmlurl url="ftp://ftp.gtk.org/pub/gtk/perl"
  name="ftp://ftp.gtk.org/pub/gtk/perl">
609 610
<P>
<item>Guile bindings. The home page is at
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
611 612 613 614
  <htmlurl url="http://www.ping.de/sites/zagadka/guile-gtk"
  name="http://www.ping.de/sites/zagadka/guile-gtk">.
  By the way, Guile is the GNU Project's implemention of R4RS Scheme (the
  standard). If you like Scheme, you may want to take a look at this.
Shawn Amundson's avatar
Shawn Amundson committed
615
<p>
616

Shawn Amundson's avatar
Shawn Amundson committed
617
<item>David Monniaux reports:
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
618 619
  <quote>I've started a gtk-O'Caml binding system.
  The basics of the system, including callbacks, work fine.
Shawn Amundson's avatar
Shawn Amundson committed
620

BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
621 622 623 624
  The current development is in
  <htmlurl url="http://www.ens-lyon.fr/~dmonniau/arcs"
  name="http://www.ens-lyon.fr/~dmonniau/arcs">
  </quote>
Tony Gale's avatar
Tony Gale committed
625

BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
626
<item> Several python bindings have been done:
627
<p>
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643
  <itemize>
  <item>pygtk is at 
  <htmlurl url="http://www.daa.com.au/~james/pygtk" 
  name="http://www.daa.com.au/~james/pygtk"> and 
  <htmlurl url="ftp://ftp.gtk.org/pub/gtk/python"
  name="ftp://ftp.gtk.org/pub/gtk/python">

  <item>python-gtk is at
  <htmlurl url="http://www.ucalgary.ca/~nascheme/python-gtk" 
  name="http://www.ucalgary.ca/~nascheme/python-gtk">
  </itemize>
<p>
<item>There's are a couple of OpenGL/Mesa widgets available for
GTK+. I suggest you start at
  <htmlurl url="http://www.student.oulu.fi/~jlof/gtkglarea/index.html" 
  name="http://www.student.oulu.fi/~jlof/gtkglarea/index.html">
644
<p>
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
645 646
<item>Last, there are a lot of other language bindings for languages such as 
  Eiffel, TOM, Pascal, Pike, etc.
Tony Gale's avatar
Tony Gale committed
647

Shawn Amundson's avatar
Shawn Amundson committed
648
</itemize>
Tony Gale's avatar
Tony Gale committed
649

650
<!-- ***************************************************************** -->
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
651
<sect>Development with GTK+: the begining
Tony Gale's avatar
Tony Gale committed
652 653 654 655 656 657
<!-- ***************************************************************** -->
<!-- ----------------------------------------------------------------- -->
<sect1>How do I get started?
<p>
So, after you have installed GTK+ there are a couple of things that can
ease you into developing applications with it. There is the
658 659
GTK+ Tutorial <htmlurl url="http://www.gtk.org/tutorial/" 
name="&lt;http://www.gtk.org/tutorial/&gt;">, which is undergoing 
660
development. This will introduce you to writing applications using C.
Tony Gale's avatar
Tony Gale committed
661 662 663 664

The Tutorial doesn't (yet) contain information on all of the widgets
that are in GTK+. For example code on how to use the basics of all the
GTK+ widgets you should look at the file gtk/testgtk.c (and associated
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
665
source files) within the GTK+ distribution. Looking at these examples will
Tony Gale's avatar
Tony Gale committed
666 667
give you a good grounding on what the widgets can do.

BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813
<!-- ----------------------------------------------------------------- -->
<sect1>I tried to compile a small <tt/Hello World/ of mine, but it failed. Any clue?
<p>
Since you are good at coding, we will not deal with compile time error here :).

The classic command line to compile a GTK+ based program is

<verb>
gcc -o myprg [c files list] `gtk-config --cflags --libs`
</verb>

You should notice the backquote character which is used in this command line.
A common mistake when you start a GTK+ based development is to use quote 
instead of backquotes. If you do so, the compiler will complain about an 
unknown file called 'gtk-config --cflags --libs'. The text in
backquotes is an instruction to your shell to substitute the output of
executing this text into the command line.

The command line above ensure that:
<itemize>

  <item>the correct C compiler flags will be used to compile the program
        (including the complete C header directory list)

  <item>your program will be linked with the needed libraries.

</itemize>

<sect1>What about using the <tt/make/ utility?
<p>
This is a sample makefile which compile a GTK+ based program:

<tscreen><verb>
# basic GTK+ app makefile
SOURCES = myprg.c foo.c bar.c
OBJS    = ${SOURCES:.c=.o}
CFLAGS  = `gtk-config --cflags`
LDADD   = `gtk-config --libs`
CC      = gcc
PACKAGE = myprg

all : ${OBJS}
        ${CC} -o ${PACKAGE} ${OBJS} ${LDADD}

.c.o:
        ${CC} ${CFLAGS} -c $<

# end of file
</verb></tscreen>

For more information about the <tt/make/ utility, you should read either the
related man page or the relevant info file.

<sect1>I use the backquote stuff in my makefiles, but my make process failed.
<p>
The backquote construction seems to not be accepted by some old <tt/make/
utilities. If you use one of these, the make process will probably fail.
In order to have the backquote syntax working again, you should use the
GNU make utility (get it on the GNU ftp server at
<htmlurl url="ftp://ftp.gnu.org/" name="ftp://ftp.gnu.org/">).

<!-- ----------------------------------------------------------------- -->
<sect1>I want to add some configure stuff, how could I do this?
<p>
To use autoconf/automake, you must first install the relevant packages. These
are:

<itemize>
  <item>the m4 preprocessor v1.4 or better
  <item>autoconf v2.13 or better
  <item>automake v1.4 or better
</itemize>

You'll find these packages on the GNU main ftp server (<htmlurl 
url="ftp://ftp.gnu.org/" name="ftp://ftp.gnu.org/">) or on any GNU mirror.

In order to use the powerfull autoconf/automake scheme, you must create
a configure.in which may look like:

<tscreen><verb>
dnl Process this file with autoconf to produce a configure script.
dnl configure.in for a GTK+ based program

AC_INIT(myprg.c)dnl
AM_INIT_AUTOMAKE(mypkbname,0.0.1)dnl
AM_CONFIG_HEADER(config.h)dnl

dnl Checks for programs.
AC_PROG_CC dnl check for the c compiler
dnl you should add CFLAGS="" here, 'cos it is set to -g by PROG_CC

dnl Checks for libraries.
AM_PATH_GTK(1.2.0,,AC_MSG_ERROR(mypkgname 0.1 needs GTK))dnl

AC_OUTPUT(
	Makefile
)dnl
</verb></tscreen>

You must add a Makefile.am file:

<tscreen><verb>
bin_PROGRAMS    = myprg
myprg_SOURCES   = myprg.c foo.c bar.c
INCLUDES        = @GTK_CFLAGS@
LDADD           = @GTK_LIBS@
CLEANFILES      = *~
DISTCLEANFILES  = .deps/*.P
</verb></tscreen>

then, to use these, simply type the following commands:

<verb>
aclocal
autoheader
autoconf
automake --add-missing --include-deps --foreign 
</verb>

For further informations, you should look at the autoconf and the automake
documentation (the shipped info files are really easy to understand, and there
are plenty of web resources that deal with autoconf and/or automake).

<!-- ----------------------------------------------------------------- -->
<sect1>I try to debug my GTK+ application with gdb, but it hangs my X server when I hit some breakpoint. Any Idea ?
<p>
From Federico Mena Quintero:
<quote>
X is not locked up.  It is likely that you are hitting a breakpoint
inside a callback that is called from a place in Gtk that has a mouse
grab.
<P>
Run your program with the "--sync" option; it will make it easier to
debug. Also, you may want to use the console for running the
debugger, and just let the program run in another console with the X
server.
</quote>

Eric Mouw had another solution:
<quote>
An old terminal connected to an otherwise unused serial port is also great
for debugging X programs. Old vt100/vt220 terminals are dirt cheap but a
bit hard to get (here in The Netherlands, YMMV).
</quote>

<!-- ***************************************************************** -->
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
814
<sect>Development with GTK+: general questions
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
815 816
<!-- ***************************************************************** -->
<!-- ----------------------------------------------------------------- -->
Tony Gale's avatar
Tony Gale committed
817 818 819
<sect1>What widgets are in GTK?
<p>
The GTK+ Tutorial lists the following widgets:
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
820

Tony Gale's avatar
Tony Gale committed
821
<verb>
822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861
  GtkObject
   +GtkData
   | +GtkAdjustment
   | `GtkTooltips
   `GtkWidget
     +GtkContainer
     | +GtkBin
     | | +GtkAlignment
     | | +GtkEventBox
     | | +GtkFrame
     | | | `GtkAspectFrame
     | | +GtkHandleBox
     | | +GtkItem
     | | | +GtkListItem
     | | | +GtkMenuItem
     | | | | `GtkCheckMenuItem
     | | | |   `GtkRadioMenuItem
     | | | `GtkTreeItem
     | | +GtkViewport
     | | `GtkWindow
     | |   +GtkColorSelectionDialog
     | |   +GtkDialog
     | |   | `GtkInputDialog
     | |   `GtkFileSelection
     | +GtkBox
     | | +GtkButtonBox
     | | | +GtkHButtonBox
     | | | `GtkVButtonBox
     | | +GtkHBox
     | | | +GtkCombo
     | | | `GtkStatusbar
     | | `GtkVBox
     | |   +GtkColorSelection
     | |   `GtkGammaCurve
     | +GtkButton
     | | +GtkOptionMenu
     | | `GtkToggleButton
     | |   `GtkCheckButton
     | |     `GtkRadioButton
     | +GtkCList
862
     |   `GtkCTree
863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902
     | +GtkFixed
     | +GtkList
     | +GtkMenuShell
     | | +GtkMenuBar
     | | `GtkMenu
     | +GtkNotebook
     | +GtkPaned
     | | +GtkHPaned
     | | `GtkVPaned
     | +GtkScrolledWindow
     | +GtkTable
     | +GtkToolbar
     | `GtkTree
     +GtkDrawingArea
     | `GtkCurve
     +GtkEditable
     | +GtkEntry
     | | `GtkSpinButton
     | `GtkText
     +GtkMisc
     | +GtkArrow
     | +GtkImage
     | +GtkLabel
     | | `GtkTipsQuery
     | `GtkPixmap
     +GtkPreview
     +GtkProgressBar
     +GtkRange
     | +GtkScale
     | | +GtkHScale
     | | `GtkVScale
     | `GtkScrollbar
     |   +GtkHScrollbar
     |   `GtkVScrollbar
     +GtkRuler
     | +GtkHRuler
     | `GtkVRuler
     `GtkSeparator
       +GtkHSeparator
       `GtkVSeparator
Tony Gale's avatar
Tony Gale committed
903
</verb>
904

905 906 907
<!-- ----------------------------------------------------------------- -->
<sect1>Is GTK+ thread safe? How do I write multi-threaded GTK+ applications?
<p>
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952
The GLib library can be used in a thread-safe mode by calling
g_thread_init() before making any other GLib calls. In this mode GLib
automatically locks all internal data structures as needed.  This
does not mean that two threads can simultaneously access, for
example, a single hash table, but they can access two different hash
tables simultaneously. If two different threads need to access the
same hash table, the application is responsible for locking
itself.

When GLib is intialized to be thread-safe, GTK+ is
<em>thread aware</em>. There is a single global lock
that you must acquire with gdk_threads_enter() before
making any GDK calls, and release with gdk_threads_leave()
afterwards.

A minimal main program for a threaded GTK+ application
looks like:

<verb>
int
main (int argc, char *argv[])
{
  GtkWidget *window;

  g_thread_init(NULL);
  gtk_init(&amp;argc, &amp;argv);

  window = create_window();
  gtk_widget_show(window);

  gdk_threads_enter();
  gtk_main();
  gdk_threads_leave();

  return(0);
}
</verb>

Callbacks require a bit of attention. Callbacks from GTK+
(signals) are made within the GTK+ lock. However callbacks
from GLib (timeouts, IO callbacks, and idle functions)
are made outside of the GTK+ lock. So, within a signal
handler you do not need to call gdk_threads_enter(), but
within the other types of callbacks, you do.

953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095
Erik Mouw contributed the following code example to illustrate how to
use threads within GTK+ programs.

<tscreen><verb>
/*-------------------------------------------------------------------------
 * Filename:      gtk-thread.c
 * Version:       0.99.1
 * Copyright:     Copyright (C) 1999, Erik Mouw
 * Author:        Erik Mouw <J.A.K.Mouw@its.tudelft.nl>
 * Description:   GTK threads example. 
 * Created at:    Sun Oct 17 21:27:09 1999
 * Modified by:   Erik Mouw <J.A.K.Mouw@its.tudelft.nl>
 * Modified at:   Sun Oct 24 17:21:41 1999
 *-----------------------------------------------------------------------*/
/*
 * Compile with:
 *
 * cc -o gtk-thread gtk-thread.c `gtk-config --cflags --libs gthread`
 *
 * Thanks to Sebastian Wilhelmi and Owen Taylor for pointing out some
 * bugs.
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <gtk/gtk.h>
#include <glib.h>
#include <pthread.h>

#define YES_IT_IS    (1)
#define NO_IT_IS_NOT (0)

typedef struct 
{
  GtkWidget *label;
  int what;
} yes_or_no_args;

G_LOCK_DEFINE_STATIC (yes_or_no);
static volatile int yes_or_no = YES_IT_IS;

void destroy(GtkWidget *widget, gpointer data)
{
  gtk_main_quit();
}

void *argument_thread(void *args)
{
  yes_or_no_args *data = (yes_or_no_args *)args;
  gboolean say_something;

  for(;;)
    {
      /* sleep a while */
      sleep(rand() / (RAND_MAX / 3) + 1);

      /* lock the yes_or_no_variable */
      G_LOCK(yes_or_no);

      /* do we have to say something? */
      say_something = (yes_or_no != data->what);

      if(say_something)
	{
	  /* set the variable */
	  yes_or_no = data->what;
	}

      /* Unlock the yes_or_no variable */
      G_UNLOCK(yes_or_no);

      if(say_something)
	{
	  /* get GTK thread lock */
	  gdk_threads_enter();

	  /* set label text */
	  if(data->what == YES_IT_IS)
	    gtk_label_set_text(GTK_LABEL(data->label), "O yes, it is!");
	  else
	    gtk_label_set_text(GTK_LABEL(data->label), "O no, it isn't!");

	  /* release GTK thread lock */
	  gdk_threads_leave();
	}
    }

  return(NULL);
}

int main(int argc, char *argv[])
{
  GtkWidget *window;
  GtkWidget *label;
  yes_or_no_args yes_args, no_args;
  pthread_t no_tid, yes_tid;

  /* init threads */
  g_thread_init(NULL);

  /* init gtk */
  gtk_init(&amp;argc, &amp;argv);

  /* init random number generator */
  srand((unsigned int)time(NULL));

  /* create a window */
  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

  gtk_signal_connect(GTK_OBJECT (window), "destroy",
		     GTK_SIGNAL_FUNC(destroy), NULL);

  gtk_container_set_border_width(GTK_CONTAINER (window), 10);

  /* create a label */
  label = gtk_label_new("And now for something completely different ...");
  gtk_container_add(GTK_CONTAINER(window), label);
  
  /* show everything */
  gtk_widget_show(label);
  gtk_widget_show (window);

  /* create the threads */
  yes_args.label = label;
  yes_args.what = YES_IT_IS;
  pthread_create(&amp;yes_tid, NULL, argument_thread, &amp;yes_args);

  no_args.label = label;
  no_args.what = NO_IT_IS_NOT;
  pthread_create(&amp;no_tid, NULL, argument_thread, &amp;no_args);

  /* enter the GTK main loop */
  gdk_threads_enter();
  gtk_main();
  gdk_threads_leave();

  return(0);
}
</verb></tscreen>

BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
1096 1097 1098
<!-- This is the old answer - TRG


1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120
Although GTK+, like many X toolkits, isn't thread safe, this does
not prohibit the development of multi-threaded applications with
GTK+. 

Rob Browning (rlb@cs.utexas.edu) describes threading techniques for
use with GTK+ (slightly edited): 

There are basically two main approaches, the first is simple, and the
second complicated. In the first, you just make sure that all GTK+ (or
X) interactions are handled by one, and
only one, thread. Any other thread that wants to draw something has
to somehow notify the "GTK+" thread, and let it handle the
actual work. 

The second approach allows you to call GTK+ (or X) functions from any
thread, but it requires some careful synchronization. The
basic idea is that you create an X protection mutex, and no one may
make any X calls without first acquiring this mutex. 

Note that this is a little effort, but it allows you to be
potentially more efficient than a completely thread safe GTK+. You
get to decide the granularity of the thread locking. You also have to
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
1121 1122
make sure that the thread that calls <tt/gtk_main()/ is holding the lock when
it calls <tt/gtk_main()/.
1123 1124

The next thing to worry about is that since you were holding the
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
1125
global mutex when you entered <tt/gtk_main()/, all callbacks will also be
1126 1127 1128 1129 1130
holding it. This means that the callback must release it if it's
going to call any other code that might reacquire it. Otherwise
you'll get deadlock. Also, you must be holding the mutex when you
finally return from the callback. 

BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
1131
In order to allow threads other than the one calling <tt/gtk_main/ to
1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145
get access to the mutex, we also need to register a work function
with GTK that allows us to release the mutex periodically.

Why can't GTK+ be thread safe by default?                           

Complexity, overhead, and manpower.  The proportion of threaded
programs is still reasonably small, and getting thread safety right is
both quite difficult and takes valuable time away from the main work
of getting a good graphics library finished.  It would be nice to have
GTK+ thread safe "out of the box", but that's not practical right now,
and it also might make GTK+ substantially less efficient if not handled
carefully.

Regardless, it's especially not a priority since relatively good
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
1146
workarounds exist. -->
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
1147
<!-- ----------------------------------------------------------------- -->
1148
<sect1>Why does this strange 'x io error' occur when I <tt/fork()/ in my GTK+ app?
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
1149 1150
<p>
This is not really a GTK+ problem, and the problem is not related to <tt/fork()/
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
1151
either. If the 'x io error' occurs then you probably use the <tt/exit()/ function
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
1152 1153 1154 1155 1156 1157 1158 1159
in order to exit from the child process.

When GDK opens an X display, it creates a socket file descriptor. When you use
the <tt/exit()/ function, you implicitly close all the open file descriptors,
and the underlying X library really doesn't like this.

The right function to use here is <tt/_exit()/. 

1160
Erik Mouw contributed the following code example to illustrate handling
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
1161
fork() and exit().
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
1162 1163

<tscreen><verb>
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242
/*-------------------------------------------------------------------------
 * Filename:      gtk-fork.c
 * Version:       0.99.1
 * Copyright:     Copyright (C) 1999, Erik Mouw
 * Author:        Erik Mouw <J.A.K.Mouw@its.tudelft.nl>
 * Description:   GTK+ fork example
 * Created at:    Thu Sep 23 21:37:55 1999
 * Modified by:   Erik Mouw <J.A.K.Mouw@its.tudelft.nl>
 * Modified at:   Thu Sep 23 22:39:39 1999
 *-----------------------------------------------------------------------*/
/*
 * Compile with:
 *
 * cc -o gtk-fork gtk-fork.c `gtk-config --cflags --libs`
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <gtk/gtk.h>

void sigchld_handler(int num)
{
  sigset_t set, oldset;
  pid_t pid;
  int status, exitstatus;

  /* block other incoming SIGCHLD signals */
  sigemptyset(&amp;set);
  sigaddset(&amp;set, SIGCHLD);
  sigprocmask(SIG_BLOCK, &amp;set, &amp;oldset);

  /* wait for child */
  while((pid = waitpid((pid_t)-1, &amp;status, WNOHANG)) > 0)
    {
      if(WIFEXITED(status))
	{
	  exitstatus = WEXITSTATUS(status);

	  fprintf(stderr, 
		  "Parent: child exited, pid = %d, exit status = %d\n", 
		  (int)pid, exitstatus);
	}
      else if(WIFSIGNALED(status))
	{
	  exitstatus = WTERMSIG(status);

	  fprintf(stderr,
		  "Parent: child terminated by signal %d, pid = %d\n",
		  exitstatus, (int)pid);
	}
      else if(WIFSTOPPED(status))
	{
	  exitstatus = WSTOPSIG(status);

	  fprintf(stderr,
		  "Parent: child stopped by signal %d, pid = %d\n",
		  exitstatus, (int)pid);
	}
      else
	{
	  fprintf(stderr,
		  "Parent: child exited magically, pid = %d\n",
		  (int)pid);
	}
    }

  /* re-install the signal handler (some systems need this) */
  signal(SIGCHLD, sigchld_handler);
  
  /* and unblock it */
  sigemptyset(&amp;set);
  sigaddset(&amp;set, SIGCHLD);
  sigprocmask(SIG_UNBLOCK, &amp;set, &amp;oldset);
}
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
1243

BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260
gint delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
{
  return(FALSE);
}

void destroy(GtkWidget *widget, gpointer data)
{
  gtk_main_quit();
}

void fork_me(GtkWidget *widget, gpointer data)
{
  pid_t pid;

  pid = fork();

  if(pid == -1)
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
1261
    {
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
1262
      /* ouch, fork() failed */
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
1263 1264 1265
      perror("fork");
      exit(-1);
    }
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
1266
  else if(pid == 0)
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
1267
    {
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
1268 1269 1270 1271 1272 1273 1274 1275 1276 1277
      /* child */
      fprintf(stderr, "Child: pid = %d\n", (int)getpid());

      execlp("ls", "ls", "-CF", "/", NULL);
      
      /* if exec() returns, there is something wrong */
      perror("execlp");

      /* exit child. note the use of _exit() instead of exit() */
      _exit(-1);
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
1278
    }
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
1279
  else
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
1280
    {
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
1281 1282
      /* parent */
      fprintf(stderr, "Parent: forked a child with pid = %d\n", (int)pid);
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
1283
    }
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331
}

int main(int argc, char *argv[])
{
  GtkWidget *window;
  GtkWidget *button;

  gtk_init(&amp;argc, &amp;argv);

  /* the basic stuff: make a window and set callbacks for destroy and
   * delete events 
   */
  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

  gtk_signal_connect(GTK_OBJECT (window), "delete_event",
		     GTK_SIGNAL_FUNC(delete_event), NULL);
          
  gtk_signal_connect(GTK_OBJECT (window), "destroy",
		     GTK_SIGNAL_FUNC(destroy), NULL);

#if (GTK_MAJOR_VERSION == 1) && (GTK_MINOR_VERSION == 0)
  gtk_container_border_width(GTK_CONTAINER (window), 10);
#else  
  gtk_container_set_border_width(GTK_CONTAINER (window), 10);
#endif

  /* add a button to do something usefull */
  button = gtk_button_new_with_label("Fork me!");
          
  gtk_signal_connect(GTK_OBJECT (button), "clicked",
		     GTK_SIGNAL_FUNC(fork_me), NULL);

  gtk_container_add(GTK_CONTAINER(window), button);
          
  /* show everything */
  gtk_widget_show (button);
  gtk_widget_show (window);


  /* install a signal handler for SIGCHLD signals */
  signal(SIGCHLD, sigchld_handler);

  
  /* main loop */
  gtk_main ();

  exit(0);         
}
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353
</verb></tscreen>

<!-- ----------------------------------------------------------------- -->
<sect1>Why don't the contents of a button move when the button is pressed? Here's a patch to make it work that way...
<p>
From: Peter Mattis

<quote>
The reason buttons don't move their child down and to the right when
they are depressed is because I don't think that's what is happening
visually. My view of buttons is that you are looking at them straight
on. That is, the user interface lies in a plane and you're above it
looking straight at it. When a button gets pressed it moves directly
away from you. To be absolutely correct I guess the child should
actually shrink a tiny amount. But I don't see why the child should
shift down and to the left. Remember, the child is supposed to be
attached to the buttons surface. Its not good for it to appear like
the child is slipping on the surface of the button.
<P>
On a more practical note, I did implement this at one point and
determined it didn't look good and removed it.
</quote>     
1354

BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383
<!-- ----------------------------------------------------------------- -->
<sect1>How to I identifiy a widgets top level window or other ancestor?
<p>
There are a couple of ways to find the top level parent of a
widget. The easier way is to call the <tt/gtk_widget_top_level()/
function that returns a pointer to a GtkWidget that is the top level
window.

A more complicated way to do this (but less limited, as it allows
the user to get the closest ancestor of a known type) is to use
<tt/gtk_widget_get_ancestor()/ as in:

<tscreen><verb>
      GtkWidget       *widget;
      
      widget = gtk_widget_get_ancestor(w, GTK_TYPE_WINDOW);
</verb></tscreen>

Since virtually all the GTK_TYPEs can be used as the second parameter of
this function, you can get any parent widget of a particular
widget. Suppose you have an hbox which contains a vbox, which in turn contains
some other atomic widget (entry, label, etc. To find the master hbox
using the <tt/entry/ widget simply use:

<tscreen><verb>
      GtkWidget       *hbox;
      hbox = gtk_widget_get_ancestor(w, GTK_TYPE_HBOX);
</verb></tscreen>

1384
<!-- ----------------------------------------------------------------- -->
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
1385 1386 1387 1388 1389 1390 1391
<sect1>How do I get the Window ID of a GtkWindow?
<p>
The actual Gdk/X window will be created when the widget gets
realized. You can get the Window ID with:

<verb>
#include <gdk/gdkx.h>
BST 1999 Tony Gale's avatar
BST 1999 Tony Gale committed
1392