]> Pileus Git - ~andy/gtk/blobdiff - docs/gtkfaq.sgml
FAQ Update: - Minor cleanups (Emmanuel, me) - New questions: I need to add
[~andy/gtk] / docs / gtkfaq.sgml
index 766c2affac97cda05cda0550c5e9eb6304620940..e5f0bdf42a97dee72714dcf4e82086bf04a7b900 100644 (file)
@@ -7,9 +7,9 @@
 <title>GTK+ FAQ
 
 <!-- NOTE: Use only one author tag, otherwise sgml2txt barfs - TRG --> 
-<author>Nathan Froyd, Tony Gale, Shawn T. Amundson, Emmanuel Deloget
+<author>Tony Gale, Shawn T. Amundson, Emmanuel Deloget, Nathan Froyd
 
-<date>August 29th 1999
+<date>March 9th 2000
 
 <abstract> This document is intended to answer questions that are likely to be 
 frequently asked by programmers using GTK+ or people who are just looking at 
@@ -91,9 +91,9 @@ enhancement to the original gtk that adds object oriented features."
 <p>
 GTK+ == Gimp Toolkit
 
-GDK == Gtk+ Drawing Kit
+GDK == GTK+ Drawing Kit
 
-GLib == G Library
+GLib == G Libray
 
 <!-- ----------------------------------------------------------------- -->
 <sect1>Where is the documentation for GTK+?
@@ -109,15 +109,28 @@ 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">
 
-There is also a book available that details programming with GTK+ and
-GDK which has been written by Eric Harlow. It is entitled "Developing
-Linux Applications with GTK+ and GDK" and is available at all good
-book stores. The ISBN is 0-7357-0021-4
-
+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>
 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">
 
+<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>
+
 <!-- ----------------------------------------------------------------- -->
 <sect1>Is there a mailing list (or mailing list archive) for GTK+?
 <p>
@@ -129,9 +142,10 @@ name="http://www.gtk.org/mailinglists.html">
 <!-- ----------------------------------------------------------------- -->
 <sect1>How to get help with GTK+
 <p>
-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.
+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.
 
 <!-- ----------------------------------------------------------------- -->
 <sect1>How to report bugs in GTK+
@@ -166,25 +180,24 @@ Then describe the bug. Include:
 
 <item> How to reproduce the bug. 
 
-  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.
+  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.
 
-  (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 
+  (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
   you are using)
 
 <item> If the bug was a crash, the exact text that was printed out
   when the crash occured.
 
-<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.
+<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.
 </itemize>
 
 <!-- ----------------------------------------------------------------- -->
@@ -246,30 +259,28 @@ Some of these are:
         a GTK+ based RAD tool which produces GTK+ applications
 </itemize>
 <p>
-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
+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
 there.
 
 <!-- ----------------------------------------------------------------- -->
 <sect1>I'm looking for an application to write in GTK+. How about an IRC client? 
 <p> 
 
-Ask on gtk-list for suggestions. There are at least three IRC
-clients already under development (probably more in fact. The server at
+Ask on gtk-list for suggestions. There are at least three IRC clients
+already under development (probably more in fact. The server at
 <htmlurl url="http://www.forcix.cx/irc-clients.html"
 name="http://www.forcix.cx/irc-clients.html"> list a bunch of them).
 
 <itemize>
+<item>X-Chat.
 <item>girc. (Included with GNOME)
-<item>Bezerk (<htmlurl url="http://www.gtk.org/~trog/"
-                       name="http://www.gtk.org/~trog/">)
 <item>gsirc. (In the gnome CVS tree)
 </itemize>
 
 <!-- ***************************************************************** -->
 <sect>How to find, configure, install, and troubleshoot GTK+
-
 <!-- ***************************************************************** -->
 
 <!-- ----------------------------------------------------------------- -->
@@ -301,6 +312,7 @@ Here's a few mirror sites to get you started:
 <item>US - ftp://ftp.insync.net/pub/mirrors/ftp.gimp.org/
 </itemize>
 
+<!-- ----------------------------------------------------------------- -->
 <sect1>How do I configure/compile GTK+?
 <p>
 Generally, all you will need to do is issue the commands:
@@ -314,21 +326,22 @@ in the gtk+-version/ directory.
 <sect1>When compiling GTK+ I get an error like: 
 <tt/make: file `Makefile' line 456: Syntax error/
 <p>
-Make sure that you are using GNU make (use <tt/make -v/ to check). There are
-many weird and wonderful versions of make out there, and not all of them
-handle the automatically generated Makefiles.
+Make sure that you are using GNU make (use <tt/make -v/ to
+check). There are many weird and wonderful versions of make out there,
+and not all of them handle the automatically generated Makefiles.
 
 <!-- ----------------------------------------------------------------- -->
  
 <sect1>I've compiled and installed GTK+, but I can't get any programs to link with it!
 <p>
-This problem is most often encountered when the GTK+ libraries can't be 
-found or are the wrong version. Generally, the compiler will complain about an
-'unresolved symbol'.  There are two things you need to check:
+This problem is most often encountered when the GTK+ libraries can't
+be found or are the wrong version. Generally, the compiler will
+complain about an 'unresolved symbol'.  There are two things you need
+to check:
 <itemize>
-<item>Make sure that the libraries can be found. You want to edit 
-/etc/ld.so.conf to include the directories which contain the GTK libraries,
- so it looks something like:
+<item>Make sure that the libraries can be found. You want to edit
+/etc/ld.so.conf to include the directories which contain the GTK
+libraries, so it looks something like:
 <verb>
 /usr/X11R6/lib
 /usr/local/lib
@@ -358,13 +371,13 @@ system), issue the command
 <verb>
 rpm -e gtk gtk-devel
 </verb>
-You may also want to remove the packages that depend on gtk (rpm will tell you
-which ones they are).  If you don't have a RedHat Linux system, check to make sure
-that neither <verb>/usr/lib</verb> or <verb>/usr/local/lib</verb> contain any of
-the libraries libgtk, libgdk, libglib, or libgck.  If they do exist, remove them
-(and any gtk include files, such as /usr/include/gtk and /usr/include/gdk) 
-and reinstall gtk+.
-</itemize>
+You may also want to remove the packages that depend on gtk (rpm will
+tell you which ones they are). If you don't have a RedHat Linux
+system, check to make sure that neither <verb>/usr/lib</verb> or
+<verb>/usr/local/lib</verb> contain any of the libraries libgtk,
+libgdk, libglib, or libgck.  If they do exist, remove them (and any
+gtk include files, such as /usr/include/gtk and /usr/include/gdk) and
+reinstall gtk+.  </itemize>
 
 <!-- ----------------------------------------------------------------- -->
 <sect1>When compiling programs with GTK+, I get compiler error messages about not being able to find <tt/"glibconfig.h"/.
@@ -455,7 +468,7 @@ Normal people should use the packaged releases.
 The CVS toolset is available as RPM packages from the usual RedHat sites.
 The latest version is available at 
 <htmlurl url="http://download.cyclic.com/pub/" 
-name="&lt;http://download.cyclic.com/pub/&gt;">
+name="http://download.cyclic.com/pub/">
 
 Anyone can download the latest CVS version of GTK+ by using anonymous access
 using the following steps:
@@ -484,8 +497,8 @@ as well:
 <verb>
 cvs -z3 get glib
 </verb>
-
 </itemize>
+
 <!-- ----------------------------------------------------------------- -->
 <sect1>How can I contribute to GTK+?
 <p>
@@ -540,7 +553,7 @@ gladly be included.
 <!-- ----------------------------------------------------------------- -->
 <sect1>Is anyone working on bindings for languages other than C?
 <p>
-The GTK+ home page (<htmlurl url="http://www.gtk.org/" 
+The GTK+ home page (<htmlurl url="http://www.gtk.org/"
 name="http://www.gtk.org/">) presents a list of GTK+ bindings.
 
 <itemize>
@@ -638,19 +651,21 @@ GTK+. I suggest you start at
 <!-- ***************************************************************** -->
 <sect>Development with GTK+: the begining
 <!-- ***************************************************************** -->
+
+
 <!-- ----------------------------------------------------------------- -->
 <sect1>How do I get started?
 <p>
 So, after you have installed GTK+ there are a couple of things that can
 ease you into developing applications with it. There is the
 GTK+ Tutorial <htmlurl url="http://www.gtk.org/tutorial/" 
-name="&lt;http://www.gtk.org/tutorial/&gt;">, which is undergoing 
+name="http://www.gtk.org/tutorial/">, which is undergoing 
 development. This will introduce you to writing applications using C.
 
 The Tutorial doesn't (yet) contain information on all of the widgets
 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
-source files) within the GTK+ distribution. Looking at these exmaples will
+source files) within the GTK+ distribution. Looking at these examples will
 give you a good grounding on what the widgets can do.
 
 <!-- ----------------------------------------------------------------- -->
@@ -681,6 +696,7 @@ The command line above ensure that:
 
 </itemize>
 
+<!-- ----------------------------------------------------------------- -->
 <sect1>What about using the <tt/make/ utility?
 <p>
 This is a sample makefile which compile a GTK+ based program:
@@ -729,7 +745,7 @@ are:
 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
+In order to use the powerful autoconf/automake scheme, you must create
 a configure.in which may look like:
 
 <tscreen><verb>
@@ -737,7 +753,7 @@ dnl Process this file with autoconf to produce a configure script.
 dnl configure.in for a GTK+ based program
 
 AC_INIT(myprg.c)dnl
-AM_INIT_AUTOMAKE(mypkbname,0.0.1)dnl
+AM_INIT_AUTOMAKE(mypkgname,0.0.1)dnl
 AM_CONFIG_HEADER(config.h)dnl
 
 dnl Checks for programs.
@@ -763,6 +779,14 @@ CLEANFILES      = *~
 DISTCLEANFILES  = .deps/*.P
 </verb></tscreen>
 
+If your project contains more than one subdirectory, you'll have to
+create one Makefile.am in each directory plus a master Makefile.am
+which will look like:
+
+<tscreen><verb>
+SUBDIRS         = mydir1 mydir2 mydir3
+</verb></tscreen>
+
 then, to use these, simply type the following commands:
 
 <verb>
@@ -772,9 +796,10 @@ autoconf
 automake --add-missing --include-deps --foreign 
 </verb>
 
-For further informations, you should look at the autoconf and the automake
-documentation (the shipped info files are really easy to understand, and there
-are plenty of web resources that deal with autoconf and/or automake).
+For further information, you should look at the autoconf and the
+automake documentation (the shipped info files are really easy to
+understand, and there are plenty of web resources that deal with
+autoconf and automake).
 
 <!-- ----------------------------------------------------------------- -->
 <sect1>I try to debug my GTK+ application with gdb, but it hangs my X server when I hit some breakpoint. Any Idea ?
@@ -801,6 +826,7 @@ bit hard to get (here in The Netherlands, YMMV).
 <!-- ***************************************************************** -->
 <sect>Development with GTK+: general questions
 <!-- ***************************************************************** -->
+
 <!-- ----------------------------------------------------------------- -->
 <sect1>What widgets are in GTK?
 <p>
@@ -938,8 +964,150 @@ 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.
 
-<!-- This is the old answer - TRG
+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>
+
+<!-- This is the old answer - TRG
 
 Although GTK+, like many X toolkits, isn't thread safe, this does
 not prohibit the development of multi-threaded applications with
@@ -988,49 +1156,195 @@ and it also might make GTK+ substantially less efficient if not handled
 carefully.
 
 Regardless, it's especially not a priority since relatively good
-workarounds exist. -->
+workarounds exist. 
+-->
+
 <!-- ----------------------------------------------------------------- -->
-<sect1>Why do this strange 'x io error' occur when I <tt/fork()/ in my GTK+ app?
+<sect1>Why does this strange 'x io error' occur when I <tt/fork()/ in my GTK+ app?
 <p>
-This is not really a GTK+ problem, and the problem is not related to <tt/fork()/
-too. If the 'x io error' occurs then you probably use the <tt/exit()/ function
-in order to exit from the child process.
+This is not really a GTK+ problem, and the problem is not related to
+<tt/fork()/ either. If the 'x io error' occurs then you probably use
+the <tt/exit()/ function in order to exit from the child process.
 
-When GDK opens an X display, it creates a socket file descriptor. When you use
-the <tt/exit()/ function, you implicitly close all the open file descriptors,
-and the underlying X library really doesn't like this.
+When GDK opens an X display, it creates a socket file descriptor. When
+you use the <tt/exit()/ function, you implicitly close all the open
+file descriptors, and the underlying X library really doesn't like
+this.
 
 The right function to use here is <tt/_exit()/. 
 
-Erik Mouw gave the following piece of code about the fork()/exit() problem
-(slightly modified)
+Erik Mouw contributed the following code example to illustrate
+handling fork() and exit().
 
 <tscreen><verb>
-  int pid = fork();
+/*-------------------------------------------------------------------------
+ * 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;
 
-  if(pid==-1)
+  /* 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);
+}
+
+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)
+    {
+      /* ouch, fork() failed */
       perror("fork");
       exit(-1);
     }
-  else if(pid==0) /* child */
+  else if(pid == 0)
     {
-      retval=system("a command"); /* can use exec* functions here */
-      _exit(retval);  /* notice _exit() instead of exit() */
+      /* 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);
     }
-  else /* parent */
+  else
     {
-      for(;;)
-        {
-          if(waitpid(pid, &amp;status, WNOHANG) == pid)
-            {
-              waitpid(pid, &amp;status, WUNTRACED); /* anti zombie code */
-              break;
-            }
-        }
-
-      return(WEXITSTATUS(status));
+      /* parent */
+      fprintf(stderr, "Parent: forked a child with pid = %d\n", (int)pid);
     }
+}
+
+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);         
+}
 </verb></tscreen>
 
 <!-- ----------------------------------------------------------------- -->
@@ -1072,11 +1386,11 @@ the user to get the closest ancestor of a known type) is to use
       widget = gtk_widget_get_ancestor(w, GTK_TYPE_WINDOW);
 </verb></tscreen>
 
-Since virtually all the GTK_TYPEs can be used as the second parameter of
-this function, you can get any parent widget of a particular
-widget. Suppose you have an hbox which contains a vbox, which in turn contains
-some other atomic widget (entry, label, etc. To find the master hbox
-using the <tt/entry/ widget simply use:
+Since virtually all the GTK_TYPEs can be used as the second parameter
+of this function, you can get any parent widget of a particular
+widget. Suppose you have an hbox which contains a vbox, which in turn
+contains some other atomic widget (entry, label, etc. To find the
+master hbox using the <tt/entry/ widget simply use:
 
 <tscreen><verb>
       GtkWidget       *hbox;
@@ -1084,7 +1398,18 @@ using the <tt/entry/ widget simply use:
 </verb></tscreen>
 
 <!-- ----------------------------------------------------------------- -->
+<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>
+
+Window xwin = GDK_WINDOW_XWINDOW (GTK_WIDGET (my_window)->window);
+</verb>
 
+<!-- ----------------------------------------------------------------- -->
 <sect1>How do I catch a double click event (in a list widget, for example)?
 <p>
 Tim Janik wrote to gtk-list (slightly modified):
@@ -1140,40 +1465,56 @@ mind.)
 <!-- ----------------------------------------------------------------- -->
 <sect1>By the way, what are the differences between signals and events?
 <p>
-First of all, Havoc Pennington gives a rather complete description of the
-differences between events and signals in his free book (two chapters can
-be found at <htmlurl url="http://www106.pair.com/rhp/sample_chapters.html"
+First of all, Havoc Pennington gives a rather complete description of
+the differences between events and signals in his free book (two
+chapters can be found at <htmlurl
+url="http://www106.pair.com/rhp/sample_chapters.html"
 name="http://www106.pair.com/rhp/sample_chapters.html">).
 
 Moreover, Havoc posted this to the <tt/gtk-list/
 <quote>
-  Events are a stream of messages received from the X server. They drive the
-  Gtk main loop; which more or less amounts to "wait for events, process
-  them" (not exactly, it is really more general than that and can wait on
-  many different input streams at once). Events are a Gdk/Xlib concept.
+  Events are a stream of messages received from the X server. They
+  drive the Gtk main loop; which more or less amounts to "wait for
+  events, process them" (not exactly, it is really more general than
+  that and can wait on many different input streams at once). Events
+  are a Gdk/Xlib concept.
 <P>
-  Signals are a feature of GtkObject and its subclasses. They have nothing
-  to do with any input stream; really a signal is just a way to keep a list
-  of callbacks around and invoke them ("emit" the signal). There are lots of
-  details and extra features of course. Signals are emitted by object
-  instances, and are entirely unrelated to the Gtk main loop.
-  Conventionally, signals are emitted "when something changes" about the
-  object emitting the signal.
+  Signals are a feature of GtkObject and its subclasses. They have
+  nothing to do with any input stream; really a signal is just a way
+  to keep a list of callbacks around and invoke them ("emit" the
+  signal). There are lots of details and extra features of
+  course. Signals are emitted by object instances, and are entirely
+  unrelated to the Gtk main loop.  Conventionally, signals are emitted
+  "when something changes" about the object emitting the signal.
 <P>
-  Signals and events only come together because GtkWidget happens to emit
-  signals when it gets events. This is purely a convenience, so you can
-  connect callbacks to be invoked when a particular widget receives a
-  particular event. There is nothing about this that makes signals and
-  events inherently related concepts, any more than emitting a signal when
-  you click a button makes button clicking and signals related concepts.
+  Signals and events only come together because GtkWidget happens to
+  emit signals when it gets events. This is purely a convenience, so
+  you can connect callbacks to be invoked when a particular widget
+  receives a particular event. There is nothing about this that makes
+  signals and events inherently related concepts, any more than
+  emitting a signal when you click a button makes button clicking and
+  signals related concepts.
 </quote>
 
+<!-- ----------------------------------------------------------------- -->
+<sect1>Data I pass to the <tt/delete_event/ (or other event) handler gets corrupted.
+<p>
+All event handlers take an additional argument which contains
+information about the event that triggered the handler. So, a
+<tt/delete_event/ handler must be declared as:
+
+<tscreen><verb>
+gint delete_event_handler (GtkWidget   *widget,
+                           GdkEventAny *event,
+                           gpointer     data);
+</verb></tscreen>
+
 <!-- ----------------------------------------------------------------- -->
 <sect1>I have my signal connected to the the (whatever) event, but it seems I don't catch it. What's wrong?
 <p>
-There is some special initialisation to do in order to catch some 
-particular events. In fact, you must set the correct event mask bit of your
-widget before getting some particular events.
+There is some special initialisation to do in order to catch some
+particular events. In fact, you must set the correct event mask bit of
+your widget before getting some particular events.
 
 For example, 
 
@@ -1186,6 +1527,47 @@ simply us the GDK_ALL_EVENTS_MASK event mask.
 
 All the event masks are defined in the <tt/gdktypes.h/ file.
 
+<!-- ----------------------------------------------------------------- -->
+<sect1>I need to add a new signal to a GTK+ widget. Any idea?
+<p>
+If the signal you want to add may be beneficial for other GTK+ users,
+you may want to submit a patch that presents your changes. Check the
+tutorial for more information about adding signals to a widget class.
+
+If you don't think it is the case or if your patch is not applied
+you'll have to use the <tt/gtk_object_class_user_signal_new/
+function. <tt/gtk_object_class_user_signal_new/ allows you to add a
+new signal to a predefined GTK+ widget without any modification of the
+GTK+ source code. The new signal can be emited with
+<tt/gtk_signal_emit/ and can be handled in the same way as other
+signals.
+
+Tim Janik posted this code snippet:
+
+<tscreen><verb>
+static guint signal_user_action = 0;
+
+signal_user_action =
+  gtk_object_class_user_signal_new (gtk_type_class (GTK_TYPE_WIDGET),
+                    "user_action",
+                    GTK_RUN_LAST | GTK_RUN_ACTION,
+                    gtk_marshal_NONE__POINTER,
+                    GTK_TYPE_NONE, 1,
+                    GTK_TYPE_POINTER);
+
+void
+gtk_widget_user_action (GtkWidget *widget,
+                        gpointer   act_data)
+{
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+
+  gtk_signal_emit (GTK_OBJECT (widget), signal_user_action, act_data);
+}
+</verb></tscreen>
+
+If you want your new signal to have more than the classical gpointer
+parameter, you'll have to play with GTK+ marshallers.
+
 <!-- ----------------------------------------------------------------- -->
 <sect1>Is it possible to get some text displayed which is truncated to fit inside its allocation? 
 <p>
@@ -1199,7 +1581,7 @@ performance penalty.
 Its possible that, in the long term, the best solution to such
 problems might be just to change gtk to give labels X windows.
 A short term workaround is to put the label widget inside another
-widget that does get it's own window - one possible candidate would
+widget that does get its own window - one possible candidate would
 be the viewport widget.
 
 <tscreen><verb>
@@ -1228,15 +1610,14 @@ closing the window do <tt/gtk_grab_remove(my_window)/.
 <sect1>Why doesn't my widget (e.g. progressbar) update?
 <p>
 
-You are probably doing all the changes within a function 
-without returning control to <tt/gtk_main()/. This may be the case if you do some 
-lengthy calculation in your code. Most drawing updates are only 
+You are probably doing all the changes within a function without
+returning control to <tt/gtk_main()/. This may be the case if you do
+some lengthy calculation in your code. Most drawing updates are only
 placed on a queue, which is processed within <tt/gtk_main()/. You can
 force the drawing queue to be processed using something like:
 
 <tscreen><verb>
-while (gtk_events_pending())
-        gtk_main_iteration();
+while (gtk_main_iteration(FALSE));
 </verb></tscreen>
 
 inside you're function that changes the widget.
@@ -1248,18 +1629,19 @@ high priority idle function).
 <!-- ----------------------------------------------------------------- -->
 <sect1>How do I attach data to some GTK+ object/widget?
 <p>
-First of all, the attached data is stored in the object_data field of a 
-GtkObject. The type of this field is GData, which is defined in glib.h. 
-So you should read the gdataset.c file in your glib source directory very 
-carefully.
+First of all, the attached data is stored in the object_data field of
+a GtkObject. The type of this field is GData, which is defined in
+glib.h.  So you should read the gdataset.c file in your glib source
+directory very carefully.
 
-There are two (easy) ways to attach some data to a gtk object. 
-Using <tt/gtk_object_set_data()/ and <tt/gtk_object_get_data()/ seems to be the 
-most common way to do this, as it provides a powerfull interface 
-to connect objects and data.
+There are two (easy) ways to attach some data to a gtk object.  Using
+<tt/gtk_object_set_data()/ and <tt/gtk_object_get_data()/ seems to be
+the most common way to do this, as it provides a powerful interface to
+connect objects and data.
 
 <tscreen><verb>
 void gtk_object_set_data(GtkObject *object, const gchar *key, gpointer data);
+
 gpointer gtk_object_get_data(GtkObject *object, const gchar *key);
 </verb></tscreen>
 
@@ -1285,12 +1667,11 @@ with some old gtk packages.
 <!-- ----------------------------------------------------------------- -->
 <sect1>How do I remove the data I have attached to an object?
 <p>
-When attaching the data to the object, you can use the 
-<tt/gtk_object_set_data_full()/
-function. The three first arguments of the function are the same as in
-<tt/gtk_object_set_data()/. The fourth one is a pointer to a callback function
-which is called when the data is destroyed. The data is destroyed when
-you:
+When attaching the data to the object, you can use the
+<tt/gtk_object_set_data_full()/ function. The three first arguments of
+the function are the same as in <tt/gtk_object_set_data()/. The fourth
+one is a pointer to a callback function which is called when the data
+is destroyed. The data is destroyed when you:
 
 <itemize>
 <item> destroy the object
@@ -1298,51 +1679,92 @@ you:
 <item> replace the data with NULL (with the same key)
 </itemize>
 
+<!-- ----------------------------------------------------------------- -->
+<sect1>How do I reparent a widget?
+<p>
+The normal way to reparent (ie change the owner) of a widget should be
+to use the function:
+
+<tscreen><verb>
+void gtk_widget_reparent (GtkWidget *widget, 
+                          GtkWidget *new_parent)
+</verb></tscreen>
+
+But this is only a "should be" since this function does not correctly
+do its job on some specific widgets. The main goal of
+gtk_widget_reparent() is to avoid unrealizing widget if both widget
+and new_parent are realized (in this case, widget->window is
+successfully reparented). The problem here is that some widgets in the
+GTK+ hierarchy have multiple attached X subwindows and this is notably
+the case for the GtkSpinButton widget. For those,
+gtk_widget_reparent() will fail by leaving an unrealized child window
+where it should not.
+
+To avoid this problem, simply use the following code snippet: 
+
+<tscreen><verb>
+     gtk_widget_ref(widget);
+     gtk_container_remove(GTK_CONTAINER(old_parent), widget);
+     gtk_container_add(GTK_CONTAINER(new_parent), widget);
+     gtk_widget_unref(widget);
+</verb></tscreen>
+
 <!-- ----------------------------------------------------------------- -->
 <sect1>How could I get any widgets position?
 <p>
-As Tim Janik pointed out, there are different cases, and each case requires
-a different solution.
+As Tim Janik pointed out, there are different cases, and each case
+requires a different solution.
 
 <itemize>
-<item>  If you want the position of a widget relative to its parent, you should
-        use <tt/widget->allocation.x/ and <tt/widget->allocation.y/.
-<item>  If you want the position of a window relative to the X root window,
-        you should use <tt/gdk_window_get_geometry()/ or 
+<item> If you want the position of a widget relative to its parent,
+        you should use <tt/widget->allocation.x/ and
+        <tt/widget->allocation.y/.
+<item> If you want the position of a window relative to the X root
+        window, you should use <tt/gdk_window_get_geometry()/
+        <tt/gdk_window_get_position()/ or
         <tt/gdk_window_get_origin()/.
-<item>  Last but not least, if you want to get a Window Manager frame position,
-        you should use <tt/gdk_window_get_deskrelative_origin()/.
+<item> If you want to get the position of the window (including the WM
+        decorations), you should use
+        <tt/gdk_window_get_root_origin()/.
+<item> Last but not least, if you want to get a Window Manager frame
+        position, you should use
+        <tt/gdk_window_get_deskrelative_origin()/.
 </itemize>
 
+Your choice of Window Manager will have an effect of the results of
+the above functions. You should keep this in mind when writing your
+application. This is dependant upon how the Window Managers manage the
+decorations that they add around windows.
+
 <!-- ----------------------------------------------------------------- -->
 <sect1>How do I set the size of a widget/window? How do I prevent the user resizing my window?
 <p>
 The <tt/gtk_widget_set_uposition()/ function is used to set the
 position of any widget.
 
-The <tt/gtk_widget_set_usize()/ function is used to set the
-size of a widget. In order to use all the features that are provided by
-this function when it acts on a window, you may want to use the
+The <tt/gtk_widget_set_usize()/ function is used to set the size of a
+widget. In order to use all the features that are provided by this
+function when it acts on a window, you may want to use the
 <tt/gtk_window_set_policy/ function. The definition of these functions
-is:
+are:
 
 <tscreen><verb>
-void        gtk_widget_set_usize (GtkWidget *widget,
-                                  gint width,
-                                  gint height);
-
-void        gtk_window_set_policy (GtkWindow *window,
-                                   gint allow_shrink,
-                                   gint allow_grow,
-                                   gint auto_shrink);
+void gtk_widget_set_usize (GtkWidget *widget,
+                           gint width,
+                           gint height);
+
+void gtk_window_set_policy (GtkWindow *window,
+                            gint allow_shrink,
+                            gint allow_grow,
+                            gint auto_shrink);
 </verb></tscreen>
 
 <tt/Auto_shrink/ will automatically shrink the window when the
 requested size of the child widgets goes below the current size of the
-window. <tt/Allow_shrink/ will give the user the authorisation to
-make the window smaller that it should normally be. <tt/Allow_grow/
-will give the user will have the ability to make the window
-bigger. The default values for these parameters are:
+window. <tt/Allow_shrink/ will give the user the authorisation to make
+the window smaller that it should normally be. <tt/Allow_grow/ will
+give the user will have the ability to make the window bigger. The
+default values for these parameters are:
 
 <tscreen><verb>
 allow_shrink = FALSE
@@ -1350,6 +1772,25 @@ allow_grow   = TRUE
 auto_shrink  = FALSE
 </verb></tscreen>
 
+The <tt/gtk_widget_set_usize()/ functions is not the easiest way to
+set a window size since you cannot decrease this window size with
+another call to this function unless you call it twice, as in:
+
+<tscreen><verb>
+     gtk_widget_set_usize(your_widget, -1, -1);
+     gtk_widget_set_usize(your_widget, new_x_size, new_y_size);
+</verb></tscreen>
+
+Another way to set the size of and/or move a window is to use the
+<tt/gdk_window_move_resize()/ function which uses to work fine both to
+grow or to shrink the window:
+
+<tscreen><verb>
+     gdk_window_move_resize(window->window, 
+                            x_pos, y_pos, 
+                            x_size, y_size);
+</verb></tscreen>
+
 <!-- ----------------------------------------------------------------- -->
 <sect1>How do I add a popup menu to my GTK+ application?
 <p>
@@ -1377,18 +1818,18 @@ static gint button_press (GtkWidget *widget, GdkEvent *event)
 <!-- ----------------------------------------------------------------- -->
 <sect1>How do I disable or enable a widget, such as a button?
 <p>
-To disable (or to enable) a widget, use the <tt/gtk_widget_set_sensitive()/
-function. The first parameter is you widget pointer. The second parameter
-is a boolean value: when this value is TRUE, the widget is enabled.
+To disable (or to enable) a widget, use the
+<tt/gtk_widget_set_sensitive()/ function. The first parameter is you
+widget pointer. The second parameter is a boolean value: when this
+value is TRUE, the widget is enabled.
 
 <!-- ----------------------------------------------------------------- -->
-
 <sect1>Shouldn't the text argument in the gtk_clist_* functions be declared const?
 <p>
 For example:
 <verb>
-gint gtk_clist_prepend (GtkCList    *clist,
-                        gchar       *text[]);
+gint gtk_clist_prepend (GtkCList *clist,
+                        gchar    *text[]);
 </verb>
 
 Answer: No, while a type "gchar*" (pointer to char) can automatically
@@ -1397,10 +1838,60 @@ apply for "gchar *[]" (array of an unspecified number of pointers to
 char) into "const gchar *[]" (array of an unspecified number of
 pointers to const char).
 
-The type qualifier "const" may be subject to automatic casting, but
-in the array case, it is not the array itself that needs the (const)
+The type qualifier "const" may be subject to automatic casting, but in
+the array case, it is not the array itself that needs the (const)
 qualified cast, but its members, thus changing the whole type.
 
+<!-- ----------------------------------------------------------------- -->
+<sect1>How do I render pixels (image data) to the screen?
+<p>
+There are several ways to approach this. The simplest way is to use
+GdkRGB, see gdk/gdkrgb.h. You create an RGB buffer, render to your RGB
+buffer, then use GdkRGB routines to copy your RGB buffer to a drawing
+area or custom widget. The book "GTK+/Gnome Application Development"
+gives some details; GdkRGB is also documented in the GTK+ reference
+documentation.
+
+If you're writing a game or other graphics-intensive application, you
+might consider a more elaborate solution. OpenGL is the graphics
+standard that will let you access hardware accelaration in future
+versions of XFree86; so for maximum speed, you probably want to use
+OpenGL. A GtkGLArea widget is available for using OpenGL with GTK+
+(but GtkGLArea does not come with GTK+ itself). There are also several
+open source game libraries, such as ClanLib and Loki's Simple
+DirectMedia Layer library (SDL).
+
+You do NOT want to use <tt/gdk_draw_point()/, that will be extremely
+slow.
+
+<!-- ----------------------------------------------------------------- -->
+<sect1>How do I create a pixmap without having my window realized/shown?
+<p>
+Functions such as <tt/gdk_pixmap_create_from_xpm()/ require a valid
+window as a parameter. During the initialisation phase of an
+application, a valid window may not be available without showing a
+window, which may be inappropriate. In order to avoid this, a
+function such as <tt/gdk_pixmap_colormap_create_from_xpm/ can be used,
+as in:
+
+<tscreen><verb>
+  char *pixfile = "foo.xpm";
+  GtkWidget *top, *box, *pixw;
+  GdkPixmap *pixmap, *pixmap_mask;
+
+  top = gtk_window_new (GKT_WINDOW_TOPLEVEL);
+  box = gtk_hbox_new (FALSE, 4);
+  gtk_conainer_add (GTK_CONTAINER(top), box);
+  pixmap = gdk_pixmap_colormap_create_from_xpm (
+               NULL, gtk_widget_get_colormap(top),
+               &amp;pixmap_mask, NULL, pixfile);
+  pixw = gtk_pixmap_new (pixmap, pixmap_mask);
+  gdk_pixmap_unref (pixmap);
+  gdk_pixmap_unref (pixmap_mask);
+
+</verb></tscreen>
+
 <!-- ***************************************************************** -->
 <sect>Development with GTK+: widget specific questions 
 <!-- ***************************************************************** -->
@@ -1439,22 +1930,23 @@ of GTK_LIST(AnyGtkList)->selection:
 selection_mode          GTK_LIST()->selection contents
 ------------------------------------------------------
 
-GTK_SELECTION_SINGLE)   selection is either NULL
+GTK_SELECTION_SINGLE    selection is either NULL
                         or contains a GList* pointer
                         for a single selected item.
 
-GTK_SELECTION_BROWSE)   selection is NULL if the list
+GTK_SELECTION_BROWSE    selection is NULL if the list
                         contains no widgets, otherwise
                         it contains a GList* pointer
                         for one GList structure.
-GTK_SELECTION_MULTIPLE) selection is NULL if no listitems
+
+GTK_SELECTION_MULTIPLE  selection is NULL if no listitems
                         are selected or a a GList* pointer
                         for the first selected item. that
                         in turn points to a GList structure
                         for the second selected item and so
-                        on
+                        on.
 
-GTK_SELECTION_EXTENDED) selection is NULL.
+GTK_SELECTION_EXTENDED  selection is NULL.
 </verb>
 
 The data field of the GList structure GTK_LIST(MyGtkList)->selection points
@@ -1507,6 +1999,25 @@ To get known about the selection:
 }
 </verb></tscreen>
 
+<!-- ----------------------------------------------------------------- -->
+<sect1>How do I stop the column headings of a GtkCList disappearing
+when the list is scrolled?
+<p>
+This happens when a GtkCList is packed into a GtkScrolledWindow using
+the function <tt/gtk_scroll_window_add_with_viewport()/. The prefered
+method of adding a CList to a scrolled window is to use the function
+<tt/gtk_container_add/, as in:
+
+<tscreen><verb>
+    GtkWidget *scrolled, *clist;
+    char *titles[] = { "Title1" , "Title2" };
+
+    scrolled = gtk_scrolled_window_new(NULL, NULL);
+
+    clist = gtk_clist_new_with_titles(2, titles);
+    gtk_container_add(GTK_CONTAINER(scrolled), clist);
+</verb></tscreen>
+
 <!-- ----------------------------------------------------------------- --><p>
 <sect1>I don't want the user of my applications to enter text into a GtkCombo. Any idea?
 <p>
@@ -1530,7 +2041,8 @@ Set the editable parameter to FALSE to disable typing into the entry.
 <!-- ----------------------------------------------------------------- -->
 <sect1>How do I catch a combo box change?
 <p>
-The entry which is associated to your GtkCombo send a "changed" signal when:
+The entry which is associated to your GtkCombo send a "changed" signal
+when:
 <itemize>
       <item>some text is typed in
       <item>the selection of the combo box is changed
@@ -1562,8 +2074,8 @@ gtk_widget_show(menuitem);
 <!-- ----------------------------------------------------------------- -->
 <sect1>How can I right justify a menu, such as Help? 
 <p>
-Depending on if you use the MenuFactory or not, there are two ways to proceed.
-With the MenuFactory, use something like the following:
+Depending on if you use the MenuFactory or not, there are two ways to
+proceed.  With the MenuFactory, use something like the following:
 
 <tscreen><verb>
 menu_path = gtk_menu_factory_find (factory,  "<MyApp>/Help");
@@ -1579,11 +2091,11 @@ gtk_menu_item_right_justify(my_menu_item);
 <!-- ----------------------------------------------------------------- -->
 <sect1>How do I add some underlined accelerators to menu items?
 <p>
-Damon Chaplin, the technical force behind the Glade project, provided the
-following code sample (this code is an output from Glade). It creates a
-small <tt/File/ menu item with only one child (<tt/New/). The F in <tt/File/ 
-and the N in <tt/New/ are underlined, and the relevant accelerators are 
-created.
+Damon Chaplin, the technical force behind the Glade project, provided
+the following code sample (this code is an output from Glade). It
+creates a small <tt/File/ menu item with only one child
+(<tt/New/). The F in <tt/File/ and the N in <tt/New/ are underlined,
+and the relevant accelerators are created.
 
 <tscreen><verb>
   menubar1 = gtk_menu_bar_new ();
@@ -1615,21 +2127,65 @@ created.
   gtk_container_add (GTK_CONTAINER (file1_menu), new1);
 </verb></tscreen>
 
+<!-- ----------------------------------------------------------------- -->
+<sect1>How can I retrieve the text from a GtkMenuItem?
+<p>
+You can usually retrieve the label of a specific GtkMenuItem with:
+
+<tscreen><verb>
+    if (GTK_BIN (menu_item)->child)
+    {
+      GtkWidget *child = GTK_BIN (menu_item)->child;
+  
+      /* do stuff with child */
+      if (GTK_IS_LABEL (child))
+      {
+        gchar *text;
+    
+        gtk_label_get (GTK_LABEL (child), &amp;text);
+        g_print ("menu item text: %s\n", text);
+      }
+    }
+</verb></tscreen>
+
+To get the active menu item from a GtkOptionMenu you can do:
+<tscreen><verb>
+if (GTK_OPTION_MENU (option_menu)->menu_item)
+{
+  GtkWidget *menu_item = GTK_OPTION_MENU (option_menu)->menu_item;
+}
+</verb></tscreen>
+
+But, there's a catch. For this specific case, you can <bf>not</bf> get
+the label widget from <tt/menu_item/ with the above code, because the
+option menu reparents the menu_item's child temporarily to display the
+currently active contents. So to retrive the child of the currently
+active menu_item of an option menu, you'll have to do:
+
+<tscreen><verb>
+    if (GTK_BIN (option_menu)->child)
+    {
+      GtkWidget *child = GTK_BIN (option_menu)->child;
+
+      /* do stuff with child */
+    }
+</verb></tscreen>
+
 <!-- ----------------------------------------------------------------- -->
 <sect1>How do I right (or otherwise) justify a GtkLabel?
 <p>
-Are you sure you want to <em>justify</em> the labels?  The label class contains 
-the <tt/gtk_label_set_justify()/ function that is used to control the 
-justification of a multi-line label.
+Are you sure you want to <em>justify</em> the labels?  The label class
+contains the <tt/gtk_label_set_justify()/ function that is used to
+control the justification of a multi-line label.
 
-What you probably want is to set the <em>alignment</em> of the label, ie right 
-align it, center it or left align it. If you want to do this, you 
-should use:
+What you probably want is to set the <em>alignment</em> of the label,
+ie right align it, center it or left align it. If you want to do this,
+you should use:
 
 <tscreen><verb>
-void gtk_misc_set_alignment     (GtkMisc *misc,
-                                gfloat xalign,
-                                gfloat yalign);
+void gtk_misc_set_alignment (GtkMisc *misc,
+                             gfloat xalign,
+                             gfloat yalign);
 </verb></tscreen>
 
 where the <tt/xalign/ and <tt/yalign/ values are floats in [0.00;1.00].
@@ -1647,6 +2203,17 @@ gtk_misc_set_alignment(GTK_MISK(label), 0.5f, 0.5f);
 gtk_misc_set_alignment(GTK_MISK(label), 1.0f, 1.0f);
 </verb></tscreen>
 
+<!-- ----------------------------------------------------------------- -->
+<sect1>How do I set the background color of a GtkLabel widget?
+<p>
+The Gtklabel widget is one of a few GTK+ widgets that don't create
+their own window to render themselves into. Instead, they draw
+themselves directly onto their parents window.
+
+This means that in order to set the background color for a GtkLabel
+widget, you need to change the background color of its parent,
+i.e. the object that you pack it into.
+
 <!-- ----------------------------------------------------------------- -->
 <sect1>How do I set the color and font of a GtkLabel using a Resource File?
 <p>
@@ -1684,9 +2251,9 @@ widget, which can be done using:
 <!-- ----------------------------------------------------------------- -->
 <sect1>How do I configure Tooltips in a Resource File?
 <p>
-The tooltip's window is named "gtk-tooltips", GtkTooltips in itself is not
-a GtkWidget (though a GtkObject) and as such is not attempted to match any
-widget styles.
+The tooltip's window is named "gtk-tooltips", GtkTooltips in itself is
+not a GtkWidget (though a GtkObject) and as such is not attempted to
+match any widget styles.
 
 So, you resource file should look something like:
 <verb> 
@@ -1696,12 +2263,6 @@ style "postie"
 }
 widget "gtk-tooltips*" style "postie"
 </verb>
-<sect1>How do I use horizontal scrollbars with a GtkText widget?
-<p>
-The short answer is that you can't. The current version of the GtkText
-widget does not support horizontal scrolling. There is an intention to
-completely rewrite the GtkText widget, at which time this limitation
-will be removed.
 
 <!-- ----------------------------------------------------------------- -->
 <sect1>I can't add more than (something like) 2000 chars in a GtkEntry. What's wrong?
@@ -1722,6 +2283,100 @@ the number of chars in the entry to 2047.
     max_length = MIN (2047, entry->text_max_length);
 </verb></tscreen>
 
+<!-- ----------------------------------------------------------------- -->
+<sect1>How do I make a GtkEntry widget activate on pressing the Return key?
+<p>
+The Entry widget emits an 'activate' signal when you press return in
+it. Just attach to the activate signal on the entry and do whatever you
+want to do. Typical code would be:
+
+<tscreen><verb>
+  entry = gtk_entry_new();
+  gtk_signal_connect (GTK_OBJECT(entry), "activate",
+                      GTK_SIGNAL_FUNC(entry_callback),
+                      NULL);
+</verb></tscreen>
+
+<!-- ----------------------------------------------------------------- -->
+<sect1>How do I validate/limit/filter the input to a GtkEntry?
+<p>
+If you want to validate the text that a user enters into a GtkEntry
+widget you can attach to the "insert_text" signal of the entry, and
+modify the text within the callback function. The example below forces
+all characters to uppercase, and limits the range of characters to
+A-Z. Note that the entry is cast to an object of type GtkEditable,
+from which GtkEntry is derived.
+
+<tscreen><verb>
+#include <ctype.h>
+#include <gtk/gtk.h>
+
+void insert_text_handler (GtkEntry    *entry,
+                          const gchar *text,
+                          gint         length,
+                          gint        *position,
+                          gpointer     data)
+{
+  GtkEditable *editable = GTK_EDITABLE(entry);
+  int i, count=0;
+  gchar *result = g_new (gchar, length);
+
+  for (i=0; i < length; i++) {
+    if (!isalpha(text[i]))
+      continue;
+    result[count++] = islower(text[i]) ? toupper(text[i]) : text[i];
+  }
+  
+  if (count > 0) {
+    gtk_signal_handler_block_by_func (GTK_OBJECT (editable),
+                                     GTK_SIGNAL_FUNC (insert_text_handler),
+                                     data);
+    gtk_editable_insert_text (editable, result, count, position);
+    gtk_signal_handler_unblock_by_func (GTK_OBJECT (editable),
+                                       GTK_SIGNAL_FUNC (insert_text_handler),
+                                       data);
+  }
+  gtk_signal_emit_stop_by_name (GTK_OBJECT (editable), "insert_text");
+  
+  g_free (result);
+}
+
+int main (int   argc,
+          char *argv[])
+{
+  GtkWidget *window;
+  GtkWidget *entry;
+  
+  gtk_init (&amp;argc, &amp;argv);
+  
+  /* create a new window */
+  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_title(GTK_WINDOW (window), "GTK Entry");
+  gtk_signal_connect(GTK_OBJECT (window), "delete_event",
+                    (GtkSignalFunc) gtk_exit, NULL);
+  
+  entry = gtk_entry_new();
+  gtk_signal_connect(GTK_OBJECT(entry), "insert_text",
+                    GTK_SIGNAL_FUNC(insert_text_handler),
+                    NULL);
+  gtk_container_add(GTK_CONTAINER (window), entry);
+  gtk_widget_show(entry);
+  
+  gtk_widget_show(window);
+  
+  gtk_main();
+  return(0);
+}
+</verb></tscreen>
+
+<!-- ----------------------------------------------------------------- -->
+<sect1>How do I use horizontal scrollbars with a GtkText widget?
+<p>
+The short answer is that you can't. The current version of the GtkText
+widget does not support horizontal scrolling. There is an intention to
+completely rewrite the GtkText widget, at which time this limitation
+will be removed.
+
 <!-- ----------------------------------------------------------------- -->
 <sect1>How do I change the font of a GtkText widget?
 <p>
@@ -1752,22 +2407,23 @@ load a font using, for example:
 Notice that the response is valid for any object that inherits from the 
 GtkEditable class.
 
-Are you sure that you want to move the cursor position? Most of the time,
-while the cursor position is good, the insertion point does not match the
-cursor position. If this apply to what you really want, then you should use
-the <tt/gtk_text_set_point()/ function. If you want to set the insertion point
-at the current cursor position, use the following:
+Are you sure that you want to move the cursor position? Most of the
+time, while the cursor position is good, the insertion point does not
+match the cursor position. If this apply to what you really want, then
+you should use the <tt/gtk_text_set_point()/ function. If you want to
+set the insertion point at the current cursor position, use the
+following:
 
 <tscreen><verb>
   gtk_text_set_point(GTK_TEXT(text),
-      gtk_editable_get_position(GTK_EDITABLE(text)));
+  gtk_editable_get_position(GTK_EDITABLE(text)));
 </verb></tscreen>
 
 If you want the insertion point to follow the cursor at all time, you
 should probably catch the button press event, and then move the
-insertion point. Be careful : you'll have to catch it after the widget 
-has changed the cursor position though. Thomas Mailund Jensen proposed the
-following code:
+insertion point. Be careful : you'll have to catch it after the widget
+has changed the cursor position though. Thomas Mailund Jensen proposed
+the following code:
 
 <tscreen><verb>
 static void
@@ -1775,7 +2431,7 @@ insert_bar (GtkWidget *text)
 {
   /* jump to cursor mark */
   gtk_text_set_point (GTK_TEXT (text),
-      gtk_editable_get_position (GTK_EDITABLE  (text)));
+  gtk_editable_get_position (GTK_EDITABLE  (text)));
 
   gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL,
      "bar", strlen ("bar"));
@@ -1814,12 +2470,12 @@ Now, if you really want to change the cursor position, you should use the
 <!-- ----------------------------------------------------------------- -->
 <sect1>What is GDK?
 <p>
-GDK is basically a wrapper around the standard Xlib function calls. If you are
-at all familiar with Xlib, a lot of the functions in GDK will require little 
-or no getting used to. All functions are written to provide an way 
-to access Xlib functions in an easier and slightly more intuitive manner. 
-In addition, since GDK uses GLib (see below), it will be more portable 
-and safer to use on multiple platforms.
+GDK is basically a wrapper around the standard Xlib function calls. If
+you are at all familiar with Xlib, a lot of the functions in GDK will
+require little or no getting used to. All functions are written to
+provide an way to access Xlib functions in an easier and slightly more
+intuitive manner.  In addition, since GDK uses GLib (see below), it
+will be more portable and safer to use on multiple platforms.
 
 <!-- Examples, anybody? I've been mulling some over. NF -->
    
@@ -1954,24 +2610,76 @@ reference on the first node of the list.
 <!-- I believe it should be better :) ED -->
 <!-- Linked lists are pretty standard data structures - don't want to
      over do it - TRG -->
+
+<!-- ----------------------------------------------------------------- -->
+<sect1>Memory does not seem to be released when I free the list nodes I've allocated
+<p>
+GLib tries to be "intelligent" on this special issue: it assumes that
+you are likely to reuse the objects, so caches the allocated memory.
+If you do not want to use this behavior, you'll probably want to set
+up a special allocator.
+
+To quote Tim Janik:
+<quote>
+If you have a certain portion of code that uses *lots* of GLists or
+GNodes, and you know you'd better want to release all of them after a
+short while, you'd want to use a GAllocator. Pushing an allocator into
+g_list will make all subsequent glist operations private to that
+allocator's memory pool (and thus you have to take care to pop the
+allocator again, before making any external calls):
+</quote>
+
+<tscreen><verb>
+GAllocator *allocator;
+GList *list = NULL;
+guint i;
+
+/* set a new allocation pool for GList nodes */
+allocator = g_allocator_new ("list heap", 1024);
+g_list_push_allocator (allocator);
+
+/* do some list operations */
+for (i = 0; i < 4096; i++)
+  list = g_list_prepend (list, NULL);
+list = g_list_reverse (list);
+
+/* beware to pop allocator befor calling external functions */
+g_list_pop_allocator ();
+gtk_label_set_text (GTK_LABEL (some_label), "some text");
+
+/* and set our private glist pool again */
+g_list_push_allocator (allocator);
+
+/* do some list operations */
+g_list_free (list);
+list = NULL;
+for (i = 0; i < 4096; i++)
+  list = g_list_prepend (list, NULL);
+  
+/* and back out (while freeing all of the list nodes in our pool) */
+g_list_pop_allocator ();
+g_allocator_free (allocator);
+</verb></tscreen>
+
 <!-- ----------------------------------------------------------------- -->
 <sect1>Why use g_print, g_malloc, g_strdup and fellow glib functions?  
 <p>
 Thanks to Tim Janik who wrote to gtk-list: (slightly modified)
 <quote>
-Regarding g_malloc(), g_free() and siblings, these functions are much safer
-than their libc equivalents. For example, g_free() just returns if called 
-with NULL. Also, if USE_DMALLOC is defined, the definition for these 
-functions changes (in glib.h) to use MALLOC(), FREE() etc...  If MEM_PROFILE
-or MEM_CHECK are defined, there are even small statistics made counting
-the used block sizes (shown by g_mem_profile() / g_mem_check()).
-<P>
+Regarding g_malloc(), g_free() and siblings, these functions are much
+safer than their libc equivalents. For example, g_free() just returns
+if called with NULL. Also, if USE_DMALLOC is defined, the definition
+for these functions changes (in glib.h) to use MALLOC(), FREE() etc...
+If MEM_PROFILE or MEM_CHECK are defined, there are even small
+statistics made counting the used block sizes (shown by
+g_mem_profile() / g_mem_check()).
+<p>
 Considering the fact that glib provides an interface for memory chunks
 to save space if you have lots of blocks that are always the same size
 and to mark them ALLOC_ONLY if needed, it is just straight forward to
 create a small saver (debug able) wrapper around the normal malloc/free
 stuff as well - just like gdk covers Xlib. ;)
-<P>
+<p>
 Using g_error() and g_warning() inside of applications like the GIMP
 that fully rely on gtk even gives the opportunity to pop up a window
 showing the messages inside of a gtk window with your own handler
@@ -2123,7 +2831,7 @@ main (int argc, char *argv[])
   /* give the error handler an idea on how the input is named */
   scanner->input_name = "test text";
 
-  /* scanning loop, we parse the input untill it's end is reached,
+  /* scanning loop, we parse the input until its end is reached,
    * the scanner encountered a lexing error, or our sub routine came
    * across invalid syntax
    */
@@ -2153,9 +2861,10 @@ main (int argc, char *argv[])
 }
 </verb>
 
-You need to understand that the scanner will parse it's input and
+You need to understand that the scanner will parse its input and
 tokenize it, it is up to you to interpret these tokens, not define
-their types before they get parsed, e.g. watch gscanner parse a string:
+their types before they get parsed, e.g. watch gscanner parse a
+string:
  
 <verb>
 "hi i am 17"
@@ -2223,45 +2932,51 @@ have not accepted "hi 7 am 17" or "hi i hi 17".
 <!-- ***************************************************************** -->
 <sect>GTK+ FAQ Contributions, Maintainers and Copyright
 <p>
-If you would like to make a contribution to the FAQ, send either one of us
-an e-mail message with the exact text you think should be included (question and
-answer).  With your help, this document can grow and become more useful!
+If you would like to make a contribution to the FAQ, send either one
+of us an e-mail message with the exact text you think should be
+included (question and answer). With your help, this document can grow
+and become more useful!
 
-This document is maintained by Nathan Froyd 
-<htmlurl url="mailto:maestrox@geocities.com" 
+This document is maintained by 
+Tony Gale <htmlurl url="mailto:gale@gtk.org" 
+name="&lt;gale@gtk.org&gt;"> 
+Nathan Froyd <htmlurl url="mailto:maestrox@geocities.com" 
 name="&lt;maestrox@geocities.com&gt;">,
-Tony Gale <htmlurl url="mailto:gale@gimp.org" 
-name="&lt;gale@gimp.org&gt;"> and 
+and 
 Emmanuel Deloget <htmlurl url="mailto:logout@free.fr"
 name="&lt;logout@free.fr&gt;">.
 This FAQ was created by Shawn T. Amundson 
 <htmlurl url="mailto:amundson@gimp.org" 
 name="&lt;amundson@gimp.org&gt;"> who continues to provide support.
 
-The GTK+ FAQ is Copyright (C) 1997,1998, 1999 by Shawn T. Amundson, 
-Nathan Froyd and Tony Gale, Emmanuel Deloget.
+Contributions should be sent to Tony Gale <htmlurl
+url="mailto:gale@gtk.org" name="&lt;gale@gtk.org&gt;">
+
+The GTK+ FAQ is Copyright (C) 1997-2000 by Shawn T. Amundson, 
+Tony Gale, Emmanuel Deloget and Nathan Froyd.
 
-Permission is granted to make and distribute verbatim copies of 
-this manual provided the copyright notice and this permission notice 
-are preserved on all copies.
+Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
 
-Permission is granted to copy and distribute modified versions of 
-this document under the conditions for verbatim copying, provided 
-that this copyright notice is included exactly as in the original, 
-and that the entire resulting derived work is distributed under 
-the terms of a permission notice identical to this one.
+Permission is granted to copy and distribute modified versions of this
+document under the conditions for verbatim copying, provided that this
+copyright notice is included exactly as in the original, and that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
 
-Permission is granted to copy and distribute translations of 
-this document into another language,  under the above conditions 
-for modified versions.
+Permission is granted to copy and distribute translations of this
+document into another language, under the above conditions for
+modified versions.
 
-If you are intending to incorporate this document into a published work, 
-please contact one of the maintainers, and we will make an effort to ensure 
-that you have the most up to date information available.
+If you are intending to incorporate this document into a published
+work, please contact one of the maintainers, and we will make an
+effort to ensure that you have the most up to date information
+available.
 
 There is no guarentee that this document lives up to its intended
-purpose.  This is simply provided as a free resource.  As such,
-the authors and maintainers of the information provided within can 
-not make any guarentee that the information is even accurate.
+purpose.  This is simply provided as a free resource.  As such, the
+authors and maintainers of the information provided within can not
+make any guarentee that the information is even accurate.
 
 </article>