]> Pileus Git - ~andy/gtk/commitdiff
Initial revision
authorElliot Lee <sopwith@src.gnome.org>
Mon, 24 Nov 1997 22:37:52 +0000 (22:37 +0000)
committerElliot Lee <sopwith@src.gnome.org>
Mon, 24 Nov 1997 22:37:52 +0000 (22:37 +0000)
322 files changed:
.cvsignore [new file with mode: 0644]
AUTHORS [new file with mode: 0644]
COPYING [new file with mode: 0644]
ChangeLog [new file with mode: 0644]
ChangeLog.pre-2-0 [new file with mode: 0644]
ChangeLog.pre-2-10 [new file with mode: 0644]
ChangeLog.pre-2-2 [new file with mode: 0644]
ChangeLog.pre-2-4 [new file with mode: 0644]
ChangeLog.pre-2-6 [new file with mode: 0644]
ChangeLog.pre-2-8 [new file with mode: 0644]
INSTALL [new file with mode: 0644]
Makefile.am [new file with mode: 0644]
NEWS [new file with mode: 0644]
README [new file with mode: 0644]
TODO [new file with mode: 0644]
acconfig.h [new file with mode: 0644]
aclocal.m4 [new file with mode: 0644]
config.guess [new file with mode: 0755]
config.h.in [new file with mode: 0644]
config.sub [new file with mode: 0755]
configure.in [new file with mode: 0644]
docs/.cvsignore [new file with mode: 0644]
docs/Makefile.am [new file with mode: 0644]
docs/gdk.texi [new file with mode: 0644]
docs/gtk.texi [new file with mode: 0644]
docs/macros.texi [new file with mode: 0644]
docs/texinfo.tex [new file with mode: 0644]
gdk/.cvsignore [new file with mode: 0644]
gdk/Makefile.am [new file with mode: 0644]
gdk/gdk.c [new file with mode: 0644]
gdk/gdk.h [new file with mode: 0644]
gdk/gdkcolor.c [new file with mode: 0644]
gdk/gdkcursor.c [new file with mode: 0644]
gdk/gdkdraw.c [new file with mode: 0644]
gdk/gdkfont.c [new file with mode: 0644]
gdk/gdkgc.c [new file with mode: 0644]
gdk/gdkglobals.c [new file with mode: 0644]
gdk/gdkimage.c [new file with mode: 0644]
gdk/gdkinput.c [new file with mode: 0644]
gdk/gdkinput.h [new file with mode: 0644]
gdk/gdkinputcommon.h [new file with mode: 0644]
gdk/gdkinputgxi.h [new file with mode: 0644]
gdk/gdkinputnone.h [new file with mode: 0644]
gdk/gdkinputxfree.h [new file with mode: 0644]
gdk/gdkpixmap.c [new file with mode: 0644]
gdk/gdkprivate.h [new file with mode: 0644]
gdk/gdkproperty.c [new file with mode: 0644]
gdk/gdkrectangle.c [new file with mode: 0644]
gdk/gdkselection.c [new file with mode: 0644]
gdk/gdktypes.h [new file with mode: 0644]
gdk/gdkvisual.c [new file with mode: 0644]
gdk/gdkwindow.c [new file with mode: 0644]
gdk/gdkx.h [new file with mode: 0644]
gdk/gdkxid.c [new file with mode: 0644]
gdk/gxid.c [new file with mode: 0644]
gdk/gxid_lib.c [new file with mode: 0644]
gdk/gxid_lib.h [new file with mode: 0644]
gdk/gxid_proto.h [new file with mode: 0644]
gdk/makecursors [new file with mode: 0755]
gdk/makecursors.sed [new file with mode: 0644]
gdk/makekeysyms [new file with mode: 0755]
gdk/makekeysyms.sed [new file with mode: 0644]
gdk/x11/gdkcolor-x11.c [new file with mode: 0644]
gdk/x11/gdkcursor-x11.c [new file with mode: 0644]
gdk/x11/gdkfont-x11.c [new file with mode: 0644]
gdk/x11/gdkglobals-x11.c [new file with mode: 0644]
gdk/x11/gdkimage-x11.c [new file with mode: 0644]
gdk/x11/gdkinput-gxi.c [new file with mode: 0644]
gdk/x11/gdkinput-none.c [new file with mode: 0644]
gdk/x11/gdkinput-x11.c [new file with mode: 0644]
gdk/x11/gdkinput-xfree.c [new file with mode: 0644]
gdk/x11/gdkinput.c [new file with mode: 0644]
gdk/x11/gdkmain-x11.c [new file with mode: 0644]
gdk/x11/gdkpixmap-x11.c [new file with mode: 0644]
gdk/x11/gdkproperty-x11.c [new file with mode: 0644]
gdk/x11/gdkselection-x11.c [new file with mode: 0644]
gdk/x11/gdkvisual-x11.c [new file with mode: 0644]
gdk/x11/gdkwindow-x11.c [new file with mode: 0644]
gdk/x11/gdkx.h [new file with mode: 0644]
gdk/x11/gdkxid.c [new file with mode: 0644]
gdk/x11/gxid.c [new file with mode: 0644]
gdk/x11/gxid_lib.c [new file with mode: 0644]
gdk/x11/gxid_lib.h [new file with mode: 0644]
gdk/x11/gxid_proto.h [new file with mode: 0644]
glib/.cvsignore [new file with mode: 0644]
glib/AUTHORS [new file with mode: 0644]
glib/COPYING [new file with mode: 0644]
glib/ChangeLog [new file with mode: 0644]
glib/INSTALL [new file with mode: 0644]
glib/Makefile.am [new file with mode: 0644]
glib/NEWS [new file with mode: 0644]
glib/README [new file with mode: 0644]
glib/acconfig.h [new file with mode: 0644]
glib/aclocal.m4 [new file with mode: 0644]
glib/config.guess [new file with mode: 0755]
glib/config.sub [new file with mode: 0755]
glib/configure [new file with mode: 0755]
glib/configure.in [new file with mode: 0644]
glib/garray.c [new file with mode: 0644]
glib/gcache.c [new file with mode: 0644]
glib/gerror.c [new file with mode: 0644]
glib/ghash.c [new file with mode: 0644]
glib/glib.h [new file with mode: 0644]
glib/glibconfig.h.in [new file with mode: 0644]
glib/glist.c [new file with mode: 0644]
glib/gmem.c [new file with mode: 0644]
glib/gprimes.c [new file with mode: 0644]
glib/gslist.c [new file with mode: 0644]
glib/gstring.c [new file with mode: 0644]
glib/gtimer.c [new file with mode: 0644]
glib/gtree.c [new file with mode: 0644]
glib/gutils.c [new file with mode: 0644]
glib/install-sh [new file with mode: 0755]
glib/ltconfig [new file with mode: 0755]
glib/ltmain.sh [new file with mode: 0644]
glib/missing [new file with mode: 0755]
glib/mkinstalldirs [new file with mode: 0755]
glib/stamp-h.in [new file with mode: 0644]
glib/testglib.c [new file with mode: 0644]
gtk+.prj [new file with mode: 0644]
gtk+.xconfig.in [new file with mode: 0644]
gtk/.cvsignore [new file with mode: 0644]
gtk/3DRings.xpm [new file with mode: 0644]
gtk/FilesQueue.xpm [new file with mode: 0644]
gtk/Makefile.am [new file with mode: 0644]
gtk/Modeller.xpm [new file with mode: 0644]
gtk/fnmatch.c [new file with mode: 0644]
gtk/fnmatch.h [new file with mode: 0644]
gtk/gentypeinfo.el [new file with mode: 0644]
gtk/gtk.defs [new file with mode: 0644]
gtk/gtk.h [new file with mode: 0644]
gtk/gtkaccelerator.c [new file with mode: 0644]
gtk/gtkaccelerator.h [new file with mode: 0644]
gtk/gtkadjustment.c [new file with mode: 0644]
gtk/gtkadjustment.h [new file with mode: 0644]
gtk/gtkalignment.c [new file with mode: 0644]
gtk/gtkalignment.h [new file with mode: 0644]
gtk/gtkarrow.c [new file with mode: 0644]
gtk/gtkarrow.h [new file with mode: 0644]
gtk/gtkaspectframe.c [new file with mode: 0644]
gtk/gtkaspectframe.h [new file with mode: 0644]
gtk/gtkbbox.c [new file with mode: 0644]
gtk/gtkbbox.h [new file with mode: 0644]
gtk/gtkbin.c [new file with mode: 0644]
gtk/gtkbin.h [new file with mode: 0644]
gtk/gtkbox.c [new file with mode: 0644]
gtk/gtkbox.h [new file with mode: 0644]
gtk/gtkbutton.c [new file with mode: 0644]
gtk/gtkbutton.h [new file with mode: 0644]
gtk/gtkcheckbutton.c [new file with mode: 0644]
gtk/gtkcheckbutton.h [new file with mode: 0644]
gtk/gtkcheckmenuitem.c [new file with mode: 0644]
gtk/gtkcheckmenuitem.h [new file with mode: 0644]
gtk/gtkcolorsel.c [new file with mode: 0644]
gtk/gtkcolorsel.h [new file with mode: 0644]
gtk/gtkcontainer.c [new file with mode: 0644]
gtk/gtkcontainer.h [new file with mode: 0644]
gtk/gtkcurve.c [new file with mode: 0644]
gtk/gtkcurve.h [new file with mode: 0644]
gtk/gtkdata.c [new file with mode: 0644]
gtk/gtkdata.h [new file with mode: 0644]
gtk/gtkdialog.c [new file with mode: 0644]
gtk/gtkdialog.h [new file with mode: 0644]
gtk/gtkdrawingarea.c [new file with mode: 0644]
gtk/gtkdrawingarea.h [new file with mode: 0644]
gtk/gtkentry.c [new file with mode: 0644]
gtk/gtkentry.h [new file with mode: 0644]
gtk/gtkenums.h [new file with mode: 0644]
gtk/gtkeventbox.c [new file with mode: 0644]
gtk/gtkeventbox.h [new file with mode: 0644]
gtk/gtkfilesel.c [new file with mode: 0644]
gtk/gtkfilesel.h [new file with mode: 0644]
gtk/gtkfixed.c [new file with mode: 0644]
gtk/gtkfixed.h [new file with mode: 0644]
gtk/gtkframe.c [new file with mode: 0644]
gtk/gtkframe.h [new file with mode: 0644]
gtk/gtkgamma.c [new file with mode: 0644]
gtk/gtkgamma.h [new file with mode: 0644]
gtk/gtkgc.c [new file with mode: 0644]
gtk/gtkgc.h [new file with mode: 0644]
gtk/gtkhbbox.c [new file with mode: 0644]
gtk/gtkhbbox.h [new file with mode: 0644]
gtk/gtkhbox.c [new file with mode: 0644]
gtk/gtkhbox.h [new file with mode: 0644]
gtk/gtkhpaned.c [new file with mode: 0644]
gtk/gtkhpaned.h [new file with mode: 0644]
gtk/gtkhruler.c [new file with mode: 0644]
gtk/gtkhruler.h [new file with mode: 0644]
gtk/gtkhscale.c [new file with mode: 0644]
gtk/gtkhscale.h [new file with mode: 0644]
gtk/gtkhscrollbar.c [new file with mode: 0644]
gtk/gtkhscrollbar.h [new file with mode: 0644]
gtk/gtkhseparator.c [new file with mode: 0644]
gtk/gtkhseparator.h [new file with mode: 0644]
gtk/gtkimage.c [new file with mode: 0644]
gtk/gtkimage.h [new file with mode: 0644]
gtk/gtkinputdialog.c [new file with mode: 0644]
gtk/gtkinputdialog.h [new file with mode: 0644]
gtk/gtkitem.c [new file with mode: 0644]
gtk/gtkitem.h [new file with mode: 0644]
gtk/gtklabel.c [new file with mode: 0644]
gtk/gtklabel.h [new file with mode: 0644]
gtk/gtklist.c [new file with mode: 0644]
gtk/gtklist.h [new file with mode: 0644]
gtk/gtklistitem.c [new file with mode: 0644]
gtk/gtklistitem.h [new file with mode: 0644]
gtk/gtkmain.c [new file with mode: 0644]
gtk/gtkmain.h [new file with mode: 0644]
gtk/gtkmenu.c [new file with mode: 0644]
gtk/gtkmenu.h [new file with mode: 0644]
gtk/gtkmenubar.c [new file with mode: 0644]
gtk/gtkmenubar.h [new file with mode: 0644]
gtk/gtkmenufactory.c [new file with mode: 0644]
gtk/gtkmenufactory.h [new file with mode: 0644]
gtk/gtkmenuitem.c [new file with mode: 0644]
gtk/gtkmenuitem.h [new file with mode: 0644]
gtk/gtkmenushell.c [new file with mode: 0644]
gtk/gtkmenushell.h [new file with mode: 0644]
gtk/gtkmisc.c [new file with mode: 0644]
gtk/gtkmisc.h [new file with mode: 0644]
gtk/gtknotebook.c [new file with mode: 0644]
gtk/gtknotebook.h [new file with mode: 0644]
gtk/gtkobject.c [new file with mode: 0644]
gtk/gtkobject.h [new file with mode: 0644]
gtk/gtkoptionmenu.c [new file with mode: 0644]
gtk/gtkoptionmenu.h [new file with mode: 0644]
gtk/gtkpaned.c [new file with mode: 0644]
gtk/gtkpaned.h [new file with mode: 0644]
gtk/gtkpixmap.c [new file with mode: 0644]
gtk/gtkpixmap.h [new file with mode: 0644]
gtk/gtkpreview.c [new file with mode: 0644]
gtk/gtkpreview.h [new file with mode: 0644]
gtk/gtkprogressbar.c [new file with mode: 0644]
gtk/gtkprogressbar.h [new file with mode: 0644]
gtk/gtkradiobutton.c [new file with mode: 0644]
gtk/gtkradiobutton.h [new file with mode: 0644]
gtk/gtkradiomenuitem.c [new file with mode: 0644]
gtk/gtkradiomenuitem.h [new file with mode: 0644]
gtk/gtkrange.c [new file with mode: 0644]
gtk/gtkrange.h [new file with mode: 0644]
gtk/gtkrc.c [new file with mode: 0644]
gtk/gtkrc.h [new file with mode: 0644]
gtk/gtkruler.c [new file with mode: 0644]
gtk/gtkruler.h [new file with mode: 0644]
gtk/gtkscale.c [new file with mode: 0644]
gtk/gtkscale.h [new file with mode: 0644]
gtk/gtkscrollbar.c [new file with mode: 0644]
gtk/gtkscrollbar.h [new file with mode: 0644]
gtk/gtkscrolledwindow.c [new file with mode: 0644]
gtk/gtkscrolledwindow.h [new file with mode: 0644]
gtk/gtkselection.c [new file with mode: 0644]
gtk/gtkselection.h [new file with mode: 0644]
gtk/gtkseparator.c [new file with mode: 0644]
gtk/gtkseparator.h [new file with mode: 0644]
gtk/gtksignal.c [new file with mode: 0644]
gtk/gtksignal.h [new file with mode: 0644]
gtk/gtkstyle.c [new file with mode: 0644]
gtk/gtkstyle.h [new file with mode: 0644]
gtk/gtktable.c [new file with mode: 0644]
gtk/gtktable.h [new file with mode: 0644]
gtk/gtktext.c [new file with mode: 0644]
gtk/gtktext.h [new file with mode: 0644]
gtk/gtktogglebutton.c [new file with mode: 0644]
gtk/gtktogglebutton.h [new file with mode: 0644]
gtk/gtktooltips.c [new file with mode: 0644]
gtk/gtktooltips.h [new file with mode: 0644]
gtk/gtktree.c [new file with mode: 0644]
gtk/gtktree.h [new file with mode: 0644]
gtk/gtktreeitem.c [new file with mode: 0644]
gtk/gtktreeitem.h [new file with mode: 0644]
gtk/gtktypebuiltins.c [new file with mode: 0644]
gtk/gtktypebuiltins.h [new file with mode: 0644]
gtk/gtktypeutils.c [new file with mode: 0644]
gtk/gtktypeutils.h [new file with mode: 0644]
gtk/gtkvbbox.c [new file with mode: 0644]
gtk/gtkvbbox.h [new file with mode: 0644]
gtk/gtkvbox.c [new file with mode: 0644]
gtk/gtkvbox.h [new file with mode: 0644]
gtk/gtkviewport.c [new file with mode: 0644]
gtk/gtkviewport.h [new file with mode: 0644]
gtk/gtkvpaned.c [new file with mode: 0644]
gtk/gtkvpaned.h [new file with mode: 0644]
gtk/gtkvruler.c [new file with mode: 0644]
gtk/gtkvruler.h [new file with mode: 0644]
gtk/gtkvscale.c [new file with mode: 0644]
gtk/gtkvscale.h [new file with mode: 0644]
gtk/gtkvscrollbar.c [new file with mode: 0644]
gtk/gtkvscrollbar.h [new file with mode: 0644]
gtk/gtkvseparator.c [new file with mode: 0644]
gtk/gtkvseparator.h [new file with mode: 0644]
gtk/gtkwidget.c [new file with mode: 0644]
gtk/gtkwidget.h [new file with mode: 0644]
gtk/gtkwindow.c [new file with mode: 0644]
gtk/gtkwindow.h [new file with mode: 0644]
gtk/line-arrow.xbm [new file with mode: 0644]
gtk/line-wrap.xbm [new file with mode: 0644]
gtk/marble.xpm [new file with mode: 0644]
gtk/parent [new file with mode: 0644]
gtk/runelisp [new file with mode: 0644]
gtk/simple.c [new file with mode: 0644]
gtk/test.xpm [new file with mode: 0644]
gtk/testgtk.c [new file with mode: 0644]
gtk/testgtkrc [new file with mode: 0644]
gtk/testinput.c [new file with mode: 0644]
gtk/testselection.c [new file with mode: 0644]
install-sh [new file with mode: 0755]
ltconfig [new file with mode: 0755]
ltmain.sh [new file with mode: 0644]
makecopyright [new file with mode: 0755]
missing [new file with mode: 0755]
mkinstalldirs [new file with mode: 0755]
stamp-h.in [new file with mode: 0644]
tests/3DRings.xpm [new file with mode: 0644]
tests/FilesQueue.xpm [new file with mode: 0644]
tests/Modeller.xpm [new file with mode: 0644]
tests/marble.xpm [new file with mode: 0644]
tests/simple.c [new file with mode: 0644]
tests/test.xpm [new file with mode: 0644]
tests/testgtk.c [new file with mode: 0644]
tests/testgtkrc [new file with mode: 0644]
tests/testinput.c [new file with mode: 0644]
tests/testselection.c [new file with mode: 0644]

diff --git a/.cvsignore b/.cvsignore
new file mode 100644 (file)
index 0000000..0858b39
--- /dev/null
@@ -0,0 +1,10 @@
+*.lo
+config.log
+config.h
+libtool
+config.status
+stamp-h
+Makefile
+gtk+.xconfig
+config.cache
+
diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..f1adbf1
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,3 @@
+Peter Mattis    (petm@xcf.berkeley.edu)
+Spencer Kimball (spencer@xcf.berkeley.edu)
+Josh MacDonald  (jmacd@xcf.berkeley.edu)
diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..eb685a5
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,481 @@
+                 GNU LIBRARY GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+                    675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL.  It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it.  You can use it for
+your libraries, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library.  If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+\f
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software.  To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+  Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs.  This
+license, the GNU Library General Public License, applies to certain
+designated libraries.  This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+  The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it.  Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program.  However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+  Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries.  We
+concluded that weaker conditions might promote sharing better.
+
+  However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves.  This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them.  (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.)  The hope is that this
+will lead to faster development of free libraries.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+  Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+\f
+                 GNU LIBRARY GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License").  Each licensee is
+addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+\f
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+  6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    c) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    d) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+\f
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Library General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                           NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+\f
+     Appendix: How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..a065ebe
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,1140 @@
+Mon Nov 17 1997 Jay Painter <jpaint@serv.net>
+       * gtkviewport.c: Raph's Mon, 10 Nov 1997 patch to gtk-list 
+       to fix some viewport bugs
+
+Mon Nov 17 1997 Jay Painter <jpaint@serv.net>
+       * gtk/gtkwidget.c: gtk-ajaborsk-971016-2
+       A little patch again to prevent user to use gtk_widget_set_events()
+       when a widget is already realized.
+       In this case, the gtk_widget_set_events() doesn't work.
+
+Mon Nov 17 1997 Jay Painter <jpaint@serv.net>
+       * gtk/gtkwindow.c: gtk-ajaborsk-971016-1
+       This small patch correct position for GTK_WIN_POS_CENTER and
+       GTK_WIN_POS_MOUSE GtkWindow positions.
+
+Sat Nov 15 1997 Jay Painter <jpaint@serv.net>
+       * gdk/gdkgc.c: added function gdk_gc_set_clip_rectangle
+       * gdk/gdk.h: header for above
+
+Sat Nov 15 1997 Jay Painter <jpaint@serv.net>
+       * gdk/gdkgc.c: added function gdk_gc_set_clip_rectangle
+       * gdk/gdk.h: header for above
+
+Wed Nov 12 1997 Jay Painter <jpaint@serv.net>
+       * gdk/gdkpixmap.c: Patrice Fortier's patch for transparent pixmaps.
+       * gdk/gdk.h:
+         gdk/gdkdraw.c: Patrice Fortier's patch to add pixel draw function.
+
+Sun Nov  9 1997 Jay Painter <jpaint@serv.net>
+       * Fixed problems with makefiles relating to the bug
+       which required glib to be installed.
+       * Fixed makefiles to incluce the xpm's in gtk+/gtk needed
+       for testgtk.
+       * Updated gtk+ and gtk+/glib to libtool-1.0f
+
+Fri Nov  7 1997 Jay Painter <jpaint@serv.net>
+       * gtk/gtktext.c: return char_widths[ch & 0xff]; in line 2152
+
+Thr Nov  5 1997 Jay Painter <jpaint@serv.net>
+       * gtk/testgtk.c: added drag and drop test, removed the test hack
+       from the button test
+
+Tue Nov  4 08:28:57 1997  Federico Mena  <federico@bananoid.nuclecu.unam.mx>
+
+       * gtk/gtkmain.c (gtk_handle_idle): Patch from David Mosberger to
+       avoid crashes when handling idle function (this manifested itself
+       in the Umax and Microtek backends in SANE.
+
+Sun Nov  2 07:34:56 1997  Tim Janik  <timj@psynet.net>
+
+       * gtk/gtkfilesel.c: Small fixes about a segmentation viaolation
+       cause by a double click in the directoy list (introduced by my
+       previous changes).
+       
+       * gtk/gtklist.c: Small fixes to gtk_list_add() and gtk_list_remove().
+       
+       * gtk/testgtk.c (list_add): Applied Stefan Wille's patch to make this
+       function do something ;).
+
+Fri Oct 31 Jay Painter <jpaint@serv.net>
+       *gdk/gdk.c: reformatted DND code for GTK coding standards
+       *gdk/gdkwindow.c: changed memory allocation for DND to q_mem stuff
+
+Thu Oct 30 Jay Painter <jpaint@serv.net>
+       * gdk/gdkwindow.c: 
+       * gdk/gdk/gdk.h:
+       * gtk/gtkwidget.h:
+       * gtk/gtkwidget.c: Applied Stephan Willie's shaped window patch
+
+       * gdk/gdkwindow: 
+       * gdk/gdk.h:
+       * gtk/gtkwidget.h:
+       * gtk/gtkwidget.c: reformatted the DND code to conform to GTK
+               coding standards
+
+       * gtk/testgtk: massive fixes, SW's shaped window example
+
+Thu Oct 30 07:33:27 1997  Tim Janik  <timj@psynet.net>
+
+       * gtk/gtklistitem.c (gtk_real_list_item_toggle): applied Johannes
+       Keukelaar's <johannes@nada.kth.se> patch for keyboard support in
+       GtkList widgets.
+
+       * gtk/gtkfilesel.c: adapted dir and file list selection
+       behaviour to deal with keyboard selections. this is a little
+       bit tricky: in the dir list it just changes the entrys value on a one
+       button press. but on a keyboard selection via gtk_widget_activate() it
+       does a new population (likewise on a double click) as this seems more
+       obvious.
+
+1997-10-25  Marius Vollmer  <mvo@zagadka.ping.de>
+
+       * gdk/gdkcolor.c (gdk_colormap_get_system): Initialize
+       private->ref_count.
+
+Wed Oct 22 09:47:43 1997  Tim Janik  <timj@psynet.net>
+
+       * gtk/gtkwindow.c (gtk_window_key_release_event): Fixed a stupid
+       bug that caused the key_release_event to be propagated twice.
+
+Sun Oct 12 11:01:43 1997  Tim Janik  <timj@psynet.net>
+
+        * acconfig.h:
+        * configure.in:
+       * gdk/gdkimage.c: Added configure check for IPC_RMID_DEFERRED_RELEASE,
+       because shmat() fails after a shmctl(..., IPC_RMID,...) for OSF1 V3.2,
+       SunOS 4.1.1, 5.5, 5.5.1, 5.6, IRIX 5.2 and 6.2.
+
+Mon Oct  6 11:59:07 1997  Federico Mena  <federico@bananoid.nuclecu.unam.mx>
+
+       * gdk/gdk.c (gdk_event_translate): In line 1693, fixed typo that
+       would cause motion notify events not to be delivered.
+
+Sun Oct  5 18:15:06 1997  Federico Mena  <federico@bananoid.nuclecu.unam.mx>
+
+       * gtk/gtkrc.c (gtk_rc_parse_bg_pixmap): Changed strdup() for
+       g_strdup().
+
+Wed Sep 24 17:16:34 1997  Peter Mattis  <pmattis@bjork.inktomi.com>
+
+       * configure.in: Fixed a stupid error in the test for libXext that
+       would cause it to fail if X_EXTRA_LIBS was not empty.
+
+       * gtk/gtkmain.h (gtk-timj-970919.patch):
+       * gtk/gtkmain.c (gtk-timj-970919.patch): new function
+       `gtk_idle_remove_by_data' to remove all idle callbacks that take a
+       specific piece of data as argument.  (gtk_get_current_event):
+       remove idles through gtk_idle_remove_by_data.
+        
+       * gtk/gtkwidget.c (gtk-timj-970919.patch):
+        (gtk_widget_destroy): remove pending idles for
+        widgets that have GTK_REDRAW_PENDING or GTK_RESIZE_PENDING and
+        GTK_ANCHORED set (only anchored widgets can have a resize queue
+        handler pending). widgets that have GTK_RESIZE_NEEDED will be removed
+        from their anchored toplevels `resize_widgets' list.
+        
+        (gtk_widget_queue_draw): let the widget remember the queue handler
+        tag (through `redraw_handler_key') for later call to `gtk_idle_remove'.
+        
+        (gtk_widget_queue_resize): let the widget remember the queue handler
+        tag (through `resize_handler_key') for later call to `gtk_idle_remove'.
+        corrected referencing the toplevel widget for which the handler is
+        pending. if a widget is added to the `resize_widgets' list of a
+        toplevel widget, GTK_RESIZE_NEEDED is set and it's referenced.
+        
+        (gtk_real_widget_queue_resize): on the deletion of the `resize_widgets'
+        list, unset GTK_RESIZE_NEEDED and unreference the removed widgets.
+        
+       * gtk/gtkwindow.c (gtk-timj-970919.patch):
+        (gtk_real_window_move_resize): move `resize_containers = NULL'
+        initialization out of if-statement.
+        while stepping through the `resize_widgets' list, unreference the
+        widgets and clear GTK_RESIZE_NEEDED. if a widget realy needs are
+        resize, they are flagged through GTK_RESIZE_NEEDED now (instead of
+        GTK_RESIZE_PENDING, as this is indicative for a pending handler).
+        added checks to provide segfaulting if a widgets parent pointer
+        is NULL (e.g. on toplevel widgets that have GTK_RESIZE_NEEDED set).
+
+Tue Sep 23 13:23:27 1997  Federico Mena  <federico@bananoid.nuclecu.unam.mx>
+
+       * gdk/gdkimage.c: Applied Tim Janik's patch to mark shm segments
+       as IPC_RMID so that they are automatically removed always.
+
+       * gdk/gdkfont.c: Removed casts from lvalues.
+
+       * gtk/gtkmain.c: Removed GTK_RETLOC_*() (which do a cast) from lvalues.
+
+       * gtk/gtkaccelerator.c (gtk_accelerator_table_remove): Added
+       "const" to the accelerator_key param to be consistent with the
+       declaration in gtkaccelerator.h.  The const is not useful in this
+       case, anyway.
+
+Tue Sep 16 13:11:06 1997  Peter Mattis  <pmattis@bjork.inktomi.com>
+
+       * gtkpreview.c: Andrew Logan Kieschnick's change to eliminate
+       round-off error when gamma is set to 1.0.
+
+       * gtkrange.c:
+       * gtkviewport.c: Jay Painter's changes to modify the way in which
+       viewports resize.
+
+       * gdkinput.c:
+       * gdkinputgxi.h:
+       * gdkinputxfree.h:
+       * gtk/Makefile.am:
+       * gtk.h:
+       * gtkeventbox.c:
+       * gtkeventbox.h: Owen Taylor's event box widget and fixes for X
+       input support (that I had broken).
+
+       * gdk.h:
+       * gdkwindow.c:
+       * gtksignal.h:
+       * gtksignal.c: Elliot Lee's changes to support Objective C. (id is
+       apparently a reserved word in Objective C).
+
+Sun Sep 14 22:33:15 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwidget.c (gtk_widget_queue_resize): If the toplevel container
+       is invisible we simply call "gtk_container_need_resize" on
+       it. This fixes a bug with option menus not redrawing correctly.
+
+       * gtkmenuitem.c (gtk_menu_item_enter): (gtk_menu_item_leave):
+       These functions now simply pass the event on to their parent. This
+       is necessary for menus to work properly due to the change in how
+       grabs are dealts with.
+
+       * gtkwindow.c (gtk_real_window_move_resize): Fixed a bug that
+       caused the GTK_RESIZE_PENDING flag to not be unset in some cases.
+
+Fri Sep  5 20:49:37 1997  Marius Vollmer  <mvo@zagadka.ping.de>
+
+       Bug fixes:
+
+       * Makefile.am: Added PATCHES to EXTRA_DIST.
+       * gtk/gtkpixmap.c (gtk_pixmap_new): Move the "pixmap != NULL" test
+       after the allocation of the pixmap.
+
+       To shut up the compiler:
+
+       * gtk/gtkfilesel.c (get_pwdb): Initialize home_dir.
+       * gtk/gtkmain.c (gtk_init): Replace comments around calls to
+       g_set_*_handler with "if (0)".
+       * gtk/gtkrc.c (gtk_rc_get_token): Initialize hex_number and
+       float_number.
+       * gtk/gtkwindow.c (gtk_window_key_press_event): Initialize
+       direction.
+
+       Changes to the type system in gtk/:
+
+       * Makefile.am: Added gtktypebuiltins.h to gtkinclude_HEADERS.
+       Added gtk.defs, runelisp, gentypeinfo.el and gtktypebuiltins.c to
+       EXTRA_DIST.  Added rules to generate gtktypebuiltins.* from
+       gtk.defs.
+
+       * runelisp, gentypeinfo.el, gtk.defs: New files.
+
+       * gtkaccelerator.c, gtkaccelerator.h (gtk_accelerator_table_ref):
+       Return the table so that this function can be used as the `copy'
+       function for GTK_TYPE_BOXED values.
+       * gtkstyle.c, gtkstyle.h (gtk_style_ref): Likewise.
+
+       * gtkenums.h: Removed GtkArgType enum.
+
+       * gtkmain.c (gtk_init): Call gtk_type_init to initialize the type
+       system.
+
+       * gtkobject.c (gtk_object_init_type): New function to take over
+       for gtk_object_get_type. (gtk_object_get_type): Just return the
+       constant GTK_TYPE_OBJECT. (gtk_object_collect_args): Do the right
+       thing for the new GTK_TYPE_* types.
+       * gtksignal.c (gtk_params_get): Likewise.
+
+       * gtktypeutils.c: (gtk_type_init_builtin_types): New
+       function. (gtk_type_init): Call it.  Also made non-static.
+       (gtk_type_unique): The allocation scheme for numerical ids has
+       changed: The low 8 bits hold the appropriate GtkFundamentalType of
+       a type, the rest is a globally unique sequence number.
+       (gtk_type_hash): Use the sequence number of a key to hash it.
+       (gtk_type_register_builtin): New function.
+
+       * gtktypeutils.h: (GtkFundamentalType): New enumeration of the
+       fundamental types. (GTK_TYPE_MAKE, GTK_FUNDAMENTAL_TYPE,
+       GTK_TYPE_SEQNO): New macros to work with the new id scheme.
+       (GtkArg): Added fields for new types and renamed old ones.  GtkArg
+       should now be a mostly opaque structure, except name and type.
+       (GTK_VALUE_*): New macros to access the values of a GtkArg.
+       (GTK_RETLOC_*): New macros to access the location of a return
+       value that is contained in a GtkArg.  * gtktypebuiltins.h: New
+       file to access the typeids of the builtin types.
+
+       * gtkwidget.h (GTK_TYPE_WIDGET): New macro to access the type id
+       of the widget class.
+
+       Thru out: Changed GTK_ARG_* to the appropriate GTK_TYPE_*.
+       Changed access to GtkArg structure to the appropriate GTK_VALUE_*
+       or GTK_RETLOC_* macro.  Changed GtkArgType to GtkType.  Changed
+       some guints to GtkType.
+
+       General changes in gtk/ to support interpreters:
+
+       * gtkradiobutton.c (gtk_radio_button_new_from_widget,
+       gtk_radio_button_new_with_label_from_widget): New functions.
+
+       * gtksignal.c (gtk_signal_connect_no_marshal): New function.
+       (struct _GtkHandler): Added no_marshal and destroy_func fields.
+       (gtk_signal_handler_new): Initialize them.
+       (gtk_signal_connect_by_type): Added no_marshal and destroy_func
+       arguments.  Changed all callers.
+       (gtk_signal_destroy): Invoke destroy_func if there is one and the
+       global destroy func does not apply.  (gtk_handlers_run): If the
+       handler has no_marshal set, call its function directly without
+       going thru the signal's marshaller.
+
+Wed Sep  3 09:56:22 1997  RHS Linux User  <pmattis@bjork.inktomi.com>
+
+       * gtkrange.c: Changed the way the range control focus was drawn so
+       that the range control is drawn correctly when it does not have
+       the focus.
+
+Tue Sep  2 17:41:17 1997  RHS Linux User  <pmattis@bjork.inktomi.com>
+
+       * gtkwidget.c: 'gtk_real_widget_queue_resize' should only remove
+       the "resize_widgets" if another resize is not pending.
+
+Mon Sep  1 18:28:08 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmain.c: Changed the way GDK_DELETE events are handled. Only,
+       if 'gtk_widget_event' returns TRUE is the widget destroyed. By
+       default, 'gtk_widget_event' will return FALSE causing the window
+       to not be destroyed. This prevents segfaults in the GIMP and other
+       programs that do not correctly handle GDK_DELETE events.
+
+       * gtkmain.c: Added modal dialog support by allowing events
+       destined for a child of the grab widget to go to the child instead
+       of the grab widget. (Added 'gtk_widget_is_ancestor' to determine
+       the relationship between the grab widget and the event widget).
+
+       * *.[ch]: Incorprated a whole mess of patches. (Started keeping
+       the ChangeLog up to date again).
+
+Thu Jun  5 17:22:21 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenufactory.c:
+       * gtkmenufactory.h: Added 'gtk_menu_factory_remove_*'
+       calls. Removing entries/paths causes the associated widgets to be
+       destroyed.
+
+       * gtkwidget.c:
+       * gtkwidget.h: Calling 'gtk_widget_set_style' is used as an
+       indication that the programmer specifically wants that style to be
+       used. RC-style substitution is disabled for the widget after such
+       a call.
+
+       * gtkpixmap.c:
+       * gtkpixmap.h:
+       * gtkimage.c:
+       * gtkimage.h: Changed to use clip mask and a single pixmap (or
+       image) to deal with transparent areas.
+
+       * gdkpixmap.c: Modified xpm loading routines to optionally return
+       a clip mask.
+
+       * gdkgc.c:
+       * gdkdraw.c:
+       * gdktypes.h: Modifications to allow clip masks to be used with
+       gc's. Clip masks are bitmaps that specify drawable regions.
+
+Thu May  1 03:11:51 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkscrolledwindow.c: Scrolled windows need to have the
+       GTK_NO_WINDOW flag set. Not having it set caused an obscure
+       redrawing bug.
+
+Wed Apr 30 12:38:03 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkhruler.c:
+       * gtkvruler.c: Fixed a small bug that caused the indicator to be
+       positioned slightly off.
+
+Sun Apr 27 14:28:21 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenushell.c:
+       * gtkmenushell.h:
+       * gtkmenu.c:
+       * gtkmenu.h: Changes so that if a menu is popped up there is a
+       timeout period during which a menu item will not be activated and
+       if the mouse button is released in that period the menu will stay
+       popped up.
+
+       * gtkcurve.c:
+       * gtkcurve.h: Included curve widget courtesy of David
+       Mosberger-Tang (davidm@azstarnet.com).
+
+       * gtkentry.c:
+       * gtkentry.h: Changed "insert" and "delete" signals to
+       "insert_text" and "delete_text" respectively. (The symbol "delete"
+       cannot be used since it is a C++ reserved word).
+
+Sat Apr 19 01:43:49 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenufactory.c: A path which ends in "<nothing>" will cause an
+       invisible (hidden) menu entry to be created. This is useful for
+       setting an accelerator key for which a corresponding menu entry is
+       not desired.
+
+       * gtktooltips.c: Fixed some problems with destruction of the
+       active tip widget not properly updating the tooltips data
+       structures.
+
+Fri Apr 18 15:09:45 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkcontainer.c:
+       * gtklist.c:
+       * gtkwidget.c:
+       * gtkwidget.h: Patch from Owen Taylor (owt1@cornell.edu) which
+       fixes problems with destruction of objects and with destruction of
+       objects which hold the focus.
+
+Thu Apr 17 11:29:15 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenushell.c: Incorrect logic in
+       'gtk_menu_shell_button_release' for deciding when a menu should
+       stay popped up when the mouse button is released.
+
+       * *.c: Miscellaneous fixes from folks on the net.
+
+Tue Apr 15 02:43:17 1997  Peter Mattis  <pmattis@localhost>
+
+       * *.c:
+       * gtkwidget.h: Added GTK_BASIC widget flag which when set
+       specifies a widget as "basic". A "basic" widget is one which
+       doesn't take input events. For example, labels, pixmaps, boxes,
+       tables, alignments, etc.
+
+Sat Apr 12 15:23:08 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkcolorsel.c: Add "#include <math.h>" to define M_PI.
+
+       * gtksignal.c: Fixed a bug in 'gtk_signal_emit' which showed up
+       because of the new cast checking macros. The 'object' was being
+       accessed after it had been destroyed.
+
+       * gtkoptionmenu.c: Fixed bug with using 'GTK_BIN' instead of
+       'GTK_BUTTON' which showed up because of the new cast checking
+       macros.
+
+       * *.h: 'GTK_CHECK_CAST', 'GTK_CHECK_CLASS_CAST' and
+       'GTK_CHECK_TYPE' used by standard widget macros everywhere.
+
+Wed Apr  9 00:54:17 1997  Peter Mattis  <pmattis@localhost>
+
+       * docs/gtk.texi: Started further work on documentation. Major
+       changes and additions are being made.
+
+       * gtkarrow.c:
+       * gtkarrow.h: Removed function 'gtk_arrow_get'.
+
+       * gtkcontainer.c: 'gtk_container_check_resize' no performs
+       additional checking to account for the case where the containers
+       allocation is no longer sufficient because its parent (or its
+       parents parent, etc.) needs to resize its children.
+
+Tue Apr  8 21:15:50 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkstyle.c: Fixed a bug in 'gtk_style_init' in which the font
+       was not ref'd (via 'gdk_font_ref'), but was free'd (via in
+       'gdk_font_free') in 'gtk_style_destroy'. (David
+       Mosberger-Tang). Also cleaned up 'gtk_style_destroy' while I was
+       at it.
+
+       * gtkmain.c: Fixed a bug in 'gtk_propogate_event' which caused
+       entry widgets (and probably other widgets) not to be destroyed in
+       some instances.
+
+Mon Apr  7 01:20:38 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkentry.c:
+       * gtkentry.h: Changed the "insert_text", "delete_text" and
+       "changed_text" signals to "insert", "delete", and "changed"
+       respectively. They really should have been named this way
+       originally except the previous signal mechanism prevented
+       duplicate signal names. ("changed" is also used by adjustments).
+
+       * gtkradiomenuitem.c:
+       * gtkradiomenuitem.h: New widget.
+
+       * gtkcheckmenuitem.c:
+       * gtkcheckmenuitem.h: New widget.
+
+       * gtksignal.c: Modified 'gtk_signal_lookup' to require an object
+       type to be passed as a parameter. In addition, signals are now
+       only needed to be uniquely defined in their branch of the class
+       hierarchy. This allows the same signal name to be used in two
+       different branches of the class hierarchy. For instance, the
+       "changed" signal is used both by adjustments and entries...in
+       different ways!
+
+       * gtktypeutils.c: Added 'gtk_type_parent' which returns the parent
+       type for a given type.
+
+Sun Apr  6 22:08:35 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwidget.c: If a widget is set insensitive it loses the focus
+       if it had it.
+
+       * gtkcontainer.c: Insensitive widgets no longer participate in tab
+       traversal.
+
+       * gtkscrolledwindow.c: The "viewport" child is now destroyed and a
+       container class "foreach" function was written (which fixes the
+       sensitivity bug).
+
+Sat Apr  5 14:25:38 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkhscrollbar.c:
+       * gtkvscrollbar.c: Fixed trough size allocation bug.
+
+       * gtkhscale.c:
+       * gtkvscale.c: Fixed trough size allocation and position bug that
+       showed up when scales were placed in notebooks.
+
+Thu Mar 27 17:45:54 1997  David Mosberger-Tang  <davidm@azstarnet.com>
+
+        * gtk/gtkmain.c (gtk_handle_idle): Fix appending pending_idles to
+        idle_functions so it works even when idle_functions is empty.
+
+Sat Mar 15 14:15:59 1997  Peter Mattis  <pmattis@localhost>
+
+       * *.[ch]: Moved '*_class_init' and '*_init' function declarations
+       for widgets into the source file as those functions no longer had
+       to be public.
+
+       * gtkcheckbutton.c: Fixed redrawing of check button.
+
+       * gtkframe.c: Fixed redrawing of frame when the shadow type is
+       changed.
+
+Sat Mar  8 15:19:23 1997  Peter Mattis  <pmattis@localhost>
+
+       * gdkimage.c: Fixed a stupid bug with 'gdk_image_new' which
+       potentially added a NULL image to "image_list" and caused problems
+       when 'gdk_image_exit' was called.
+
+Wed Mar  5 00:40:08 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkpreview.c: Massively changed the colormap handling used by
+       the preview widget. Gray previews are now dithered. A single
+       visual and colormap is shared by the color and gray previews. A
+       GTK_PREVIEW_INFO property is installed on the root window in
+       certain cases to allow multiple GTK programs to share the system
+       colormap.
+
+Sun Mar  2 05:43:06 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkcheckbutton.c: 'gtk_checkbutton_size_allocate' was allocating
+       too much space to its children and not leaving the check button
+       room for the focus border.
+
+       * gtknotebook.c: 'gtk_notebook_size_request' wasn't requesting
+       enough space when the notebook tabs are visible.
+
+Sat Mar  1 01:59:35 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkpreview.c: Fixed a problem with 'gtk_preview_put' when the
+       image byte order is GDK_MSB_FIRST.
+
+       * gtksignal.c:
+       * gtksignal.h: Added 'gtk_signal_connect_after' and
+       'gtk_signal_connect_object_after' functions. These connect signal
+       handlers which will run after the class function associated with
+       the signal.
+
+       * gtkstyle.c: Fixed a stupid bug in 'gtk_style_new_from_key' that
+       was causing twice as many styles to be created as necesary.
+
+       * gtkwidget.c: 'gtk_real_widget_size_allocate' erases the widgets
+       old allocation if it has the GTK_NO_WINDOW flag set.
+
+       * gtkwidget.c: 'gtk_real_widget_unmap' now erases the widget if it
+       has the GTK_NO_WINDOW flag set.
+
+       * gtklabel.c: Removed 'gtk_label_unmap' as similar functionality
+       was added to gtk_real_widget_unmap.
+
+       * gtkbin.c: Modified 'gtk_bin_map' and 'gtk_bin_unmap' so that it
+       erases and draws the widget if it has the GTK_NO_WINDOW flag set.
+
+       * gtkframe.c: Modified 'gtk_frame_size_allocate' so that it erases
+       the old allocation.
+
+Fri Feb 28 03:27:05 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwindow.c: 'gtk_window_set_title' now changes the window title
+       if the window is already realized.
+
+       * gtkentry.c: 'gtk_entry_set_text' was emitting both a
+       "delete_text" and a "changed_text" signal. Modified so that it
+       only emits a "changed_text" signal.
+
+       * gtkpreview.c: Modified to work correctly on systems with MSB
+       byte order. The colormap for TRUE and DIRECT color displays is now
+       created if the default visual is not equal to the visual we are
+       using.
+
+       * gtkstyle.c: 'gtk_style_attach' and 'gtk_style_find' weren't
+       working properly in the presence of multiple colormaps are
+       different depth visuals.
+
+       * gtkcontainer.c: Massively improved focus traversal using tab and
+       arrow keys. It now uses the layout of the widgets to determine
+       where to move the focus to.
+
+Mon Feb 24 03:24:02 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenufactory.c: Set the accelerator table field for menus when
+       they are created.
+
+       * gtkmenu.c:
+       * gtkmenu.h: Added a default accelerator table field to menus so
+       that runtime modification of accelerator keys in menus can work
+       better.
+
+       * gtkrange.c: 'gtk_range_default_{h,v}motion' had faulty logic for
+       deciding what to do when the slider was at the edge of the
+       trough. They previously didn't update the adjustment value event
+       if the value wasn't what it should be when the slider was at the
+       edge of the trough.
+
+       * gtkviewport.c: 'gtk_viewport_size_allocate' and
+       'gtk_viewport_adjustment_value_changed' both had the potential for
+       performing a divide by 0. Checks are now in place to prevent this.
+
+       * gtkmenu.c: 'gtk_menu_map' now makes sure the menu lies on screen
+       if the position function is NULL.
+
+       * gtkentry.c: Modified selection handling. 'gtk_delete_selection'
+       actually removes the X selection now. 'gtk_entry_destroy' removes
+       the selection as well and relies on the change in "gdk.c" to make
+       sure the selection event will not be sent to a non-existant
+       window.
+
+       * gdk.c: Selection events are only passed on if the selection
+       owner is not NULL.
+
+       * gtkstyle.c: 'gtk_style_detach' and 'gtk_style_destroy' were not
+       destroying the black and white gc's.
+
+Sun Feb 23 19:17:56 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwindow.c: 'gtk_window_size_request' was setting the window
+       hints. This was also being done in 'gtk_window_map', so the
+       instance being done in 'gtk_window_size_request' was removed.
+
+Fri Feb 21 01:04:01 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwidget.c: 'gtk_widget_draw' has to use the widgets allocated
+       position for the drawing rectangle when the widget has the
+       GTK_NO_WINDOW flag set.
+
+       * gtkwidget.c: In 'gtk_widget_init' the visual and colormap were
+       being directly compared against 'default_visual' and
+       'default_colormap' instead of calling
+       'gtk_widget_get_default_{visual,colormap}'.
+
+       * gdkrectangle.c: Amazing! There was a bug in the
+       'gtk_rectangle_intersect' logic. Its been there for near eternity
+       and I never noticed.
+
+       * gtkpreview.c:
+       * gtkpreview.h: Created preview widget which allows drawing to an
+       rgb or grayscale buffer which is automatically displayed on the
+       screen. Performs dithering as necessary.
+
+Thu Feb 20 20:33:21 1997  Peter Mattis  <pmattis@localhost>
+
+       * gdkwindow.c: Modified the logic in 'gdk_window_new' which
+       determined when to add a window to the WM_COLORMAP_WINDOWS
+       property.
+
+Wed Feb 19 19:55:29 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkruler.c: 'gtk_ruler_make_pixmap' was always destroying the
+       old backing store and creating a new one even when it would create
+       a new one of exactly the same size as the old one.
+
+Tue Feb 18 18:32:10 1997  Peter Mattis  <pmattis@localhost>
+
+       * gmem.c: 'g_mem_chunk_alloc' was incorrectly modifying the mem
+       areas free mem field when reallocating a previously freed
+       atom. This caused a fairly severe memory leak.
+
+       * gtkmenushell.c: 'gtk_menu_shell_button_release' had a bug in the
+       logic for deciding whether to initiate an X pointer grab or not
+       when the mouse button was released. It now only initiates a grab
+       if the mouse is released within an active menu item.
+
+Fri Feb 14 00:57:40 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtknotebook.c: Changed the look of notebook tabs slightly.
+
+       * gtkentry.c:
+       * gtkentry.h: Deleting an entry widget which is holding the X
+       selection presents some difficulties. The X selection must be
+       released, but the widget can't be destroyed until the
+       SELECTION_CLEAR event is received that the X server will send in
+       response to clearing the X selection. There are probably still
+       bugs in the current method of entry widget deletion when the X
+       selection is held.
+
+       * gtkmain.c: 'gtk_propagate_event' was not properly destroying the
+       toplevel window when receiving a key press event.
+
+       * gtkwidget.c: Setting a widget insensitive did not cause it to
+       redraw. It now does.
+
+Thu Feb 13 16:59:07 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkviewport.c: 'gtk_viewport_size_allocate' was allocating its
+       child widget an adjusted allocation. Since the actual scrolling
+       has handled by a subwindow this caused the child to be double
+       scrolled. Modified to always set the child allocations origin to
+       (0, 0).
+
+Wed Feb 12 01:06:48 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkentry.c: Text is now centered vertically. Previously it was
+       pushed up against the top. This problem was only evident when the
+       widget was allocated more vertical space than it requested.
+
+       * gtkfilesel.c: 'gtk_file_selection_key_press' was previously only
+       a stub for tab completion. The actual tab completion call had been
+       left out. (Oops!)
+
+Tue Feb 11 01:43:08 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtksignal.c: 'gtk_signal_disconnect_by_data' was going into a
+       loop and crashing. Bad logic. Fixed.
+
+       * gtkmain.c: An idle function which returns FALSE will be removed
+       from the list of idle functions. This makes the functioning of
+       idle functions and timeouts more similar.
+
+       * gtkentry.c: 'gtk_entry_get_text' now returns an empty string
+       when the actual text is NULL. This allows "stupid" programs to use
+       the value returned by 'gtk_entry_get_text' blindly (without
+       checking to see if its NULL).
+
+       * gtkradiobutton.c: Modified 'gtk_radio_button_clicked' so that
+       'gtk_toggle_button_toggled' is called _after_ the widget state is
+       changed.
+
+       * gtksignal.c:
+       * gtksignal.h: Added 'gtk_signal_name' which returns the character
+       string name for a given signal number.
+
+       * gtkwidget.c: 'gtk_widget_set_parent' checks to see if the widget
+       is now "anchored" through the parent chain to a widget which is
+       GTK_ANCHORED. If it is, then it changes the widgets style using
+       'gtk_rc_get_style' and recursively performs the same operation on
+       the widgets children. This is necessary is 'gtk_rc_get_style' only
+       works properly on "anchored" widgets.
+
+       * gtkwindow.c: Modified GTK_WIN_POS logic so that it is only used
+       immediately after the window has been shown.
+
+       * gtkmenu.c: 'gtk_menu_key_press'. Can now change menu item
+       accelerator keys on the fly. Why? Why not. Cool/useless feature of
+       the day.
+
+       * gtkmenuitem.c: Accelerator key drawing. Somehow that never got
+       finished. (Oops!)
+
+       * gtkdrawingarea.c: 'gtk_drawing_area_size_allocate' was not
+       actually installed during 'gtk_drawing_area_class_init'. (Oops!)
+
+       * gtkframe.c: 'gtk_frame_size_request' fixed size requisition
+       problem caused by unsigned arithmetic.
+
+       * gtkwindow.c: Modified window widget so that it only uses the
+       widget uposition auxiliary information immediately after it has
+       been shown. This prevents the annoying bug which can cause a
+       uposition'ed window to jump back to its original position after
+       the user moves it.
+
+       * gtkwidget.c: Need to ref and unref style in
+       'gtk_widget_{push,pop}_style' to make sure that a style on the
+       style stack is not destroyed.
+
+       * gtktogglebutton.c: 'gtk_toggle_button_set_state' now calls
+       gtk_button_clicked to actually change the state of the
+       button. In this way, radio buttons can now perform the appropriate
+       actions when the toggle button state is set.
+
+Mon Feb 10 00:27:39 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtklist.c: 'gtk_list_select_item' and 'gtk_list_unselect_item'
+       were casting a GList* variable to a a GtkWidget* variable. Bad bad
+       bad. (Tim Janik).
+
+       * gtksignal.c: Modified 'gtk_signal_connect' and
+       'gtk_signal_connect_object' to warn when a signal type cannot be
+       found.
+
+Sun Feb  9 00:15:30 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkoptionmenu.c:
+       * gtkoptionmenu.h: Changed option menus back to being derived from
+       buttons. This fixes up some screwiness with their user
+       interaction.
+
+       * gtkwindow.c: Modified key press handler to support focus
+       traversal.
+
+       * gtkcontainer.c:
+       * gtkcontainer.h: Added default focus traversal back in.
+
+Sat Feb  8 10:44:38 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkviewport.h:
+       * gtkviewport.c: Massively sped up viewport scrolling. Used to be
+       reallocating child's size (offset) each time a scrollbar
+       moved. Now a subwindow is moved. All the children are moved
+       automatically by moving the subwindow. Much much much faster.
+
+Tue Feb  4 00:20:44 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtree.c: Changed 'g_tree_node_search' to use a loop instead of
+       recursion.
+
+Mon Feb  3 11:30:03 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkbutton.c: Removed 'parent_destroy' global and replaced it
+       with 'parent_class' global to reflect style used in other
+       widgets.
+
+       * gtknotebook.c: Tab labels were being allocated less than their
+       requested size.
+
+       * gtkrange.c:
+       * gtkrange.h: Moved the "digits" field of scales into the range
+       type. The adjustment value for scales is truncated to the number
+       of visible digits instead of being left untouched.
+
+       * gtree.c: Fixed a bug in the AVL tree implementation. Single
+       rotations were always being performed during insertion. It is
+       sometimes necessary to perform a double rotation.
+
+       * gtklabel.c: Modified 'gtk_label_expose' to only draw the label
+       when the allocated space is greater than or equal to the requested
+       space.
+
+       * gtklabel.c: Added call to 'gtk_widget_unmap' to
+       'gtk_label_destroy' in order for the label to redraw correctly
+       (erase itself) when destroyed.
+
+       * gtklabel.c: Added 'gtk_label_unmap' call which erases the labels
+       allocation when it gets unmapped.
+
+       * *.h: Removed a few remaining instances of using "class" as a
+       parameter name. (Causes problems for C++).
+
+Fri Jan 31 12:26:50 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkcontainer.c: 'gtk_container_enable_resize' needs to call
+       'gtk_container_check_resize' instead of
+       'gtk_container_need_resize'.
+
+       * gtkwidget.c: 'gtk_real_widget_show' now maps the widget if its
+       parent is mapped.
+
+       * gtkscrolledwindow.c: Fixed size allocation when the scrollbar
+       policy's are GTK_POLICY_AUTOMATIC. Doing it correctly is harder
+       than I originally thought.
+
+       * gtklist.c: Added 'gtk_list_child_position' to determine the
+       integer position in a list of a child. Filled in the
+       'gtk_list_item_select' and 'gtk_list_item_unselect' stubs.
+
+Thu Jan 30 16:08:06 1997  Peter Mattis  <pmattis@localhost>
+
+       * gmem.c: Changed the implementation of G_ALLOC_AND_FREE mem
+       chunks. They used to allocate SIZEOF_VOID_P extra bytes per atom
+       in order to keep track of which mem area they were allocated
+       from. Now the mem area is determined by searching through an AVL
+       tree of the mem areas for a mem chunk and comparing memory
+       locations. A little slower, but makes G_ALLOC_AND_FREE mem chunks
+       much more attractive.
+
+       * gtree.c: Added an AVL tree implementation to glib.
+
+       * gtksignal.c:
+       * gstring.c: va_arg (arg_list, {char, short}) is
+       invalid. Arguments passed in a variable argument list are
+       promoted. ({char, short}->int). Seemed to work ok before under
+       Linux. Crashed under FreeBSD.
+
+Tue Jan 28 02:27:51 1997  Peter Mattis  <pmattis@localhost>
+
+       * gdkwindow.c: Fixed a major slowdown apparent in the file
+       selection dialog which was caused by calling
+       'gtk_window_add_colormap_windows' way way way too often.
+
+       * *.c: Many widgets called 'gtk_container_need_resize' when
+       something internal changed which would cause the widget to grow or
+       shrink. The assumption was made that the widget would change size
+       and an expose event would be generated. This happens "most" of the
+       time. But its possible for certain widgets to change size without
+       generating expose events, or for its internal geometry to change
+       without a change of size which would mean no expose event was
+       generated. So a wrapper function called
+       'gtk_container_check_resize' was created and
+       'gtk_container_need_resize' was modified so that it returns FALSE
+       if a resize was actually generated and TRUE if nothing
+       changed. This allows 'gtk_container_check_resize' to initiate a
+       'gtk_widget_size_allocate' and 'gtk_widget_draw' to emulate the
+       expose event.
+
+Sat Jan 25 14:17:44 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmain.c: Fixed a bug with propogating key press events. The
+       events were sent 2 times to the toplevel windows which caused the
+       focus widget to be activated twice when the space bar was pressed.
+
+       * */configure.in:
+       * */Makefile.am: Added support for libtool and removed the old
+       shared library configuration craziness.
+
+Fri Jan 24 12:59:22 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtktext.c:
+       * gtktext.h: Josh's fixes and additions to the text widget.
+
+       * gtkfill.c:
+       * gtkfill.h: Filler widget useful for filling space in a
+       table. Can specify a minimum size. Used by the canvas widget.
+
+       * gtknotebook.c:
+       * gtknotebook.h: Made outline of notebook widget.
+
+       * gtkcanvas.c:
+       * gtkcanvas.h: Started canvas widget. A composite of 2 rulers (w/
+       an origin), 2 scrolllbars. Guides, grids, snap to.
+
+Sun Jan 19 18:26:45 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkdialog.c:
+       * gtkdialog.h: Created dialog widget which creates a standard
+       looking dialog with buttons along the button and a separator.
+
+       * gtkxid.c: Generalized the window table code for looking up a gdk
+       window based on an XID to work for any XID and a piece of
+       data. Can now look up gdk fonts based on their XID.
+
+       * gtkruler.c:
+       * gtkruler.h:
+       * gtkhruler.c:
+       * gtkhruler.h:
+       * gtkvruler.c:
+       * gtkvruler.h: Started conversion of the ruler widget.
+
+       * gtktext.c:
+       * gtktext.h: Started conversion of the text widget. Scrolling
+       doesn't work.
+
+       * gtkmain.c: Fixed a fairly major bug. The event widget needs to
+       be in a call for the entire duration of handling an event. Not
+       just for when the event widget itself is handling the event.
+
+       * gtkfilesel.c: Fixed up some bugs with resizing.
+
+Fri Jan 10 14:18:03 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwidget.c:
+       * gtkwidget.h:
+       * gtkentry.c:
+       * gtkentry.h: Support for selections.
+
+       * gdkselection.c:
+       * gdk.c:
+       * gdktypes.h:
+       * gdk.h: Gdk support for X selections. Currently only text
+       selections are supported.
+
+       * gtksignal.c: Fixed a major bug which occurred when destroying an
+       object. Memory was being written to after it was freed.
+
+       * gtkfilesel.c:
+       * gtkfilesel.h: Hooked up more functionality to the file selection
+       dialog.
+
+Wed Jan  8 18:13:53 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkfilesel.c:
+       * gtkfilesel.h: Mostly converted old file selection dialog
+       widget. The widget is derived from the GtkWindow class and is
+       quite a bit simpler in the widget code.
+
+       * gtkwidget.c: Fixed 'gtk_widget_grab_focus' and
+       'gtk_widget_grab_default' to check that the toplevel widget is a
+       type of window (which includes classes derived from windows).
+
+Tue Jan  7 01:12:32 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwindow.c: Was calling 'gtk_window_resize' twice in a
+       row...why?
+
+       * gtksignal.c:
+       * gtksignal.h:
+       * *.c: Changed 'gtk_signal_new' so that the class function that is
+       called when the signal is emitted can be called either before,
+       after or both before and after the calling of any signal
+       handlers.
+
+       * gtkobject.c:
+       * gtkobject.h: Added 'object_data' mechanism for storing data
+       associated with a character string key in objects. Removed
+       'user_data' field of objects and changed
+       'gtk_object_{get,set}_user_data' to use the object data
+       mechanism. Removed 'handlers' field of objects.
+
+       * gtkwidget.c:
+       * gtkwidget.h:
+       * gtkwindow.c: Modified aux info mechanism to use object data
+       mechanism.
+
+       * gtksignal.c: Modified signal mechanism to use object data
+       mechanism instead of 'handlers' field.
+
+
+Mon Jan  6 15:10:16 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenushell.c: Fixed up button press handling so as to conform
+       more closely to that used by Motif.
+
+Wed Jan  1 21:27:17 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenu.c:
+       * gtkmenu.h:
+       * gtkmenubar.c:
+       * gtkmenubar.h:
+       * gtkmenushell.c:
+       * gtkmenushell.h: Reorganization of menu-ing code so that code
+       duplication is reduced. The menu shell now contains most of the
+       code for menu-ing interaction while menus and menubars simply layout
+       their child menu items in the appropriate place.
+
+Sun Dec 29 17:48:18 1996  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenu.c:
+       * gtkmenubar.c:
+       * gtkmenuitem.h:
+       * gtkmenuitem.c: Modifications so that menu item accelerators and
+       the submenu indicator are drawn correctly and the correct amount
+       of space is allocated.
+
+Sat Dec 28 00:32:13 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtkmenufactory.h:
+       * gtkmenufactory.c: Started menu factories as an easy method to
+       create and manipulate menus.
+
+Fri Dec 27 13:17:34 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtkmenu.c:
+       * gtkmenu.h:
+       * gtkmenubar.c:
+       * gtkmenubar.h:
+       * gtkmenuitem.c:
+       * gtkmenuitem.h:
+       * gtkmenushell.c:
+       * gtkmenushell.h: Implemented basic menu functionality. Menubars
+       and popup menus work. Submenus work. (Much left to be done).
+
+Wed Dec 18 15:27:05 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtktypeutils.h:
+       * gtktypeutils.c: Added 'gtk_type_from_name' which returns a type
+       identifier given a type name. Implemented using a second hash
+       table keyed by type names.
+
+       * gtkbutton.c:
+       * gtktogglebutton.c: Fixed very small messed-up drawing bug when a
+       button loses its focus.
+
+       * gtkwidget.h:
+       * gtkwidget.c:
+       * gtkbutton.c:
+       * gtkwindow.c: Added default button handling. Default buttons now
+       draw correctly and pressing return or enter causes the default
+       button (if one exists) to be activated.
+
+Tue Dec 17 19:32:21 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtkhscale.c:
+       * gtkvscale.c: Overrode 'draw_slider' method of ranges in order to
+       draw the slider of scales with a line in them so as to be closer
+       to the Motif look-and-feel.
+
+       * gtkwindow.c: Modified 'gtk_window_focus_in_event' so that focus
+       in events are only handled when the window is visible. Fixes a bug
+       where spurious focus in events get sent when a window is being
+       hidden.
+
+       * gtkwidget.h: Added 'activate_signal' field to the GtkWidgetClass
+       structure. Added 'gtk_widget_activate' call to emit the activate
+       signal for a widget if it is non-zero.
+
+Tue Dec 10 15:59:45 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtkwidget.c: 'gtk_widget_set_name' oops in strdup'ing the old
+       "widget->name" instead of the new one we are setting.
+
+       * gtkrc.c: 'gtk_rc_widget_path' changed to use
+       'gtk_widget_get_name' instead of accessing the "widget->name"
+       field directly.
+
+       * gtkwidget.c: Added 'gtk_widget_get_name' function which returns
+       the widgets name if it exists and the widgets type name if it does
+       not.
+
+       * gtkcheckbutton.c: Added 'gtk_check_button_draw'
+       function. Modified 'gtk_check_button_expose' to pass an expose
+       event to child instead of callings its draw function.
+
+       * gtkentry.c: 'gtk_entry_draw_text' why was "+1" being added to
+       the font->ascent to calculate the font position? This was wrong
+       and caused some characters in fonts to be clipped. (Notably "g").
+
+       * gtkentry.c: 'gtk_entry_realize' specify GTK_BUTTON1_MOTION_MASK
+       and GTK_POINTER_MOTION_HINT_MASK for _both_ windows.
+
+       * gtkmain.c: 'gtk_propagate_event' needs to set the GTK_IN_CALL
+       flag for the object before calling 'gtk_widget_event' and needs to
+       destroy the object if necessary after 'gtk_widget_event' returns.
+
+       * gtkradiobutton.c: 'gtk_radio_button_clicked' needs to call
+       'gtk_toggle_button_toggled' when the currently active button is
+       toggled.
+
+       * gtkwidget.c: 'gtk_real_widget_hide' needs to call
+       'gtk_widget_unmap' if the widget is currently mapped.
+
+       * gtkwindow.c: Prevent automatic resizing after the user has
+       specified a new window size. Add 'handling_resize' flag to
+       windows.
+
+       * gtkscrolledwindow.c: Implement the GTK_POLICY_AUTOMATIC
+       scrollbar policy. Need to connect to the adjustments 'changed'
+       signal and notice when the scrollbars aren't in use.
+
+       * gtkcontainer.c: 'gtk_container_init' must set 'auto_resize' and
+       'need_resize' fields to TRUE and FALSE respectively.
+
+       * gtkwidget.c: 'gtk_widget_set_parent' must all set a widgets state
+       to its parents state.
+
+Sun Dec  1 01:31:01 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * Started ChangeLog
diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0
new file mode 100644 (file)
index 0000000..a065ebe
--- /dev/null
@@ -0,0 +1,1140 @@
+Mon Nov 17 1997 Jay Painter <jpaint@serv.net>
+       * gtkviewport.c: Raph's Mon, 10 Nov 1997 patch to gtk-list 
+       to fix some viewport bugs
+
+Mon Nov 17 1997 Jay Painter <jpaint@serv.net>
+       * gtk/gtkwidget.c: gtk-ajaborsk-971016-2
+       A little patch again to prevent user to use gtk_widget_set_events()
+       when a widget is already realized.
+       In this case, the gtk_widget_set_events() doesn't work.
+
+Mon Nov 17 1997 Jay Painter <jpaint@serv.net>
+       * gtk/gtkwindow.c: gtk-ajaborsk-971016-1
+       This small patch correct position for GTK_WIN_POS_CENTER and
+       GTK_WIN_POS_MOUSE GtkWindow positions.
+
+Sat Nov 15 1997 Jay Painter <jpaint@serv.net>
+       * gdk/gdkgc.c: added function gdk_gc_set_clip_rectangle
+       * gdk/gdk.h: header for above
+
+Sat Nov 15 1997 Jay Painter <jpaint@serv.net>
+       * gdk/gdkgc.c: added function gdk_gc_set_clip_rectangle
+       * gdk/gdk.h: header for above
+
+Wed Nov 12 1997 Jay Painter <jpaint@serv.net>
+       * gdk/gdkpixmap.c: Patrice Fortier's patch for transparent pixmaps.
+       * gdk/gdk.h:
+         gdk/gdkdraw.c: Patrice Fortier's patch to add pixel draw function.
+
+Sun Nov  9 1997 Jay Painter <jpaint@serv.net>
+       * Fixed problems with makefiles relating to the bug
+       which required glib to be installed.
+       * Fixed makefiles to incluce the xpm's in gtk+/gtk needed
+       for testgtk.
+       * Updated gtk+ and gtk+/glib to libtool-1.0f
+
+Fri Nov  7 1997 Jay Painter <jpaint@serv.net>
+       * gtk/gtktext.c: return char_widths[ch & 0xff]; in line 2152
+
+Thr Nov  5 1997 Jay Painter <jpaint@serv.net>
+       * gtk/testgtk.c: added drag and drop test, removed the test hack
+       from the button test
+
+Tue Nov  4 08:28:57 1997  Federico Mena  <federico@bananoid.nuclecu.unam.mx>
+
+       * gtk/gtkmain.c (gtk_handle_idle): Patch from David Mosberger to
+       avoid crashes when handling idle function (this manifested itself
+       in the Umax and Microtek backends in SANE.
+
+Sun Nov  2 07:34:56 1997  Tim Janik  <timj@psynet.net>
+
+       * gtk/gtkfilesel.c: Small fixes about a segmentation viaolation
+       cause by a double click in the directoy list (introduced by my
+       previous changes).
+       
+       * gtk/gtklist.c: Small fixes to gtk_list_add() and gtk_list_remove().
+       
+       * gtk/testgtk.c (list_add): Applied Stefan Wille's patch to make this
+       function do something ;).
+
+Fri Oct 31 Jay Painter <jpaint@serv.net>
+       *gdk/gdk.c: reformatted DND code for GTK coding standards
+       *gdk/gdkwindow.c: changed memory allocation for DND to q_mem stuff
+
+Thu Oct 30 Jay Painter <jpaint@serv.net>
+       * gdk/gdkwindow.c: 
+       * gdk/gdk/gdk.h:
+       * gtk/gtkwidget.h:
+       * gtk/gtkwidget.c: Applied Stephan Willie's shaped window patch
+
+       * gdk/gdkwindow: 
+       * gdk/gdk.h:
+       * gtk/gtkwidget.h:
+       * gtk/gtkwidget.c: reformatted the DND code to conform to GTK
+               coding standards
+
+       * gtk/testgtk: massive fixes, SW's shaped window example
+
+Thu Oct 30 07:33:27 1997  Tim Janik  <timj@psynet.net>
+
+       * gtk/gtklistitem.c (gtk_real_list_item_toggle): applied Johannes
+       Keukelaar's <johannes@nada.kth.se> patch for keyboard support in
+       GtkList widgets.
+
+       * gtk/gtkfilesel.c: adapted dir and file list selection
+       behaviour to deal with keyboard selections. this is a little
+       bit tricky: in the dir list it just changes the entrys value on a one
+       button press. but on a keyboard selection via gtk_widget_activate() it
+       does a new population (likewise on a double click) as this seems more
+       obvious.
+
+1997-10-25  Marius Vollmer  <mvo@zagadka.ping.de>
+
+       * gdk/gdkcolor.c (gdk_colormap_get_system): Initialize
+       private->ref_count.
+
+Wed Oct 22 09:47:43 1997  Tim Janik  <timj@psynet.net>
+
+       * gtk/gtkwindow.c (gtk_window_key_release_event): Fixed a stupid
+       bug that caused the key_release_event to be propagated twice.
+
+Sun Oct 12 11:01:43 1997  Tim Janik  <timj@psynet.net>
+
+        * acconfig.h:
+        * configure.in:
+       * gdk/gdkimage.c: Added configure check for IPC_RMID_DEFERRED_RELEASE,
+       because shmat() fails after a shmctl(..., IPC_RMID,...) for OSF1 V3.2,
+       SunOS 4.1.1, 5.5, 5.5.1, 5.6, IRIX 5.2 and 6.2.
+
+Mon Oct  6 11:59:07 1997  Federico Mena  <federico@bananoid.nuclecu.unam.mx>
+
+       * gdk/gdk.c (gdk_event_translate): In line 1693, fixed typo that
+       would cause motion notify events not to be delivered.
+
+Sun Oct  5 18:15:06 1997  Federico Mena  <federico@bananoid.nuclecu.unam.mx>
+
+       * gtk/gtkrc.c (gtk_rc_parse_bg_pixmap): Changed strdup() for
+       g_strdup().
+
+Wed Sep 24 17:16:34 1997  Peter Mattis  <pmattis@bjork.inktomi.com>
+
+       * configure.in: Fixed a stupid error in the test for libXext that
+       would cause it to fail if X_EXTRA_LIBS was not empty.
+
+       * gtk/gtkmain.h (gtk-timj-970919.patch):
+       * gtk/gtkmain.c (gtk-timj-970919.patch): new function
+       `gtk_idle_remove_by_data' to remove all idle callbacks that take a
+       specific piece of data as argument.  (gtk_get_current_event):
+       remove idles through gtk_idle_remove_by_data.
+        
+       * gtk/gtkwidget.c (gtk-timj-970919.patch):
+        (gtk_widget_destroy): remove pending idles for
+        widgets that have GTK_REDRAW_PENDING or GTK_RESIZE_PENDING and
+        GTK_ANCHORED set (only anchored widgets can have a resize queue
+        handler pending). widgets that have GTK_RESIZE_NEEDED will be removed
+        from their anchored toplevels `resize_widgets' list.
+        
+        (gtk_widget_queue_draw): let the widget remember the queue handler
+        tag (through `redraw_handler_key') for later call to `gtk_idle_remove'.
+        
+        (gtk_widget_queue_resize): let the widget remember the queue handler
+        tag (through `resize_handler_key') for later call to `gtk_idle_remove'.
+        corrected referencing the toplevel widget for which the handler is
+        pending. if a widget is added to the `resize_widgets' list of a
+        toplevel widget, GTK_RESIZE_NEEDED is set and it's referenced.
+        
+        (gtk_real_widget_queue_resize): on the deletion of the `resize_widgets'
+        list, unset GTK_RESIZE_NEEDED and unreference the removed widgets.
+        
+       * gtk/gtkwindow.c (gtk-timj-970919.patch):
+        (gtk_real_window_move_resize): move `resize_containers = NULL'
+        initialization out of if-statement.
+        while stepping through the `resize_widgets' list, unreference the
+        widgets and clear GTK_RESIZE_NEEDED. if a widget realy needs are
+        resize, they are flagged through GTK_RESIZE_NEEDED now (instead of
+        GTK_RESIZE_PENDING, as this is indicative for a pending handler).
+        added checks to provide segfaulting if a widgets parent pointer
+        is NULL (e.g. on toplevel widgets that have GTK_RESIZE_NEEDED set).
+
+Tue Sep 23 13:23:27 1997  Federico Mena  <federico@bananoid.nuclecu.unam.mx>
+
+       * gdk/gdkimage.c: Applied Tim Janik's patch to mark shm segments
+       as IPC_RMID so that they are automatically removed always.
+
+       * gdk/gdkfont.c: Removed casts from lvalues.
+
+       * gtk/gtkmain.c: Removed GTK_RETLOC_*() (which do a cast) from lvalues.
+
+       * gtk/gtkaccelerator.c (gtk_accelerator_table_remove): Added
+       "const" to the accelerator_key param to be consistent with the
+       declaration in gtkaccelerator.h.  The const is not useful in this
+       case, anyway.
+
+Tue Sep 16 13:11:06 1997  Peter Mattis  <pmattis@bjork.inktomi.com>
+
+       * gtkpreview.c: Andrew Logan Kieschnick's change to eliminate
+       round-off error when gamma is set to 1.0.
+
+       * gtkrange.c:
+       * gtkviewport.c: Jay Painter's changes to modify the way in which
+       viewports resize.
+
+       * gdkinput.c:
+       * gdkinputgxi.h:
+       * gdkinputxfree.h:
+       * gtk/Makefile.am:
+       * gtk.h:
+       * gtkeventbox.c:
+       * gtkeventbox.h: Owen Taylor's event box widget and fixes for X
+       input support (that I had broken).
+
+       * gdk.h:
+       * gdkwindow.c:
+       * gtksignal.h:
+       * gtksignal.c: Elliot Lee's changes to support Objective C. (id is
+       apparently a reserved word in Objective C).
+
+Sun Sep 14 22:33:15 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwidget.c (gtk_widget_queue_resize): If the toplevel container
+       is invisible we simply call "gtk_container_need_resize" on
+       it. This fixes a bug with option menus not redrawing correctly.
+
+       * gtkmenuitem.c (gtk_menu_item_enter): (gtk_menu_item_leave):
+       These functions now simply pass the event on to their parent. This
+       is necessary for menus to work properly due to the change in how
+       grabs are dealts with.
+
+       * gtkwindow.c (gtk_real_window_move_resize): Fixed a bug that
+       caused the GTK_RESIZE_PENDING flag to not be unset in some cases.
+
+Fri Sep  5 20:49:37 1997  Marius Vollmer  <mvo@zagadka.ping.de>
+
+       Bug fixes:
+
+       * Makefile.am: Added PATCHES to EXTRA_DIST.
+       * gtk/gtkpixmap.c (gtk_pixmap_new): Move the "pixmap != NULL" test
+       after the allocation of the pixmap.
+
+       To shut up the compiler:
+
+       * gtk/gtkfilesel.c (get_pwdb): Initialize home_dir.
+       * gtk/gtkmain.c (gtk_init): Replace comments around calls to
+       g_set_*_handler with "if (0)".
+       * gtk/gtkrc.c (gtk_rc_get_token): Initialize hex_number and
+       float_number.
+       * gtk/gtkwindow.c (gtk_window_key_press_event): Initialize
+       direction.
+
+       Changes to the type system in gtk/:
+
+       * Makefile.am: Added gtktypebuiltins.h to gtkinclude_HEADERS.
+       Added gtk.defs, runelisp, gentypeinfo.el and gtktypebuiltins.c to
+       EXTRA_DIST.  Added rules to generate gtktypebuiltins.* from
+       gtk.defs.
+
+       * runelisp, gentypeinfo.el, gtk.defs: New files.
+
+       * gtkaccelerator.c, gtkaccelerator.h (gtk_accelerator_table_ref):
+       Return the table so that this function can be used as the `copy'
+       function for GTK_TYPE_BOXED values.
+       * gtkstyle.c, gtkstyle.h (gtk_style_ref): Likewise.
+
+       * gtkenums.h: Removed GtkArgType enum.
+
+       * gtkmain.c (gtk_init): Call gtk_type_init to initialize the type
+       system.
+
+       * gtkobject.c (gtk_object_init_type): New function to take over
+       for gtk_object_get_type. (gtk_object_get_type): Just return the
+       constant GTK_TYPE_OBJECT. (gtk_object_collect_args): Do the right
+       thing for the new GTK_TYPE_* types.
+       * gtksignal.c (gtk_params_get): Likewise.
+
+       * gtktypeutils.c: (gtk_type_init_builtin_types): New
+       function. (gtk_type_init): Call it.  Also made non-static.
+       (gtk_type_unique): The allocation scheme for numerical ids has
+       changed: The low 8 bits hold the appropriate GtkFundamentalType of
+       a type, the rest is a globally unique sequence number.
+       (gtk_type_hash): Use the sequence number of a key to hash it.
+       (gtk_type_register_builtin): New function.
+
+       * gtktypeutils.h: (GtkFundamentalType): New enumeration of the
+       fundamental types. (GTK_TYPE_MAKE, GTK_FUNDAMENTAL_TYPE,
+       GTK_TYPE_SEQNO): New macros to work with the new id scheme.
+       (GtkArg): Added fields for new types and renamed old ones.  GtkArg
+       should now be a mostly opaque structure, except name and type.
+       (GTK_VALUE_*): New macros to access the values of a GtkArg.
+       (GTK_RETLOC_*): New macros to access the location of a return
+       value that is contained in a GtkArg.  * gtktypebuiltins.h: New
+       file to access the typeids of the builtin types.
+
+       * gtkwidget.h (GTK_TYPE_WIDGET): New macro to access the type id
+       of the widget class.
+
+       Thru out: Changed GTK_ARG_* to the appropriate GTK_TYPE_*.
+       Changed access to GtkArg structure to the appropriate GTK_VALUE_*
+       or GTK_RETLOC_* macro.  Changed GtkArgType to GtkType.  Changed
+       some guints to GtkType.
+
+       General changes in gtk/ to support interpreters:
+
+       * gtkradiobutton.c (gtk_radio_button_new_from_widget,
+       gtk_radio_button_new_with_label_from_widget): New functions.
+
+       * gtksignal.c (gtk_signal_connect_no_marshal): New function.
+       (struct _GtkHandler): Added no_marshal and destroy_func fields.
+       (gtk_signal_handler_new): Initialize them.
+       (gtk_signal_connect_by_type): Added no_marshal and destroy_func
+       arguments.  Changed all callers.
+       (gtk_signal_destroy): Invoke destroy_func if there is one and the
+       global destroy func does not apply.  (gtk_handlers_run): If the
+       handler has no_marshal set, call its function directly without
+       going thru the signal's marshaller.
+
+Wed Sep  3 09:56:22 1997  RHS Linux User  <pmattis@bjork.inktomi.com>
+
+       * gtkrange.c: Changed the way the range control focus was drawn so
+       that the range control is drawn correctly when it does not have
+       the focus.
+
+Tue Sep  2 17:41:17 1997  RHS Linux User  <pmattis@bjork.inktomi.com>
+
+       * gtkwidget.c: 'gtk_real_widget_queue_resize' should only remove
+       the "resize_widgets" if another resize is not pending.
+
+Mon Sep  1 18:28:08 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmain.c: Changed the way GDK_DELETE events are handled. Only,
+       if 'gtk_widget_event' returns TRUE is the widget destroyed. By
+       default, 'gtk_widget_event' will return FALSE causing the window
+       to not be destroyed. This prevents segfaults in the GIMP and other
+       programs that do not correctly handle GDK_DELETE events.
+
+       * gtkmain.c: Added modal dialog support by allowing events
+       destined for a child of the grab widget to go to the child instead
+       of the grab widget. (Added 'gtk_widget_is_ancestor' to determine
+       the relationship between the grab widget and the event widget).
+
+       * *.[ch]: Incorprated a whole mess of patches. (Started keeping
+       the ChangeLog up to date again).
+
+Thu Jun  5 17:22:21 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenufactory.c:
+       * gtkmenufactory.h: Added 'gtk_menu_factory_remove_*'
+       calls. Removing entries/paths causes the associated widgets to be
+       destroyed.
+
+       * gtkwidget.c:
+       * gtkwidget.h: Calling 'gtk_widget_set_style' is used as an
+       indication that the programmer specifically wants that style to be
+       used. RC-style substitution is disabled for the widget after such
+       a call.
+
+       * gtkpixmap.c:
+       * gtkpixmap.h:
+       * gtkimage.c:
+       * gtkimage.h: Changed to use clip mask and a single pixmap (or
+       image) to deal with transparent areas.
+
+       * gdkpixmap.c: Modified xpm loading routines to optionally return
+       a clip mask.
+
+       * gdkgc.c:
+       * gdkdraw.c:
+       * gdktypes.h: Modifications to allow clip masks to be used with
+       gc's. Clip masks are bitmaps that specify drawable regions.
+
+Thu May  1 03:11:51 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkscrolledwindow.c: Scrolled windows need to have the
+       GTK_NO_WINDOW flag set. Not having it set caused an obscure
+       redrawing bug.
+
+Wed Apr 30 12:38:03 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkhruler.c:
+       * gtkvruler.c: Fixed a small bug that caused the indicator to be
+       positioned slightly off.
+
+Sun Apr 27 14:28:21 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenushell.c:
+       * gtkmenushell.h:
+       * gtkmenu.c:
+       * gtkmenu.h: Changes so that if a menu is popped up there is a
+       timeout period during which a menu item will not be activated and
+       if the mouse button is released in that period the menu will stay
+       popped up.
+
+       * gtkcurve.c:
+       * gtkcurve.h: Included curve widget courtesy of David
+       Mosberger-Tang (davidm@azstarnet.com).
+
+       * gtkentry.c:
+       * gtkentry.h: Changed "insert" and "delete" signals to
+       "insert_text" and "delete_text" respectively. (The symbol "delete"
+       cannot be used since it is a C++ reserved word).
+
+Sat Apr 19 01:43:49 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenufactory.c: A path which ends in "<nothing>" will cause an
+       invisible (hidden) menu entry to be created. This is useful for
+       setting an accelerator key for which a corresponding menu entry is
+       not desired.
+
+       * gtktooltips.c: Fixed some problems with destruction of the
+       active tip widget not properly updating the tooltips data
+       structures.
+
+Fri Apr 18 15:09:45 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkcontainer.c:
+       * gtklist.c:
+       * gtkwidget.c:
+       * gtkwidget.h: Patch from Owen Taylor (owt1@cornell.edu) which
+       fixes problems with destruction of objects and with destruction of
+       objects which hold the focus.
+
+Thu Apr 17 11:29:15 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenushell.c: Incorrect logic in
+       'gtk_menu_shell_button_release' for deciding when a menu should
+       stay popped up when the mouse button is released.
+
+       * *.c: Miscellaneous fixes from folks on the net.
+
+Tue Apr 15 02:43:17 1997  Peter Mattis  <pmattis@localhost>
+
+       * *.c:
+       * gtkwidget.h: Added GTK_BASIC widget flag which when set
+       specifies a widget as "basic". A "basic" widget is one which
+       doesn't take input events. For example, labels, pixmaps, boxes,
+       tables, alignments, etc.
+
+Sat Apr 12 15:23:08 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkcolorsel.c: Add "#include <math.h>" to define M_PI.
+
+       * gtksignal.c: Fixed a bug in 'gtk_signal_emit' which showed up
+       because of the new cast checking macros. The 'object' was being
+       accessed after it had been destroyed.
+
+       * gtkoptionmenu.c: Fixed bug with using 'GTK_BIN' instead of
+       'GTK_BUTTON' which showed up because of the new cast checking
+       macros.
+
+       * *.h: 'GTK_CHECK_CAST', 'GTK_CHECK_CLASS_CAST' and
+       'GTK_CHECK_TYPE' used by standard widget macros everywhere.
+
+Wed Apr  9 00:54:17 1997  Peter Mattis  <pmattis@localhost>
+
+       * docs/gtk.texi: Started further work on documentation. Major
+       changes and additions are being made.
+
+       * gtkarrow.c:
+       * gtkarrow.h: Removed function 'gtk_arrow_get'.
+
+       * gtkcontainer.c: 'gtk_container_check_resize' no performs
+       additional checking to account for the case where the containers
+       allocation is no longer sufficient because its parent (or its
+       parents parent, etc.) needs to resize its children.
+
+Tue Apr  8 21:15:50 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkstyle.c: Fixed a bug in 'gtk_style_init' in which the font
+       was not ref'd (via 'gdk_font_ref'), but was free'd (via in
+       'gdk_font_free') in 'gtk_style_destroy'. (David
+       Mosberger-Tang). Also cleaned up 'gtk_style_destroy' while I was
+       at it.
+
+       * gtkmain.c: Fixed a bug in 'gtk_propogate_event' which caused
+       entry widgets (and probably other widgets) not to be destroyed in
+       some instances.
+
+Mon Apr  7 01:20:38 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkentry.c:
+       * gtkentry.h: Changed the "insert_text", "delete_text" and
+       "changed_text" signals to "insert", "delete", and "changed"
+       respectively. They really should have been named this way
+       originally except the previous signal mechanism prevented
+       duplicate signal names. ("changed" is also used by adjustments).
+
+       * gtkradiomenuitem.c:
+       * gtkradiomenuitem.h: New widget.
+
+       * gtkcheckmenuitem.c:
+       * gtkcheckmenuitem.h: New widget.
+
+       * gtksignal.c: Modified 'gtk_signal_lookup' to require an object
+       type to be passed as a parameter. In addition, signals are now
+       only needed to be uniquely defined in their branch of the class
+       hierarchy. This allows the same signal name to be used in two
+       different branches of the class hierarchy. For instance, the
+       "changed" signal is used both by adjustments and entries...in
+       different ways!
+
+       * gtktypeutils.c: Added 'gtk_type_parent' which returns the parent
+       type for a given type.
+
+Sun Apr  6 22:08:35 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwidget.c: If a widget is set insensitive it loses the focus
+       if it had it.
+
+       * gtkcontainer.c: Insensitive widgets no longer participate in tab
+       traversal.
+
+       * gtkscrolledwindow.c: The "viewport" child is now destroyed and a
+       container class "foreach" function was written (which fixes the
+       sensitivity bug).
+
+Sat Apr  5 14:25:38 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkhscrollbar.c:
+       * gtkvscrollbar.c: Fixed trough size allocation bug.
+
+       * gtkhscale.c:
+       * gtkvscale.c: Fixed trough size allocation and position bug that
+       showed up when scales were placed in notebooks.
+
+Thu Mar 27 17:45:54 1997  David Mosberger-Tang  <davidm@azstarnet.com>
+
+        * gtk/gtkmain.c (gtk_handle_idle): Fix appending pending_idles to
+        idle_functions so it works even when idle_functions is empty.
+
+Sat Mar 15 14:15:59 1997  Peter Mattis  <pmattis@localhost>
+
+       * *.[ch]: Moved '*_class_init' and '*_init' function declarations
+       for widgets into the source file as those functions no longer had
+       to be public.
+
+       * gtkcheckbutton.c: Fixed redrawing of check button.
+
+       * gtkframe.c: Fixed redrawing of frame when the shadow type is
+       changed.
+
+Sat Mar  8 15:19:23 1997  Peter Mattis  <pmattis@localhost>
+
+       * gdkimage.c: Fixed a stupid bug with 'gdk_image_new' which
+       potentially added a NULL image to "image_list" and caused problems
+       when 'gdk_image_exit' was called.
+
+Wed Mar  5 00:40:08 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkpreview.c: Massively changed the colormap handling used by
+       the preview widget. Gray previews are now dithered. A single
+       visual and colormap is shared by the color and gray previews. A
+       GTK_PREVIEW_INFO property is installed on the root window in
+       certain cases to allow multiple GTK programs to share the system
+       colormap.
+
+Sun Mar  2 05:43:06 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkcheckbutton.c: 'gtk_checkbutton_size_allocate' was allocating
+       too much space to its children and not leaving the check button
+       room for the focus border.
+
+       * gtknotebook.c: 'gtk_notebook_size_request' wasn't requesting
+       enough space when the notebook tabs are visible.
+
+Sat Mar  1 01:59:35 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkpreview.c: Fixed a problem with 'gtk_preview_put' when the
+       image byte order is GDK_MSB_FIRST.
+
+       * gtksignal.c:
+       * gtksignal.h: Added 'gtk_signal_connect_after' and
+       'gtk_signal_connect_object_after' functions. These connect signal
+       handlers which will run after the class function associated with
+       the signal.
+
+       * gtkstyle.c: Fixed a stupid bug in 'gtk_style_new_from_key' that
+       was causing twice as many styles to be created as necesary.
+
+       * gtkwidget.c: 'gtk_real_widget_size_allocate' erases the widgets
+       old allocation if it has the GTK_NO_WINDOW flag set.
+
+       * gtkwidget.c: 'gtk_real_widget_unmap' now erases the widget if it
+       has the GTK_NO_WINDOW flag set.
+
+       * gtklabel.c: Removed 'gtk_label_unmap' as similar functionality
+       was added to gtk_real_widget_unmap.
+
+       * gtkbin.c: Modified 'gtk_bin_map' and 'gtk_bin_unmap' so that it
+       erases and draws the widget if it has the GTK_NO_WINDOW flag set.
+
+       * gtkframe.c: Modified 'gtk_frame_size_allocate' so that it erases
+       the old allocation.
+
+Fri Feb 28 03:27:05 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwindow.c: 'gtk_window_set_title' now changes the window title
+       if the window is already realized.
+
+       * gtkentry.c: 'gtk_entry_set_text' was emitting both a
+       "delete_text" and a "changed_text" signal. Modified so that it
+       only emits a "changed_text" signal.
+
+       * gtkpreview.c: Modified to work correctly on systems with MSB
+       byte order. The colormap for TRUE and DIRECT color displays is now
+       created if the default visual is not equal to the visual we are
+       using.
+
+       * gtkstyle.c: 'gtk_style_attach' and 'gtk_style_find' weren't
+       working properly in the presence of multiple colormaps are
+       different depth visuals.
+
+       * gtkcontainer.c: Massively improved focus traversal using tab and
+       arrow keys. It now uses the layout of the widgets to determine
+       where to move the focus to.
+
+Mon Feb 24 03:24:02 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenufactory.c: Set the accelerator table field for menus when
+       they are created.
+
+       * gtkmenu.c:
+       * gtkmenu.h: Added a default accelerator table field to menus so
+       that runtime modification of accelerator keys in menus can work
+       better.
+
+       * gtkrange.c: 'gtk_range_default_{h,v}motion' had faulty logic for
+       deciding what to do when the slider was at the edge of the
+       trough. They previously didn't update the adjustment value event
+       if the value wasn't what it should be when the slider was at the
+       edge of the trough.
+
+       * gtkviewport.c: 'gtk_viewport_size_allocate' and
+       'gtk_viewport_adjustment_value_changed' both had the potential for
+       performing a divide by 0. Checks are now in place to prevent this.
+
+       * gtkmenu.c: 'gtk_menu_map' now makes sure the menu lies on screen
+       if the position function is NULL.
+
+       * gtkentry.c: Modified selection handling. 'gtk_delete_selection'
+       actually removes the X selection now. 'gtk_entry_destroy' removes
+       the selection as well and relies on the change in "gdk.c" to make
+       sure the selection event will not be sent to a non-existant
+       window.
+
+       * gdk.c: Selection events are only passed on if the selection
+       owner is not NULL.
+
+       * gtkstyle.c: 'gtk_style_detach' and 'gtk_style_destroy' were not
+       destroying the black and white gc's.
+
+Sun Feb 23 19:17:56 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwindow.c: 'gtk_window_size_request' was setting the window
+       hints. This was also being done in 'gtk_window_map', so the
+       instance being done in 'gtk_window_size_request' was removed.
+
+Fri Feb 21 01:04:01 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwidget.c: 'gtk_widget_draw' has to use the widgets allocated
+       position for the drawing rectangle when the widget has the
+       GTK_NO_WINDOW flag set.
+
+       * gtkwidget.c: In 'gtk_widget_init' the visual and colormap were
+       being directly compared against 'default_visual' and
+       'default_colormap' instead of calling
+       'gtk_widget_get_default_{visual,colormap}'.
+
+       * gdkrectangle.c: Amazing! There was a bug in the
+       'gtk_rectangle_intersect' logic. Its been there for near eternity
+       and I never noticed.
+
+       * gtkpreview.c:
+       * gtkpreview.h: Created preview widget which allows drawing to an
+       rgb or grayscale buffer which is automatically displayed on the
+       screen. Performs dithering as necessary.
+
+Thu Feb 20 20:33:21 1997  Peter Mattis  <pmattis@localhost>
+
+       * gdkwindow.c: Modified the logic in 'gdk_window_new' which
+       determined when to add a window to the WM_COLORMAP_WINDOWS
+       property.
+
+Wed Feb 19 19:55:29 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkruler.c: 'gtk_ruler_make_pixmap' was always destroying the
+       old backing store and creating a new one even when it would create
+       a new one of exactly the same size as the old one.
+
+Tue Feb 18 18:32:10 1997  Peter Mattis  <pmattis@localhost>
+
+       * gmem.c: 'g_mem_chunk_alloc' was incorrectly modifying the mem
+       areas free mem field when reallocating a previously freed
+       atom. This caused a fairly severe memory leak.
+
+       * gtkmenushell.c: 'gtk_menu_shell_button_release' had a bug in the
+       logic for deciding whether to initiate an X pointer grab or not
+       when the mouse button was released. It now only initiates a grab
+       if the mouse is released within an active menu item.
+
+Fri Feb 14 00:57:40 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtknotebook.c: Changed the look of notebook tabs slightly.
+
+       * gtkentry.c:
+       * gtkentry.h: Deleting an entry widget which is holding the X
+       selection presents some difficulties. The X selection must be
+       released, but the widget can't be destroyed until the
+       SELECTION_CLEAR event is received that the X server will send in
+       response to clearing the X selection. There are probably still
+       bugs in the current method of entry widget deletion when the X
+       selection is held.
+
+       * gtkmain.c: 'gtk_propagate_event' was not properly destroying the
+       toplevel window when receiving a key press event.
+
+       * gtkwidget.c: Setting a widget insensitive did not cause it to
+       redraw. It now does.
+
+Thu Feb 13 16:59:07 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkviewport.c: 'gtk_viewport_size_allocate' was allocating its
+       child widget an adjusted allocation. Since the actual scrolling
+       has handled by a subwindow this caused the child to be double
+       scrolled. Modified to always set the child allocations origin to
+       (0, 0).
+
+Wed Feb 12 01:06:48 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkentry.c: Text is now centered vertically. Previously it was
+       pushed up against the top. This problem was only evident when the
+       widget was allocated more vertical space than it requested.
+
+       * gtkfilesel.c: 'gtk_file_selection_key_press' was previously only
+       a stub for tab completion. The actual tab completion call had been
+       left out. (Oops!)
+
+Tue Feb 11 01:43:08 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtksignal.c: 'gtk_signal_disconnect_by_data' was going into a
+       loop and crashing. Bad logic. Fixed.
+
+       * gtkmain.c: An idle function which returns FALSE will be removed
+       from the list of idle functions. This makes the functioning of
+       idle functions and timeouts more similar.
+
+       * gtkentry.c: 'gtk_entry_get_text' now returns an empty string
+       when the actual text is NULL. This allows "stupid" programs to use
+       the value returned by 'gtk_entry_get_text' blindly (without
+       checking to see if its NULL).
+
+       * gtkradiobutton.c: Modified 'gtk_radio_button_clicked' so that
+       'gtk_toggle_button_toggled' is called _after_ the widget state is
+       changed.
+
+       * gtksignal.c:
+       * gtksignal.h: Added 'gtk_signal_name' which returns the character
+       string name for a given signal number.
+
+       * gtkwidget.c: 'gtk_widget_set_parent' checks to see if the widget
+       is now "anchored" through the parent chain to a widget which is
+       GTK_ANCHORED. If it is, then it changes the widgets style using
+       'gtk_rc_get_style' and recursively performs the same operation on
+       the widgets children. This is necessary is 'gtk_rc_get_style' only
+       works properly on "anchored" widgets.
+
+       * gtkwindow.c: Modified GTK_WIN_POS logic so that it is only used
+       immediately after the window has been shown.
+
+       * gtkmenu.c: 'gtk_menu_key_press'. Can now change menu item
+       accelerator keys on the fly. Why? Why not. Cool/useless feature of
+       the day.
+
+       * gtkmenuitem.c: Accelerator key drawing. Somehow that never got
+       finished. (Oops!)
+
+       * gtkdrawingarea.c: 'gtk_drawing_area_size_allocate' was not
+       actually installed during 'gtk_drawing_area_class_init'. (Oops!)
+
+       * gtkframe.c: 'gtk_frame_size_request' fixed size requisition
+       problem caused by unsigned arithmetic.
+
+       * gtkwindow.c: Modified window widget so that it only uses the
+       widget uposition auxiliary information immediately after it has
+       been shown. This prevents the annoying bug which can cause a
+       uposition'ed window to jump back to its original position after
+       the user moves it.
+
+       * gtkwidget.c: Need to ref and unref style in
+       'gtk_widget_{push,pop}_style' to make sure that a style on the
+       style stack is not destroyed.
+
+       * gtktogglebutton.c: 'gtk_toggle_button_set_state' now calls
+       gtk_button_clicked to actually change the state of the
+       button. In this way, radio buttons can now perform the appropriate
+       actions when the toggle button state is set.
+
+Mon Feb 10 00:27:39 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtklist.c: 'gtk_list_select_item' and 'gtk_list_unselect_item'
+       were casting a GList* variable to a a GtkWidget* variable. Bad bad
+       bad. (Tim Janik).
+
+       * gtksignal.c: Modified 'gtk_signal_connect' and
+       'gtk_signal_connect_object' to warn when a signal type cannot be
+       found.
+
+Sun Feb  9 00:15:30 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkoptionmenu.c:
+       * gtkoptionmenu.h: Changed option menus back to being derived from
+       buttons. This fixes up some screwiness with their user
+       interaction.
+
+       * gtkwindow.c: Modified key press handler to support focus
+       traversal.
+
+       * gtkcontainer.c:
+       * gtkcontainer.h: Added default focus traversal back in.
+
+Sat Feb  8 10:44:38 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkviewport.h:
+       * gtkviewport.c: Massively sped up viewport scrolling. Used to be
+       reallocating child's size (offset) each time a scrollbar
+       moved. Now a subwindow is moved. All the children are moved
+       automatically by moving the subwindow. Much much much faster.
+
+Tue Feb  4 00:20:44 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtree.c: Changed 'g_tree_node_search' to use a loop instead of
+       recursion.
+
+Mon Feb  3 11:30:03 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkbutton.c: Removed 'parent_destroy' global and replaced it
+       with 'parent_class' global to reflect style used in other
+       widgets.
+
+       * gtknotebook.c: Tab labels were being allocated less than their
+       requested size.
+
+       * gtkrange.c:
+       * gtkrange.h: Moved the "digits" field of scales into the range
+       type. The adjustment value for scales is truncated to the number
+       of visible digits instead of being left untouched.
+
+       * gtree.c: Fixed a bug in the AVL tree implementation. Single
+       rotations were always being performed during insertion. It is
+       sometimes necessary to perform a double rotation.
+
+       * gtklabel.c: Modified 'gtk_label_expose' to only draw the label
+       when the allocated space is greater than or equal to the requested
+       space.
+
+       * gtklabel.c: Added call to 'gtk_widget_unmap' to
+       'gtk_label_destroy' in order for the label to redraw correctly
+       (erase itself) when destroyed.
+
+       * gtklabel.c: Added 'gtk_label_unmap' call which erases the labels
+       allocation when it gets unmapped.
+
+       * *.h: Removed a few remaining instances of using "class" as a
+       parameter name. (Causes problems for C++).
+
+Fri Jan 31 12:26:50 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkcontainer.c: 'gtk_container_enable_resize' needs to call
+       'gtk_container_check_resize' instead of
+       'gtk_container_need_resize'.
+
+       * gtkwidget.c: 'gtk_real_widget_show' now maps the widget if its
+       parent is mapped.
+
+       * gtkscrolledwindow.c: Fixed size allocation when the scrollbar
+       policy's are GTK_POLICY_AUTOMATIC. Doing it correctly is harder
+       than I originally thought.
+
+       * gtklist.c: Added 'gtk_list_child_position' to determine the
+       integer position in a list of a child. Filled in the
+       'gtk_list_item_select' and 'gtk_list_item_unselect' stubs.
+
+Thu Jan 30 16:08:06 1997  Peter Mattis  <pmattis@localhost>
+
+       * gmem.c: Changed the implementation of G_ALLOC_AND_FREE mem
+       chunks. They used to allocate SIZEOF_VOID_P extra bytes per atom
+       in order to keep track of which mem area they were allocated
+       from. Now the mem area is determined by searching through an AVL
+       tree of the mem areas for a mem chunk and comparing memory
+       locations. A little slower, but makes G_ALLOC_AND_FREE mem chunks
+       much more attractive.
+
+       * gtree.c: Added an AVL tree implementation to glib.
+
+       * gtksignal.c:
+       * gstring.c: va_arg (arg_list, {char, short}) is
+       invalid. Arguments passed in a variable argument list are
+       promoted. ({char, short}->int). Seemed to work ok before under
+       Linux. Crashed under FreeBSD.
+
+Tue Jan 28 02:27:51 1997  Peter Mattis  <pmattis@localhost>
+
+       * gdkwindow.c: Fixed a major slowdown apparent in the file
+       selection dialog which was caused by calling
+       'gtk_window_add_colormap_windows' way way way too often.
+
+       * *.c: Many widgets called 'gtk_container_need_resize' when
+       something internal changed which would cause the widget to grow or
+       shrink. The assumption was made that the widget would change size
+       and an expose event would be generated. This happens "most" of the
+       time. But its possible for certain widgets to change size without
+       generating expose events, or for its internal geometry to change
+       without a change of size which would mean no expose event was
+       generated. So a wrapper function called
+       'gtk_container_check_resize' was created and
+       'gtk_container_need_resize' was modified so that it returns FALSE
+       if a resize was actually generated and TRUE if nothing
+       changed. This allows 'gtk_container_check_resize' to initiate a
+       'gtk_widget_size_allocate' and 'gtk_widget_draw' to emulate the
+       expose event.
+
+Sat Jan 25 14:17:44 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmain.c: Fixed a bug with propogating key press events. The
+       events were sent 2 times to the toplevel windows which caused the
+       focus widget to be activated twice when the space bar was pressed.
+
+       * */configure.in:
+       * */Makefile.am: Added support for libtool and removed the old
+       shared library configuration craziness.
+
+Fri Jan 24 12:59:22 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtktext.c:
+       * gtktext.h: Josh's fixes and additions to the text widget.
+
+       * gtkfill.c:
+       * gtkfill.h: Filler widget useful for filling space in a
+       table. Can specify a minimum size. Used by the canvas widget.
+
+       * gtknotebook.c:
+       * gtknotebook.h: Made outline of notebook widget.
+
+       * gtkcanvas.c:
+       * gtkcanvas.h: Started canvas widget. A composite of 2 rulers (w/
+       an origin), 2 scrolllbars. Guides, grids, snap to.
+
+Sun Jan 19 18:26:45 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkdialog.c:
+       * gtkdialog.h: Created dialog widget which creates a standard
+       looking dialog with buttons along the button and a separator.
+
+       * gtkxid.c: Generalized the window table code for looking up a gdk
+       window based on an XID to work for any XID and a piece of
+       data. Can now look up gdk fonts based on their XID.
+
+       * gtkruler.c:
+       * gtkruler.h:
+       * gtkhruler.c:
+       * gtkhruler.h:
+       * gtkvruler.c:
+       * gtkvruler.h: Started conversion of the ruler widget.
+
+       * gtktext.c:
+       * gtktext.h: Started conversion of the text widget. Scrolling
+       doesn't work.
+
+       * gtkmain.c: Fixed a fairly major bug. The event widget needs to
+       be in a call for the entire duration of handling an event. Not
+       just for when the event widget itself is handling the event.
+
+       * gtkfilesel.c: Fixed up some bugs with resizing.
+
+Fri Jan 10 14:18:03 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwidget.c:
+       * gtkwidget.h:
+       * gtkentry.c:
+       * gtkentry.h: Support for selections.
+
+       * gdkselection.c:
+       * gdk.c:
+       * gdktypes.h:
+       * gdk.h: Gdk support for X selections. Currently only text
+       selections are supported.
+
+       * gtksignal.c: Fixed a major bug which occurred when destroying an
+       object. Memory was being written to after it was freed.
+
+       * gtkfilesel.c:
+       * gtkfilesel.h: Hooked up more functionality to the file selection
+       dialog.
+
+Wed Jan  8 18:13:53 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkfilesel.c:
+       * gtkfilesel.h: Mostly converted old file selection dialog
+       widget. The widget is derived from the GtkWindow class and is
+       quite a bit simpler in the widget code.
+
+       * gtkwidget.c: Fixed 'gtk_widget_grab_focus' and
+       'gtk_widget_grab_default' to check that the toplevel widget is a
+       type of window (which includes classes derived from windows).
+
+Tue Jan  7 01:12:32 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwindow.c: Was calling 'gtk_window_resize' twice in a
+       row...why?
+
+       * gtksignal.c:
+       * gtksignal.h:
+       * *.c: Changed 'gtk_signal_new' so that the class function that is
+       called when the signal is emitted can be called either before,
+       after or both before and after the calling of any signal
+       handlers.
+
+       * gtkobject.c:
+       * gtkobject.h: Added 'object_data' mechanism for storing data
+       associated with a character string key in objects. Removed
+       'user_data' field of objects and changed
+       'gtk_object_{get,set}_user_data' to use the object data
+       mechanism. Removed 'handlers' field of objects.
+
+       * gtkwidget.c:
+       * gtkwidget.h:
+       * gtkwindow.c: Modified aux info mechanism to use object data
+       mechanism.
+
+       * gtksignal.c: Modified signal mechanism to use object data
+       mechanism instead of 'handlers' field.
+
+
+Mon Jan  6 15:10:16 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenushell.c: Fixed up button press handling so as to conform
+       more closely to that used by Motif.
+
+Wed Jan  1 21:27:17 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenu.c:
+       * gtkmenu.h:
+       * gtkmenubar.c:
+       * gtkmenubar.h:
+       * gtkmenushell.c:
+       * gtkmenushell.h: Reorganization of menu-ing code so that code
+       duplication is reduced. The menu shell now contains most of the
+       code for menu-ing interaction while menus and menubars simply layout
+       their child menu items in the appropriate place.
+
+Sun Dec 29 17:48:18 1996  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenu.c:
+       * gtkmenubar.c:
+       * gtkmenuitem.h:
+       * gtkmenuitem.c: Modifications so that menu item accelerators and
+       the submenu indicator are drawn correctly and the correct amount
+       of space is allocated.
+
+Sat Dec 28 00:32:13 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtkmenufactory.h:
+       * gtkmenufactory.c: Started menu factories as an easy method to
+       create and manipulate menus.
+
+Fri Dec 27 13:17:34 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtkmenu.c:
+       * gtkmenu.h:
+       * gtkmenubar.c:
+       * gtkmenubar.h:
+       * gtkmenuitem.c:
+       * gtkmenuitem.h:
+       * gtkmenushell.c:
+       * gtkmenushell.h: Implemented basic menu functionality. Menubars
+       and popup menus work. Submenus work. (Much left to be done).
+
+Wed Dec 18 15:27:05 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtktypeutils.h:
+       * gtktypeutils.c: Added 'gtk_type_from_name' which returns a type
+       identifier given a type name. Implemented using a second hash
+       table keyed by type names.
+
+       * gtkbutton.c:
+       * gtktogglebutton.c: Fixed very small messed-up drawing bug when a
+       button loses its focus.
+
+       * gtkwidget.h:
+       * gtkwidget.c:
+       * gtkbutton.c:
+       * gtkwindow.c: Added default button handling. Default buttons now
+       draw correctly and pressing return or enter causes the default
+       button (if one exists) to be activated.
+
+Tue Dec 17 19:32:21 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtkhscale.c:
+       * gtkvscale.c: Overrode 'draw_slider' method of ranges in order to
+       draw the slider of scales with a line in them so as to be closer
+       to the Motif look-and-feel.
+
+       * gtkwindow.c: Modified 'gtk_window_focus_in_event' so that focus
+       in events are only handled when the window is visible. Fixes a bug
+       where spurious focus in events get sent when a window is being
+       hidden.
+
+       * gtkwidget.h: Added 'activate_signal' field to the GtkWidgetClass
+       structure. Added 'gtk_widget_activate' call to emit the activate
+       signal for a widget if it is non-zero.
+
+Tue Dec 10 15:59:45 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtkwidget.c: 'gtk_widget_set_name' oops in strdup'ing the old
+       "widget->name" instead of the new one we are setting.
+
+       * gtkrc.c: 'gtk_rc_widget_path' changed to use
+       'gtk_widget_get_name' instead of accessing the "widget->name"
+       field directly.
+
+       * gtkwidget.c: Added 'gtk_widget_get_name' function which returns
+       the widgets name if it exists and the widgets type name if it does
+       not.
+
+       * gtkcheckbutton.c: Added 'gtk_check_button_draw'
+       function. Modified 'gtk_check_button_expose' to pass an expose
+       event to child instead of callings its draw function.
+
+       * gtkentry.c: 'gtk_entry_draw_text' why was "+1" being added to
+       the font->ascent to calculate the font position? This was wrong
+       and caused some characters in fonts to be clipped. (Notably "g").
+
+       * gtkentry.c: 'gtk_entry_realize' specify GTK_BUTTON1_MOTION_MASK
+       and GTK_POINTER_MOTION_HINT_MASK for _both_ windows.
+
+       * gtkmain.c: 'gtk_propagate_event' needs to set the GTK_IN_CALL
+       flag for the object before calling 'gtk_widget_event' and needs to
+       destroy the object if necessary after 'gtk_widget_event' returns.
+
+       * gtkradiobutton.c: 'gtk_radio_button_clicked' needs to call
+       'gtk_toggle_button_toggled' when the currently active button is
+       toggled.
+
+       * gtkwidget.c: 'gtk_real_widget_hide' needs to call
+       'gtk_widget_unmap' if the widget is currently mapped.
+
+       * gtkwindow.c: Prevent automatic resizing after the user has
+       specified a new window size. Add 'handling_resize' flag to
+       windows.
+
+       * gtkscrolledwindow.c: Implement the GTK_POLICY_AUTOMATIC
+       scrollbar policy. Need to connect to the adjustments 'changed'
+       signal and notice when the scrollbars aren't in use.
+
+       * gtkcontainer.c: 'gtk_container_init' must set 'auto_resize' and
+       'need_resize' fields to TRUE and FALSE respectively.
+
+       * gtkwidget.c: 'gtk_widget_set_parent' must all set a widgets state
+       to its parents state.
+
+Sun Dec  1 01:31:01 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * Started ChangeLog
diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10
new file mode 100644 (file)
index 0000000..a065ebe
--- /dev/null
@@ -0,0 +1,1140 @@
+Mon Nov 17 1997 Jay Painter <jpaint@serv.net>
+       * gtkviewport.c: Raph's Mon, 10 Nov 1997 patch to gtk-list 
+       to fix some viewport bugs
+
+Mon Nov 17 1997 Jay Painter <jpaint@serv.net>
+       * gtk/gtkwidget.c: gtk-ajaborsk-971016-2
+       A little patch again to prevent user to use gtk_widget_set_events()
+       when a widget is already realized.
+       In this case, the gtk_widget_set_events() doesn't work.
+
+Mon Nov 17 1997 Jay Painter <jpaint@serv.net>
+       * gtk/gtkwindow.c: gtk-ajaborsk-971016-1
+       This small patch correct position for GTK_WIN_POS_CENTER and
+       GTK_WIN_POS_MOUSE GtkWindow positions.
+
+Sat Nov 15 1997 Jay Painter <jpaint@serv.net>
+       * gdk/gdkgc.c: added function gdk_gc_set_clip_rectangle
+       * gdk/gdk.h: header for above
+
+Sat Nov 15 1997 Jay Painter <jpaint@serv.net>
+       * gdk/gdkgc.c: added function gdk_gc_set_clip_rectangle
+       * gdk/gdk.h: header for above
+
+Wed Nov 12 1997 Jay Painter <jpaint@serv.net>
+       * gdk/gdkpixmap.c: Patrice Fortier's patch for transparent pixmaps.
+       * gdk/gdk.h:
+         gdk/gdkdraw.c: Patrice Fortier's patch to add pixel draw function.
+
+Sun Nov  9 1997 Jay Painter <jpaint@serv.net>
+       * Fixed problems with makefiles relating to the bug
+       which required glib to be installed.
+       * Fixed makefiles to incluce the xpm's in gtk+/gtk needed
+       for testgtk.
+       * Updated gtk+ and gtk+/glib to libtool-1.0f
+
+Fri Nov  7 1997 Jay Painter <jpaint@serv.net>
+       * gtk/gtktext.c: return char_widths[ch & 0xff]; in line 2152
+
+Thr Nov  5 1997 Jay Painter <jpaint@serv.net>
+       * gtk/testgtk.c: added drag and drop test, removed the test hack
+       from the button test
+
+Tue Nov  4 08:28:57 1997  Federico Mena  <federico@bananoid.nuclecu.unam.mx>
+
+       * gtk/gtkmain.c (gtk_handle_idle): Patch from David Mosberger to
+       avoid crashes when handling idle function (this manifested itself
+       in the Umax and Microtek backends in SANE.
+
+Sun Nov  2 07:34:56 1997  Tim Janik  <timj@psynet.net>
+
+       * gtk/gtkfilesel.c: Small fixes about a segmentation viaolation
+       cause by a double click in the directoy list (introduced by my
+       previous changes).
+       
+       * gtk/gtklist.c: Small fixes to gtk_list_add() and gtk_list_remove().
+       
+       * gtk/testgtk.c (list_add): Applied Stefan Wille's patch to make this
+       function do something ;).
+
+Fri Oct 31 Jay Painter <jpaint@serv.net>
+       *gdk/gdk.c: reformatted DND code for GTK coding standards
+       *gdk/gdkwindow.c: changed memory allocation for DND to q_mem stuff
+
+Thu Oct 30 Jay Painter <jpaint@serv.net>
+       * gdk/gdkwindow.c: 
+       * gdk/gdk/gdk.h:
+       * gtk/gtkwidget.h:
+       * gtk/gtkwidget.c: Applied Stephan Willie's shaped window patch
+
+       * gdk/gdkwindow: 
+       * gdk/gdk.h:
+       * gtk/gtkwidget.h:
+       * gtk/gtkwidget.c: reformatted the DND code to conform to GTK
+               coding standards
+
+       * gtk/testgtk: massive fixes, SW's shaped window example
+
+Thu Oct 30 07:33:27 1997  Tim Janik  <timj@psynet.net>
+
+       * gtk/gtklistitem.c (gtk_real_list_item_toggle): applied Johannes
+       Keukelaar's <johannes@nada.kth.se> patch for keyboard support in
+       GtkList widgets.
+
+       * gtk/gtkfilesel.c: adapted dir and file list selection
+       behaviour to deal with keyboard selections. this is a little
+       bit tricky: in the dir list it just changes the entrys value on a one
+       button press. but on a keyboard selection via gtk_widget_activate() it
+       does a new population (likewise on a double click) as this seems more
+       obvious.
+
+1997-10-25  Marius Vollmer  <mvo@zagadka.ping.de>
+
+       * gdk/gdkcolor.c (gdk_colormap_get_system): Initialize
+       private->ref_count.
+
+Wed Oct 22 09:47:43 1997  Tim Janik  <timj@psynet.net>
+
+       * gtk/gtkwindow.c (gtk_window_key_release_event): Fixed a stupid
+       bug that caused the key_release_event to be propagated twice.
+
+Sun Oct 12 11:01:43 1997  Tim Janik  <timj@psynet.net>
+
+        * acconfig.h:
+        * configure.in:
+       * gdk/gdkimage.c: Added configure check for IPC_RMID_DEFERRED_RELEASE,
+       because shmat() fails after a shmctl(..., IPC_RMID,...) for OSF1 V3.2,
+       SunOS 4.1.1, 5.5, 5.5.1, 5.6, IRIX 5.2 and 6.2.
+
+Mon Oct  6 11:59:07 1997  Federico Mena  <federico@bananoid.nuclecu.unam.mx>
+
+       * gdk/gdk.c (gdk_event_translate): In line 1693, fixed typo that
+       would cause motion notify events not to be delivered.
+
+Sun Oct  5 18:15:06 1997  Federico Mena  <federico@bananoid.nuclecu.unam.mx>
+
+       * gtk/gtkrc.c (gtk_rc_parse_bg_pixmap): Changed strdup() for
+       g_strdup().
+
+Wed Sep 24 17:16:34 1997  Peter Mattis  <pmattis@bjork.inktomi.com>
+
+       * configure.in: Fixed a stupid error in the test for libXext that
+       would cause it to fail if X_EXTRA_LIBS was not empty.
+
+       * gtk/gtkmain.h (gtk-timj-970919.patch):
+       * gtk/gtkmain.c (gtk-timj-970919.patch): new function
+       `gtk_idle_remove_by_data' to remove all idle callbacks that take a
+       specific piece of data as argument.  (gtk_get_current_event):
+       remove idles through gtk_idle_remove_by_data.
+        
+       * gtk/gtkwidget.c (gtk-timj-970919.patch):
+        (gtk_widget_destroy): remove pending idles for
+        widgets that have GTK_REDRAW_PENDING or GTK_RESIZE_PENDING and
+        GTK_ANCHORED set (only anchored widgets can have a resize queue
+        handler pending). widgets that have GTK_RESIZE_NEEDED will be removed
+        from their anchored toplevels `resize_widgets' list.
+        
+        (gtk_widget_queue_draw): let the widget remember the queue handler
+        tag (through `redraw_handler_key') for later call to `gtk_idle_remove'.
+        
+        (gtk_widget_queue_resize): let the widget remember the queue handler
+        tag (through `resize_handler_key') for later call to `gtk_idle_remove'.
+        corrected referencing the toplevel widget for which the handler is
+        pending. if a widget is added to the `resize_widgets' list of a
+        toplevel widget, GTK_RESIZE_NEEDED is set and it's referenced.
+        
+        (gtk_real_widget_queue_resize): on the deletion of the `resize_widgets'
+        list, unset GTK_RESIZE_NEEDED and unreference the removed widgets.
+        
+       * gtk/gtkwindow.c (gtk-timj-970919.patch):
+        (gtk_real_window_move_resize): move `resize_containers = NULL'
+        initialization out of if-statement.
+        while stepping through the `resize_widgets' list, unreference the
+        widgets and clear GTK_RESIZE_NEEDED. if a widget realy needs are
+        resize, they are flagged through GTK_RESIZE_NEEDED now (instead of
+        GTK_RESIZE_PENDING, as this is indicative for a pending handler).
+        added checks to provide segfaulting if a widgets parent pointer
+        is NULL (e.g. on toplevel widgets that have GTK_RESIZE_NEEDED set).
+
+Tue Sep 23 13:23:27 1997  Federico Mena  <federico@bananoid.nuclecu.unam.mx>
+
+       * gdk/gdkimage.c: Applied Tim Janik's patch to mark shm segments
+       as IPC_RMID so that they are automatically removed always.
+
+       * gdk/gdkfont.c: Removed casts from lvalues.
+
+       * gtk/gtkmain.c: Removed GTK_RETLOC_*() (which do a cast) from lvalues.
+
+       * gtk/gtkaccelerator.c (gtk_accelerator_table_remove): Added
+       "const" to the accelerator_key param to be consistent with the
+       declaration in gtkaccelerator.h.  The const is not useful in this
+       case, anyway.
+
+Tue Sep 16 13:11:06 1997  Peter Mattis  <pmattis@bjork.inktomi.com>
+
+       * gtkpreview.c: Andrew Logan Kieschnick's change to eliminate
+       round-off error when gamma is set to 1.0.
+
+       * gtkrange.c:
+       * gtkviewport.c: Jay Painter's changes to modify the way in which
+       viewports resize.
+
+       * gdkinput.c:
+       * gdkinputgxi.h:
+       * gdkinputxfree.h:
+       * gtk/Makefile.am:
+       * gtk.h:
+       * gtkeventbox.c:
+       * gtkeventbox.h: Owen Taylor's event box widget and fixes for X
+       input support (that I had broken).
+
+       * gdk.h:
+       * gdkwindow.c:
+       * gtksignal.h:
+       * gtksignal.c: Elliot Lee's changes to support Objective C. (id is
+       apparently a reserved word in Objective C).
+
+Sun Sep 14 22:33:15 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwidget.c (gtk_widget_queue_resize): If the toplevel container
+       is invisible we simply call "gtk_container_need_resize" on
+       it. This fixes a bug with option menus not redrawing correctly.
+
+       * gtkmenuitem.c (gtk_menu_item_enter): (gtk_menu_item_leave):
+       These functions now simply pass the event on to their parent. This
+       is necessary for menus to work properly due to the change in how
+       grabs are dealts with.
+
+       * gtkwindow.c (gtk_real_window_move_resize): Fixed a bug that
+       caused the GTK_RESIZE_PENDING flag to not be unset in some cases.
+
+Fri Sep  5 20:49:37 1997  Marius Vollmer  <mvo@zagadka.ping.de>
+
+       Bug fixes:
+
+       * Makefile.am: Added PATCHES to EXTRA_DIST.
+       * gtk/gtkpixmap.c (gtk_pixmap_new): Move the "pixmap != NULL" test
+       after the allocation of the pixmap.
+
+       To shut up the compiler:
+
+       * gtk/gtkfilesel.c (get_pwdb): Initialize home_dir.
+       * gtk/gtkmain.c (gtk_init): Replace comments around calls to
+       g_set_*_handler with "if (0)".
+       * gtk/gtkrc.c (gtk_rc_get_token): Initialize hex_number and
+       float_number.
+       * gtk/gtkwindow.c (gtk_window_key_press_event): Initialize
+       direction.
+
+       Changes to the type system in gtk/:
+
+       * Makefile.am: Added gtktypebuiltins.h to gtkinclude_HEADERS.
+       Added gtk.defs, runelisp, gentypeinfo.el and gtktypebuiltins.c to
+       EXTRA_DIST.  Added rules to generate gtktypebuiltins.* from
+       gtk.defs.
+
+       * runelisp, gentypeinfo.el, gtk.defs: New files.
+
+       * gtkaccelerator.c, gtkaccelerator.h (gtk_accelerator_table_ref):
+       Return the table so that this function can be used as the `copy'
+       function for GTK_TYPE_BOXED values.
+       * gtkstyle.c, gtkstyle.h (gtk_style_ref): Likewise.
+
+       * gtkenums.h: Removed GtkArgType enum.
+
+       * gtkmain.c (gtk_init): Call gtk_type_init to initialize the type
+       system.
+
+       * gtkobject.c (gtk_object_init_type): New function to take over
+       for gtk_object_get_type. (gtk_object_get_type): Just return the
+       constant GTK_TYPE_OBJECT. (gtk_object_collect_args): Do the right
+       thing for the new GTK_TYPE_* types.
+       * gtksignal.c (gtk_params_get): Likewise.
+
+       * gtktypeutils.c: (gtk_type_init_builtin_types): New
+       function. (gtk_type_init): Call it.  Also made non-static.
+       (gtk_type_unique): The allocation scheme for numerical ids has
+       changed: The low 8 bits hold the appropriate GtkFundamentalType of
+       a type, the rest is a globally unique sequence number.
+       (gtk_type_hash): Use the sequence number of a key to hash it.
+       (gtk_type_register_builtin): New function.
+
+       * gtktypeutils.h: (GtkFundamentalType): New enumeration of the
+       fundamental types. (GTK_TYPE_MAKE, GTK_FUNDAMENTAL_TYPE,
+       GTK_TYPE_SEQNO): New macros to work with the new id scheme.
+       (GtkArg): Added fields for new types and renamed old ones.  GtkArg
+       should now be a mostly opaque structure, except name and type.
+       (GTK_VALUE_*): New macros to access the values of a GtkArg.
+       (GTK_RETLOC_*): New macros to access the location of a return
+       value that is contained in a GtkArg.  * gtktypebuiltins.h: New
+       file to access the typeids of the builtin types.
+
+       * gtkwidget.h (GTK_TYPE_WIDGET): New macro to access the type id
+       of the widget class.
+
+       Thru out: Changed GTK_ARG_* to the appropriate GTK_TYPE_*.
+       Changed access to GtkArg structure to the appropriate GTK_VALUE_*
+       or GTK_RETLOC_* macro.  Changed GtkArgType to GtkType.  Changed
+       some guints to GtkType.
+
+       General changes in gtk/ to support interpreters:
+
+       * gtkradiobutton.c (gtk_radio_button_new_from_widget,
+       gtk_radio_button_new_with_label_from_widget): New functions.
+
+       * gtksignal.c (gtk_signal_connect_no_marshal): New function.
+       (struct _GtkHandler): Added no_marshal and destroy_func fields.
+       (gtk_signal_handler_new): Initialize them.
+       (gtk_signal_connect_by_type): Added no_marshal and destroy_func
+       arguments.  Changed all callers.
+       (gtk_signal_destroy): Invoke destroy_func if there is one and the
+       global destroy func does not apply.  (gtk_handlers_run): If the
+       handler has no_marshal set, call its function directly without
+       going thru the signal's marshaller.
+
+Wed Sep  3 09:56:22 1997  RHS Linux User  <pmattis@bjork.inktomi.com>
+
+       * gtkrange.c: Changed the way the range control focus was drawn so
+       that the range control is drawn correctly when it does not have
+       the focus.
+
+Tue Sep  2 17:41:17 1997  RHS Linux User  <pmattis@bjork.inktomi.com>
+
+       * gtkwidget.c: 'gtk_real_widget_queue_resize' should only remove
+       the "resize_widgets" if another resize is not pending.
+
+Mon Sep  1 18:28:08 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmain.c: Changed the way GDK_DELETE events are handled. Only,
+       if 'gtk_widget_event' returns TRUE is the widget destroyed. By
+       default, 'gtk_widget_event' will return FALSE causing the window
+       to not be destroyed. This prevents segfaults in the GIMP and other
+       programs that do not correctly handle GDK_DELETE events.
+
+       * gtkmain.c: Added modal dialog support by allowing events
+       destined for a child of the grab widget to go to the child instead
+       of the grab widget. (Added 'gtk_widget_is_ancestor' to determine
+       the relationship between the grab widget and the event widget).
+
+       * *.[ch]: Incorprated a whole mess of patches. (Started keeping
+       the ChangeLog up to date again).
+
+Thu Jun  5 17:22:21 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenufactory.c:
+       * gtkmenufactory.h: Added 'gtk_menu_factory_remove_*'
+       calls. Removing entries/paths causes the associated widgets to be
+       destroyed.
+
+       * gtkwidget.c:
+       * gtkwidget.h: Calling 'gtk_widget_set_style' is used as an
+       indication that the programmer specifically wants that style to be
+       used. RC-style substitution is disabled for the widget after such
+       a call.
+
+       * gtkpixmap.c:
+       * gtkpixmap.h:
+       * gtkimage.c:
+       * gtkimage.h: Changed to use clip mask and a single pixmap (or
+       image) to deal with transparent areas.
+
+       * gdkpixmap.c: Modified xpm loading routines to optionally return
+       a clip mask.
+
+       * gdkgc.c:
+       * gdkdraw.c:
+       * gdktypes.h: Modifications to allow clip masks to be used with
+       gc's. Clip masks are bitmaps that specify drawable regions.
+
+Thu May  1 03:11:51 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkscrolledwindow.c: Scrolled windows need to have the
+       GTK_NO_WINDOW flag set. Not having it set caused an obscure
+       redrawing bug.
+
+Wed Apr 30 12:38:03 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkhruler.c:
+       * gtkvruler.c: Fixed a small bug that caused the indicator to be
+       positioned slightly off.
+
+Sun Apr 27 14:28:21 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenushell.c:
+       * gtkmenushell.h:
+       * gtkmenu.c:
+       * gtkmenu.h: Changes so that if a menu is popped up there is a
+       timeout period during which a menu item will not be activated and
+       if the mouse button is released in that period the menu will stay
+       popped up.
+
+       * gtkcurve.c:
+       * gtkcurve.h: Included curve widget courtesy of David
+       Mosberger-Tang (davidm@azstarnet.com).
+
+       * gtkentry.c:
+       * gtkentry.h: Changed "insert" and "delete" signals to
+       "insert_text" and "delete_text" respectively. (The symbol "delete"
+       cannot be used since it is a C++ reserved word).
+
+Sat Apr 19 01:43:49 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenufactory.c: A path which ends in "<nothing>" will cause an
+       invisible (hidden) menu entry to be created. This is useful for
+       setting an accelerator key for which a corresponding menu entry is
+       not desired.
+
+       * gtktooltips.c: Fixed some problems with destruction of the
+       active tip widget not properly updating the tooltips data
+       structures.
+
+Fri Apr 18 15:09:45 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkcontainer.c:
+       * gtklist.c:
+       * gtkwidget.c:
+       * gtkwidget.h: Patch from Owen Taylor (owt1@cornell.edu) which
+       fixes problems with destruction of objects and with destruction of
+       objects which hold the focus.
+
+Thu Apr 17 11:29:15 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenushell.c: Incorrect logic in
+       'gtk_menu_shell_button_release' for deciding when a menu should
+       stay popped up when the mouse button is released.
+
+       * *.c: Miscellaneous fixes from folks on the net.
+
+Tue Apr 15 02:43:17 1997  Peter Mattis  <pmattis@localhost>
+
+       * *.c:
+       * gtkwidget.h: Added GTK_BASIC widget flag which when set
+       specifies a widget as "basic". A "basic" widget is one which
+       doesn't take input events. For example, labels, pixmaps, boxes,
+       tables, alignments, etc.
+
+Sat Apr 12 15:23:08 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkcolorsel.c: Add "#include <math.h>" to define M_PI.
+
+       * gtksignal.c: Fixed a bug in 'gtk_signal_emit' which showed up
+       because of the new cast checking macros. The 'object' was being
+       accessed after it had been destroyed.
+
+       * gtkoptionmenu.c: Fixed bug with using 'GTK_BIN' instead of
+       'GTK_BUTTON' which showed up because of the new cast checking
+       macros.
+
+       * *.h: 'GTK_CHECK_CAST', 'GTK_CHECK_CLASS_CAST' and
+       'GTK_CHECK_TYPE' used by standard widget macros everywhere.
+
+Wed Apr  9 00:54:17 1997  Peter Mattis  <pmattis@localhost>
+
+       * docs/gtk.texi: Started further work on documentation. Major
+       changes and additions are being made.
+
+       * gtkarrow.c:
+       * gtkarrow.h: Removed function 'gtk_arrow_get'.
+
+       * gtkcontainer.c: 'gtk_container_check_resize' no performs
+       additional checking to account for the case where the containers
+       allocation is no longer sufficient because its parent (or its
+       parents parent, etc.) needs to resize its children.
+
+Tue Apr  8 21:15:50 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkstyle.c: Fixed a bug in 'gtk_style_init' in which the font
+       was not ref'd (via 'gdk_font_ref'), but was free'd (via in
+       'gdk_font_free') in 'gtk_style_destroy'. (David
+       Mosberger-Tang). Also cleaned up 'gtk_style_destroy' while I was
+       at it.
+
+       * gtkmain.c: Fixed a bug in 'gtk_propogate_event' which caused
+       entry widgets (and probably other widgets) not to be destroyed in
+       some instances.
+
+Mon Apr  7 01:20:38 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkentry.c:
+       * gtkentry.h: Changed the "insert_text", "delete_text" and
+       "changed_text" signals to "insert", "delete", and "changed"
+       respectively. They really should have been named this way
+       originally except the previous signal mechanism prevented
+       duplicate signal names. ("changed" is also used by adjustments).
+
+       * gtkradiomenuitem.c:
+       * gtkradiomenuitem.h: New widget.
+
+       * gtkcheckmenuitem.c:
+       * gtkcheckmenuitem.h: New widget.
+
+       * gtksignal.c: Modified 'gtk_signal_lookup' to require an object
+       type to be passed as a parameter. In addition, signals are now
+       only needed to be uniquely defined in their branch of the class
+       hierarchy. This allows the same signal name to be used in two
+       different branches of the class hierarchy. For instance, the
+       "changed" signal is used both by adjustments and entries...in
+       different ways!
+
+       * gtktypeutils.c: Added 'gtk_type_parent' which returns the parent
+       type for a given type.
+
+Sun Apr  6 22:08:35 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwidget.c: If a widget is set insensitive it loses the focus
+       if it had it.
+
+       * gtkcontainer.c: Insensitive widgets no longer participate in tab
+       traversal.
+
+       * gtkscrolledwindow.c: The "viewport" child is now destroyed and a
+       container class "foreach" function was written (which fixes the
+       sensitivity bug).
+
+Sat Apr  5 14:25:38 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkhscrollbar.c:
+       * gtkvscrollbar.c: Fixed trough size allocation bug.
+
+       * gtkhscale.c:
+       * gtkvscale.c: Fixed trough size allocation and position bug that
+       showed up when scales were placed in notebooks.
+
+Thu Mar 27 17:45:54 1997  David Mosberger-Tang  <davidm@azstarnet.com>
+
+        * gtk/gtkmain.c (gtk_handle_idle): Fix appending pending_idles to
+        idle_functions so it works even when idle_functions is empty.
+
+Sat Mar 15 14:15:59 1997  Peter Mattis  <pmattis@localhost>
+
+       * *.[ch]: Moved '*_class_init' and '*_init' function declarations
+       for widgets into the source file as those functions no longer had
+       to be public.
+
+       * gtkcheckbutton.c: Fixed redrawing of check button.
+
+       * gtkframe.c: Fixed redrawing of frame when the shadow type is
+       changed.
+
+Sat Mar  8 15:19:23 1997  Peter Mattis  <pmattis@localhost>
+
+       * gdkimage.c: Fixed a stupid bug with 'gdk_image_new' which
+       potentially added a NULL image to "image_list" and caused problems
+       when 'gdk_image_exit' was called.
+
+Wed Mar  5 00:40:08 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkpreview.c: Massively changed the colormap handling used by
+       the preview widget. Gray previews are now dithered. A single
+       visual and colormap is shared by the color and gray previews. A
+       GTK_PREVIEW_INFO property is installed on the root window in
+       certain cases to allow multiple GTK programs to share the system
+       colormap.
+
+Sun Mar  2 05:43:06 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkcheckbutton.c: 'gtk_checkbutton_size_allocate' was allocating
+       too much space to its children and not leaving the check button
+       room for the focus border.
+
+       * gtknotebook.c: 'gtk_notebook_size_request' wasn't requesting
+       enough space when the notebook tabs are visible.
+
+Sat Mar  1 01:59:35 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkpreview.c: Fixed a problem with 'gtk_preview_put' when the
+       image byte order is GDK_MSB_FIRST.
+
+       * gtksignal.c:
+       * gtksignal.h: Added 'gtk_signal_connect_after' and
+       'gtk_signal_connect_object_after' functions. These connect signal
+       handlers which will run after the class function associated with
+       the signal.
+
+       * gtkstyle.c: Fixed a stupid bug in 'gtk_style_new_from_key' that
+       was causing twice as many styles to be created as necesary.
+
+       * gtkwidget.c: 'gtk_real_widget_size_allocate' erases the widgets
+       old allocation if it has the GTK_NO_WINDOW flag set.
+
+       * gtkwidget.c: 'gtk_real_widget_unmap' now erases the widget if it
+       has the GTK_NO_WINDOW flag set.
+
+       * gtklabel.c: Removed 'gtk_label_unmap' as similar functionality
+       was added to gtk_real_widget_unmap.
+
+       * gtkbin.c: Modified 'gtk_bin_map' and 'gtk_bin_unmap' so that it
+       erases and draws the widget if it has the GTK_NO_WINDOW flag set.
+
+       * gtkframe.c: Modified 'gtk_frame_size_allocate' so that it erases
+       the old allocation.
+
+Fri Feb 28 03:27:05 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwindow.c: 'gtk_window_set_title' now changes the window title
+       if the window is already realized.
+
+       * gtkentry.c: 'gtk_entry_set_text' was emitting both a
+       "delete_text" and a "changed_text" signal. Modified so that it
+       only emits a "changed_text" signal.
+
+       * gtkpreview.c: Modified to work correctly on systems with MSB
+       byte order. The colormap for TRUE and DIRECT color displays is now
+       created if the default visual is not equal to the visual we are
+       using.
+
+       * gtkstyle.c: 'gtk_style_attach' and 'gtk_style_find' weren't
+       working properly in the presence of multiple colormaps are
+       different depth visuals.
+
+       * gtkcontainer.c: Massively improved focus traversal using tab and
+       arrow keys. It now uses the layout of the widgets to determine
+       where to move the focus to.
+
+Mon Feb 24 03:24:02 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenufactory.c: Set the accelerator table field for menus when
+       they are created.
+
+       * gtkmenu.c:
+       * gtkmenu.h: Added a default accelerator table field to menus so
+       that runtime modification of accelerator keys in menus can work
+       better.
+
+       * gtkrange.c: 'gtk_range_default_{h,v}motion' had faulty logic for
+       deciding what to do when the slider was at the edge of the
+       trough. They previously didn't update the adjustment value event
+       if the value wasn't what it should be when the slider was at the
+       edge of the trough.
+
+       * gtkviewport.c: 'gtk_viewport_size_allocate' and
+       'gtk_viewport_adjustment_value_changed' both had the potential for
+       performing a divide by 0. Checks are now in place to prevent this.
+
+       * gtkmenu.c: 'gtk_menu_map' now makes sure the menu lies on screen
+       if the position function is NULL.
+
+       * gtkentry.c: Modified selection handling. 'gtk_delete_selection'
+       actually removes the X selection now. 'gtk_entry_destroy' removes
+       the selection as well and relies on the change in "gdk.c" to make
+       sure the selection event will not be sent to a non-existant
+       window.
+
+       * gdk.c: Selection events are only passed on if the selection
+       owner is not NULL.
+
+       * gtkstyle.c: 'gtk_style_detach' and 'gtk_style_destroy' were not
+       destroying the black and white gc's.
+
+Sun Feb 23 19:17:56 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwindow.c: 'gtk_window_size_request' was setting the window
+       hints. This was also being done in 'gtk_window_map', so the
+       instance being done in 'gtk_window_size_request' was removed.
+
+Fri Feb 21 01:04:01 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwidget.c: 'gtk_widget_draw' has to use the widgets allocated
+       position for the drawing rectangle when the widget has the
+       GTK_NO_WINDOW flag set.
+
+       * gtkwidget.c: In 'gtk_widget_init' the visual and colormap were
+       being directly compared against 'default_visual' and
+       'default_colormap' instead of calling
+       'gtk_widget_get_default_{visual,colormap}'.
+
+       * gdkrectangle.c: Amazing! There was a bug in the
+       'gtk_rectangle_intersect' logic. Its been there for near eternity
+       and I never noticed.
+
+       * gtkpreview.c:
+       * gtkpreview.h: Created preview widget which allows drawing to an
+       rgb or grayscale buffer which is automatically displayed on the
+       screen. Performs dithering as necessary.
+
+Thu Feb 20 20:33:21 1997  Peter Mattis  <pmattis@localhost>
+
+       * gdkwindow.c: Modified the logic in 'gdk_window_new' which
+       determined when to add a window to the WM_COLORMAP_WINDOWS
+       property.
+
+Wed Feb 19 19:55:29 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkruler.c: 'gtk_ruler_make_pixmap' was always destroying the
+       old backing store and creating a new one even when it would create
+       a new one of exactly the same size as the old one.
+
+Tue Feb 18 18:32:10 1997  Peter Mattis  <pmattis@localhost>
+
+       * gmem.c: 'g_mem_chunk_alloc' was incorrectly modifying the mem
+       areas free mem field when reallocating a previously freed
+       atom. This caused a fairly severe memory leak.
+
+       * gtkmenushell.c: 'gtk_menu_shell_button_release' had a bug in the
+       logic for deciding whether to initiate an X pointer grab or not
+       when the mouse button was released. It now only initiates a grab
+       if the mouse is released within an active menu item.
+
+Fri Feb 14 00:57:40 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtknotebook.c: Changed the look of notebook tabs slightly.
+
+       * gtkentry.c:
+       * gtkentry.h: Deleting an entry widget which is holding the X
+       selection presents some difficulties. The X selection must be
+       released, but the widget can't be destroyed until the
+       SELECTION_CLEAR event is received that the X server will send in
+       response to clearing the X selection. There are probably still
+       bugs in the current method of entry widget deletion when the X
+       selection is held.
+
+       * gtkmain.c: 'gtk_propagate_event' was not properly destroying the
+       toplevel window when receiving a key press event.
+
+       * gtkwidget.c: Setting a widget insensitive did not cause it to
+       redraw. It now does.
+
+Thu Feb 13 16:59:07 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkviewport.c: 'gtk_viewport_size_allocate' was allocating its
+       child widget an adjusted allocation. Since the actual scrolling
+       has handled by a subwindow this caused the child to be double
+       scrolled. Modified to always set the child allocations origin to
+       (0, 0).
+
+Wed Feb 12 01:06:48 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkentry.c: Text is now centered vertically. Previously it was
+       pushed up against the top. This problem was only evident when the
+       widget was allocated more vertical space than it requested.
+
+       * gtkfilesel.c: 'gtk_file_selection_key_press' was previously only
+       a stub for tab completion. The actual tab completion call had been
+       left out. (Oops!)
+
+Tue Feb 11 01:43:08 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtksignal.c: 'gtk_signal_disconnect_by_data' was going into a
+       loop and crashing. Bad logic. Fixed.
+
+       * gtkmain.c: An idle function which returns FALSE will be removed
+       from the list of idle functions. This makes the functioning of
+       idle functions and timeouts more similar.
+
+       * gtkentry.c: 'gtk_entry_get_text' now returns an empty string
+       when the actual text is NULL. This allows "stupid" programs to use
+       the value returned by 'gtk_entry_get_text' blindly (without
+       checking to see if its NULL).
+
+       * gtkradiobutton.c: Modified 'gtk_radio_button_clicked' so that
+       'gtk_toggle_button_toggled' is called _after_ the widget state is
+       changed.
+
+       * gtksignal.c:
+       * gtksignal.h: Added 'gtk_signal_name' which returns the character
+       string name for a given signal number.
+
+       * gtkwidget.c: 'gtk_widget_set_parent' checks to see if the widget
+       is now "anchored" through the parent chain to a widget which is
+       GTK_ANCHORED. If it is, then it changes the widgets style using
+       'gtk_rc_get_style' and recursively performs the same operation on
+       the widgets children. This is necessary is 'gtk_rc_get_style' only
+       works properly on "anchored" widgets.
+
+       * gtkwindow.c: Modified GTK_WIN_POS logic so that it is only used
+       immediately after the window has been shown.
+
+       * gtkmenu.c: 'gtk_menu_key_press'. Can now change menu item
+       accelerator keys on the fly. Why? Why not. Cool/useless feature of
+       the day.
+
+       * gtkmenuitem.c: Accelerator key drawing. Somehow that never got
+       finished. (Oops!)
+
+       * gtkdrawingarea.c: 'gtk_drawing_area_size_allocate' was not
+       actually installed during 'gtk_drawing_area_class_init'. (Oops!)
+
+       * gtkframe.c: 'gtk_frame_size_request' fixed size requisition
+       problem caused by unsigned arithmetic.
+
+       * gtkwindow.c: Modified window widget so that it only uses the
+       widget uposition auxiliary information immediately after it has
+       been shown. This prevents the annoying bug which can cause a
+       uposition'ed window to jump back to its original position after
+       the user moves it.
+
+       * gtkwidget.c: Need to ref and unref style in
+       'gtk_widget_{push,pop}_style' to make sure that a style on the
+       style stack is not destroyed.
+
+       * gtktogglebutton.c: 'gtk_toggle_button_set_state' now calls
+       gtk_button_clicked to actually change the state of the
+       button. In this way, radio buttons can now perform the appropriate
+       actions when the toggle button state is set.
+
+Mon Feb 10 00:27:39 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtklist.c: 'gtk_list_select_item' and 'gtk_list_unselect_item'
+       were casting a GList* variable to a a GtkWidget* variable. Bad bad
+       bad. (Tim Janik).
+
+       * gtksignal.c: Modified 'gtk_signal_connect' and
+       'gtk_signal_connect_object' to warn when a signal type cannot be
+       found.
+
+Sun Feb  9 00:15:30 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkoptionmenu.c:
+       * gtkoptionmenu.h: Changed option menus back to being derived from
+       buttons. This fixes up some screwiness with their user
+       interaction.
+
+       * gtkwindow.c: Modified key press handler to support focus
+       traversal.
+
+       * gtkcontainer.c:
+       * gtkcontainer.h: Added default focus traversal back in.
+
+Sat Feb  8 10:44:38 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkviewport.h:
+       * gtkviewport.c: Massively sped up viewport scrolling. Used to be
+       reallocating child's size (offset) each time a scrollbar
+       moved. Now a subwindow is moved. All the children are moved
+       automatically by moving the subwindow. Much much much faster.
+
+Tue Feb  4 00:20:44 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtree.c: Changed 'g_tree_node_search' to use a loop instead of
+       recursion.
+
+Mon Feb  3 11:30:03 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkbutton.c: Removed 'parent_destroy' global and replaced it
+       with 'parent_class' global to reflect style used in other
+       widgets.
+
+       * gtknotebook.c: Tab labels were being allocated less than their
+       requested size.
+
+       * gtkrange.c:
+       * gtkrange.h: Moved the "digits" field of scales into the range
+       type. The adjustment value for scales is truncated to the number
+       of visible digits instead of being left untouched.
+
+       * gtree.c: Fixed a bug in the AVL tree implementation. Single
+       rotations were always being performed during insertion. It is
+       sometimes necessary to perform a double rotation.
+
+       * gtklabel.c: Modified 'gtk_label_expose' to only draw the label
+       when the allocated space is greater than or equal to the requested
+       space.
+
+       * gtklabel.c: Added call to 'gtk_widget_unmap' to
+       'gtk_label_destroy' in order for the label to redraw correctly
+       (erase itself) when destroyed.
+
+       * gtklabel.c: Added 'gtk_label_unmap' call which erases the labels
+       allocation when it gets unmapped.
+
+       * *.h: Removed a few remaining instances of using "class" as a
+       parameter name. (Causes problems for C++).
+
+Fri Jan 31 12:26:50 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkcontainer.c: 'gtk_container_enable_resize' needs to call
+       'gtk_container_check_resize' instead of
+       'gtk_container_need_resize'.
+
+       * gtkwidget.c: 'gtk_real_widget_show' now maps the widget if its
+       parent is mapped.
+
+       * gtkscrolledwindow.c: Fixed size allocation when the scrollbar
+       policy's are GTK_POLICY_AUTOMATIC. Doing it correctly is harder
+       than I originally thought.
+
+       * gtklist.c: Added 'gtk_list_child_position' to determine the
+       integer position in a list of a child. Filled in the
+       'gtk_list_item_select' and 'gtk_list_item_unselect' stubs.
+
+Thu Jan 30 16:08:06 1997  Peter Mattis  <pmattis@localhost>
+
+       * gmem.c: Changed the implementation of G_ALLOC_AND_FREE mem
+       chunks. They used to allocate SIZEOF_VOID_P extra bytes per atom
+       in order to keep track of which mem area they were allocated
+       from. Now the mem area is determined by searching through an AVL
+       tree of the mem areas for a mem chunk and comparing memory
+       locations. A little slower, but makes G_ALLOC_AND_FREE mem chunks
+       much more attractive.
+
+       * gtree.c: Added an AVL tree implementation to glib.
+
+       * gtksignal.c:
+       * gstring.c: va_arg (arg_list, {char, short}) is
+       invalid. Arguments passed in a variable argument list are
+       promoted. ({char, short}->int). Seemed to work ok before under
+       Linux. Crashed under FreeBSD.
+
+Tue Jan 28 02:27:51 1997  Peter Mattis  <pmattis@localhost>
+
+       * gdkwindow.c: Fixed a major slowdown apparent in the file
+       selection dialog which was caused by calling
+       'gtk_window_add_colormap_windows' way way way too often.
+
+       * *.c: Many widgets called 'gtk_container_need_resize' when
+       something internal changed which would cause the widget to grow or
+       shrink. The assumption was made that the widget would change size
+       and an expose event would be generated. This happens "most" of the
+       time. But its possible for certain widgets to change size without
+       generating expose events, or for its internal geometry to change
+       without a change of size which would mean no expose event was
+       generated. So a wrapper function called
+       'gtk_container_check_resize' was created and
+       'gtk_container_need_resize' was modified so that it returns FALSE
+       if a resize was actually generated and TRUE if nothing
+       changed. This allows 'gtk_container_check_resize' to initiate a
+       'gtk_widget_size_allocate' and 'gtk_widget_draw' to emulate the
+       expose event.
+
+Sat Jan 25 14:17:44 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmain.c: Fixed a bug with propogating key press events. The
+       events were sent 2 times to the toplevel windows which caused the
+       focus widget to be activated twice when the space bar was pressed.
+
+       * */configure.in:
+       * */Makefile.am: Added support for libtool and removed the old
+       shared library configuration craziness.
+
+Fri Jan 24 12:59:22 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtktext.c:
+       * gtktext.h: Josh's fixes and additions to the text widget.
+
+       * gtkfill.c:
+       * gtkfill.h: Filler widget useful for filling space in a
+       table. Can specify a minimum size. Used by the canvas widget.
+
+       * gtknotebook.c:
+       * gtknotebook.h: Made outline of notebook widget.
+
+       * gtkcanvas.c:
+       * gtkcanvas.h: Started canvas widget. A composite of 2 rulers (w/
+       an origin), 2 scrolllbars. Guides, grids, snap to.
+
+Sun Jan 19 18:26:45 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkdialog.c:
+       * gtkdialog.h: Created dialog widget which creates a standard
+       looking dialog with buttons along the button and a separator.
+
+       * gtkxid.c: Generalized the window table code for looking up a gdk
+       window based on an XID to work for any XID and a piece of
+       data. Can now look up gdk fonts based on their XID.
+
+       * gtkruler.c:
+       * gtkruler.h:
+       * gtkhruler.c:
+       * gtkhruler.h:
+       * gtkvruler.c:
+       * gtkvruler.h: Started conversion of the ruler widget.
+
+       * gtktext.c:
+       * gtktext.h: Started conversion of the text widget. Scrolling
+       doesn't work.
+
+       * gtkmain.c: Fixed a fairly major bug. The event widget needs to
+       be in a call for the entire duration of handling an event. Not
+       just for when the event widget itself is handling the event.
+
+       * gtkfilesel.c: Fixed up some bugs with resizing.
+
+Fri Jan 10 14:18:03 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwidget.c:
+       * gtkwidget.h:
+       * gtkentry.c:
+       * gtkentry.h: Support for selections.
+
+       * gdkselection.c:
+       * gdk.c:
+       * gdktypes.h:
+       * gdk.h: Gdk support for X selections. Currently only text
+       selections are supported.
+
+       * gtksignal.c: Fixed a major bug which occurred when destroying an
+       object. Memory was being written to after it was freed.
+
+       * gtkfilesel.c:
+       * gtkfilesel.h: Hooked up more functionality to the file selection
+       dialog.
+
+Wed Jan  8 18:13:53 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkfilesel.c:
+       * gtkfilesel.h: Mostly converted old file selection dialog
+       widget. The widget is derived from the GtkWindow class and is
+       quite a bit simpler in the widget code.
+
+       * gtkwidget.c: Fixed 'gtk_widget_grab_focus' and
+       'gtk_widget_grab_default' to check that the toplevel widget is a
+       type of window (which includes classes derived from windows).
+
+Tue Jan  7 01:12:32 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwindow.c: Was calling 'gtk_window_resize' twice in a
+       row...why?
+
+       * gtksignal.c:
+       * gtksignal.h:
+       * *.c: Changed 'gtk_signal_new' so that the class function that is
+       called when the signal is emitted can be called either before,
+       after or both before and after the calling of any signal
+       handlers.
+
+       * gtkobject.c:
+       * gtkobject.h: Added 'object_data' mechanism for storing data
+       associated with a character string key in objects. Removed
+       'user_data' field of objects and changed
+       'gtk_object_{get,set}_user_data' to use the object data
+       mechanism. Removed 'handlers' field of objects.
+
+       * gtkwidget.c:
+       * gtkwidget.h:
+       * gtkwindow.c: Modified aux info mechanism to use object data
+       mechanism.
+
+       * gtksignal.c: Modified signal mechanism to use object data
+       mechanism instead of 'handlers' field.
+
+
+Mon Jan  6 15:10:16 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenushell.c: Fixed up button press handling so as to conform
+       more closely to that used by Motif.
+
+Wed Jan  1 21:27:17 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenu.c:
+       * gtkmenu.h:
+       * gtkmenubar.c:
+       * gtkmenubar.h:
+       * gtkmenushell.c:
+       * gtkmenushell.h: Reorganization of menu-ing code so that code
+       duplication is reduced. The menu shell now contains most of the
+       code for menu-ing interaction while menus and menubars simply layout
+       their child menu items in the appropriate place.
+
+Sun Dec 29 17:48:18 1996  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenu.c:
+       * gtkmenubar.c:
+       * gtkmenuitem.h:
+       * gtkmenuitem.c: Modifications so that menu item accelerators and
+       the submenu indicator are drawn correctly and the correct amount
+       of space is allocated.
+
+Sat Dec 28 00:32:13 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtkmenufactory.h:
+       * gtkmenufactory.c: Started menu factories as an easy method to
+       create and manipulate menus.
+
+Fri Dec 27 13:17:34 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtkmenu.c:
+       * gtkmenu.h:
+       * gtkmenubar.c:
+       * gtkmenubar.h:
+       * gtkmenuitem.c:
+       * gtkmenuitem.h:
+       * gtkmenushell.c:
+       * gtkmenushell.h: Implemented basic menu functionality. Menubars
+       and popup menus work. Submenus work. (Much left to be done).
+
+Wed Dec 18 15:27:05 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtktypeutils.h:
+       * gtktypeutils.c: Added 'gtk_type_from_name' which returns a type
+       identifier given a type name. Implemented using a second hash
+       table keyed by type names.
+
+       * gtkbutton.c:
+       * gtktogglebutton.c: Fixed very small messed-up drawing bug when a
+       button loses its focus.
+
+       * gtkwidget.h:
+       * gtkwidget.c:
+       * gtkbutton.c:
+       * gtkwindow.c: Added default button handling. Default buttons now
+       draw correctly and pressing return or enter causes the default
+       button (if one exists) to be activated.
+
+Tue Dec 17 19:32:21 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtkhscale.c:
+       * gtkvscale.c: Overrode 'draw_slider' method of ranges in order to
+       draw the slider of scales with a line in them so as to be closer
+       to the Motif look-and-feel.
+
+       * gtkwindow.c: Modified 'gtk_window_focus_in_event' so that focus
+       in events are only handled when the window is visible. Fixes a bug
+       where spurious focus in events get sent when a window is being
+       hidden.
+
+       * gtkwidget.h: Added 'activate_signal' field to the GtkWidgetClass
+       structure. Added 'gtk_widget_activate' call to emit the activate
+       signal for a widget if it is non-zero.
+
+Tue Dec 10 15:59:45 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtkwidget.c: 'gtk_widget_set_name' oops in strdup'ing the old
+       "widget->name" instead of the new one we are setting.
+
+       * gtkrc.c: 'gtk_rc_widget_path' changed to use
+       'gtk_widget_get_name' instead of accessing the "widget->name"
+       field directly.
+
+       * gtkwidget.c: Added 'gtk_widget_get_name' function which returns
+       the widgets name if it exists and the widgets type name if it does
+       not.
+
+       * gtkcheckbutton.c: Added 'gtk_check_button_draw'
+       function. Modified 'gtk_check_button_expose' to pass an expose
+       event to child instead of callings its draw function.
+
+       * gtkentry.c: 'gtk_entry_draw_text' why was "+1" being added to
+       the font->ascent to calculate the font position? This was wrong
+       and caused some characters in fonts to be clipped. (Notably "g").
+
+       * gtkentry.c: 'gtk_entry_realize' specify GTK_BUTTON1_MOTION_MASK
+       and GTK_POINTER_MOTION_HINT_MASK for _both_ windows.
+
+       * gtkmain.c: 'gtk_propagate_event' needs to set the GTK_IN_CALL
+       flag for the object before calling 'gtk_widget_event' and needs to
+       destroy the object if necessary after 'gtk_widget_event' returns.
+
+       * gtkradiobutton.c: 'gtk_radio_button_clicked' needs to call
+       'gtk_toggle_button_toggled' when the currently active button is
+       toggled.
+
+       * gtkwidget.c: 'gtk_real_widget_hide' needs to call
+       'gtk_widget_unmap' if the widget is currently mapped.
+
+       * gtkwindow.c: Prevent automatic resizing after the user has
+       specified a new window size. Add 'handling_resize' flag to
+       windows.
+
+       * gtkscrolledwindow.c: Implement the GTK_POLICY_AUTOMATIC
+       scrollbar policy. Need to connect to the adjustments 'changed'
+       signal and notice when the scrollbars aren't in use.
+
+       * gtkcontainer.c: 'gtk_container_init' must set 'auto_resize' and
+       'need_resize' fields to TRUE and FALSE respectively.
+
+       * gtkwidget.c: 'gtk_widget_set_parent' must all set a widgets state
+       to its parents state.
+
+Sun Dec  1 01:31:01 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * Started ChangeLog
diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2
new file mode 100644 (file)
index 0000000..a065ebe
--- /dev/null
@@ -0,0 +1,1140 @@
+Mon Nov 17 1997 Jay Painter <jpaint@serv.net>
+       * gtkviewport.c: Raph's Mon, 10 Nov 1997 patch to gtk-list 
+       to fix some viewport bugs
+
+Mon Nov 17 1997 Jay Painter <jpaint@serv.net>
+       * gtk/gtkwidget.c: gtk-ajaborsk-971016-2
+       A little patch again to prevent user to use gtk_widget_set_events()
+       when a widget is already realized.
+       In this case, the gtk_widget_set_events() doesn't work.
+
+Mon Nov 17 1997 Jay Painter <jpaint@serv.net>
+       * gtk/gtkwindow.c: gtk-ajaborsk-971016-1
+       This small patch correct position for GTK_WIN_POS_CENTER and
+       GTK_WIN_POS_MOUSE GtkWindow positions.
+
+Sat Nov 15 1997 Jay Painter <jpaint@serv.net>
+       * gdk/gdkgc.c: added function gdk_gc_set_clip_rectangle
+       * gdk/gdk.h: header for above
+
+Sat Nov 15 1997 Jay Painter <jpaint@serv.net>
+       * gdk/gdkgc.c: added function gdk_gc_set_clip_rectangle
+       * gdk/gdk.h: header for above
+
+Wed Nov 12 1997 Jay Painter <jpaint@serv.net>
+       * gdk/gdkpixmap.c: Patrice Fortier's patch for transparent pixmaps.
+       * gdk/gdk.h:
+         gdk/gdkdraw.c: Patrice Fortier's patch to add pixel draw function.
+
+Sun Nov  9 1997 Jay Painter <jpaint@serv.net>
+       * Fixed problems with makefiles relating to the bug
+       which required glib to be installed.
+       * Fixed makefiles to incluce the xpm's in gtk+/gtk needed
+       for testgtk.
+       * Updated gtk+ and gtk+/glib to libtool-1.0f
+
+Fri Nov  7 1997 Jay Painter <jpaint@serv.net>
+       * gtk/gtktext.c: return char_widths[ch & 0xff]; in line 2152
+
+Thr Nov  5 1997 Jay Painter <jpaint@serv.net>
+       * gtk/testgtk.c: added drag and drop test, removed the test hack
+       from the button test
+
+Tue Nov  4 08:28:57 1997  Federico Mena  <federico@bananoid.nuclecu.unam.mx>
+
+       * gtk/gtkmain.c (gtk_handle_idle): Patch from David Mosberger to
+       avoid crashes when handling idle function (this manifested itself
+       in the Umax and Microtek backends in SANE.
+
+Sun Nov  2 07:34:56 1997  Tim Janik  <timj@psynet.net>
+
+       * gtk/gtkfilesel.c: Small fixes about a segmentation viaolation
+       cause by a double click in the directoy list (introduced by my
+       previous changes).
+       
+       * gtk/gtklist.c: Small fixes to gtk_list_add() and gtk_list_remove().
+       
+       * gtk/testgtk.c (list_add): Applied Stefan Wille's patch to make this
+       function do something ;).
+
+Fri Oct 31 Jay Painter <jpaint@serv.net>
+       *gdk/gdk.c: reformatted DND code for GTK coding standards
+       *gdk/gdkwindow.c: changed memory allocation for DND to q_mem stuff
+
+Thu Oct 30 Jay Painter <jpaint@serv.net>
+       * gdk/gdkwindow.c: 
+       * gdk/gdk/gdk.h:
+       * gtk/gtkwidget.h:
+       * gtk/gtkwidget.c: Applied Stephan Willie's shaped window patch
+
+       * gdk/gdkwindow: 
+       * gdk/gdk.h:
+       * gtk/gtkwidget.h:
+       * gtk/gtkwidget.c: reformatted the DND code to conform to GTK
+               coding standards
+
+       * gtk/testgtk: massive fixes, SW's shaped window example
+
+Thu Oct 30 07:33:27 1997  Tim Janik  <timj@psynet.net>
+
+       * gtk/gtklistitem.c (gtk_real_list_item_toggle): applied Johannes
+       Keukelaar's <johannes@nada.kth.se> patch for keyboard support in
+       GtkList widgets.
+
+       * gtk/gtkfilesel.c: adapted dir and file list selection
+       behaviour to deal with keyboard selections. this is a little
+       bit tricky: in the dir list it just changes the entrys value on a one
+       button press. but on a keyboard selection via gtk_widget_activate() it
+       does a new population (likewise on a double click) as this seems more
+       obvious.
+
+1997-10-25  Marius Vollmer  <mvo@zagadka.ping.de>
+
+       * gdk/gdkcolor.c (gdk_colormap_get_system): Initialize
+       private->ref_count.
+
+Wed Oct 22 09:47:43 1997  Tim Janik  <timj@psynet.net>
+
+       * gtk/gtkwindow.c (gtk_window_key_release_event): Fixed a stupid
+       bug that caused the key_release_event to be propagated twice.
+
+Sun Oct 12 11:01:43 1997  Tim Janik  <timj@psynet.net>
+
+        * acconfig.h:
+        * configure.in:
+       * gdk/gdkimage.c: Added configure check for IPC_RMID_DEFERRED_RELEASE,
+       because shmat() fails after a shmctl(..., IPC_RMID,...) for OSF1 V3.2,
+       SunOS 4.1.1, 5.5, 5.5.1, 5.6, IRIX 5.2 and 6.2.
+
+Mon Oct  6 11:59:07 1997  Federico Mena  <federico@bananoid.nuclecu.unam.mx>
+
+       * gdk/gdk.c (gdk_event_translate): In line 1693, fixed typo that
+       would cause motion notify events not to be delivered.
+
+Sun Oct  5 18:15:06 1997  Federico Mena  <federico@bananoid.nuclecu.unam.mx>
+
+       * gtk/gtkrc.c (gtk_rc_parse_bg_pixmap): Changed strdup() for
+       g_strdup().
+
+Wed Sep 24 17:16:34 1997  Peter Mattis  <pmattis@bjork.inktomi.com>
+
+       * configure.in: Fixed a stupid error in the test for libXext that
+       would cause it to fail if X_EXTRA_LIBS was not empty.
+
+       * gtk/gtkmain.h (gtk-timj-970919.patch):
+       * gtk/gtkmain.c (gtk-timj-970919.patch): new function
+       `gtk_idle_remove_by_data' to remove all idle callbacks that take a
+       specific piece of data as argument.  (gtk_get_current_event):
+       remove idles through gtk_idle_remove_by_data.
+        
+       * gtk/gtkwidget.c (gtk-timj-970919.patch):
+        (gtk_widget_destroy): remove pending idles for
+        widgets that have GTK_REDRAW_PENDING or GTK_RESIZE_PENDING and
+        GTK_ANCHORED set (only anchored widgets can have a resize queue
+        handler pending). widgets that have GTK_RESIZE_NEEDED will be removed
+        from their anchored toplevels `resize_widgets' list.
+        
+        (gtk_widget_queue_draw): let the widget remember the queue handler
+        tag (through `redraw_handler_key') for later call to `gtk_idle_remove'.
+        
+        (gtk_widget_queue_resize): let the widget remember the queue handler
+        tag (through `resize_handler_key') for later call to `gtk_idle_remove'.
+        corrected referencing the toplevel widget for which the handler is
+        pending. if a widget is added to the `resize_widgets' list of a
+        toplevel widget, GTK_RESIZE_NEEDED is set and it's referenced.
+        
+        (gtk_real_widget_queue_resize): on the deletion of the `resize_widgets'
+        list, unset GTK_RESIZE_NEEDED and unreference the removed widgets.
+        
+       * gtk/gtkwindow.c (gtk-timj-970919.patch):
+        (gtk_real_window_move_resize): move `resize_containers = NULL'
+        initialization out of if-statement.
+        while stepping through the `resize_widgets' list, unreference the
+        widgets and clear GTK_RESIZE_NEEDED. if a widget realy needs are
+        resize, they are flagged through GTK_RESIZE_NEEDED now (instead of
+        GTK_RESIZE_PENDING, as this is indicative for a pending handler).
+        added checks to provide segfaulting if a widgets parent pointer
+        is NULL (e.g. on toplevel widgets that have GTK_RESIZE_NEEDED set).
+
+Tue Sep 23 13:23:27 1997  Federico Mena  <federico@bananoid.nuclecu.unam.mx>
+
+       * gdk/gdkimage.c: Applied Tim Janik's patch to mark shm segments
+       as IPC_RMID so that they are automatically removed always.
+
+       * gdk/gdkfont.c: Removed casts from lvalues.
+
+       * gtk/gtkmain.c: Removed GTK_RETLOC_*() (which do a cast) from lvalues.
+
+       * gtk/gtkaccelerator.c (gtk_accelerator_table_remove): Added
+       "const" to the accelerator_key param to be consistent with the
+       declaration in gtkaccelerator.h.  The const is not useful in this
+       case, anyway.
+
+Tue Sep 16 13:11:06 1997  Peter Mattis  <pmattis@bjork.inktomi.com>
+
+       * gtkpreview.c: Andrew Logan Kieschnick's change to eliminate
+       round-off error when gamma is set to 1.0.
+
+       * gtkrange.c:
+       * gtkviewport.c: Jay Painter's changes to modify the way in which
+       viewports resize.
+
+       * gdkinput.c:
+       * gdkinputgxi.h:
+       * gdkinputxfree.h:
+       * gtk/Makefile.am:
+       * gtk.h:
+       * gtkeventbox.c:
+       * gtkeventbox.h: Owen Taylor's event box widget and fixes for X
+       input support (that I had broken).
+
+       * gdk.h:
+       * gdkwindow.c:
+       * gtksignal.h:
+       * gtksignal.c: Elliot Lee's changes to support Objective C. (id is
+       apparently a reserved word in Objective C).
+
+Sun Sep 14 22:33:15 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwidget.c (gtk_widget_queue_resize): If the toplevel container
+       is invisible we simply call "gtk_container_need_resize" on
+       it. This fixes a bug with option menus not redrawing correctly.
+
+       * gtkmenuitem.c (gtk_menu_item_enter): (gtk_menu_item_leave):
+       These functions now simply pass the event on to their parent. This
+       is necessary for menus to work properly due to the change in how
+       grabs are dealts with.
+
+       * gtkwindow.c (gtk_real_window_move_resize): Fixed a bug that
+       caused the GTK_RESIZE_PENDING flag to not be unset in some cases.
+
+Fri Sep  5 20:49:37 1997  Marius Vollmer  <mvo@zagadka.ping.de>
+
+       Bug fixes:
+
+       * Makefile.am: Added PATCHES to EXTRA_DIST.
+       * gtk/gtkpixmap.c (gtk_pixmap_new): Move the "pixmap != NULL" test
+       after the allocation of the pixmap.
+
+       To shut up the compiler:
+
+       * gtk/gtkfilesel.c (get_pwdb): Initialize home_dir.
+       * gtk/gtkmain.c (gtk_init): Replace comments around calls to
+       g_set_*_handler with "if (0)".
+       * gtk/gtkrc.c (gtk_rc_get_token): Initialize hex_number and
+       float_number.
+       * gtk/gtkwindow.c (gtk_window_key_press_event): Initialize
+       direction.
+
+       Changes to the type system in gtk/:
+
+       * Makefile.am: Added gtktypebuiltins.h to gtkinclude_HEADERS.
+       Added gtk.defs, runelisp, gentypeinfo.el and gtktypebuiltins.c to
+       EXTRA_DIST.  Added rules to generate gtktypebuiltins.* from
+       gtk.defs.
+
+       * runelisp, gentypeinfo.el, gtk.defs: New files.
+
+       * gtkaccelerator.c, gtkaccelerator.h (gtk_accelerator_table_ref):
+       Return the table so that this function can be used as the `copy'
+       function for GTK_TYPE_BOXED values.
+       * gtkstyle.c, gtkstyle.h (gtk_style_ref): Likewise.
+
+       * gtkenums.h: Removed GtkArgType enum.
+
+       * gtkmain.c (gtk_init): Call gtk_type_init to initialize the type
+       system.
+
+       * gtkobject.c (gtk_object_init_type): New function to take over
+       for gtk_object_get_type. (gtk_object_get_type): Just return the
+       constant GTK_TYPE_OBJECT. (gtk_object_collect_args): Do the right
+       thing for the new GTK_TYPE_* types.
+       * gtksignal.c (gtk_params_get): Likewise.
+
+       * gtktypeutils.c: (gtk_type_init_builtin_types): New
+       function. (gtk_type_init): Call it.  Also made non-static.
+       (gtk_type_unique): The allocation scheme for numerical ids has
+       changed: The low 8 bits hold the appropriate GtkFundamentalType of
+       a type, the rest is a globally unique sequence number.
+       (gtk_type_hash): Use the sequence number of a key to hash it.
+       (gtk_type_register_builtin): New function.
+
+       * gtktypeutils.h: (GtkFundamentalType): New enumeration of the
+       fundamental types. (GTK_TYPE_MAKE, GTK_FUNDAMENTAL_TYPE,
+       GTK_TYPE_SEQNO): New macros to work with the new id scheme.
+       (GtkArg): Added fields for new types and renamed old ones.  GtkArg
+       should now be a mostly opaque structure, except name and type.
+       (GTK_VALUE_*): New macros to access the values of a GtkArg.
+       (GTK_RETLOC_*): New macros to access the location of a return
+       value that is contained in a GtkArg.  * gtktypebuiltins.h: New
+       file to access the typeids of the builtin types.
+
+       * gtkwidget.h (GTK_TYPE_WIDGET): New macro to access the type id
+       of the widget class.
+
+       Thru out: Changed GTK_ARG_* to the appropriate GTK_TYPE_*.
+       Changed access to GtkArg structure to the appropriate GTK_VALUE_*
+       or GTK_RETLOC_* macro.  Changed GtkArgType to GtkType.  Changed
+       some guints to GtkType.
+
+       General changes in gtk/ to support interpreters:
+
+       * gtkradiobutton.c (gtk_radio_button_new_from_widget,
+       gtk_radio_button_new_with_label_from_widget): New functions.
+
+       * gtksignal.c (gtk_signal_connect_no_marshal): New function.
+       (struct _GtkHandler): Added no_marshal and destroy_func fields.
+       (gtk_signal_handler_new): Initialize them.
+       (gtk_signal_connect_by_type): Added no_marshal and destroy_func
+       arguments.  Changed all callers.
+       (gtk_signal_destroy): Invoke destroy_func if there is one and the
+       global destroy func does not apply.  (gtk_handlers_run): If the
+       handler has no_marshal set, call its function directly without
+       going thru the signal's marshaller.
+
+Wed Sep  3 09:56:22 1997  RHS Linux User  <pmattis@bjork.inktomi.com>
+
+       * gtkrange.c: Changed the way the range control focus was drawn so
+       that the range control is drawn correctly when it does not have
+       the focus.
+
+Tue Sep  2 17:41:17 1997  RHS Linux User  <pmattis@bjork.inktomi.com>
+
+       * gtkwidget.c: 'gtk_real_widget_queue_resize' should only remove
+       the "resize_widgets" if another resize is not pending.
+
+Mon Sep  1 18:28:08 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmain.c: Changed the way GDK_DELETE events are handled. Only,
+       if 'gtk_widget_event' returns TRUE is the widget destroyed. By
+       default, 'gtk_widget_event' will return FALSE causing the window
+       to not be destroyed. This prevents segfaults in the GIMP and other
+       programs that do not correctly handle GDK_DELETE events.
+
+       * gtkmain.c: Added modal dialog support by allowing events
+       destined for a child of the grab widget to go to the child instead
+       of the grab widget. (Added 'gtk_widget_is_ancestor' to determine
+       the relationship between the grab widget and the event widget).
+
+       * *.[ch]: Incorprated a whole mess of patches. (Started keeping
+       the ChangeLog up to date again).
+
+Thu Jun  5 17:22:21 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenufactory.c:
+       * gtkmenufactory.h: Added 'gtk_menu_factory_remove_*'
+       calls. Removing entries/paths causes the associated widgets to be
+       destroyed.
+
+       * gtkwidget.c:
+       * gtkwidget.h: Calling 'gtk_widget_set_style' is used as an
+       indication that the programmer specifically wants that style to be
+       used. RC-style substitution is disabled for the widget after such
+       a call.
+
+       * gtkpixmap.c:
+       * gtkpixmap.h:
+       * gtkimage.c:
+       * gtkimage.h: Changed to use clip mask and a single pixmap (or
+       image) to deal with transparent areas.
+
+       * gdkpixmap.c: Modified xpm loading routines to optionally return
+       a clip mask.
+
+       * gdkgc.c:
+       * gdkdraw.c:
+       * gdktypes.h: Modifications to allow clip masks to be used with
+       gc's. Clip masks are bitmaps that specify drawable regions.
+
+Thu May  1 03:11:51 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkscrolledwindow.c: Scrolled windows need to have the
+       GTK_NO_WINDOW flag set. Not having it set caused an obscure
+       redrawing bug.
+
+Wed Apr 30 12:38:03 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkhruler.c:
+       * gtkvruler.c: Fixed a small bug that caused the indicator to be
+       positioned slightly off.
+
+Sun Apr 27 14:28:21 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenushell.c:
+       * gtkmenushell.h:
+       * gtkmenu.c:
+       * gtkmenu.h: Changes so that if a menu is popped up there is a
+       timeout period during which a menu item will not be activated and
+       if the mouse button is released in that period the menu will stay
+       popped up.
+
+       * gtkcurve.c:
+       * gtkcurve.h: Included curve widget courtesy of David
+       Mosberger-Tang (davidm@azstarnet.com).
+
+       * gtkentry.c:
+       * gtkentry.h: Changed "insert" and "delete" signals to
+       "insert_text" and "delete_text" respectively. (The symbol "delete"
+       cannot be used since it is a C++ reserved word).
+
+Sat Apr 19 01:43:49 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenufactory.c: A path which ends in "<nothing>" will cause an
+       invisible (hidden) menu entry to be created. This is useful for
+       setting an accelerator key for which a corresponding menu entry is
+       not desired.
+
+       * gtktooltips.c: Fixed some problems with destruction of the
+       active tip widget not properly updating the tooltips data
+       structures.
+
+Fri Apr 18 15:09:45 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkcontainer.c:
+       * gtklist.c:
+       * gtkwidget.c:
+       * gtkwidget.h: Patch from Owen Taylor (owt1@cornell.edu) which
+       fixes problems with destruction of objects and with destruction of
+       objects which hold the focus.
+
+Thu Apr 17 11:29:15 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenushell.c: Incorrect logic in
+       'gtk_menu_shell_button_release' for deciding when a menu should
+       stay popped up when the mouse button is released.
+
+       * *.c: Miscellaneous fixes from folks on the net.
+
+Tue Apr 15 02:43:17 1997  Peter Mattis  <pmattis@localhost>
+
+       * *.c:
+       * gtkwidget.h: Added GTK_BASIC widget flag which when set
+       specifies a widget as "basic". A "basic" widget is one which
+       doesn't take input events. For example, labels, pixmaps, boxes,
+       tables, alignments, etc.
+
+Sat Apr 12 15:23:08 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkcolorsel.c: Add "#include <math.h>" to define M_PI.
+
+       * gtksignal.c: Fixed a bug in 'gtk_signal_emit' which showed up
+       because of the new cast checking macros. The 'object' was being
+       accessed after it had been destroyed.
+
+       * gtkoptionmenu.c: Fixed bug with using 'GTK_BIN' instead of
+       'GTK_BUTTON' which showed up because of the new cast checking
+       macros.
+
+       * *.h: 'GTK_CHECK_CAST', 'GTK_CHECK_CLASS_CAST' and
+       'GTK_CHECK_TYPE' used by standard widget macros everywhere.
+
+Wed Apr  9 00:54:17 1997  Peter Mattis  <pmattis@localhost>
+
+       * docs/gtk.texi: Started further work on documentation. Major
+       changes and additions are being made.
+
+       * gtkarrow.c:
+       * gtkarrow.h: Removed function 'gtk_arrow_get'.
+
+       * gtkcontainer.c: 'gtk_container_check_resize' no performs
+       additional checking to account for the case where the containers
+       allocation is no longer sufficient because its parent (or its
+       parents parent, etc.) needs to resize its children.
+
+Tue Apr  8 21:15:50 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkstyle.c: Fixed a bug in 'gtk_style_init' in which the font
+       was not ref'd (via 'gdk_font_ref'), but was free'd (via in
+       'gdk_font_free') in 'gtk_style_destroy'. (David
+       Mosberger-Tang). Also cleaned up 'gtk_style_destroy' while I was
+       at it.
+
+       * gtkmain.c: Fixed a bug in 'gtk_propogate_event' which caused
+       entry widgets (and probably other widgets) not to be destroyed in
+       some instances.
+
+Mon Apr  7 01:20:38 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkentry.c:
+       * gtkentry.h: Changed the "insert_text", "delete_text" and
+       "changed_text" signals to "insert", "delete", and "changed"
+       respectively. They really should have been named this way
+       originally except the previous signal mechanism prevented
+       duplicate signal names. ("changed" is also used by adjustments).
+
+       * gtkradiomenuitem.c:
+       * gtkradiomenuitem.h: New widget.
+
+       * gtkcheckmenuitem.c:
+       * gtkcheckmenuitem.h: New widget.
+
+       * gtksignal.c: Modified 'gtk_signal_lookup' to require an object
+       type to be passed as a parameter. In addition, signals are now
+       only needed to be uniquely defined in their branch of the class
+       hierarchy. This allows the same signal name to be used in two
+       different branches of the class hierarchy. For instance, the
+       "changed" signal is used both by adjustments and entries...in
+       different ways!
+
+       * gtktypeutils.c: Added 'gtk_type_parent' which returns the parent
+       type for a given type.
+
+Sun Apr  6 22:08:35 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwidget.c: If a widget is set insensitive it loses the focus
+       if it had it.
+
+       * gtkcontainer.c: Insensitive widgets no longer participate in tab
+       traversal.
+
+       * gtkscrolledwindow.c: The "viewport" child is now destroyed and a
+       container class "foreach" function was written (which fixes the
+       sensitivity bug).
+
+Sat Apr  5 14:25:38 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkhscrollbar.c:
+       * gtkvscrollbar.c: Fixed trough size allocation bug.
+
+       * gtkhscale.c:
+       * gtkvscale.c: Fixed trough size allocation and position bug that
+       showed up when scales were placed in notebooks.
+
+Thu Mar 27 17:45:54 1997  David Mosberger-Tang  <davidm@azstarnet.com>
+
+        * gtk/gtkmain.c (gtk_handle_idle): Fix appending pending_idles to
+        idle_functions so it works even when idle_functions is empty.
+
+Sat Mar 15 14:15:59 1997  Peter Mattis  <pmattis@localhost>
+
+       * *.[ch]: Moved '*_class_init' and '*_init' function declarations
+       for widgets into the source file as those functions no longer had
+       to be public.
+
+       * gtkcheckbutton.c: Fixed redrawing of check button.
+
+       * gtkframe.c: Fixed redrawing of frame when the shadow type is
+       changed.
+
+Sat Mar  8 15:19:23 1997  Peter Mattis  <pmattis@localhost>
+
+       * gdkimage.c: Fixed a stupid bug with 'gdk_image_new' which
+       potentially added a NULL image to "image_list" and caused problems
+       when 'gdk_image_exit' was called.
+
+Wed Mar  5 00:40:08 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkpreview.c: Massively changed the colormap handling used by
+       the preview widget. Gray previews are now dithered. A single
+       visual and colormap is shared by the color and gray previews. A
+       GTK_PREVIEW_INFO property is installed on the root window in
+       certain cases to allow multiple GTK programs to share the system
+       colormap.
+
+Sun Mar  2 05:43:06 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkcheckbutton.c: 'gtk_checkbutton_size_allocate' was allocating
+       too much space to its children and not leaving the check button
+       room for the focus border.
+
+       * gtknotebook.c: 'gtk_notebook_size_request' wasn't requesting
+       enough space when the notebook tabs are visible.
+
+Sat Mar  1 01:59:35 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkpreview.c: Fixed a problem with 'gtk_preview_put' when the
+       image byte order is GDK_MSB_FIRST.
+
+       * gtksignal.c:
+       * gtksignal.h: Added 'gtk_signal_connect_after' and
+       'gtk_signal_connect_object_after' functions. These connect signal
+       handlers which will run after the class function associated with
+       the signal.
+
+       * gtkstyle.c: Fixed a stupid bug in 'gtk_style_new_from_key' that
+       was causing twice as many styles to be created as necesary.
+
+       * gtkwidget.c: 'gtk_real_widget_size_allocate' erases the widgets
+       old allocation if it has the GTK_NO_WINDOW flag set.
+
+       * gtkwidget.c: 'gtk_real_widget_unmap' now erases the widget if it
+       has the GTK_NO_WINDOW flag set.
+
+       * gtklabel.c: Removed 'gtk_label_unmap' as similar functionality
+       was added to gtk_real_widget_unmap.
+
+       * gtkbin.c: Modified 'gtk_bin_map' and 'gtk_bin_unmap' so that it
+       erases and draws the widget if it has the GTK_NO_WINDOW flag set.
+
+       * gtkframe.c: Modified 'gtk_frame_size_allocate' so that it erases
+       the old allocation.
+
+Fri Feb 28 03:27:05 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwindow.c: 'gtk_window_set_title' now changes the window title
+       if the window is already realized.
+
+       * gtkentry.c: 'gtk_entry_set_text' was emitting both a
+       "delete_text" and a "changed_text" signal. Modified so that it
+       only emits a "changed_text" signal.
+
+       * gtkpreview.c: Modified to work correctly on systems with MSB
+       byte order. The colormap for TRUE and DIRECT color displays is now
+       created if the default visual is not equal to the visual we are
+       using.
+
+       * gtkstyle.c: 'gtk_style_attach' and 'gtk_style_find' weren't
+       working properly in the presence of multiple colormaps are
+       different depth visuals.
+
+       * gtkcontainer.c: Massively improved focus traversal using tab and
+       arrow keys. It now uses the layout of the widgets to determine
+       where to move the focus to.
+
+Mon Feb 24 03:24:02 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenufactory.c: Set the accelerator table field for menus when
+       they are created.
+
+       * gtkmenu.c:
+       * gtkmenu.h: Added a default accelerator table field to menus so
+       that runtime modification of accelerator keys in menus can work
+       better.
+
+       * gtkrange.c: 'gtk_range_default_{h,v}motion' had faulty logic for
+       deciding what to do when the slider was at the edge of the
+       trough. They previously didn't update the adjustment value event
+       if the value wasn't what it should be when the slider was at the
+       edge of the trough.
+
+       * gtkviewport.c: 'gtk_viewport_size_allocate' and
+       'gtk_viewport_adjustment_value_changed' both had the potential for
+       performing a divide by 0. Checks are now in place to prevent this.
+
+       * gtkmenu.c: 'gtk_menu_map' now makes sure the menu lies on screen
+       if the position function is NULL.
+
+       * gtkentry.c: Modified selection handling. 'gtk_delete_selection'
+       actually removes the X selection now. 'gtk_entry_destroy' removes
+       the selection as well and relies on the change in "gdk.c" to make
+       sure the selection event will not be sent to a non-existant
+       window.
+
+       * gdk.c: Selection events are only passed on if the selection
+       owner is not NULL.
+
+       * gtkstyle.c: 'gtk_style_detach' and 'gtk_style_destroy' were not
+       destroying the black and white gc's.
+
+Sun Feb 23 19:17:56 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwindow.c: 'gtk_window_size_request' was setting the window
+       hints. This was also being done in 'gtk_window_map', so the
+       instance being done in 'gtk_window_size_request' was removed.
+
+Fri Feb 21 01:04:01 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwidget.c: 'gtk_widget_draw' has to use the widgets allocated
+       position for the drawing rectangle when the widget has the
+       GTK_NO_WINDOW flag set.
+
+       * gtkwidget.c: In 'gtk_widget_init' the visual and colormap were
+       being directly compared against 'default_visual' and
+       'default_colormap' instead of calling
+       'gtk_widget_get_default_{visual,colormap}'.
+
+       * gdkrectangle.c: Amazing! There was a bug in the
+       'gtk_rectangle_intersect' logic. Its been there for near eternity
+       and I never noticed.
+
+       * gtkpreview.c:
+       * gtkpreview.h: Created preview widget which allows drawing to an
+       rgb or grayscale buffer which is automatically displayed on the
+       screen. Performs dithering as necessary.
+
+Thu Feb 20 20:33:21 1997  Peter Mattis  <pmattis@localhost>
+
+       * gdkwindow.c: Modified the logic in 'gdk_window_new' which
+       determined when to add a window to the WM_COLORMAP_WINDOWS
+       property.
+
+Wed Feb 19 19:55:29 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkruler.c: 'gtk_ruler_make_pixmap' was always destroying the
+       old backing store and creating a new one even when it would create
+       a new one of exactly the same size as the old one.
+
+Tue Feb 18 18:32:10 1997  Peter Mattis  <pmattis@localhost>
+
+       * gmem.c: 'g_mem_chunk_alloc' was incorrectly modifying the mem
+       areas free mem field when reallocating a previously freed
+       atom. This caused a fairly severe memory leak.
+
+       * gtkmenushell.c: 'gtk_menu_shell_button_release' had a bug in the
+       logic for deciding whether to initiate an X pointer grab or not
+       when the mouse button was released. It now only initiates a grab
+       if the mouse is released within an active menu item.
+
+Fri Feb 14 00:57:40 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtknotebook.c: Changed the look of notebook tabs slightly.
+
+       * gtkentry.c:
+       * gtkentry.h: Deleting an entry widget which is holding the X
+       selection presents some difficulties. The X selection must be
+       released, but the widget can't be destroyed until the
+       SELECTION_CLEAR event is received that the X server will send in
+       response to clearing the X selection. There are probably still
+       bugs in the current method of entry widget deletion when the X
+       selection is held.
+
+       * gtkmain.c: 'gtk_propagate_event' was not properly destroying the
+       toplevel window when receiving a key press event.
+
+       * gtkwidget.c: Setting a widget insensitive did not cause it to
+       redraw. It now does.
+
+Thu Feb 13 16:59:07 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkviewport.c: 'gtk_viewport_size_allocate' was allocating its
+       child widget an adjusted allocation. Since the actual scrolling
+       has handled by a subwindow this caused the child to be double
+       scrolled. Modified to always set the child allocations origin to
+       (0, 0).
+
+Wed Feb 12 01:06:48 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkentry.c: Text is now centered vertically. Previously it was
+       pushed up against the top. This problem was only evident when the
+       widget was allocated more vertical space than it requested.
+
+       * gtkfilesel.c: 'gtk_file_selection_key_press' was previously only
+       a stub for tab completion. The actual tab completion call had been
+       left out. (Oops!)
+
+Tue Feb 11 01:43:08 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtksignal.c: 'gtk_signal_disconnect_by_data' was going into a
+       loop and crashing. Bad logic. Fixed.
+
+       * gtkmain.c: An idle function which returns FALSE will be removed
+       from the list of idle functions. This makes the functioning of
+       idle functions and timeouts more similar.
+
+       * gtkentry.c: 'gtk_entry_get_text' now returns an empty string
+       when the actual text is NULL. This allows "stupid" programs to use
+       the value returned by 'gtk_entry_get_text' blindly (without
+       checking to see if its NULL).
+
+       * gtkradiobutton.c: Modified 'gtk_radio_button_clicked' so that
+       'gtk_toggle_button_toggled' is called _after_ the widget state is
+       changed.
+
+       * gtksignal.c:
+       * gtksignal.h: Added 'gtk_signal_name' which returns the character
+       string name for a given signal number.
+
+       * gtkwidget.c: 'gtk_widget_set_parent' checks to see if the widget
+       is now "anchored" through the parent chain to a widget which is
+       GTK_ANCHORED. If it is, then it changes the widgets style using
+       'gtk_rc_get_style' and recursively performs the same operation on
+       the widgets children. This is necessary is 'gtk_rc_get_style' only
+       works properly on "anchored" widgets.
+
+       * gtkwindow.c: Modified GTK_WIN_POS logic so that it is only used
+       immediately after the window has been shown.
+
+       * gtkmenu.c: 'gtk_menu_key_press'. Can now change menu item
+       accelerator keys on the fly. Why? Why not. Cool/useless feature of
+       the day.
+
+       * gtkmenuitem.c: Accelerator key drawing. Somehow that never got
+       finished. (Oops!)
+
+       * gtkdrawingarea.c: 'gtk_drawing_area_size_allocate' was not
+       actually installed during 'gtk_drawing_area_class_init'. (Oops!)
+
+       * gtkframe.c: 'gtk_frame_size_request' fixed size requisition
+       problem caused by unsigned arithmetic.
+
+       * gtkwindow.c: Modified window widget so that it only uses the
+       widget uposition auxiliary information immediately after it has
+       been shown. This prevents the annoying bug which can cause a
+       uposition'ed window to jump back to its original position after
+       the user moves it.
+
+       * gtkwidget.c: Need to ref and unref style in
+       'gtk_widget_{push,pop}_style' to make sure that a style on the
+       style stack is not destroyed.
+
+       * gtktogglebutton.c: 'gtk_toggle_button_set_state' now calls
+       gtk_button_clicked to actually change the state of the
+       button. In this way, radio buttons can now perform the appropriate
+       actions when the toggle button state is set.
+
+Mon Feb 10 00:27:39 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtklist.c: 'gtk_list_select_item' and 'gtk_list_unselect_item'
+       were casting a GList* variable to a a GtkWidget* variable. Bad bad
+       bad. (Tim Janik).
+
+       * gtksignal.c: Modified 'gtk_signal_connect' and
+       'gtk_signal_connect_object' to warn when a signal type cannot be
+       found.
+
+Sun Feb  9 00:15:30 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkoptionmenu.c:
+       * gtkoptionmenu.h: Changed option menus back to being derived from
+       buttons. This fixes up some screwiness with their user
+       interaction.
+
+       * gtkwindow.c: Modified key press handler to support focus
+       traversal.
+
+       * gtkcontainer.c:
+       * gtkcontainer.h: Added default focus traversal back in.
+
+Sat Feb  8 10:44:38 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkviewport.h:
+       * gtkviewport.c: Massively sped up viewport scrolling. Used to be
+       reallocating child's size (offset) each time a scrollbar
+       moved. Now a subwindow is moved. All the children are moved
+       automatically by moving the subwindow. Much much much faster.
+
+Tue Feb  4 00:20:44 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtree.c: Changed 'g_tree_node_search' to use a loop instead of
+       recursion.
+
+Mon Feb  3 11:30:03 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkbutton.c: Removed 'parent_destroy' global and replaced it
+       with 'parent_class' global to reflect style used in other
+       widgets.
+
+       * gtknotebook.c: Tab labels were being allocated less than their
+       requested size.
+
+       * gtkrange.c:
+       * gtkrange.h: Moved the "digits" field of scales into the range
+       type. The adjustment value for scales is truncated to the number
+       of visible digits instead of being left untouched.
+
+       * gtree.c: Fixed a bug in the AVL tree implementation. Single
+       rotations were always being performed during insertion. It is
+       sometimes necessary to perform a double rotation.
+
+       * gtklabel.c: Modified 'gtk_label_expose' to only draw the label
+       when the allocated space is greater than or equal to the requested
+       space.
+
+       * gtklabel.c: Added call to 'gtk_widget_unmap' to
+       'gtk_label_destroy' in order for the label to redraw correctly
+       (erase itself) when destroyed.
+
+       * gtklabel.c: Added 'gtk_label_unmap' call which erases the labels
+       allocation when it gets unmapped.
+
+       * *.h: Removed a few remaining instances of using "class" as a
+       parameter name. (Causes problems for C++).
+
+Fri Jan 31 12:26:50 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkcontainer.c: 'gtk_container_enable_resize' needs to call
+       'gtk_container_check_resize' instead of
+       'gtk_container_need_resize'.
+
+       * gtkwidget.c: 'gtk_real_widget_show' now maps the widget if its
+       parent is mapped.
+
+       * gtkscrolledwindow.c: Fixed size allocation when the scrollbar
+       policy's are GTK_POLICY_AUTOMATIC. Doing it correctly is harder
+       than I originally thought.
+
+       * gtklist.c: Added 'gtk_list_child_position' to determine the
+       integer position in a list of a child. Filled in the
+       'gtk_list_item_select' and 'gtk_list_item_unselect' stubs.
+
+Thu Jan 30 16:08:06 1997  Peter Mattis  <pmattis@localhost>
+
+       * gmem.c: Changed the implementation of G_ALLOC_AND_FREE mem
+       chunks. They used to allocate SIZEOF_VOID_P extra bytes per atom
+       in order to keep track of which mem area they were allocated
+       from. Now the mem area is determined by searching through an AVL
+       tree of the mem areas for a mem chunk and comparing memory
+       locations. A little slower, but makes G_ALLOC_AND_FREE mem chunks
+       much more attractive.
+
+       * gtree.c: Added an AVL tree implementation to glib.
+
+       * gtksignal.c:
+       * gstring.c: va_arg (arg_list, {char, short}) is
+       invalid. Arguments passed in a variable argument list are
+       promoted. ({char, short}->int). Seemed to work ok before under
+       Linux. Crashed under FreeBSD.
+
+Tue Jan 28 02:27:51 1997  Peter Mattis  <pmattis@localhost>
+
+       * gdkwindow.c: Fixed a major slowdown apparent in the file
+       selection dialog which was caused by calling
+       'gtk_window_add_colormap_windows' way way way too often.
+
+       * *.c: Many widgets called 'gtk_container_need_resize' when
+       something internal changed which would cause the widget to grow or
+       shrink. The assumption was made that the widget would change size
+       and an expose event would be generated. This happens "most" of the
+       time. But its possible for certain widgets to change size without
+       generating expose events, or for its internal geometry to change
+       without a change of size which would mean no expose event was
+       generated. So a wrapper function called
+       'gtk_container_check_resize' was created and
+       'gtk_container_need_resize' was modified so that it returns FALSE
+       if a resize was actually generated and TRUE if nothing
+       changed. This allows 'gtk_container_check_resize' to initiate a
+       'gtk_widget_size_allocate' and 'gtk_widget_draw' to emulate the
+       expose event.
+
+Sat Jan 25 14:17:44 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmain.c: Fixed a bug with propogating key press events. The
+       events were sent 2 times to the toplevel windows which caused the
+       focus widget to be activated twice when the space bar was pressed.
+
+       * */configure.in:
+       * */Makefile.am: Added support for libtool and removed the old
+       shared library configuration craziness.
+
+Fri Jan 24 12:59:22 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtktext.c:
+       * gtktext.h: Josh's fixes and additions to the text widget.
+
+       * gtkfill.c:
+       * gtkfill.h: Filler widget useful for filling space in a
+       table. Can specify a minimum size. Used by the canvas widget.
+
+       * gtknotebook.c:
+       * gtknotebook.h: Made outline of notebook widget.
+
+       * gtkcanvas.c:
+       * gtkcanvas.h: Started canvas widget. A composite of 2 rulers (w/
+       an origin), 2 scrolllbars. Guides, grids, snap to.
+
+Sun Jan 19 18:26:45 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkdialog.c:
+       * gtkdialog.h: Created dialog widget which creates a standard
+       looking dialog with buttons along the button and a separator.
+
+       * gtkxid.c: Generalized the window table code for looking up a gdk
+       window based on an XID to work for any XID and a piece of
+       data. Can now look up gdk fonts based on their XID.
+
+       * gtkruler.c:
+       * gtkruler.h:
+       * gtkhruler.c:
+       * gtkhruler.h:
+       * gtkvruler.c:
+       * gtkvruler.h: Started conversion of the ruler widget.
+
+       * gtktext.c:
+       * gtktext.h: Started conversion of the text widget. Scrolling
+       doesn't work.
+
+       * gtkmain.c: Fixed a fairly major bug. The event widget needs to
+       be in a call for the entire duration of handling an event. Not
+       just for when the event widget itself is handling the event.
+
+       * gtkfilesel.c: Fixed up some bugs with resizing.
+
+Fri Jan 10 14:18:03 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwidget.c:
+       * gtkwidget.h:
+       * gtkentry.c:
+       * gtkentry.h: Support for selections.
+
+       * gdkselection.c:
+       * gdk.c:
+       * gdktypes.h:
+       * gdk.h: Gdk support for X selections. Currently only text
+       selections are supported.
+
+       * gtksignal.c: Fixed a major bug which occurred when destroying an
+       object. Memory was being written to after it was freed.
+
+       * gtkfilesel.c:
+       * gtkfilesel.h: Hooked up more functionality to the file selection
+       dialog.
+
+Wed Jan  8 18:13:53 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkfilesel.c:
+       * gtkfilesel.h: Mostly converted old file selection dialog
+       widget. The widget is derived from the GtkWindow class and is
+       quite a bit simpler in the widget code.
+
+       * gtkwidget.c: Fixed 'gtk_widget_grab_focus' and
+       'gtk_widget_grab_default' to check that the toplevel widget is a
+       type of window (which includes classes derived from windows).
+
+Tue Jan  7 01:12:32 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwindow.c: Was calling 'gtk_window_resize' twice in a
+       row...why?
+
+       * gtksignal.c:
+       * gtksignal.h:
+       * *.c: Changed 'gtk_signal_new' so that the class function that is
+       called when the signal is emitted can be called either before,
+       after or both before and after the calling of any signal
+       handlers.
+
+       * gtkobject.c:
+       * gtkobject.h: Added 'object_data' mechanism for storing data
+       associated with a character string key in objects. Removed
+       'user_data' field of objects and changed
+       'gtk_object_{get,set}_user_data' to use the object data
+       mechanism. Removed 'handlers' field of objects.
+
+       * gtkwidget.c:
+       * gtkwidget.h:
+       * gtkwindow.c: Modified aux info mechanism to use object data
+       mechanism.
+
+       * gtksignal.c: Modified signal mechanism to use object data
+       mechanism instead of 'handlers' field.
+
+
+Mon Jan  6 15:10:16 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenushell.c: Fixed up button press handling so as to conform
+       more closely to that used by Motif.
+
+Wed Jan  1 21:27:17 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenu.c:
+       * gtkmenu.h:
+       * gtkmenubar.c:
+       * gtkmenubar.h:
+       * gtkmenushell.c:
+       * gtkmenushell.h: Reorganization of menu-ing code so that code
+       duplication is reduced. The menu shell now contains most of the
+       code for menu-ing interaction while menus and menubars simply layout
+       their child menu items in the appropriate place.
+
+Sun Dec 29 17:48:18 1996  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenu.c:
+       * gtkmenubar.c:
+       * gtkmenuitem.h:
+       * gtkmenuitem.c: Modifications so that menu item accelerators and
+       the submenu indicator are drawn correctly and the correct amount
+       of space is allocated.
+
+Sat Dec 28 00:32:13 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtkmenufactory.h:
+       * gtkmenufactory.c: Started menu factories as an easy method to
+       create and manipulate menus.
+
+Fri Dec 27 13:17:34 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtkmenu.c:
+       * gtkmenu.h:
+       * gtkmenubar.c:
+       * gtkmenubar.h:
+       * gtkmenuitem.c:
+       * gtkmenuitem.h:
+       * gtkmenushell.c:
+       * gtkmenushell.h: Implemented basic menu functionality. Menubars
+       and popup menus work. Submenus work. (Much left to be done).
+
+Wed Dec 18 15:27:05 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtktypeutils.h:
+       * gtktypeutils.c: Added 'gtk_type_from_name' which returns a type
+       identifier given a type name. Implemented using a second hash
+       table keyed by type names.
+
+       * gtkbutton.c:
+       * gtktogglebutton.c: Fixed very small messed-up drawing bug when a
+       button loses its focus.
+
+       * gtkwidget.h:
+       * gtkwidget.c:
+       * gtkbutton.c:
+       * gtkwindow.c: Added default button handling. Default buttons now
+       draw correctly and pressing return or enter causes the default
+       button (if one exists) to be activated.
+
+Tue Dec 17 19:32:21 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtkhscale.c:
+       * gtkvscale.c: Overrode 'draw_slider' method of ranges in order to
+       draw the slider of scales with a line in them so as to be closer
+       to the Motif look-and-feel.
+
+       * gtkwindow.c: Modified 'gtk_window_focus_in_event' so that focus
+       in events are only handled when the window is visible. Fixes a bug
+       where spurious focus in events get sent when a window is being
+       hidden.
+
+       * gtkwidget.h: Added 'activate_signal' field to the GtkWidgetClass
+       structure. Added 'gtk_widget_activate' call to emit the activate
+       signal for a widget if it is non-zero.
+
+Tue Dec 10 15:59:45 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtkwidget.c: 'gtk_widget_set_name' oops in strdup'ing the old
+       "widget->name" instead of the new one we are setting.
+
+       * gtkrc.c: 'gtk_rc_widget_path' changed to use
+       'gtk_widget_get_name' instead of accessing the "widget->name"
+       field directly.
+
+       * gtkwidget.c: Added 'gtk_widget_get_name' function which returns
+       the widgets name if it exists and the widgets type name if it does
+       not.
+
+       * gtkcheckbutton.c: Added 'gtk_check_button_draw'
+       function. Modified 'gtk_check_button_expose' to pass an expose
+       event to child instead of callings its draw function.
+
+       * gtkentry.c: 'gtk_entry_draw_text' why was "+1" being added to
+       the font->ascent to calculate the font position? This was wrong
+       and caused some characters in fonts to be clipped. (Notably "g").
+
+       * gtkentry.c: 'gtk_entry_realize' specify GTK_BUTTON1_MOTION_MASK
+       and GTK_POINTER_MOTION_HINT_MASK for _both_ windows.
+
+       * gtkmain.c: 'gtk_propagate_event' needs to set the GTK_IN_CALL
+       flag for the object before calling 'gtk_widget_event' and needs to
+       destroy the object if necessary after 'gtk_widget_event' returns.
+
+       * gtkradiobutton.c: 'gtk_radio_button_clicked' needs to call
+       'gtk_toggle_button_toggled' when the currently active button is
+       toggled.
+
+       * gtkwidget.c: 'gtk_real_widget_hide' needs to call
+       'gtk_widget_unmap' if the widget is currently mapped.
+
+       * gtkwindow.c: Prevent automatic resizing after the user has
+       specified a new window size. Add 'handling_resize' flag to
+       windows.
+
+       * gtkscrolledwindow.c: Implement the GTK_POLICY_AUTOMATIC
+       scrollbar policy. Need to connect to the adjustments 'changed'
+       signal and notice when the scrollbars aren't in use.
+
+       * gtkcontainer.c: 'gtk_container_init' must set 'auto_resize' and
+       'need_resize' fields to TRUE and FALSE respectively.
+
+       * gtkwidget.c: 'gtk_widget_set_parent' must all set a widgets state
+       to its parents state.
+
+Sun Dec  1 01:31:01 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * Started ChangeLog
diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4
new file mode 100644 (file)
index 0000000..a065ebe
--- /dev/null
@@ -0,0 +1,1140 @@
+Mon Nov 17 1997 Jay Painter <jpaint@serv.net>
+       * gtkviewport.c: Raph's Mon, 10 Nov 1997 patch to gtk-list 
+       to fix some viewport bugs
+
+Mon Nov 17 1997 Jay Painter <jpaint@serv.net>
+       * gtk/gtkwidget.c: gtk-ajaborsk-971016-2
+       A little patch again to prevent user to use gtk_widget_set_events()
+       when a widget is already realized.
+       In this case, the gtk_widget_set_events() doesn't work.
+
+Mon Nov 17 1997 Jay Painter <jpaint@serv.net>
+       * gtk/gtkwindow.c: gtk-ajaborsk-971016-1
+       This small patch correct position for GTK_WIN_POS_CENTER and
+       GTK_WIN_POS_MOUSE GtkWindow positions.
+
+Sat Nov 15 1997 Jay Painter <jpaint@serv.net>
+       * gdk/gdkgc.c: added function gdk_gc_set_clip_rectangle
+       * gdk/gdk.h: header for above
+
+Sat Nov 15 1997 Jay Painter <jpaint@serv.net>
+       * gdk/gdkgc.c: added function gdk_gc_set_clip_rectangle
+       * gdk/gdk.h: header for above
+
+Wed Nov 12 1997 Jay Painter <jpaint@serv.net>
+       * gdk/gdkpixmap.c: Patrice Fortier's patch for transparent pixmaps.
+       * gdk/gdk.h:
+         gdk/gdkdraw.c: Patrice Fortier's patch to add pixel draw function.
+
+Sun Nov  9 1997 Jay Painter <jpaint@serv.net>
+       * Fixed problems with makefiles relating to the bug
+       which required glib to be installed.
+       * Fixed makefiles to incluce the xpm's in gtk+/gtk needed
+       for testgtk.
+       * Updated gtk+ and gtk+/glib to libtool-1.0f
+
+Fri Nov  7 1997 Jay Painter <jpaint@serv.net>
+       * gtk/gtktext.c: return char_widths[ch & 0xff]; in line 2152
+
+Thr Nov  5 1997 Jay Painter <jpaint@serv.net>
+       * gtk/testgtk.c: added drag and drop test, removed the test hack
+       from the button test
+
+Tue Nov  4 08:28:57 1997  Federico Mena  <federico@bananoid.nuclecu.unam.mx>
+
+       * gtk/gtkmain.c (gtk_handle_idle): Patch from David Mosberger to
+       avoid crashes when handling idle function (this manifested itself
+       in the Umax and Microtek backends in SANE.
+
+Sun Nov  2 07:34:56 1997  Tim Janik  <timj@psynet.net>
+
+       * gtk/gtkfilesel.c: Small fixes about a segmentation viaolation
+       cause by a double click in the directoy list (introduced by my
+       previous changes).
+       
+       * gtk/gtklist.c: Small fixes to gtk_list_add() and gtk_list_remove().
+       
+       * gtk/testgtk.c (list_add): Applied Stefan Wille's patch to make this
+       function do something ;).
+
+Fri Oct 31 Jay Painter <jpaint@serv.net>
+       *gdk/gdk.c: reformatted DND code for GTK coding standards
+       *gdk/gdkwindow.c: changed memory allocation for DND to q_mem stuff
+
+Thu Oct 30 Jay Painter <jpaint@serv.net>
+       * gdk/gdkwindow.c: 
+       * gdk/gdk/gdk.h:
+       * gtk/gtkwidget.h:
+       * gtk/gtkwidget.c: Applied Stephan Willie's shaped window patch
+
+       * gdk/gdkwindow: 
+       * gdk/gdk.h:
+       * gtk/gtkwidget.h:
+       * gtk/gtkwidget.c: reformatted the DND code to conform to GTK
+               coding standards
+
+       * gtk/testgtk: massive fixes, SW's shaped window example
+
+Thu Oct 30 07:33:27 1997  Tim Janik  <timj@psynet.net>
+
+       * gtk/gtklistitem.c (gtk_real_list_item_toggle): applied Johannes
+       Keukelaar's <johannes@nada.kth.se> patch for keyboard support in
+       GtkList widgets.
+
+       * gtk/gtkfilesel.c: adapted dir and file list selection
+       behaviour to deal with keyboard selections. this is a little
+       bit tricky: in the dir list it just changes the entrys value on a one
+       button press. but on a keyboard selection via gtk_widget_activate() it
+       does a new population (likewise on a double click) as this seems more
+       obvious.
+
+1997-10-25  Marius Vollmer  <mvo@zagadka.ping.de>
+
+       * gdk/gdkcolor.c (gdk_colormap_get_system): Initialize
+       private->ref_count.
+
+Wed Oct 22 09:47:43 1997  Tim Janik  <timj@psynet.net>
+
+       * gtk/gtkwindow.c (gtk_window_key_release_event): Fixed a stupid
+       bug that caused the key_release_event to be propagated twice.
+
+Sun Oct 12 11:01:43 1997  Tim Janik  <timj@psynet.net>
+
+        * acconfig.h:
+        * configure.in:
+       * gdk/gdkimage.c: Added configure check for IPC_RMID_DEFERRED_RELEASE,
+       because shmat() fails after a shmctl(..., IPC_RMID,...) for OSF1 V3.2,
+       SunOS 4.1.1, 5.5, 5.5.1, 5.6, IRIX 5.2 and 6.2.
+
+Mon Oct  6 11:59:07 1997  Federico Mena  <federico@bananoid.nuclecu.unam.mx>
+
+       * gdk/gdk.c (gdk_event_translate): In line 1693, fixed typo that
+       would cause motion notify events not to be delivered.
+
+Sun Oct  5 18:15:06 1997  Federico Mena  <federico@bananoid.nuclecu.unam.mx>
+
+       * gtk/gtkrc.c (gtk_rc_parse_bg_pixmap): Changed strdup() for
+       g_strdup().
+
+Wed Sep 24 17:16:34 1997  Peter Mattis  <pmattis@bjork.inktomi.com>
+
+       * configure.in: Fixed a stupid error in the test for libXext that
+       would cause it to fail if X_EXTRA_LIBS was not empty.
+
+       * gtk/gtkmain.h (gtk-timj-970919.patch):
+       * gtk/gtkmain.c (gtk-timj-970919.patch): new function
+       `gtk_idle_remove_by_data' to remove all idle callbacks that take a
+       specific piece of data as argument.  (gtk_get_current_event):
+       remove idles through gtk_idle_remove_by_data.
+        
+       * gtk/gtkwidget.c (gtk-timj-970919.patch):
+        (gtk_widget_destroy): remove pending idles for
+        widgets that have GTK_REDRAW_PENDING or GTK_RESIZE_PENDING and
+        GTK_ANCHORED set (only anchored widgets can have a resize queue
+        handler pending). widgets that have GTK_RESIZE_NEEDED will be removed
+        from their anchored toplevels `resize_widgets' list.
+        
+        (gtk_widget_queue_draw): let the widget remember the queue handler
+        tag (through `redraw_handler_key') for later call to `gtk_idle_remove'.
+        
+        (gtk_widget_queue_resize): let the widget remember the queue handler
+        tag (through `resize_handler_key') for later call to `gtk_idle_remove'.
+        corrected referencing the toplevel widget for which the handler is
+        pending. if a widget is added to the `resize_widgets' list of a
+        toplevel widget, GTK_RESIZE_NEEDED is set and it's referenced.
+        
+        (gtk_real_widget_queue_resize): on the deletion of the `resize_widgets'
+        list, unset GTK_RESIZE_NEEDED and unreference the removed widgets.
+        
+       * gtk/gtkwindow.c (gtk-timj-970919.patch):
+        (gtk_real_window_move_resize): move `resize_containers = NULL'
+        initialization out of if-statement.
+        while stepping through the `resize_widgets' list, unreference the
+        widgets and clear GTK_RESIZE_NEEDED. if a widget realy needs are
+        resize, they are flagged through GTK_RESIZE_NEEDED now (instead of
+        GTK_RESIZE_PENDING, as this is indicative for a pending handler).
+        added checks to provide segfaulting if a widgets parent pointer
+        is NULL (e.g. on toplevel widgets that have GTK_RESIZE_NEEDED set).
+
+Tue Sep 23 13:23:27 1997  Federico Mena  <federico@bananoid.nuclecu.unam.mx>
+
+       * gdk/gdkimage.c: Applied Tim Janik's patch to mark shm segments
+       as IPC_RMID so that they are automatically removed always.
+
+       * gdk/gdkfont.c: Removed casts from lvalues.
+
+       * gtk/gtkmain.c: Removed GTK_RETLOC_*() (which do a cast) from lvalues.
+
+       * gtk/gtkaccelerator.c (gtk_accelerator_table_remove): Added
+       "const" to the accelerator_key param to be consistent with the
+       declaration in gtkaccelerator.h.  The const is not useful in this
+       case, anyway.
+
+Tue Sep 16 13:11:06 1997  Peter Mattis  <pmattis@bjork.inktomi.com>
+
+       * gtkpreview.c: Andrew Logan Kieschnick's change to eliminate
+       round-off error when gamma is set to 1.0.
+
+       * gtkrange.c:
+       * gtkviewport.c: Jay Painter's changes to modify the way in which
+       viewports resize.
+
+       * gdkinput.c:
+       * gdkinputgxi.h:
+       * gdkinputxfree.h:
+       * gtk/Makefile.am:
+       * gtk.h:
+       * gtkeventbox.c:
+       * gtkeventbox.h: Owen Taylor's event box widget and fixes for X
+       input support (that I had broken).
+
+       * gdk.h:
+       * gdkwindow.c:
+       * gtksignal.h:
+       * gtksignal.c: Elliot Lee's changes to support Objective C. (id is
+       apparently a reserved word in Objective C).
+
+Sun Sep 14 22:33:15 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwidget.c (gtk_widget_queue_resize): If the toplevel container
+       is invisible we simply call "gtk_container_need_resize" on
+       it. This fixes a bug with option menus not redrawing correctly.
+
+       * gtkmenuitem.c (gtk_menu_item_enter): (gtk_menu_item_leave):
+       These functions now simply pass the event on to their parent. This
+       is necessary for menus to work properly due to the change in how
+       grabs are dealts with.
+
+       * gtkwindow.c (gtk_real_window_move_resize): Fixed a bug that
+       caused the GTK_RESIZE_PENDING flag to not be unset in some cases.
+
+Fri Sep  5 20:49:37 1997  Marius Vollmer  <mvo@zagadka.ping.de>
+
+       Bug fixes:
+
+       * Makefile.am: Added PATCHES to EXTRA_DIST.
+       * gtk/gtkpixmap.c (gtk_pixmap_new): Move the "pixmap != NULL" test
+       after the allocation of the pixmap.
+
+       To shut up the compiler:
+
+       * gtk/gtkfilesel.c (get_pwdb): Initialize home_dir.
+       * gtk/gtkmain.c (gtk_init): Replace comments around calls to
+       g_set_*_handler with "if (0)".
+       * gtk/gtkrc.c (gtk_rc_get_token): Initialize hex_number and
+       float_number.
+       * gtk/gtkwindow.c (gtk_window_key_press_event): Initialize
+       direction.
+
+       Changes to the type system in gtk/:
+
+       * Makefile.am: Added gtktypebuiltins.h to gtkinclude_HEADERS.
+       Added gtk.defs, runelisp, gentypeinfo.el and gtktypebuiltins.c to
+       EXTRA_DIST.  Added rules to generate gtktypebuiltins.* from
+       gtk.defs.
+
+       * runelisp, gentypeinfo.el, gtk.defs: New files.
+
+       * gtkaccelerator.c, gtkaccelerator.h (gtk_accelerator_table_ref):
+       Return the table so that this function can be used as the `copy'
+       function for GTK_TYPE_BOXED values.
+       * gtkstyle.c, gtkstyle.h (gtk_style_ref): Likewise.
+
+       * gtkenums.h: Removed GtkArgType enum.
+
+       * gtkmain.c (gtk_init): Call gtk_type_init to initialize the type
+       system.
+
+       * gtkobject.c (gtk_object_init_type): New function to take over
+       for gtk_object_get_type. (gtk_object_get_type): Just return the
+       constant GTK_TYPE_OBJECT. (gtk_object_collect_args): Do the right
+       thing for the new GTK_TYPE_* types.
+       * gtksignal.c (gtk_params_get): Likewise.
+
+       * gtktypeutils.c: (gtk_type_init_builtin_types): New
+       function. (gtk_type_init): Call it.  Also made non-static.
+       (gtk_type_unique): The allocation scheme for numerical ids has
+       changed: The low 8 bits hold the appropriate GtkFundamentalType of
+       a type, the rest is a globally unique sequence number.
+       (gtk_type_hash): Use the sequence number of a key to hash it.
+       (gtk_type_register_builtin): New function.
+
+       * gtktypeutils.h: (GtkFundamentalType): New enumeration of the
+       fundamental types. (GTK_TYPE_MAKE, GTK_FUNDAMENTAL_TYPE,
+       GTK_TYPE_SEQNO): New macros to work with the new id scheme.
+       (GtkArg): Added fields for new types and renamed old ones.  GtkArg
+       should now be a mostly opaque structure, except name and type.
+       (GTK_VALUE_*): New macros to access the values of a GtkArg.
+       (GTK_RETLOC_*): New macros to access the location of a return
+       value that is contained in a GtkArg.  * gtktypebuiltins.h: New
+       file to access the typeids of the builtin types.
+
+       * gtkwidget.h (GTK_TYPE_WIDGET): New macro to access the type id
+       of the widget class.
+
+       Thru out: Changed GTK_ARG_* to the appropriate GTK_TYPE_*.
+       Changed access to GtkArg structure to the appropriate GTK_VALUE_*
+       or GTK_RETLOC_* macro.  Changed GtkArgType to GtkType.  Changed
+       some guints to GtkType.
+
+       General changes in gtk/ to support interpreters:
+
+       * gtkradiobutton.c (gtk_radio_button_new_from_widget,
+       gtk_radio_button_new_with_label_from_widget): New functions.
+
+       * gtksignal.c (gtk_signal_connect_no_marshal): New function.
+       (struct _GtkHandler): Added no_marshal and destroy_func fields.
+       (gtk_signal_handler_new): Initialize them.
+       (gtk_signal_connect_by_type): Added no_marshal and destroy_func
+       arguments.  Changed all callers.
+       (gtk_signal_destroy): Invoke destroy_func if there is one and the
+       global destroy func does not apply.  (gtk_handlers_run): If the
+       handler has no_marshal set, call its function directly without
+       going thru the signal's marshaller.
+
+Wed Sep  3 09:56:22 1997  RHS Linux User  <pmattis@bjork.inktomi.com>
+
+       * gtkrange.c: Changed the way the range control focus was drawn so
+       that the range control is drawn correctly when it does not have
+       the focus.
+
+Tue Sep  2 17:41:17 1997  RHS Linux User  <pmattis@bjork.inktomi.com>
+
+       * gtkwidget.c: 'gtk_real_widget_queue_resize' should only remove
+       the "resize_widgets" if another resize is not pending.
+
+Mon Sep  1 18:28:08 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmain.c: Changed the way GDK_DELETE events are handled. Only,
+       if 'gtk_widget_event' returns TRUE is the widget destroyed. By
+       default, 'gtk_widget_event' will return FALSE causing the window
+       to not be destroyed. This prevents segfaults in the GIMP and other
+       programs that do not correctly handle GDK_DELETE events.
+
+       * gtkmain.c: Added modal dialog support by allowing events
+       destined for a child of the grab widget to go to the child instead
+       of the grab widget. (Added 'gtk_widget_is_ancestor' to determine
+       the relationship between the grab widget and the event widget).
+
+       * *.[ch]: Incorprated a whole mess of patches. (Started keeping
+       the ChangeLog up to date again).
+
+Thu Jun  5 17:22:21 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenufactory.c:
+       * gtkmenufactory.h: Added 'gtk_menu_factory_remove_*'
+       calls. Removing entries/paths causes the associated widgets to be
+       destroyed.
+
+       * gtkwidget.c:
+       * gtkwidget.h: Calling 'gtk_widget_set_style' is used as an
+       indication that the programmer specifically wants that style to be
+       used. RC-style substitution is disabled for the widget after such
+       a call.
+
+       * gtkpixmap.c:
+       * gtkpixmap.h:
+       * gtkimage.c:
+       * gtkimage.h: Changed to use clip mask and a single pixmap (or
+       image) to deal with transparent areas.
+
+       * gdkpixmap.c: Modified xpm loading routines to optionally return
+       a clip mask.
+
+       * gdkgc.c:
+       * gdkdraw.c:
+       * gdktypes.h: Modifications to allow clip masks to be used with
+       gc's. Clip masks are bitmaps that specify drawable regions.
+
+Thu May  1 03:11:51 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkscrolledwindow.c: Scrolled windows need to have the
+       GTK_NO_WINDOW flag set. Not having it set caused an obscure
+       redrawing bug.
+
+Wed Apr 30 12:38:03 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkhruler.c:
+       * gtkvruler.c: Fixed a small bug that caused the indicator to be
+       positioned slightly off.
+
+Sun Apr 27 14:28:21 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenushell.c:
+       * gtkmenushell.h:
+       * gtkmenu.c:
+       * gtkmenu.h: Changes so that if a menu is popped up there is a
+       timeout period during which a menu item will not be activated and
+       if the mouse button is released in that period the menu will stay
+       popped up.
+
+       * gtkcurve.c:
+       * gtkcurve.h: Included curve widget courtesy of David
+       Mosberger-Tang (davidm@azstarnet.com).
+
+       * gtkentry.c:
+       * gtkentry.h: Changed "insert" and "delete" signals to
+       "insert_text" and "delete_text" respectively. (The symbol "delete"
+       cannot be used since it is a C++ reserved word).
+
+Sat Apr 19 01:43:49 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenufactory.c: A path which ends in "<nothing>" will cause an
+       invisible (hidden) menu entry to be created. This is useful for
+       setting an accelerator key for which a corresponding menu entry is
+       not desired.
+
+       * gtktooltips.c: Fixed some problems with destruction of the
+       active tip widget not properly updating the tooltips data
+       structures.
+
+Fri Apr 18 15:09:45 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkcontainer.c:
+       * gtklist.c:
+       * gtkwidget.c:
+       * gtkwidget.h: Patch from Owen Taylor (owt1@cornell.edu) which
+       fixes problems with destruction of objects and with destruction of
+       objects which hold the focus.
+
+Thu Apr 17 11:29:15 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenushell.c: Incorrect logic in
+       'gtk_menu_shell_button_release' for deciding when a menu should
+       stay popped up when the mouse button is released.
+
+       * *.c: Miscellaneous fixes from folks on the net.
+
+Tue Apr 15 02:43:17 1997  Peter Mattis  <pmattis@localhost>
+
+       * *.c:
+       * gtkwidget.h: Added GTK_BASIC widget flag which when set
+       specifies a widget as "basic". A "basic" widget is one which
+       doesn't take input events. For example, labels, pixmaps, boxes,
+       tables, alignments, etc.
+
+Sat Apr 12 15:23:08 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkcolorsel.c: Add "#include <math.h>" to define M_PI.
+
+       * gtksignal.c: Fixed a bug in 'gtk_signal_emit' which showed up
+       because of the new cast checking macros. The 'object' was being
+       accessed after it had been destroyed.
+
+       * gtkoptionmenu.c: Fixed bug with using 'GTK_BIN' instead of
+       'GTK_BUTTON' which showed up because of the new cast checking
+       macros.
+
+       * *.h: 'GTK_CHECK_CAST', 'GTK_CHECK_CLASS_CAST' and
+       'GTK_CHECK_TYPE' used by standard widget macros everywhere.
+
+Wed Apr  9 00:54:17 1997  Peter Mattis  <pmattis@localhost>
+
+       * docs/gtk.texi: Started further work on documentation. Major
+       changes and additions are being made.
+
+       * gtkarrow.c:
+       * gtkarrow.h: Removed function 'gtk_arrow_get'.
+
+       * gtkcontainer.c: 'gtk_container_check_resize' no performs
+       additional checking to account for the case where the containers
+       allocation is no longer sufficient because its parent (or its
+       parents parent, etc.) needs to resize its children.
+
+Tue Apr  8 21:15:50 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkstyle.c: Fixed a bug in 'gtk_style_init' in which the font
+       was not ref'd (via 'gdk_font_ref'), but was free'd (via in
+       'gdk_font_free') in 'gtk_style_destroy'. (David
+       Mosberger-Tang). Also cleaned up 'gtk_style_destroy' while I was
+       at it.
+
+       * gtkmain.c: Fixed a bug in 'gtk_propogate_event' which caused
+       entry widgets (and probably other widgets) not to be destroyed in
+       some instances.
+
+Mon Apr  7 01:20:38 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkentry.c:
+       * gtkentry.h: Changed the "insert_text", "delete_text" and
+       "changed_text" signals to "insert", "delete", and "changed"
+       respectively. They really should have been named this way
+       originally except the previous signal mechanism prevented
+       duplicate signal names. ("changed" is also used by adjustments).
+
+       * gtkradiomenuitem.c:
+       * gtkradiomenuitem.h: New widget.
+
+       * gtkcheckmenuitem.c:
+       * gtkcheckmenuitem.h: New widget.
+
+       * gtksignal.c: Modified 'gtk_signal_lookup' to require an object
+       type to be passed as a parameter. In addition, signals are now
+       only needed to be uniquely defined in their branch of the class
+       hierarchy. This allows the same signal name to be used in two
+       different branches of the class hierarchy. For instance, the
+       "changed" signal is used both by adjustments and entries...in
+       different ways!
+
+       * gtktypeutils.c: Added 'gtk_type_parent' which returns the parent
+       type for a given type.
+
+Sun Apr  6 22:08:35 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwidget.c: If a widget is set insensitive it loses the focus
+       if it had it.
+
+       * gtkcontainer.c: Insensitive widgets no longer participate in tab
+       traversal.
+
+       * gtkscrolledwindow.c: The "viewport" child is now destroyed and a
+       container class "foreach" function was written (which fixes the
+       sensitivity bug).
+
+Sat Apr  5 14:25:38 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkhscrollbar.c:
+       * gtkvscrollbar.c: Fixed trough size allocation bug.
+
+       * gtkhscale.c:
+       * gtkvscale.c: Fixed trough size allocation and position bug that
+       showed up when scales were placed in notebooks.
+
+Thu Mar 27 17:45:54 1997  David Mosberger-Tang  <davidm@azstarnet.com>
+
+        * gtk/gtkmain.c (gtk_handle_idle): Fix appending pending_idles to
+        idle_functions so it works even when idle_functions is empty.
+
+Sat Mar 15 14:15:59 1997  Peter Mattis  <pmattis@localhost>
+
+       * *.[ch]: Moved '*_class_init' and '*_init' function declarations
+       for widgets into the source file as those functions no longer had
+       to be public.
+
+       * gtkcheckbutton.c: Fixed redrawing of check button.
+
+       * gtkframe.c: Fixed redrawing of frame when the shadow type is
+       changed.
+
+Sat Mar  8 15:19:23 1997  Peter Mattis  <pmattis@localhost>
+
+       * gdkimage.c: Fixed a stupid bug with 'gdk_image_new' which
+       potentially added a NULL image to "image_list" and caused problems
+       when 'gdk_image_exit' was called.
+
+Wed Mar  5 00:40:08 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkpreview.c: Massively changed the colormap handling used by
+       the preview widget. Gray previews are now dithered. A single
+       visual and colormap is shared by the color and gray previews. A
+       GTK_PREVIEW_INFO property is installed on the root window in
+       certain cases to allow multiple GTK programs to share the system
+       colormap.
+
+Sun Mar  2 05:43:06 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkcheckbutton.c: 'gtk_checkbutton_size_allocate' was allocating
+       too much space to its children and not leaving the check button
+       room for the focus border.
+
+       * gtknotebook.c: 'gtk_notebook_size_request' wasn't requesting
+       enough space when the notebook tabs are visible.
+
+Sat Mar  1 01:59:35 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkpreview.c: Fixed a problem with 'gtk_preview_put' when the
+       image byte order is GDK_MSB_FIRST.
+
+       * gtksignal.c:
+       * gtksignal.h: Added 'gtk_signal_connect_after' and
+       'gtk_signal_connect_object_after' functions. These connect signal
+       handlers which will run after the class function associated with
+       the signal.
+
+       * gtkstyle.c: Fixed a stupid bug in 'gtk_style_new_from_key' that
+       was causing twice as many styles to be created as necesary.
+
+       * gtkwidget.c: 'gtk_real_widget_size_allocate' erases the widgets
+       old allocation if it has the GTK_NO_WINDOW flag set.
+
+       * gtkwidget.c: 'gtk_real_widget_unmap' now erases the widget if it
+       has the GTK_NO_WINDOW flag set.
+
+       * gtklabel.c: Removed 'gtk_label_unmap' as similar functionality
+       was added to gtk_real_widget_unmap.
+
+       * gtkbin.c: Modified 'gtk_bin_map' and 'gtk_bin_unmap' so that it
+       erases and draws the widget if it has the GTK_NO_WINDOW flag set.
+
+       * gtkframe.c: Modified 'gtk_frame_size_allocate' so that it erases
+       the old allocation.
+
+Fri Feb 28 03:27:05 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwindow.c: 'gtk_window_set_title' now changes the window title
+       if the window is already realized.
+
+       * gtkentry.c: 'gtk_entry_set_text' was emitting both a
+       "delete_text" and a "changed_text" signal. Modified so that it
+       only emits a "changed_text" signal.
+
+       * gtkpreview.c: Modified to work correctly on systems with MSB
+       byte order. The colormap for TRUE and DIRECT color displays is now
+       created if the default visual is not equal to the visual we are
+       using.
+
+       * gtkstyle.c: 'gtk_style_attach' and 'gtk_style_find' weren't
+       working properly in the presence of multiple colormaps are
+       different depth visuals.
+
+       * gtkcontainer.c: Massively improved focus traversal using tab and
+       arrow keys. It now uses the layout of the widgets to determine
+       where to move the focus to.
+
+Mon Feb 24 03:24:02 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenufactory.c: Set the accelerator table field for menus when
+       they are created.
+
+       * gtkmenu.c:
+       * gtkmenu.h: Added a default accelerator table field to menus so
+       that runtime modification of accelerator keys in menus can work
+       better.
+
+       * gtkrange.c: 'gtk_range_default_{h,v}motion' had faulty logic for
+       deciding what to do when the slider was at the edge of the
+       trough. They previously didn't update the adjustment value event
+       if the value wasn't what it should be when the slider was at the
+       edge of the trough.
+
+       * gtkviewport.c: 'gtk_viewport_size_allocate' and
+       'gtk_viewport_adjustment_value_changed' both had the potential for
+       performing a divide by 0. Checks are now in place to prevent this.
+
+       * gtkmenu.c: 'gtk_menu_map' now makes sure the menu lies on screen
+       if the position function is NULL.
+
+       * gtkentry.c: Modified selection handling. 'gtk_delete_selection'
+       actually removes the X selection now. 'gtk_entry_destroy' removes
+       the selection as well and relies on the change in "gdk.c" to make
+       sure the selection event will not be sent to a non-existant
+       window.
+
+       * gdk.c: Selection events are only passed on if the selection
+       owner is not NULL.
+
+       * gtkstyle.c: 'gtk_style_detach' and 'gtk_style_destroy' were not
+       destroying the black and white gc's.
+
+Sun Feb 23 19:17:56 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwindow.c: 'gtk_window_size_request' was setting the window
+       hints. This was also being done in 'gtk_window_map', so the
+       instance being done in 'gtk_window_size_request' was removed.
+
+Fri Feb 21 01:04:01 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwidget.c: 'gtk_widget_draw' has to use the widgets allocated
+       position for the drawing rectangle when the widget has the
+       GTK_NO_WINDOW flag set.
+
+       * gtkwidget.c: In 'gtk_widget_init' the visual and colormap were
+       being directly compared against 'default_visual' and
+       'default_colormap' instead of calling
+       'gtk_widget_get_default_{visual,colormap}'.
+
+       * gdkrectangle.c: Amazing! There was a bug in the
+       'gtk_rectangle_intersect' logic. Its been there for near eternity
+       and I never noticed.
+
+       * gtkpreview.c:
+       * gtkpreview.h: Created preview widget which allows drawing to an
+       rgb or grayscale buffer which is automatically displayed on the
+       screen. Performs dithering as necessary.
+
+Thu Feb 20 20:33:21 1997  Peter Mattis  <pmattis@localhost>
+
+       * gdkwindow.c: Modified the logic in 'gdk_window_new' which
+       determined when to add a window to the WM_COLORMAP_WINDOWS
+       property.
+
+Wed Feb 19 19:55:29 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkruler.c: 'gtk_ruler_make_pixmap' was always destroying the
+       old backing store and creating a new one even when it would create
+       a new one of exactly the same size as the old one.
+
+Tue Feb 18 18:32:10 1997  Peter Mattis  <pmattis@localhost>
+
+       * gmem.c: 'g_mem_chunk_alloc' was incorrectly modifying the mem
+       areas free mem field when reallocating a previously freed
+       atom. This caused a fairly severe memory leak.
+
+       * gtkmenushell.c: 'gtk_menu_shell_button_release' had a bug in the
+       logic for deciding whether to initiate an X pointer grab or not
+       when the mouse button was released. It now only initiates a grab
+       if the mouse is released within an active menu item.
+
+Fri Feb 14 00:57:40 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtknotebook.c: Changed the look of notebook tabs slightly.
+
+       * gtkentry.c:
+       * gtkentry.h: Deleting an entry widget which is holding the X
+       selection presents some difficulties. The X selection must be
+       released, but the widget can't be destroyed until the
+       SELECTION_CLEAR event is received that the X server will send in
+       response to clearing the X selection. There are probably still
+       bugs in the current method of entry widget deletion when the X
+       selection is held.
+
+       * gtkmain.c: 'gtk_propagate_event' was not properly destroying the
+       toplevel window when receiving a key press event.
+
+       * gtkwidget.c: Setting a widget insensitive did not cause it to
+       redraw. It now does.
+
+Thu Feb 13 16:59:07 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkviewport.c: 'gtk_viewport_size_allocate' was allocating its
+       child widget an adjusted allocation. Since the actual scrolling
+       has handled by a subwindow this caused the child to be double
+       scrolled. Modified to always set the child allocations origin to
+       (0, 0).
+
+Wed Feb 12 01:06:48 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkentry.c: Text is now centered vertically. Previously it was
+       pushed up against the top. This problem was only evident when the
+       widget was allocated more vertical space than it requested.
+
+       * gtkfilesel.c: 'gtk_file_selection_key_press' was previously only
+       a stub for tab completion. The actual tab completion call had been
+       left out. (Oops!)
+
+Tue Feb 11 01:43:08 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtksignal.c: 'gtk_signal_disconnect_by_data' was going into a
+       loop and crashing. Bad logic. Fixed.
+
+       * gtkmain.c: An idle function which returns FALSE will be removed
+       from the list of idle functions. This makes the functioning of
+       idle functions and timeouts more similar.
+
+       * gtkentry.c: 'gtk_entry_get_text' now returns an empty string
+       when the actual text is NULL. This allows "stupid" programs to use
+       the value returned by 'gtk_entry_get_text' blindly (without
+       checking to see if its NULL).
+
+       * gtkradiobutton.c: Modified 'gtk_radio_button_clicked' so that
+       'gtk_toggle_button_toggled' is called _after_ the widget state is
+       changed.
+
+       * gtksignal.c:
+       * gtksignal.h: Added 'gtk_signal_name' which returns the character
+       string name for a given signal number.
+
+       * gtkwidget.c: 'gtk_widget_set_parent' checks to see if the widget
+       is now "anchored" through the parent chain to a widget which is
+       GTK_ANCHORED. If it is, then it changes the widgets style using
+       'gtk_rc_get_style' and recursively performs the same operation on
+       the widgets children. This is necessary is 'gtk_rc_get_style' only
+       works properly on "anchored" widgets.
+
+       * gtkwindow.c: Modified GTK_WIN_POS logic so that it is only used
+       immediately after the window has been shown.
+
+       * gtkmenu.c: 'gtk_menu_key_press'. Can now change menu item
+       accelerator keys on the fly. Why? Why not. Cool/useless feature of
+       the day.
+
+       * gtkmenuitem.c: Accelerator key drawing. Somehow that never got
+       finished. (Oops!)
+
+       * gtkdrawingarea.c: 'gtk_drawing_area_size_allocate' was not
+       actually installed during 'gtk_drawing_area_class_init'. (Oops!)
+
+       * gtkframe.c: 'gtk_frame_size_request' fixed size requisition
+       problem caused by unsigned arithmetic.
+
+       * gtkwindow.c: Modified window widget so that it only uses the
+       widget uposition auxiliary information immediately after it has
+       been shown. This prevents the annoying bug which can cause a
+       uposition'ed window to jump back to its original position after
+       the user moves it.
+
+       * gtkwidget.c: Need to ref and unref style in
+       'gtk_widget_{push,pop}_style' to make sure that a style on the
+       style stack is not destroyed.
+
+       * gtktogglebutton.c: 'gtk_toggle_button_set_state' now calls
+       gtk_button_clicked to actually change the state of the
+       button. In this way, radio buttons can now perform the appropriate
+       actions when the toggle button state is set.
+
+Mon Feb 10 00:27:39 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtklist.c: 'gtk_list_select_item' and 'gtk_list_unselect_item'
+       were casting a GList* variable to a a GtkWidget* variable. Bad bad
+       bad. (Tim Janik).
+
+       * gtksignal.c: Modified 'gtk_signal_connect' and
+       'gtk_signal_connect_object' to warn when a signal type cannot be
+       found.
+
+Sun Feb  9 00:15:30 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkoptionmenu.c:
+       * gtkoptionmenu.h: Changed option menus back to being derived from
+       buttons. This fixes up some screwiness with their user
+       interaction.
+
+       * gtkwindow.c: Modified key press handler to support focus
+       traversal.
+
+       * gtkcontainer.c:
+       * gtkcontainer.h: Added default focus traversal back in.
+
+Sat Feb  8 10:44:38 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkviewport.h:
+       * gtkviewport.c: Massively sped up viewport scrolling. Used to be
+       reallocating child's size (offset) each time a scrollbar
+       moved. Now a subwindow is moved. All the children are moved
+       automatically by moving the subwindow. Much much much faster.
+
+Tue Feb  4 00:20:44 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtree.c: Changed 'g_tree_node_search' to use a loop instead of
+       recursion.
+
+Mon Feb  3 11:30:03 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkbutton.c: Removed 'parent_destroy' global and replaced it
+       with 'parent_class' global to reflect style used in other
+       widgets.
+
+       * gtknotebook.c: Tab labels were being allocated less than their
+       requested size.
+
+       * gtkrange.c:
+       * gtkrange.h: Moved the "digits" field of scales into the range
+       type. The adjustment value for scales is truncated to the number
+       of visible digits instead of being left untouched.
+
+       * gtree.c: Fixed a bug in the AVL tree implementation. Single
+       rotations were always being performed during insertion. It is
+       sometimes necessary to perform a double rotation.
+
+       * gtklabel.c: Modified 'gtk_label_expose' to only draw the label
+       when the allocated space is greater than or equal to the requested
+       space.
+
+       * gtklabel.c: Added call to 'gtk_widget_unmap' to
+       'gtk_label_destroy' in order for the label to redraw correctly
+       (erase itself) when destroyed.
+
+       * gtklabel.c: Added 'gtk_label_unmap' call which erases the labels
+       allocation when it gets unmapped.
+
+       * *.h: Removed a few remaining instances of using "class" as a
+       parameter name. (Causes problems for C++).
+
+Fri Jan 31 12:26:50 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkcontainer.c: 'gtk_container_enable_resize' needs to call
+       'gtk_container_check_resize' instead of
+       'gtk_container_need_resize'.
+
+       * gtkwidget.c: 'gtk_real_widget_show' now maps the widget if its
+       parent is mapped.
+
+       * gtkscrolledwindow.c: Fixed size allocation when the scrollbar
+       policy's are GTK_POLICY_AUTOMATIC. Doing it correctly is harder
+       than I originally thought.
+
+       * gtklist.c: Added 'gtk_list_child_position' to determine the
+       integer position in a list of a child. Filled in the
+       'gtk_list_item_select' and 'gtk_list_item_unselect' stubs.
+
+Thu Jan 30 16:08:06 1997  Peter Mattis  <pmattis@localhost>
+
+       * gmem.c: Changed the implementation of G_ALLOC_AND_FREE mem
+       chunks. They used to allocate SIZEOF_VOID_P extra bytes per atom
+       in order to keep track of which mem area they were allocated
+       from. Now the mem area is determined by searching through an AVL
+       tree of the mem areas for a mem chunk and comparing memory
+       locations. A little slower, but makes G_ALLOC_AND_FREE mem chunks
+       much more attractive.
+
+       * gtree.c: Added an AVL tree implementation to glib.
+
+       * gtksignal.c:
+       * gstring.c: va_arg (arg_list, {char, short}) is
+       invalid. Arguments passed in a variable argument list are
+       promoted. ({char, short}->int). Seemed to work ok before under
+       Linux. Crashed under FreeBSD.
+
+Tue Jan 28 02:27:51 1997  Peter Mattis  <pmattis@localhost>
+
+       * gdkwindow.c: Fixed a major slowdown apparent in the file
+       selection dialog which was caused by calling
+       'gtk_window_add_colormap_windows' way way way too often.
+
+       * *.c: Many widgets called 'gtk_container_need_resize' when
+       something internal changed which would cause the widget to grow or
+       shrink. The assumption was made that the widget would change size
+       and an expose event would be generated. This happens "most" of the
+       time. But its possible for certain widgets to change size without
+       generating expose events, or for its internal geometry to change
+       without a change of size which would mean no expose event was
+       generated. So a wrapper function called
+       'gtk_container_check_resize' was created and
+       'gtk_container_need_resize' was modified so that it returns FALSE
+       if a resize was actually generated and TRUE if nothing
+       changed. This allows 'gtk_container_check_resize' to initiate a
+       'gtk_widget_size_allocate' and 'gtk_widget_draw' to emulate the
+       expose event.
+
+Sat Jan 25 14:17:44 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmain.c: Fixed a bug with propogating key press events. The
+       events were sent 2 times to the toplevel windows which caused the
+       focus widget to be activated twice when the space bar was pressed.
+
+       * */configure.in:
+       * */Makefile.am: Added support for libtool and removed the old
+       shared library configuration craziness.
+
+Fri Jan 24 12:59:22 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtktext.c:
+       * gtktext.h: Josh's fixes and additions to the text widget.
+
+       * gtkfill.c:
+       * gtkfill.h: Filler widget useful for filling space in a
+       table. Can specify a minimum size. Used by the canvas widget.
+
+       * gtknotebook.c:
+       * gtknotebook.h: Made outline of notebook widget.
+
+       * gtkcanvas.c:
+       * gtkcanvas.h: Started canvas widget. A composite of 2 rulers (w/
+       an origin), 2 scrolllbars. Guides, grids, snap to.
+
+Sun Jan 19 18:26:45 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkdialog.c:
+       * gtkdialog.h: Created dialog widget which creates a standard
+       looking dialog with buttons along the button and a separator.
+
+       * gtkxid.c: Generalized the window table code for looking up a gdk
+       window based on an XID to work for any XID and a piece of
+       data. Can now look up gdk fonts based on their XID.
+
+       * gtkruler.c:
+       * gtkruler.h:
+       * gtkhruler.c:
+       * gtkhruler.h:
+       * gtkvruler.c:
+       * gtkvruler.h: Started conversion of the ruler widget.
+
+       * gtktext.c:
+       * gtktext.h: Started conversion of the text widget. Scrolling
+       doesn't work.
+
+       * gtkmain.c: Fixed a fairly major bug. The event widget needs to
+       be in a call for the entire duration of handling an event. Not
+       just for when the event widget itself is handling the event.
+
+       * gtkfilesel.c: Fixed up some bugs with resizing.
+
+Fri Jan 10 14:18:03 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwidget.c:
+       * gtkwidget.h:
+       * gtkentry.c:
+       * gtkentry.h: Support for selections.
+
+       * gdkselection.c:
+       * gdk.c:
+       * gdktypes.h:
+       * gdk.h: Gdk support for X selections. Currently only text
+       selections are supported.
+
+       * gtksignal.c: Fixed a major bug which occurred when destroying an
+       object. Memory was being written to after it was freed.
+
+       * gtkfilesel.c:
+       * gtkfilesel.h: Hooked up more functionality to the file selection
+       dialog.
+
+Wed Jan  8 18:13:53 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkfilesel.c:
+       * gtkfilesel.h: Mostly converted old file selection dialog
+       widget. The widget is derived from the GtkWindow class and is
+       quite a bit simpler in the widget code.
+
+       * gtkwidget.c: Fixed 'gtk_widget_grab_focus' and
+       'gtk_widget_grab_default' to check that the toplevel widget is a
+       type of window (which includes classes derived from windows).
+
+Tue Jan  7 01:12:32 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwindow.c: Was calling 'gtk_window_resize' twice in a
+       row...why?
+
+       * gtksignal.c:
+       * gtksignal.h:
+       * *.c: Changed 'gtk_signal_new' so that the class function that is
+       called when the signal is emitted can be called either before,
+       after or both before and after the calling of any signal
+       handlers.
+
+       * gtkobject.c:
+       * gtkobject.h: Added 'object_data' mechanism for storing data
+       associated with a character string key in objects. Removed
+       'user_data' field of objects and changed
+       'gtk_object_{get,set}_user_data' to use the object data
+       mechanism. Removed 'handlers' field of objects.
+
+       * gtkwidget.c:
+       * gtkwidget.h:
+       * gtkwindow.c: Modified aux info mechanism to use object data
+       mechanism.
+
+       * gtksignal.c: Modified signal mechanism to use object data
+       mechanism instead of 'handlers' field.
+
+
+Mon Jan  6 15:10:16 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenushell.c: Fixed up button press handling so as to conform
+       more closely to that used by Motif.
+
+Wed Jan  1 21:27:17 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenu.c:
+       * gtkmenu.h:
+       * gtkmenubar.c:
+       * gtkmenubar.h:
+       * gtkmenushell.c:
+       * gtkmenushell.h: Reorganization of menu-ing code so that code
+       duplication is reduced. The menu shell now contains most of the
+       code for menu-ing interaction while menus and menubars simply layout
+       their child menu items in the appropriate place.
+
+Sun Dec 29 17:48:18 1996  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenu.c:
+       * gtkmenubar.c:
+       * gtkmenuitem.h:
+       * gtkmenuitem.c: Modifications so that menu item accelerators and
+       the submenu indicator are drawn correctly and the correct amount
+       of space is allocated.
+
+Sat Dec 28 00:32:13 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtkmenufactory.h:
+       * gtkmenufactory.c: Started menu factories as an easy method to
+       create and manipulate menus.
+
+Fri Dec 27 13:17:34 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtkmenu.c:
+       * gtkmenu.h:
+       * gtkmenubar.c:
+       * gtkmenubar.h:
+       * gtkmenuitem.c:
+       * gtkmenuitem.h:
+       * gtkmenushell.c:
+       * gtkmenushell.h: Implemented basic menu functionality. Menubars
+       and popup menus work. Submenus work. (Much left to be done).
+
+Wed Dec 18 15:27:05 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtktypeutils.h:
+       * gtktypeutils.c: Added 'gtk_type_from_name' which returns a type
+       identifier given a type name. Implemented using a second hash
+       table keyed by type names.
+
+       * gtkbutton.c:
+       * gtktogglebutton.c: Fixed very small messed-up drawing bug when a
+       button loses its focus.
+
+       * gtkwidget.h:
+       * gtkwidget.c:
+       * gtkbutton.c:
+       * gtkwindow.c: Added default button handling. Default buttons now
+       draw correctly and pressing return or enter causes the default
+       button (if one exists) to be activated.
+
+Tue Dec 17 19:32:21 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtkhscale.c:
+       * gtkvscale.c: Overrode 'draw_slider' method of ranges in order to
+       draw the slider of scales with a line in them so as to be closer
+       to the Motif look-and-feel.
+
+       * gtkwindow.c: Modified 'gtk_window_focus_in_event' so that focus
+       in events are only handled when the window is visible. Fixes a bug
+       where spurious focus in events get sent when a window is being
+       hidden.
+
+       * gtkwidget.h: Added 'activate_signal' field to the GtkWidgetClass
+       structure. Added 'gtk_widget_activate' call to emit the activate
+       signal for a widget if it is non-zero.
+
+Tue Dec 10 15:59:45 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtkwidget.c: 'gtk_widget_set_name' oops in strdup'ing the old
+       "widget->name" instead of the new one we are setting.
+
+       * gtkrc.c: 'gtk_rc_widget_path' changed to use
+       'gtk_widget_get_name' instead of accessing the "widget->name"
+       field directly.
+
+       * gtkwidget.c: Added 'gtk_widget_get_name' function which returns
+       the widgets name if it exists and the widgets type name if it does
+       not.
+
+       * gtkcheckbutton.c: Added 'gtk_check_button_draw'
+       function. Modified 'gtk_check_button_expose' to pass an expose
+       event to child instead of callings its draw function.
+
+       * gtkentry.c: 'gtk_entry_draw_text' why was "+1" being added to
+       the font->ascent to calculate the font position? This was wrong
+       and caused some characters in fonts to be clipped. (Notably "g").
+
+       * gtkentry.c: 'gtk_entry_realize' specify GTK_BUTTON1_MOTION_MASK
+       and GTK_POINTER_MOTION_HINT_MASK for _both_ windows.
+
+       * gtkmain.c: 'gtk_propagate_event' needs to set the GTK_IN_CALL
+       flag for the object before calling 'gtk_widget_event' and needs to
+       destroy the object if necessary after 'gtk_widget_event' returns.
+
+       * gtkradiobutton.c: 'gtk_radio_button_clicked' needs to call
+       'gtk_toggle_button_toggled' when the currently active button is
+       toggled.
+
+       * gtkwidget.c: 'gtk_real_widget_hide' needs to call
+       'gtk_widget_unmap' if the widget is currently mapped.
+
+       * gtkwindow.c: Prevent automatic resizing after the user has
+       specified a new window size. Add 'handling_resize' flag to
+       windows.
+
+       * gtkscrolledwindow.c: Implement the GTK_POLICY_AUTOMATIC
+       scrollbar policy. Need to connect to the adjustments 'changed'
+       signal and notice when the scrollbars aren't in use.
+
+       * gtkcontainer.c: 'gtk_container_init' must set 'auto_resize' and
+       'need_resize' fields to TRUE and FALSE respectively.
+
+       * gtkwidget.c: 'gtk_widget_set_parent' must all set a widgets state
+       to its parents state.
+
+Sun Dec  1 01:31:01 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * Started ChangeLog
diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6
new file mode 100644 (file)
index 0000000..a065ebe
--- /dev/null
@@ -0,0 +1,1140 @@
+Mon Nov 17 1997 Jay Painter <jpaint@serv.net>
+       * gtkviewport.c: Raph's Mon, 10 Nov 1997 patch to gtk-list 
+       to fix some viewport bugs
+
+Mon Nov 17 1997 Jay Painter <jpaint@serv.net>
+       * gtk/gtkwidget.c: gtk-ajaborsk-971016-2
+       A little patch again to prevent user to use gtk_widget_set_events()
+       when a widget is already realized.
+       In this case, the gtk_widget_set_events() doesn't work.
+
+Mon Nov 17 1997 Jay Painter <jpaint@serv.net>
+       * gtk/gtkwindow.c: gtk-ajaborsk-971016-1
+       This small patch correct position for GTK_WIN_POS_CENTER and
+       GTK_WIN_POS_MOUSE GtkWindow positions.
+
+Sat Nov 15 1997 Jay Painter <jpaint@serv.net>
+       * gdk/gdkgc.c: added function gdk_gc_set_clip_rectangle
+       * gdk/gdk.h: header for above
+
+Sat Nov 15 1997 Jay Painter <jpaint@serv.net>
+       * gdk/gdkgc.c: added function gdk_gc_set_clip_rectangle
+       * gdk/gdk.h: header for above
+
+Wed Nov 12 1997 Jay Painter <jpaint@serv.net>
+       * gdk/gdkpixmap.c: Patrice Fortier's patch for transparent pixmaps.
+       * gdk/gdk.h:
+         gdk/gdkdraw.c: Patrice Fortier's patch to add pixel draw function.
+
+Sun Nov  9 1997 Jay Painter <jpaint@serv.net>
+       * Fixed problems with makefiles relating to the bug
+       which required glib to be installed.
+       * Fixed makefiles to incluce the xpm's in gtk+/gtk needed
+       for testgtk.
+       * Updated gtk+ and gtk+/glib to libtool-1.0f
+
+Fri Nov  7 1997 Jay Painter <jpaint@serv.net>
+       * gtk/gtktext.c: return char_widths[ch & 0xff]; in line 2152
+
+Thr Nov  5 1997 Jay Painter <jpaint@serv.net>
+       * gtk/testgtk.c: added drag and drop test, removed the test hack
+       from the button test
+
+Tue Nov  4 08:28:57 1997  Federico Mena  <federico@bananoid.nuclecu.unam.mx>
+
+       * gtk/gtkmain.c (gtk_handle_idle): Patch from David Mosberger to
+       avoid crashes when handling idle function (this manifested itself
+       in the Umax and Microtek backends in SANE.
+
+Sun Nov  2 07:34:56 1997  Tim Janik  <timj@psynet.net>
+
+       * gtk/gtkfilesel.c: Small fixes about a segmentation viaolation
+       cause by a double click in the directoy list (introduced by my
+       previous changes).
+       
+       * gtk/gtklist.c: Small fixes to gtk_list_add() and gtk_list_remove().
+       
+       * gtk/testgtk.c (list_add): Applied Stefan Wille's patch to make this
+       function do something ;).
+
+Fri Oct 31 Jay Painter <jpaint@serv.net>
+       *gdk/gdk.c: reformatted DND code for GTK coding standards
+       *gdk/gdkwindow.c: changed memory allocation for DND to q_mem stuff
+
+Thu Oct 30 Jay Painter <jpaint@serv.net>
+       * gdk/gdkwindow.c: 
+       * gdk/gdk/gdk.h:
+       * gtk/gtkwidget.h:
+       * gtk/gtkwidget.c: Applied Stephan Willie's shaped window patch
+
+       * gdk/gdkwindow: 
+       * gdk/gdk.h:
+       * gtk/gtkwidget.h:
+       * gtk/gtkwidget.c: reformatted the DND code to conform to GTK
+               coding standards
+
+       * gtk/testgtk: massive fixes, SW's shaped window example
+
+Thu Oct 30 07:33:27 1997  Tim Janik  <timj@psynet.net>
+
+       * gtk/gtklistitem.c (gtk_real_list_item_toggle): applied Johannes
+       Keukelaar's <johannes@nada.kth.se> patch for keyboard support in
+       GtkList widgets.
+
+       * gtk/gtkfilesel.c: adapted dir and file list selection
+       behaviour to deal with keyboard selections. this is a little
+       bit tricky: in the dir list it just changes the entrys value on a one
+       button press. but on a keyboard selection via gtk_widget_activate() it
+       does a new population (likewise on a double click) as this seems more
+       obvious.
+
+1997-10-25  Marius Vollmer  <mvo@zagadka.ping.de>
+
+       * gdk/gdkcolor.c (gdk_colormap_get_system): Initialize
+       private->ref_count.
+
+Wed Oct 22 09:47:43 1997  Tim Janik  <timj@psynet.net>
+
+       * gtk/gtkwindow.c (gtk_window_key_release_event): Fixed a stupid
+       bug that caused the key_release_event to be propagated twice.
+
+Sun Oct 12 11:01:43 1997  Tim Janik  <timj@psynet.net>
+
+        * acconfig.h:
+        * configure.in:
+       * gdk/gdkimage.c: Added configure check for IPC_RMID_DEFERRED_RELEASE,
+       because shmat() fails after a shmctl(..., IPC_RMID,...) for OSF1 V3.2,
+       SunOS 4.1.1, 5.5, 5.5.1, 5.6, IRIX 5.2 and 6.2.
+
+Mon Oct  6 11:59:07 1997  Federico Mena  <federico@bananoid.nuclecu.unam.mx>
+
+       * gdk/gdk.c (gdk_event_translate): In line 1693, fixed typo that
+       would cause motion notify events not to be delivered.
+
+Sun Oct  5 18:15:06 1997  Federico Mena  <federico@bananoid.nuclecu.unam.mx>
+
+       * gtk/gtkrc.c (gtk_rc_parse_bg_pixmap): Changed strdup() for
+       g_strdup().
+
+Wed Sep 24 17:16:34 1997  Peter Mattis  <pmattis@bjork.inktomi.com>
+
+       * configure.in: Fixed a stupid error in the test for libXext that
+       would cause it to fail if X_EXTRA_LIBS was not empty.
+
+       * gtk/gtkmain.h (gtk-timj-970919.patch):
+       * gtk/gtkmain.c (gtk-timj-970919.patch): new function
+       `gtk_idle_remove_by_data' to remove all idle callbacks that take a
+       specific piece of data as argument.  (gtk_get_current_event):
+       remove idles through gtk_idle_remove_by_data.
+        
+       * gtk/gtkwidget.c (gtk-timj-970919.patch):
+        (gtk_widget_destroy): remove pending idles for
+        widgets that have GTK_REDRAW_PENDING or GTK_RESIZE_PENDING and
+        GTK_ANCHORED set (only anchored widgets can have a resize queue
+        handler pending). widgets that have GTK_RESIZE_NEEDED will be removed
+        from their anchored toplevels `resize_widgets' list.
+        
+        (gtk_widget_queue_draw): let the widget remember the queue handler
+        tag (through `redraw_handler_key') for later call to `gtk_idle_remove'.
+        
+        (gtk_widget_queue_resize): let the widget remember the queue handler
+        tag (through `resize_handler_key') for later call to `gtk_idle_remove'.
+        corrected referencing the toplevel widget for which the handler is
+        pending. if a widget is added to the `resize_widgets' list of a
+        toplevel widget, GTK_RESIZE_NEEDED is set and it's referenced.
+        
+        (gtk_real_widget_queue_resize): on the deletion of the `resize_widgets'
+        list, unset GTK_RESIZE_NEEDED and unreference the removed widgets.
+        
+       * gtk/gtkwindow.c (gtk-timj-970919.patch):
+        (gtk_real_window_move_resize): move `resize_containers = NULL'
+        initialization out of if-statement.
+        while stepping through the `resize_widgets' list, unreference the
+        widgets and clear GTK_RESIZE_NEEDED. if a widget realy needs are
+        resize, they are flagged through GTK_RESIZE_NEEDED now (instead of
+        GTK_RESIZE_PENDING, as this is indicative for a pending handler).
+        added checks to provide segfaulting if a widgets parent pointer
+        is NULL (e.g. on toplevel widgets that have GTK_RESIZE_NEEDED set).
+
+Tue Sep 23 13:23:27 1997  Federico Mena  <federico@bananoid.nuclecu.unam.mx>
+
+       * gdk/gdkimage.c: Applied Tim Janik's patch to mark shm segments
+       as IPC_RMID so that they are automatically removed always.
+
+       * gdk/gdkfont.c: Removed casts from lvalues.
+
+       * gtk/gtkmain.c: Removed GTK_RETLOC_*() (which do a cast) from lvalues.
+
+       * gtk/gtkaccelerator.c (gtk_accelerator_table_remove): Added
+       "const" to the accelerator_key param to be consistent with the
+       declaration in gtkaccelerator.h.  The const is not useful in this
+       case, anyway.
+
+Tue Sep 16 13:11:06 1997  Peter Mattis  <pmattis@bjork.inktomi.com>
+
+       * gtkpreview.c: Andrew Logan Kieschnick's change to eliminate
+       round-off error when gamma is set to 1.0.
+
+       * gtkrange.c:
+       * gtkviewport.c: Jay Painter's changes to modify the way in which
+       viewports resize.
+
+       * gdkinput.c:
+       * gdkinputgxi.h:
+       * gdkinputxfree.h:
+       * gtk/Makefile.am:
+       * gtk.h:
+       * gtkeventbox.c:
+       * gtkeventbox.h: Owen Taylor's event box widget and fixes for X
+       input support (that I had broken).
+
+       * gdk.h:
+       * gdkwindow.c:
+       * gtksignal.h:
+       * gtksignal.c: Elliot Lee's changes to support Objective C. (id is
+       apparently a reserved word in Objective C).
+
+Sun Sep 14 22:33:15 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwidget.c (gtk_widget_queue_resize): If the toplevel container
+       is invisible we simply call "gtk_container_need_resize" on
+       it. This fixes a bug with option menus not redrawing correctly.
+
+       * gtkmenuitem.c (gtk_menu_item_enter): (gtk_menu_item_leave):
+       These functions now simply pass the event on to their parent. This
+       is necessary for menus to work properly due to the change in how
+       grabs are dealts with.
+
+       * gtkwindow.c (gtk_real_window_move_resize): Fixed a bug that
+       caused the GTK_RESIZE_PENDING flag to not be unset in some cases.
+
+Fri Sep  5 20:49:37 1997  Marius Vollmer  <mvo@zagadka.ping.de>
+
+       Bug fixes:
+
+       * Makefile.am: Added PATCHES to EXTRA_DIST.
+       * gtk/gtkpixmap.c (gtk_pixmap_new): Move the "pixmap != NULL" test
+       after the allocation of the pixmap.
+
+       To shut up the compiler:
+
+       * gtk/gtkfilesel.c (get_pwdb): Initialize home_dir.
+       * gtk/gtkmain.c (gtk_init): Replace comments around calls to
+       g_set_*_handler with "if (0)".
+       * gtk/gtkrc.c (gtk_rc_get_token): Initialize hex_number and
+       float_number.
+       * gtk/gtkwindow.c (gtk_window_key_press_event): Initialize
+       direction.
+
+       Changes to the type system in gtk/:
+
+       * Makefile.am: Added gtktypebuiltins.h to gtkinclude_HEADERS.
+       Added gtk.defs, runelisp, gentypeinfo.el and gtktypebuiltins.c to
+       EXTRA_DIST.  Added rules to generate gtktypebuiltins.* from
+       gtk.defs.
+
+       * runelisp, gentypeinfo.el, gtk.defs: New files.
+
+       * gtkaccelerator.c, gtkaccelerator.h (gtk_accelerator_table_ref):
+       Return the table so that this function can be used as the `copy'
+       function for GTK_TYPE_BOXED values.
+       * gtkstyle.c, gtkstyle.h (gtk_style_ref): Likewise.
+
+       * gtkenums.h: Removed GtkArgType enum.
+
+       * gtkmain.c (gtk_init): Call gtk_type_init to initialize the type
+       system.
+
+       * gtkobject.c (gtk_object_init_type): New function to take over
+       for gtk_object_get_type. (gtk_object_get_type): Just return the
+       constant GTK_TYPE_OBJECT. (gtk_object_collect_args): Do the right
+       thing for the new GTK_TYPE_* types.
+       * gtksignal.c (gtk_params_get): Likewise.
+
+       * gtktypeutils.c: (gtk_type_init_builtin_types): New
+       function. (gtk_type_init): Call it.  Also made non-static.
+       (gtk_type_unique): The allocation scheme for numerical ids has
+       changed: The low 8 bits hold the appropriate GtkFundamentalType of
+       a type, the rest is a globally unique sequence number.
+       (gtk_type_hash): Use the sequence number of a key to hash it.
+       (gtk_type_register_builtin): New function.
+
+       * gtktypeutils.h: (GtkFundamentalType): New enumeration of the
+       fundamental types. (GTK_TYPE_MAKE, GTK_FUNDAMENTAL_TYPE,
+       GTK_TYPE_SEQNO): New macros to work with the new id scheme.
+       (GtkArg): Added fields for new types and renamed old ones.  GtkArg
+       should now be a mostly opaque structure, except name and type.
+       (GTK_VALUE_*): New macros to access the values of a GtkArg.
+       (GTK_RETLOC_*): New macros to access the location of a return
+       value that is contained in a GtkArg.  * gtktypebuiltins.h: New
+       file to access the typeids of the builtin types.
+
+       * gtkwidget.h (GTK_TYPE_WIDGET): New macro to access the type id
+       of the widget class.
+
+       Thru out: Changed GTK_ARG_* to the appropriate GTK_TYPE_*.
+       Changed access to GtkArg structure to the appropriate GTK_VALUE_*
+       or GTK_RETLOC_* macro.  Changed GtkArgType to GtkType.  Changed
+       some guints to GtkType.
+
+       General changes in gtk/ to support interpreters:
+
+       * gtkradiobutton.c (gtk_radio_button_new_from_widget,
+       gtk_radio_button_new_with_label_from_widget): New functions.
+
+       * gtksignal.c (gtk_signal_connect_no_marshal): New function.
+       (struct _GtkHandler): Added no_marshal and destroy_func fields.
+       (gtk_signal_handler_new): Initialize them.
+       (gtk_signal_connect_by_type): Added no_marshal and destroy_func
+       arguments.  Changed all callers.
+       (gtk_signal_destroy): Invoke destroy_func if there is one and the
+       global destroy func does not apply.  (gtk_handlers_run): If the
+       handler has no_marshal set, call its function directly without
+       going thru the signal's marshaller.
+
+Wed Sep  3 09:56:22 1997  RHS Linux User  <pmattis@bjork.inktomi.com>
+
+       * gtkrange.c: Changed the way the range control focus was drawn so
+       that the range control is drawn correctly when it does not have
+       the focus.
+
+Tue Sep  2 17:41:17 1997  RHS Linux User  <pmattis@bjork.inktomi.com>
+
+       * gtkwidget.c: 'gtk_real_widget_queue_resize' should only remove
+       the "resize_widgets" if another resize is not pending.
+
+Mon Sep  1 18:28:08 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmain.c: Changed the way GDK_DELETE events are handled. Only,
+       if 'gtk_widget_event' returns TRUE is the widget destroyed. By
+       default, 'gtk_widget_event' will return FALSE causing the window
+       to not be destroyed. This prevents segfaults in the GIMP and other
+       programs that do not correctly handle GDK_DELETE events.
+
+       * gtkmain.c: Added modal dialog support by allowing events
+       destined for a child of the grab widget to go to the child instead
+       of the grab widget. (Added 'gtk_widget_is_ancestor' to determine
+       the relationship between the grab widget and the event widget).
+
+       * *.[ch]: Incorprated a whole mess of patches. (Started keeping
+       the ChangeLog up to date again).
+
+Thu Jun  5 17:22:21 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenufactory.c:
+       * gtkmenufactory.h: Added 'gtk_menu_factory_remove_*'
+       calls. Removing entries/paths causes the associated widgets to be
+       destroyed.
+
+       * gtkwidget.c:
+       * gtkwidget.h: Calling 'gtk_widget_set_style' is used as an
+       indication that the programmer specifically wants that style to be
+       used. RC-style substitution is disabled for the widget after such
+       a call.
+
+       * gtkpixmap.c:
+       * gtkpixmap.h:
+       * gtkimage.c:
+       * gtkimage.h: Changed to use clip mask and a single pixmap (or
+       image) to deal with transparent areas.
+
+       * gdkpixmap.c: Modified xpm loading routines to optionally return
+       a clip mask.
+
+       * gdkgc.c:
+       * gdkdraw.c:
+       * gdktypes.h: Modifications to allow clip masks to be used with
+       gc's. Clip masks are bitmaps that specify drawable regions.
+
+Thu May  1 03:11:51 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkscrolledwindow.c: Scrolled windows need to have the
+       GTK_NO_WINDOW flag set. Not having it set caused an obscure
+       redrawing bug.
+
+Wed Apr 30 12:38:03 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkhruler.c:
+       * gtkvruler.c: Fixed a small bug that caused the indicator to be
+       positioned slightly off.
+
+Sun Apr 27 14:28:21 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenushell.c:
+       * gtkmenushell.h:
+       * gtkmenu.c:
+       * gtkmenu.h: Changes so that if a menu is popped up there is a
+       timeout period during which a menu item will not be activated and
+       if the mouse button is released in that period the menu will stay
+       popped up.
+
+       * gtkcurve.c:
+       * gtkcurve.h: Included curve widget courtesy of David
+       Mosberger-Tang (davidm@azstarnet.com).
+
+       * gtkentry.c:
+       * gtkentry.h: Changed "insert" and "delete" signals to
+       "insert_text" and "delete_text" respectively. (The symbol "delete"
+       cannot be used since it is a C++ reserved word).
+
+Sat Apr 19 01:43:49 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenufactory.c: A path which ends in "<nothing>" will cause an
+       invisible (hidden) menu entry to be created. This is useful for
+       setting an accelerator key for which a corresponding menu entry is
+       not desired.
+
+       * gtktooltips.c: Fixed some problems with destruction of the
+       active tip widget not properly updating the tooltips data
+       structures.
+
+Fri Apr 18 15:09:45 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkcontainer.c:
+       * gtklist.c:
+       * gtkwidget.c:
+       * gtkwidget.h: Patch from Owen Taylor (owt1@cornell.edu) which
+       fixes problems with destruction of objects and with destruction of
+       objects which hold the focus.
+
+Thu Apr 17 11:29:15 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenushell.c: Incorrect logic in
+       'gtk_menu_shell_button_release' for deciding when a menu should
+       stay popped up when the mouse button is released.
+
+       * *.c: Miscellaneous fixes from folks on the net.
+
+Tue Apr 15 02:43:17 1997  Peter Mattis  <pmattis@localhost>
+
+       * *.c:
+       * gtkwidget.h: Added GTK_BASIC widget flag which when set
+       specifies a widget as "basic". A "basic" widget is one which
+       doesn't take input events. For example, labels, pixmaps, boxes,
+       tables, alignments, etc.
+
+Sat Apr 12 15:23:08 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkcolorsel.c: Add "#include <math.h>" to define M_PI.
+
+       * gtksignal.c: Fixed a bug in 'gtk_signal_emit' which showed up
+       because of the new cast checking macros. The 'object' was being
+       accessed after it had been destroyed.
+
+       * gtkoptionmenu.c: Fixed bug with using 'GTK_BIN' instead of
+       'GTK_BUTTON' which showed up because of the new cast checking
+       macros.
+
+       * *.h: 'GTK_CHECK_CAST', 'GTK_CHECK_CLASS_CAST' and
+       'GTK_CHECK_TYPE' used by standard widget macros everywhere.
+
+Wed Apr  9 00:54:17 1997  Peter Mattis  <pmattis@localhost>
+
+       * docs/gtk.texi: Started further work on documentation. Major
+       changes and additions are being made.
+
+       * gtkarrow.c:
+       * gtkarrow.h: Removed function 'gtk_arrow_get'.
+
+       * gtkcontainer.c: 'gtk_container_check_resize' no performs
+       additional checking to account for the case where the containers
+       allocation is no longer sufficient because its parent (or its
+       parents parent, etc.) needs to resize its children.
+
+Tue Apr  8 21:15:50 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkstyle.c: Fixed a bug in 'gtk_style_init' in which the font
+       was not ref'd (via 'gdk_font_ref'), but was free'd (via in
+       'gdk_font_free') in 'gtk_style_destroy'. (David
+       Mosberger-Tang). Also cleaned up 'gtk_style_destroy' while I was
+       at it.
+
+       * gtkmain.c: Fixed a bug in 'gtk_propogate_event' which caused
+       entry widgets (and probably other widgets) not to be destroyed in
+       some instances.
+
+Mon Apr  7 01:20:38 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkentry.c:
+       * gtkentry.h: Changed the "insert_text", "delete_text" and
+       "changed_text" signals to "insert", "delete", and "changed"
+       respectively. They really should have been named this way
+       originally except the previous signal mechanism prevented
+       duplicate signal names. ("changed" is also used by adjustments).
+
+       * gtkradiomenuitem.c:
+       * gtkradiomenuitem.h: New widget.
+
+       * gtkcheckmenuitem.c:
+       * gtkcheckmenuitem.h: New widget.
+
+       * gtksignal.c: Modified 'gtk_signal_lookup' to require an object
+       type to be passed as a parameter. In addition, signals are now
+       only needed to be uniquely defined in their branch of the class
+       hierarchy. This allows the same signal name to be used in two
+       different branches of the class hierarchy. For instance, the
+       "changed" signal is used both by adjustments and entries...in
+       different ways!
+
+       * gtktypeutils.c: Added 'gtk_type_parent' which returns the parent
+       type for a given type.
+
+Sun Apr  6 22:08:35 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwidget.c: If a widget is set insensitive it loses the focus
+       if it had it.
+
+       * gtkcontainer.c: Insensitive widgets no longer participate in tab
+       traversal.
+
+       * gtkscrolledwindow.c: The "viewport" child is now destroyed and a
+       container class "foreach" function was written (which fixes the
+       sensitivity bug).
+
+Sat Apr  5 14:25:38 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkhscrollbar.c:
+       * gtkvscrollbar.c: Fixed trough size allocation bug.
+
+       * gtkhscale.c:
+       * gtkvscale.c: Fixed trough size allocation and position bug that
+       showed up when scales were placed in notebooks.
+
+Thu Mar 27 17:45:54 1997  David Mosberger-Tang  <davidm@azstarnet.com>
+
+        * gtk/gtkmain.c (gtk_handle_idle): Fix appending pending_idles to
+        idle_functions so it works even when idle_functions is empty.
+
+Sat Mar 15 14:15:59 1997  Peter Mattis  <pmattis@localhost>
+
+       * *.[ch]: Moved '*_class_init' and '*_init' function declarations
+       for widgets into the source file as those functions no longer had
+       to be public.
+
+       * gtkcheckbutton.c: Fixed redrawing of check button.
+
+       * gtkframe.c: Fixed redrawing of frame when the shadow type is
+       changed.
+
+Sat Mar  8 15:19:23 1997  Peter Mattis  <pmattis@localhost>
+
+       * gdkimage.c: Fixed a stupid bug with 'gdk_image_new' which
+       potentially added a NULL image to "image_list" and caused problems
+       when 'gdk_image_exit' was called.
+
+Wed Mar  5 00:40:08 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkpreview.c: Massively changed the colormap handling used by
+       the preview widget. Gray previews are now dithered. A single
+       visual and colormap is shared by the color and gray previews. A
+       GTK_PREVIEW_INFO property is installed on the root window in
+       certain cases to allow multiple GTK programs to share the system
+       colormap.
+
+Sun Mar  2 05:43:06 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkcheckbutton.c: 'gtk_checkbutton_size_allocate' was allocating
+       too much space to its children and not leaving the check button
+       room for the focus border.
+
+       * gtknotebook.c: 'gtk_notebook_size_request' wasn't requesting
+       enough space when the notebook tabs are visible.
+
+Sat Mar  1 01:59:35 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkpreview.c: Fixed a problem with 'gtk_preview_put' when the
+       image byte order is GDK_MSB_FIRST.
+
+       * gtksignal.c:
+       * gtksignal.h: Added 'gtk_signal_connect_after' and
+       'gtk_signal_connect_object_after' functions. These connect signal
+       handlers which will run after the class function associated with
+       the signal.
+
+       * gtkstyle.c: Fixed a stupid bug in 'gtk_style_new_from_key' that
+       was causing twice as many styles to be created as necesary.
+
+       * gtkwidget.c: 'gtk_real_widget_size_allocate' erases the widgets
+       old allocation if it has the GTK_NO_WINDOW flag set.
+
+       * gtkwidget.c: 'gtk_real_widget_unmap' now erases the widget if it
+       has the GTK_NO_WINDOW flag set.
+
+       * gtklabel.c: Removed 'gtk_label_unmap' as similar functionality
+       was added to gtk_real_widget_unmap.
+
+       * gtkbin.c: Modified 'gtk_bin_map' and 'gtk_bin_unmap' so that it
+       erases and draws the widget if it has the GTK_NO_WINDOW flag set.
+
+       * gtkframe.c: Modified 'gtk_frame_size_allocate' so that it erases
+       the old allocation.
+
+Fri Feb 28 03:27:05 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwindow.c: 'gtk_window_set_title' now changes the window title
+       if the window is already realized.
+
+       * gtkentry.c: 'gtk_entry_set_text' was emitting both a
+       "delete_text" and a "changed_text" signal. Modified so that it
+       only emits a "changed_text" signal.
+
+       * gtkpreview.c: Modified to work correctly on systems with MSB
+       byte order. The colormap for TRUE and DIRECT color displays is now
+       created if the default visual is not equal to the visual we are
+       using.
+
+       * gtkstyle.c: 'gtk_style_attach' and 'gtk_style_find' weren't
+       working properly in the presence of multiple colormaps are
+       different depth visuals.
+
+       * gtkcontainer.c: Massively improved focus traversal using tab and
+       arrow keys. It now uses the layout of the widgets to determine
+       where to move the focus to.
+
+Mon Feb 24 03:24:02 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenufactory.c: Set the accelerator table field for menus when
+       they are created.
+
+       * gtkmenu.c:
+       * gtkmenu.h: Added a default accelerator table field to menus so
+       that runtime modification of accelerator keys in menus can work
+       better.
+
+       * gtkrange.c: 'gtk_range_default_{h,v}motion' had faulty logic for
+       deciding what to do when the slider was at the edge of the
+       trough. They previously didn't update the adjustment value event
+       if the value wasn't what it should be when the slider was at the
+       edge of the trough.
+
+       * gtkviewport.c: 'gtk_viewport_size_allocate' and
+       'gtk_viewport_adjustment_value_changed' both had the potential for
+       performing a divide by 0. Checks are now in place to prevent this.
+
+       * gtkmenu.c: 'gtk_menu_map' now makes sure the menu lies on screen
+       if the position function is NULL.
+
+       * gtkentry.c: Modified selection handling. 'gtk_delete_selection'
+       actually removes the X selection now. 'gtk_entry_destroy' removes
+       the selection as well and relies on the change in "gdk.c" to make
+       sure the selection event will not be sent to a non-existant
+       window.
+
+       * gdk.c: Selection events are only passed on if the selection
+       owner is not NULL.
+
+       * gtkstyle.c: 'gtk_style_detach' and 'gtk_style_destroy' were not
+       destroying the black and white gc's.
+
+Sun Feb 23 19:17:56 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwindow.c: 'gtk_window_size_request' was setting the window
+       hints. This was also being done in 'gtk_window_map', so the
+       instance being done in 'gtk_window_size_request' was removed.
+
+Fri Feb 21 01:04:01 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwidget.c: 'gtk_widget_draw' has to use the widgets allocated
+       position for the drawing rectangle when the widget has the
+       GTK_NO_WINDOW flag set.
+
+       * gtkwidget.c: In 'gtk_widget_init' the visual and colormap were
+       being directly compared against 'default_visual' and
+       'default_colormap' instead of calling
+       'gtk_widget_get_default_{visual,colormap}'.
+
+       * gdkrectangle.c: Amazing! There was a bug in the
+       'gtk_rectangle_intersect' logic. Its been there for near eternity
+       and I never noticed.
+
+       * gtkpreview.c:
+       * gtkpreview.h: Created preview widget which allows drawing to an
+       rgb or grayscale buffer which is automatically displayed on the
+       screen. Performs dithering as necessary.
+
+Thu Feb 20 20:33:21 1997  Peter Mattis  <pmattis@localhost>
+
+       * gdkwindow.c: Modified the logic in 'gdk_window_new' which
+       determined when to add a window to the WM_COLORMAP_WINDOWS
+       property.
+
+Wed Feb 19 19:55:29 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkruler.c: 'gtk_ruler_make_pixmap' was always destroying the
+       old backing store and creating a new one even when it would create
+       a new one of exactly the same size as the old one.
+
+Tue Feb 18 18:32:10 1997  Peter Mattis  <pmattis@localhost>
+
+       * gmem.c: 'g_mem_chunk_alloc' was incorrectly modifying the mem
+       areas free mem field when reallocating a previously freed
+       atom. This caused a fairly severe memory leak.
+
+       * gtkmenushell.c: 'gtk_menu_shell_button_release' had a bug in the
+       logic for deciding whether to initiate an X pointer grab or not
+       when the mouse button was released. It now only initiates a grab
+       if the mouse is released within an active menu item.
+
+Fri Feb 14 00:57:40 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtknotebook.c: Changed the look of notebook tabs slightly.
+
+       * gtkentry.c:
+       * gtkentry.h: Deleting an entry widget which is holding the X
+       selection presents some difficulties. The X selection must be
+       released, but the widget can't be destroyed until the
+       SELECTION_CLEAR event is received that the X server will send in
+       response to clearing the X selection. There are probably still
+       bugs in the current method of entry widget deletion when the X
+       selection is held.
+
+       * gtkmain.c: 'gtk_propagate_event' was not properly destroying the
+       toplevel window when receiving a key press event.
+
+       * gtkwidget.c: Setting a widget insensitive did not cause it to
+       redraw. It now does.
+
+Thu Feb 13 16:59:07 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkviewport.c: 'gtk_viewport_size_allocate' was allocating its
+       child widget an adjusted allocation. Since the actual scrolling
+       has handled by a subwindow this caused the child to be double
+       scrolled. Modified to always set the child allocations origin to
+       (0, 0).
+
+Wed Feb 12 01:06:48 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkentry.c: Text is now centered vertically. Previously it was
+       pushed up against the top. This problem was only evident when the
+       widget was allocated more vertical space than it requested.
+
+       * gtkfilesel.c: 'gtk_file_selection_key_press' was previously only
+       a stub for tab completion. The actual tab completion call had been
+       left out. (Oops!)
+
+Tue Feb 11 01:43:08 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtksignal.c: 'gtk_signal_disconnect_by_data' was going into a
+       loop and crashing. Bad logic. Fixed.
+
+       * gtkmain.c: An idle function which returns FALSE will be removed
+       from the list of idle functions. This makes the functioning of
+       idle functions and timeouts more similar.
+
+       * gtkentry.c: 'gtk_entry_get_text' now returns an empty string
+       when the actual text is NULL. This allows "stupid" programs to use
+       the value returned by 'gtk_entry_get_text' blindly (without
+       checking to see if its NULL).
+
+       * gtkradiobutton.c: Modified 'gtk_radio_button_clicked' so that
+       'gtk_toggle_button_toggled' is called _after_ the widget state is
+       changed.
+
+       * gtksignal.c:
+       * gtksignal.h: Added 'gtk_signal_name' which returns the character
+       string name for a given signal number.
+
+       * gtkwidget.c: 'gtk_widget_set_parent' checks to see if the widget
+       is now "anchored" through the parent chain to a widget which is
+       GTK_ANCHORED. If it is, then it changes the widgets style using
+       'gtk_rc_get_style' and recursively performs the same operation on
+       the widgets children. This is necessary is 'gtk_rc_get_style' only
+       works properly on "anchored" widgets.
+
+       * gtkwindow.c: Modified GTK_WIN_POS logic so that it is only used
+       immediately after the window has been shown.
+
+       * gtkmenu.c: 'gtk_menu_key_press'. Can now change menu item
+       accelerator keys on the fly. Why? Why not. Cool/useless feature of
+       the day.
+
+       * gtkmenuitem.c: Accelerator key drawing. Somehow that never got
+       finished. (Oops!)
+
+       * gtkdrawingarea.c: 'gtk_drawing_area_size_allocate' was not
+       actually installed during 'gtk_drawing_area_class_init'. (Oops!)
+
+       * gtkframe.c: 'gtk_frame_size_request' fixed size requisition
+       problem caused by unsigned arithmetic.
+
+       * gtkwindow.c: Modified window widget so that it only uses the
+       widget uposition auxiliary information immediately after it has
+       been shown. This prevents the annoying bug which can cause a
+       uposition'ed window to jump back to its original position after
+       the user moves it.
+
+       * gtkwidget.c: Need to ref and unref style in
+       'gtk_widget_{push,pop}_style' to make sure that a style on the
+       style stack is not destroyed.
+
+       * gtktogglebutton.c: 'gtk_toggle_button_set_state' now calls
+       gtk_button_clicked to actually change the state of the
+       button. In this way, radio buttons can now perform the appropriate
+       actions when the toggle button state is set.
+
+Mon Feb 10 00:27:39 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtklist.c: 'gtk_list_select_item' and 'gtk_list_unselect_item'
+       were casting a GList* variable to a a GtkWidget* variable. Bad bad
+       bad. (Tim Janik).
+
+       * gtksignal.c: Modified 'gtk_signal_connect' and
+       'gtk_signal_connect_object' to warn when a signal type cannot be
+       found.
+
+Sun Feb  9 00:15:30 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkoptionmenu.c:
+       * gtkoptionmenu.h: Changed option menus back to being derived from
+       buttons. This fixes up some screwiness with their user
+       interaction.
+
+       * gtkwindow.c: Modified key press handler to support focus
+       traversal.
+
+       * gtkcontainer.c:
+       * gtkcontainer.h: Added default focus traversal back in.
+
+Sat Feb  8 10:44:38 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkviewport.h:
+       * gtkviewport.c: Massively sped up viewport scrolling. Used to be
+       reallocating child's size (offset) each time a scrollbar
+       moved. Now a subwindow is moved. All the children are moved
+       automatically by moving the subwindow. Much much much faster.
+
+Tue Feb  4 00:20:44 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtree.c: Changed 'g_tree_node_search' to use a loop instead of
+       recursion.
+
+Mon Feb  3 11:30:03 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkbutton.c: Removed 'parent_destroy' global and replaced it
+       with 'parent_class' global to reflect style used in other
+       widgets.
+
+       * gtknotebook.c: Tab labels were being allocated less than their
+       requested size.
+
+       * gtkrange.c:
+       * gtkrange.h: Moved the "digits" field of scales into the range
+       type. The adjustment value for scales is truncated to the number
+       of visible digits instead of being left untouched.
+
+       * gtree.c: Fixed a bug in the AVL tree implementation. Single
+       rotations were always being performed during insertion. It is
+       sometimes necessary to perform a double rotation.
+
+       * gtklabel.c: Modified 'gtk_label_expose' to only draw the label
+       when the allocated space is greater than or equal to the requested
+       space.
+
+       * gtklabel.c: Added call to 'gtk_widget_unmap' to
+       'gtk_label_destroy' in order for the label to redraw correctly
+       (erase itself) when destroyed.
+
+       * gtklabel.c: Added 'gtk_label_unmap' call which erases the labels
+       allocation when it gets unmapped.
+
+       * *.h: Removed a few remaining instances of using "class" as a
+       parameter name. (Causes problems for C++).
+
+Fri Jan 31 12:26:50 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkcontainer.c: 'gtk_container_enable_resize' needs to call
+       'gtk_container_check_resize' instead of
+       'gtk_container_need_resize'.
+
+       * gtkwidget.c: 'gtk_real_widget_show' now maps the widget if its
+       parent is mapped.
+
+       * gtkscrolledwindow.c: Fixed size allocation when the scrollbar
+       policy's are GTK_POLICY_AUTOMATIC. Doing it correctly is harder
+       than I originally thought.
+
+       * gtklist.c: Added 'gtk_list_child_position' to determine the
+       integer position in a list of a child. Filled in the
+       'gtk_list_item_select' and 'gtk_list_item_unselect' stubs.
+
+Thu Jan 30 16:08:06 1997  Peter Mattis  <pmattis@localhost>
+
+       * gmem.c: Changed the implementation of G_ALLOC_AND_FREE mem
+       chunks. They used to allocate SIZEOF_VOID_P extra bytes per atom
+       in order to keep track of which mem area they were allocated
+       from. Now the mem area is determined by searching through an AVL
+       tree of the mem areas for a mem chunk and comparing memory
+       locations. A little slower, but makes G_ALLOC_AND_FREE mem chunks
+       much more attractive.
+
+       * gtree.c: Added an AVL tree implementation to glib.
+
+       * gtksignal.c:
+       * gstring.c: va_arg (arg_list, {char, short}) is
+       invalid. Arguments passed in a variable argument list are
+       promoted. ({char, short}->int). Seemed to work ok before under
+       Linux. Crashed under FreeBSD.
+
+Tue Jan 28 02:27:51 1997  Peter Mattis  <pmattis@localhost>
+
+       * gdkwindow.c: Fixed a major slowdown apparent in the file
+       selection dialog which was caused by calling
+       'gtk_window_add_colormap_windows' way way way too often.
+
+       * *.c: Many widgets called 'gtk_container_need_resize' when
+       something internal changed which would cause the widget to grow or
+       shrink. The assumption was made that the widget would change size
+       and an expose event would be generated. This happens "most" of the
+       time. But its possible for certain widgets to change size without
+       generating expose events, or for its internal geometry to change
+       without a change of size which would mean no expose event was
+       generated. So a wrapper function called
+       'gtk_container_check_resize' was created and
+       'gtk_container_need_resize' was modified so that it returns FALSE
+       if a resize was actually generated and TRUE if nothing
+       changed. This allows 'gtk_container_check_resize' to initiate a
+       'gtk_widget_size_allocate' and 'gtk_widget_draw' to emulate the
+       expose event.
+
+Sat Jan 25 14:17:44 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmain.c: Fixed a bug with propogating key press events. The
+       events were sent 2 times to the toplevel windows which caused the
+       focus widget to be activated twice when the space bar was pressed.
+
+       * */configure.in:
+       * */Makefile.am: Added support for libtool and removed the old
+       shared library configuration craziness.
+
+Fri Jan 24 12:59:22 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtktext.c:
+       * gtktext.h: Josh's fixes and additions to the text widget.
+
+       * gtkfill.c:
+       * gtkfill.h: Filler widget useful for filling space in a
+       table. Can specify a minimum size. Used by the canvas widget.
+
+       * gtknotebook.c:
+       * gtknotebook.h: Made outline of notebook widget.
+
+       * gtkcanvas.c:
+       * gtkcanvas.h: Started canvas widget. A composite of 2 rulers (w/
+       an origin), 2 scrolllbars. Guides, grids, snap to.
+
+Sun Jan 19 18:26:45 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkdialog.c:
+       * gtkdialog.h: Created dialog widget which creates a standard
+       looking dialog with buttons along the button and a separator.
+
+       * gtkxid.c: Generalized the window table code for looking up a gdk
+       window based on an XID to work for any XID and a piece of
+       data. Can now look up gdk fonts based on their XID.
+
+       * gtkruler.c:
+       * gtkruler.h:
+       * gtkhruler.c:
+       * gtkhruler.h:
+       * gtkvruler.c:
+       * gtkvruler.h: Started conversion of the ruler widget.
+
+       * gtktext.c:
+       * gtktext.h: Started conversion of the text widget. Scrolling
+       doesn't work.
+
+       * gtkmain.c: Fixed a fairly major bug. The event widget needs to
+       be in a call for the entire duration of handling an event. Not
+       just for when the event widget itself is handling the event.
+
+       * gtkfilesel.c: Fixed up some bugs with resizing.
+
+Fri Jan 10 14:18:03 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwidget.c:
+       * gtkwidget.h:
+       * gtkentry.c:
+       * gtkentry.h: Support for selections.
+
+       * gdkselection.c:
+       * gdk.c:
+       * gdktypes.h:
+       * gdk.h: Gdk support for X selections. Currently only text
+       selections are supported.
+
+       * gtksignal.c: Fixed a major bug which occurred when destroying an
+       object. Memory was being written to after it was freed.
+
+       * gtkfilesel.c:
+       * gtkfilesel.h: Hooked up more functionality to the file selection
+       dialog.
+
+Wed Jan  8 18:13:53 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkfilesel.c:
+       * gtkfilesel.h: Mostly converted old file selection dialog
+       widget. The widget is derived from the GtkWindow class and is
+       quite a bit simpler in the widget code.
+
+       * gtkwidget.c: Fixed 'gtk_widget_grab_focus' and
+       'gtk_widget_grab_default' to check that the toplevel widget is a
+       type of window (which includes classes derived from windows).
+
+Tue Jan  7 01:12:32 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwindow.c: Was calling 'gtk_window_resize' twice in a
+       row...why?
+
+       * gtksignal.c:
+       * gtksignal.h:
+       * *.c: Changed 'gtk_signal_new' so that the class function that is
+       called when the signal is emitted can be called either before,
+       after or both before and after the calling of any signal
+       handlers.
+
+       * gtkobject.c:
+       * gtkobject.h: Added 'object_data' mechanism for storing data
+       associated with a character string key in objects. Removed
+       'user_data' field of objects and changed
+       'gtk_object_{get,set}_user_data' to use the object data
+       mechanism. Removed 'handlers' field of objects.
+
+       * gtkwidget.c:
+       * gtkwidget.h:
+       * gtkwindow.c: Modified aux info mechanism to use object data
+       mechanism.
+
+       * gtksignal.c: Modified signal mechanism to use object data
+       mechanism instead of 'handlers' field.
+
+
+Mon Jan  6 15:10:16 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenushell.c: Fixed up button press handling so as to conform
+       more closely to that used by Motif.
+
+Wed Jan  1 21:27:17 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenu.c:
+       * gtkmenu.h:
+       * gtkmenubar.c:
+       * gtkmenubar.h:
+       * gtkmenushell.c:
+       * gtkmenushell.h: Reorganization of menu-ing code so that code
+       duplication is reduced. The menu shell now contains most of the
+       code for menu-ing interaction while menus and menubars simply layout
+       their child menu items in the appropriate place.
+
+Sun Dec 29 17:48:18 1996  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenu.c:
+       * gtkmenubar.c:
+       * gtkmenuitem.h:
+       * gtkmenuitem.c: Modifications so that menu item accelerators and
+       the submenu indicator are drawn correctly and the correct amount
+       of space is allocated.
+
+Sat Dec 28 00:32:13 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtkmenufactory.h:
+       * gtkmenufactory.c: Started menu factories as an easy method to
+       create and manipulate menus.
+
+Fri Dec 27 13:17:34 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtkmenu.c:
+       * gtkmenu.h:
+       * gtkmenubar.c:
+       * gtkmenubar.h:
+       * gtkmenuitem.c:
+       * gtkmenuitem.h:
+       * gtkmenushell.c:
+       * gtkmenushell.h: Implemented basic menu functionality. Menubars
+       and popup menus work. Submenus work. (Much left to be done).
+
+Wed Dec 18 15:27:05 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtktypeutils.h:
+       * gtktypeutils.c: Added 'gtk_type_from_name' which returns a type
+       identifier given a type name. Implemented using a second hash
+       table keyed by type names.
+
+       * gtkbutton.c:
+       * gtktogglebutton.c: Fixed very small messed-up drawing bug when a
+       button loses its focus.
+
+       * gtkwidget.h:
+       * gtkwidget.c:
+       * gtkbutton.c:
+       * gtkwindow.c: Added default button handling. Default buttons now
+       draw correctly and pressing return or enter causes the default
+       button (if one exists) to be activated.
+
+Tue Dec 17 19:32:21 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtkhscale.c:
+       * gtkvscale.c: Overrode 'draw_slider' method of ranges in order to
+       draw the slider of scales with a line in them so as to be closer
+       to the Motif look-and-feel.
+
+       * gtkwindow.c: Modified 'gtk_window_focus_in_event' so that focus
+       in events are only handled when the window is visible. Fixes a bug
+       where spurious focus in events get sent when a window is being
+       hidden.
+
+       * gtkwidget.h: Added 'activate_signal' field to the GtkWidgetClass
+       structure. Added 'gtk_widget_activate' call to emit the activate
+       signal for a widget if it is non-zero.
+
+Tue Dec 10 15:59:45 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtkwidget.c: 'gtk_widget_set_name' oops in strdup'ing the old
+       "widget->name" instead of the new one we are setting.
+
+       * gtkrc.c: 'gtk_rc_widget_path' changed to use
+       'gtk_widget_get_name' instead of accessing the "widget->name"
+       field directly.
+
+       * gtkwidget.c: Added 'gtk_widget_get_name' function which returns
+       the widgets name if it exists and the widgets type name if it does
+       not.
+
+       * gtkcheckbutton.c: Added 'gtk_check_button_draw'
+       function. Modified 'gtk_check_button_expose' to pass an expose
+       event to child instead of callings its draw function.
+
+       * gtkentry.c: 'gtk_entry_draw_text' why was "+1" being added to
+       the font->ascent to calculate the font position? This was wrong
+       and caused some characters in fonts to be clipped. (Notably "g").
+
+       * gtkentry.c: 'gtk_entry_realize' specify GTK_BUTTON1_MOTION_MASK
+       and GTK_POINTER_MOTION_HINT_MASK for _both_ windows.
+
+       * gtkmain.c: 'gtk_propagate_event' needs to set the GTK_IN_CALL
+       flag for the object before calling 'gtk_widget_event' and needs to
+       destroy the object if necessary after 'gtk_widget_event' returns.
+
+       * gtkradiobutton.c: 'gtk_radio_button_clicked' needs to call
+       'gtk_toggle_button_toggled' when the currently active button is
+       toggled.
+
+       * gtkwidget.c: 'gtk_real_widget_hide' needs to call
+       'gtk_widget_unmap' if the widget is currently mapped.
+
+       * gtkwindow.c: Prevent automatic resizing after the user has
+       specified a new window size. Add 'handling_resize' flag to
+       windows.
+
+       * gtkscrolledwindow.c: Implement the GTK_POLICY_AUTOMATIC
+       scrollbar policy. Need to connect to the adjustments 'changed'
+       signal and notice when the scrollbars aren't in use.
+
+       * gtkcontainer.c: 'gtk_container_init' must set 'auto_resize' and
+       'need_resize' fields to TRUE and FALSE respectively.
+
+       * gtkwidget.c: 'gtk_widget_set_parent' must all set a widgets state
+       to its parents state.
+
+Sun Dec  1 01:31:01 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * Started ChangeLog
diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8
new file mode 100644 (file)
index 0000000..a065ebe
--- /dev/null
@@ -0,0 +1,1140 @@
+Mon Nov 17 1997 Jay Painter <jpaint@serv.net>
+       * gtkviewport.c: Raph's Mon, 10 Nov 1997 patch to gtk-list 
+       to fix some viewport bugs
+
+Mon Nov 17 1997 Jay Painter <jpaint@serv.net>
+       * gtk/gtkwidget.c: gtk-ajaborsk-971016-2
+       A little patch again to prevent user to use gtk_widget_set_events()
+       when a widget is already realized.
+       In this case, the gtk_widget_set_events() doesn't work.
+
+Mon Nov 17 1997 Jay Painter <jpaint@serv.net>
+       * gtk/gtkwindow.c: gtk-ajaborsk-971016-1
+       This small patch correct position for GTK_WIN_POS_CENTER and
+       GTK_WIN_POS_MOUSE GtkWindow positions.
+
+Sat Nov 15 1997 Jay Painter <jpaint@serv.net>
+       * gdk/gdkgc.c: added function gdk_gc_set_clip_rectangle
+       * gdk/gdk.h: header for above
+
+Sat Nov 15 1997 Jay Painter <jpaint@serv.net>
+       * gdk/gdkgc.c: added function gdk_gc_set_clip_rectangle
+       * gdk/gdk.h: header for above
+
+Wed Nov 12 1997 Jay Painter <jpaint@serv.net>
+       * gdk/gdkpixmap.c: Patrice Fortier's patch for transparent pixmaps.
+       * gdk/gdk.h:
+         gdk/gdkdraw.c: Patrice Fortier's patch to add pixel draw function.
+
+Sun Nov  9 1997 Jay Painter <jpaint@serv.net>
+       * Fixed problems with makefiles relating to the bug
+       which required glib to be installed.
+       * Fixed makefiles to incluce the xpm's in gtk+/gtk needed
+       for testgtk.
+       * Updated gtk+ and gtk+/glib to libtool-1.0f
+
+Fri Nov  7 1997 Jay Painter <jpaint@serv.net>
+       * gtk/gtktext.c: return char_widths[ch & 0xff]; in line 2152
+
+Thr Nov  5 1997 Jay Painter <jpaint@serv.net>
+       * gtk/testgtk.c: added drag and drop test, removed the test hack
+       from the button test
+
+Tue Nov  4 08:28:57 1997  Federico Mena  <federico@bananoid.nuclecu.unam.mx>
+
+       * gtk/gtkmain.c (gtk_handle_idle): Patch from David Mosberger to
+       avoid crashes when handling idle function (this manifested itself
+       in the Umax and Microtek backends in SANE.
+
+Sun Nov  2 07:34:56 1997  Tim Janik  <timj@psynet.net>
+
+       * gtk/gtkfilesel.c: Small fixes about a segmentation viaolation
+       cause by a double click in the directoy list (introduced by my
+       previous changes).
+       
+       * gtk/gtklist.c: Small fixes to gtk_list_add() and gtk_list_remove().
+       
+       * gtk/testgtk.c (list_add): Applied Stefan Wille's patch to make this
+       function do something ;).
+
+Fri Oct 31 Jay Painter <jpaint@serv.net>
+       *gdk/gdk.c: reformatted DND code for GTK coding standards
+       *gdk/gdkwindow.c: changed memory allocation for DND to q_mem stuff
+
+Thu Oct 30 Jay Painter <jpaint@serv.net>
+       * gdk/gdkwindow.c: 
+       * gdk/gdk/gdk.h:
+       * gtk/gtkwidget.h:
+       * gtk/gtkwidget.c: Applied Stephan Willie's shaped window patch
+
+       * gdk/gdkwindow: 
+       * gdk/gdk.h:
+       * gtk/gtkwidget.h:
+       * gtk/gtkwidget.c: reformatted the DND code to conform to GTK
+               coding standards
+
+       * gtk/testgtk: massive fixes, SW's shaped window example
+
+Thu Oct 30 07:33:27 1997  Tim Janik  <timj@psynet.net>
+
+       * gtk/gtklistitem.c (gtk_real_list_item_toggle): applied Johannes
+       Keukelaar's <johannes@nada.kth.se> patch for keyboard support in
+       GtkList widgets.
+
+       * gtk/gtkfilesel.c: adapted dir and file list selection
+       behaviour to deal with keyboard selections. this is a little
+       bit tricky: in the dir list it just changes the entrys value on a one
+       button press. but on a keyboard selection via gtk_widget_activate() it
+       does a new population (likewise on a double click) as this seems more
+       obvious.
+
+1997-10-25  Marius Vollmer  <mvo@zagadka.ping.de>
+
+       * gdk/gdkcolor.c (gdk_colormap_get_system): Initialize
+       private->ref_count.
+
+Wed Oct 22 09:47:43 1997  Tim Janik  <timj@psynet.net>
+
+       * gtk/gtkwindow.c (gtk_window_key_release_event): Fixed a stupid
+       bug that caused the key_release_event to be propagated twice.
+
+Sun Oct 12 11:01:43 1997  Tim Janik  <timj@psynet.net>
+
+        * acconfig.h:
+        * configure.in:
+       * gdk/gdkimage.c: Added configure check for IPC_RMID_DEFERRED_RELEASE,
+       because shmat() fails after a shmctl(..., IPC_RMID,...) for OSF1 V3.2,
+       SunOS 4.1.1, 5.5, 5.5.1, 5.6, IRIX 5.2 and 6.2.
+
+Mon Oct  6 11:59:07 1997  Federico Mena  <federico@bananoid.nuclecu.unam.mx>
+
+       * gdk/gdk.c (gdk_event_translate): In line 1693, fixed typo that
+       would cause motion notify events not to be delivered.
+
+Sun Oct  5 18:15:06 1997  Federico Mena  <federico@bananoid.nuclecu.unam.mx>
+
+       * gtk/gtkrc.c (gtk_rc_parse_bg_pixmap): Changed strdup() for
+       g_strdup().
+
+Wed Sep 24 17:16:34 1997  Peter Mattis  <pmattis@bjork.inktomi.com>
+
+       * configure.in: Fixed a stupid error in the test for libXext that
+       would cause it to fail if X_EXTRA_LIBS was not empty.
+
+       * gtk/gtkmain.h (gtk-timj-970919.patch):
+       * gtk/gtkmain.c (gtk-timj-970919.patch): new function
+       `gtk_idle_remove_by_data' to remove all idle callbacks that take a
+       specific piece of data as argument.  (gtk_get_current_event):
+       remove idles through gtk_idle_remove_by_data.
+        
+       * gtk/gtkwidget.c (gtk-timj-970919.patch):
+        (gtk_widget_destroy): remove pending idles for
+        widgets that have GTK_REDRAW_PENDING or GTK_RESIZE_PENDING and
+        GTK_ANCHORED set (only anchored widgets can have a resize queue
+        handler pending). widgets that have GTK_RESIZE_NEEDED will be removed
+        from their anchored toplevels `resize_widgets' list.
+        
+        (gtk_widget_queue_draw): let the widget remember the queue handler
+        tag (through `redraw_handler_key') for later call to `gtk_idle_remove'.
+        
+        (gtk_widget_queue_resize): let the widget remember the queue handler
+        tag (through `resize_handler_key') for later call to `gtk_idle_remove'.
+        corrected referencing the toplevel widget for which the handler is
+        pending. if a widget is added to the `resize_widgets' list of a
+        toplevel widget, GTK_RESIZE_NEEDED is set and it's referenced.
+        
+        (gtk_real_widget_queue_resize): on the deletion of the `resize_widgets'
+        list, unset GTK_RESIZE_NEEDED and unreference the removed widgets.
+        
+       * gtk/gtkwindow.c (gtk-timj-970919.patch):
+        (gtk_real_window_move_resize): move `resize_containers = NULL'
+        initialization out of if-statement.
+        while stepping through the `resize_widgets' list, unreference the
+        widgets and clear GTK_RESIZE_NEEDED. if a widget realy needs are
+        resize, they are flagged through GTK_RESIZE_NEEDED now (instead of
+        GTK_RESIZE_PENDING, as this is indicative for a pending handler).
+        added checks to provide segfaulting if a widgets parent pointer
+        is NULL (e.g. on toplevel widgets that have GTK_RESIZE_NEEDED set).
+
+Tue Sep 23 13:23:27 1997  Federico Mena  <federico@bananoid.nuclecu.unam.mx>
+
+       * gdk/gdkimage.c: Applied Tim Janik's patch to mark shm segments
+       as IPC_RMID so that they are automatically removed always.
+
+       * gdk/gdkfont.c: Removed casts from lvalues.
+
+       * gtk/gtkmain.c: Removed GTK_RETLOC_*() (which do a cast) from lvalues.
+
+       * gtk/gtkaccelerator.c (gtk_accelerator_table_remove): Added
+       "const" to the accelerator_key param to be consistent with the
+       declaration in gtkaccelerator.h.  The const is not useful in this
+       case, anyway.
+
+Tue Sep 16 13:11:06 1997  Peter Mattis  <pmattis@bjork.inktomi.com>
+
+       * gtkpreview.c: Andrew Logan Kieschnick's change to eliminate
+       round-off error when gamma is set to 1.0.
+
+       * gtkrange.c:
+       * gtkviewport.c: Jay Painter's changes to modify the way in which
+       viewports resize.
+
+       * gdkinput.c:
+       * gdkinputgxi.h:
+       * gdkinputxfree.h:
+       * gtk/Makefile.am:
+       * gtk.h:
+       * gtkeventbox.c:
+       * gtkeventbox.h: Owen Taylor's event box widget and fixes for X
+       input support (that I had broken).
+
+       * gdk.h:
+       * gdkwindow.c:
+       * gtksignal.h:
+       * gtksignal.c: Elliot Lee's changes to support Objective C. (id is
+       apparently a reserved word in Objective C).
+
+Sun Sep 14 22:33:15 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwidget.c (gtk_widget_queue_resize): If the toplevel container
+       is invisible we simply call "gtk_container_need_resize" on
+       it. This fixes a bug with option menus not redrawing correctly.
+
+       * gtkmenuitem.c (gtk_menu_item_enter): (gtk_menu_item_leave):
+       These functions now simply pass the event on to their parent. This
+       is necessary for menus to work properly due to the change in how
+       grabs are dealts with.
+
+       * gtkwindow.c (gtk_real_window_move_resize): Fixed a bug that
+       caused the GTK_RESIZE_PENDING flag to not be unset in some cases.
+
+Fri Sep  5 20:49:37 1997  Marius Vollmer  <mvo@zagadka.ping.de>
+
+       Bug fixes:
+
+       * Makefile.am: Added PATCHES to EXTRA_DIST.
+       * gtk/gtkpixmap.c (gtk_pixmap_new): Move the "pixmap != NULL" test
+       after the allocation of the pixmap.
+
+       To shut up the compiler:
+
+       * gtk/gtkfilesel.c (get_pwdb): Initialize home_dir.
+       * gtk/gtkmain.c (gtk_init): Replace comments around calls to
+       g_set_*_handler with "if (0)".
+       * gtk/gtkrc.c (gtk_rc_get_token): Initialize hex_number and
+       float_number.
+       * gtk/gtkwindow.c (gtk_window_key_press_event): Initialize
+       direction.
+
+       Changes to the type system in gtk/:
+
+       * Makefile.am: Added gtktypebuiltins.h to gtkinclude_HEADERS.
+       Added gtk.defs, runelisp, gentypeinfo.el and gtktypebuiltins.c to
+       EXTRA_DIST.  Added rules to generate gtktypebuiltins.* from
+       gtk.defs.
+
+       * runelisp, gentypeinfo.el, gtk.defs: New files.
+
+       * gtkaccelerator.c, gtkaccelerator.h (gtk_accelerator_table_ref):
+       Return the table so that this function can be used as the `copy'
+       function for GTK_TYPE_BOXED values.
+       * gtkstyle.c, gtkstyle.h (gtk_style_ref): Likewise.
+
+       * gtkenums.h: Removed GtkArgType enum.
+
+       * gtkmain.c (gtk_init): Call gtk_type_init to initialize the type
+       system.
+
+       * gtkobject.c (gtk_object_init_type): New function to take over
+       for gtk_object_get_type. (gtk_object_get_type): Just return the
+       constant GTK_TYPE_OBJECT. (gtk_object_collect_args): Do the right
+       thing for the new GTK_TYPE_* types.
+       * gtksignal.c (gtk_params_get): Likewise.
+
+       * gtktypeutils.c: (gtk_type_init_builtin_types): New
+       function. (gtk_type_init): Call it.  Also made non-static.
+       (gtk_type_unique): The allocation scheme for numerical ids has
+       changed: The low 8 bits hold the appropriate GtkFundamentalType of
+       a type, the rest is a globally unique sequence number.
+       (gtk_type_hash): Use the sequence number of a key to hash it.
+       (gtk_type_register_builtin): New function.
+
+       * gtktypeutils.h: (GtkFundamentalType): New enumeration of the
+       fundamental types. (GTK_TYPE_MAKE, GTK_FUNDAMENTAL_TYPE,
+       GTK_TYPE_SEQNO): New macros to work with the new id scheme.
+       (GtkArg): Added fields for new types and renamed old ones.  GtkArg
+       should now be a mostly opaque structure, except name and type.
+       (GTK_VALUE_*): New macros to access the values of a GtkArg.
+       (GTK_RETLOC_*): New macros to access the location of a return
+       value that is contained in a GtkArg.  * gtktypebuiltins.h: New
+       file to access the typeids of the builtin types.
+
+       * gtkwidget.h (GTK_TYPE_WIDGET): New macro to access the type id
+       of the widget class.
+
+       Thru out: Changed GTK_ARG_* to the appropriate GTK_TYPE_*.
+       Changed access to GtkArg structure to the appropriate GTK_VALUE_*
+       or GTK_RETLOC_* macro.  Changed GtkArgType to GtkType.  Changed
+       some guints to GtkType.
+
+       General changes in gtk/ to support interpreters:
+
+       * gtkradiobutton.c (gtk_radio_button_new_from_widget,
+       gtk_radio_button_new_with_label_from_widget): New functions.
+
+       * gtksignal.c (gtk_signal_connect_no_marshal): New function.
+       (struct _GtkHandler): Added no_marshal and destroy_func fields.
+       (gtk_signal_handler_new): Initialize them.
+       (gtk_signal_connect_by_type): Added no_marshal and destroy_func
+       arguments.  Changed all callers.
+       (gtk_signal_destroy): Invoke destroy_func if there is one and the
+       global destroy func does not apply.  (gtk_handlers_run): If the
+       handler has no_marshal set, call its function directly without
+       going thru the signal's marshaller.
+
+Wed Sep  3 09:56:22 1997  RHS Linux User  <pmattis@bjork.inktomi.com>
+
+       * gtkrange.c: Changed the way the range control focus was drawn so
+       that the range control is drawn correctly when it does not have
+       the focus.
+
+Tue Sep  2 17:41:17 1997  RHS Linux User  <pmattis@bjork.inktomi.com>
+
+       * gtkwidget.c: 'gtk_real_widget_queue_resize' should only remove
+       the "resize_widgets" if another resize is not pending.
+
+Mon Sep  1 18:28:08 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmain.c: Changed the way GDK_DELETE events are handled. Only,
+       if 'gtk_widget_event' returns TRUE is the widget destroyed. By
+       default, 'gtk_widget_event' will return FALSE causing the window
+       to not be destroyed. This prevents segfaults in the GIMP and other
+       programs that do not correctly handle GDK_DELETE events.
+
+       * gtkmain.c: Added modal dialog support by allowing events
+       destined for a child of the grab widget to go to the child instead
+       of the grab widget. (Added 'gtk_widget_is_ancestor' to determine
+       the relationship between the grab widget and the event widget).
+
+       * *.[ch]: Incorprated a whole mess of patches. (Started keeping
+       the ChangeLog up to date again).
+
+Thu Jun  5 17:22:21 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenufactory.c:
+       * gtkmenufactory.h: Added 'gtk_menu_factory_remove_*'
+       calls. Removing entries/paths causes the associated widgets to be
+       destroyed.
+
+       * gtkwidget.c:
+       * gtkwidget.h: Calling 'gtk_widget_set_style' is used as an
+       indication that the programmer specifically wants that style to be
+       used. RC-style substitution is disabled for the widget after such
+       a call.
+
+       * gtkpixmap.c:
+       * gtkpixmap.h:
+       * gtkimage.c:
+       * gtkimage.h: Changed to use clip mask and a single pixmap (or
+       image) to deal with transparent areas.
+
+       * gdkpixmap.c: Modified xpm loading routines to optionally return
+       a clip mask.
+
+       * gdkgc.c:
+       * gdkdraw.c:
+       * gdktypes.h: Modifications to allow clip masks to be used with
+       gc's. Clip masks are bitmaps that specify drawable regions.
+
+Thu May  1 03:11:51 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkscrolledwindow.c: Scrolled windows need to have the
+       GTK_NO_WINDOW flag set. Not having it set caused an obscure
+       redrawing bug.
+
+Wed Apr 30 12:38:03 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkhruler.c:
+       * gtkvruler.c: Fixed a small bug that caused the indicator to be
+       positioned slightly off.
+
+Sun Apr 27 14:28:21 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenushell.c:
+       * gtkmenushell.h:
+       * gtkmenu.c:
+       * gtkmenu.h: Changes so that if a menu is popped up there is a
+       timeout period during which a menu item will not be activated and
+       if the mouse button is released in that period the menu will stay
+       popped up.
+
+       * gtkcurve.c:
+       * gtkcurve.h: Included curve widget courtesy of David
+       Mosberger-Tang (davidm@azstarnet.com).
+
+       * gtkentry.c:
+       * gtkentry.h: Changed "insert" and "delete" signals to
+       "insert_text" and "delete_text" respectively. (The symbol "delete"
+       cannot be used since it is a C++ reserved word).
+
+Sat Apr 19 01:43:49 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenufactory.c: A path which ends in "<nothing>" will cause an
+       invisible (hidden) menu entry to be created. This is useful for
+       setting an accelerator key for which a corresponding menu entry is
+       not desired.
+
+       * gtktooltips.c: Fixed some problems with destruction of the
+       active tip widget not properly updating the tooltips data
+       structures.
+
+Fri Apr 18 15:09:45 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkcontainer.c:
+       * gtklist.c:
+       * gtkwidget.c:
+       * gtkwidget.h: Patch from Owen Taylor (owt1@cornell.edu) which
+       fixes problems with destruction of objects and with destruction of
+       objects which hold the focus.
+
+Thu Apr 17 11:29:15 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenushell.c: Incorrect logic in
+       'gtk_menu_shell_button_release' for deciding when a menu should
+       stay popped up when the mouse button is released.
+
+       * *.c: Miscellaneous fixes from folks on the net.
+
+Tue Apr 15 02:43:17 1997  Peter Mattis  <pmattis@localhost>
+
+       * *.c:
+       * gtkwidget.h: Added GTK_BASIC widget flag which when set
+       specifies a widget as "basic". A "basic" widget is one which
+       doesn't take input events. For example, labels, pixmaps, boxes,
+       tables, alignments, etc.
+
+Sat Apr 12 15:23:08 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkcolorsel.c: Add "#include <math.h>" to define M_PI.
+
+       * gtksignal.c: Fixed a bug in 'gtk_signal_emit' which showed up
+       because of the new cast checking macros. The 'object' was being
+       accessed after it had been destroyed.
+
+       * gtkoptionmenu.c: Fixed bug with using 'GTK_BIN' instead of
+       'GTK_BUTTON' which showed up because of the new cast checking
+       macros.
+
+       * *.h: 'GTK_CHECK_CAST', 'GTK_CHECK_CLASS_CAST' and
+       'GTK_CHECK_TYPE' used by standard widget macros everywhere.
+
+Wed Apr  9 00:54:17 1997  Peter Mattis  <pmattis@localhost>
+
+       * docs/gtk.texi: Started further work on documentation. Major
+       changes and additions are being made.
+
+       * gtkarrow.c:
+       * gtkarrow.h: Removed function 'gtk_arrow_get'.
+
+       * gtkcontainer.c: 'gtk_container_check_resize' no performs
+       additional checking to account for the case where the containers
+       allocation is no longer sufficient because its parent (or its
+       parents parent, etc.) needs to resize its children.
+
+Tue Apr  8 21:15:50 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkstyle.c: Fixed a bug in 'gtk_style_init' in which the font
+       was not ref'd (via 'gdk_font_ref'), but was free'd (via in
+       'gdk_font_free') in 'gtk_style_destroy'. (David
+       Mosberger-Tang). Also cleaned up 'gtk_style_destroy' while I was
+       at it.
+
+       * gtkmain.c: Fixed a bug in 'gtk_propogate_event' which caused
+       entry widgets (and probably other widgets) not to be destroyed in
+       some instances.
+
+Mon Apr  7 01:20:38 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkentry.c:
+       * gtkentry.h: Changed the "insert_text", "delete_text" and
+       "changed_text" signals to "insert", "delete", and "changed"
+       respectively. They really should have been named this way
+       originally except the previous signal mechanism prevented
+       duplicate signal names. ("changed" is also used by adjustments).
+
+       * gtkradiomenuitem.c:
+       * gtkradiomenuitem.h: New widget.
+
+       * gtkcheckmenuitem.c:
+       * gtkcheckmenuitem.h: New widget.
+
+       * gtksignal.c: Modified 'gtk_signal_lookup' to require an object
+       type to be passed as a parameter. In addition, signals are now
+       only needed to be uniquely defined in their branch of the class
+       hierarchy. This allows the same signal name to be used in two
+       different branches of the class hierarchy. For instance, the
+       "changed" signal is used both by adjustments and entries...in
+       different ways!
+
+       * gtktypeutils.c: Added 'gtk_type_parent' which returns the parent
+       type for a given type.
+
+Sun Apr  6 22:08:35 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwidget.c: If a widget is set insensitive it loses the focus
+       if it had it.
+
+       * gtkcontainer.c: Insensitive widgets no longer participate in tab
+       traversal.
+
+       * gtkscrolledwindow.c: The "viewport" child is now destroyed and a
+       container class "foreach" function was written (which fixes the
+       sensitivity bug).
+
+Sat Apr  5 14:25:38 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkhscrollbar.c:
+       * gtkvscrollbar.c: Fixed trough size allocation bug.
+
+       * gtkhscale.c:
+       * gtkvscale.c: Fixed trough size allocation and position bug that
+       showed up when scales were placed in notebooks.
+
+Thu Mar 27 17:45:54 1997  David Mosberger-Tang  <davidm@azstarnet.com>
+
+        * gtk/gtkmain.c (gtk_handle_idle): Fix appending pending_idles to
+        idle_functions so it works even when idle_functions is empty.
+
+Sat Mar 15 14:15:59 1997  Peter Mattis  <pmattis@localhost>
+
+       * *.[ch]: Moved '*_class_init' and '*_init' function declarations
+       for widgets into the source file as those functions no longer had
+       to be public.
+
+       * gtkcheckbutton.c: Fixed redrawing of check button.
+
+       * gtkframe.c: Fixed redrawing of frame when the shadow type is
+       changed.
+
+Sat Mar  8 15:19:23 1997  Peter Mattis  <pmattis@localhost>
+
+       * gdkimage.c: Fixed a stupid bug with 'gdk_image_new' which
+       potentially added a NULL image to "image_list" and caused problems
+       when 'gdk_image_exit' was called.
+
+Wed Mar  5 00:40:08 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkpreview.c: Massively changed the colormap handling used by
+       the preview widget. Gray previews are now dithered. A single
+       visual and colormap is shared by the color and gray previews. A
+       GTK_PREVIEW_INFO property is installed on the root window in
+       certain cases to allow multiple GTK programs to share the system
+       colormap.
+
+Sun Mar  2 05:43:06 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkcheckbutton.c: 'gtk_checkbutton_size_allocate' was allocating
+       too much space to its children and not leaving the check button
+       room for the focus border.
+
+       * gtknotebook.c: 'gtk_notebook_size_request' wasn't requesting
+       enough space when the notebook tabs are visible.
+
+Sat Mar  1 01:59:35 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkpreview.c: Fixed a problem with 'gtk_preview_put' when the
+       image byte order is GDK_MSB_FIRST.
+
+       * gtksignal.c:
+       * gtksignal.h: Added 'gtk_signal_connect_after' and
+       'gtk_signal_connect_object_after' functions. These connect signal
+       handlers which will run after the class function associated with
+       the signal.
+
+       * gtkstyle.c: Fixed a stupid bug in 'gtk_style_new_from_key' that
+       was causing twice as many styles to be created as necesary.
+
+       * gtkwidget.c: 'gtk_real_widget_size_allocate' erases the widgets
+       old allocation if it has the GTK_NO_WINDOW flag set.
+
+       * gtkwidget.c: 'gtk_real_widget_unmap' now erases the widget if it
+       has the GTK_NO_WINDOW flag set.
+
+       * gtklabel.c: Removed 'gtk_label_unmap' as similar functionality
+       was added to gtk_real_widget_unmap.
+
+       * gtkbin.c: Modified 'gtk_bin_map' and 'gtk_bin_unmap' so that it
+       erases and draws the widget if it has the GTK_NO_WINDOW flag set.
+
+       * gtkframe.c: Modified 'gtk_frame_size_allocate' so that it erases
+       the old allocation.
+
+Fri Feb 28 03:27:05 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwindow.c: 'gtk_window_set_title' now changes the window title
+       if the window is already realized.
+
+       * gtkentry.c: 'gtk_entry_set_text' was emitting both a
+       "delete_text" and a "changed_text" signal. Modified so that it
+       only emits a "changed_text" signal.
+
+       * gtkpreview.c: Modified to work correctly on systems with MSB
+       byte order. The colormap for TRUE and DIRECT color displays is now
+       created if the default visual is not equal to the visual we are
+       using.
+
+       * gtkstyle.c: 'gtk_style_attach' and 'gtk_style_find' weren't
+       working properly in the presence of multiple colormaps are
+       different depth visuals.
+
+       * gtkcontainer.c: Massively improved focus traversal using tab and
+       arrow keys. It now uses the layout of the widgets to determine
+       where to move the focus to.
+
+Mon Feb 24 03:24:02 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenufactory.c: Set the accelerator table field for menus when
+       they are created.
+
+       * gtkmenu.c:
+       * gtkmenu.h: Added a default accelerator table field to menus so
+       that runtime modification of accelerator keys in menus can work
+       better.
+
+       * gtkrange.c: 'gtk_range_default_{h,v}motion' had faulty logic for
+       deciding what to do when the slider was at the edge of the
+       trough. They previously didn't update the adjustment value event
+       if the value wasn't what it should be when the slider was at the
+       edge of the trough.
+
+       * gtkviewport.c: 'gtk_viewport_size_allocate' and
+       'gtk_viewport_adjustment_value_changed' both had the potential for
+       performing a divide by 0. Checks are now in place to prevent this.
+
+       * gtkmenu.c: 'gtk_menu_map' now makes sure the menu lies on screen
+       if the position function is NULL.
+
+       * gtkentry.c: Modified selection handling. 'gtk_delete_selection'
+       actually removes the X selection now. 'gtk_entry_destroy' removes
+       the selection as well and relies on the change in "gdk.c" to make
+       sure the selection event will not be sent to a non-existant
+       window.
+
+       * gdk.c: Selection events are only passed on if the selection
+       owner is not NULL.
+
+       * gtkstyle.c: 'gtk_style_detach' and 'gtk_style_destroy' were not
+       destroying the black and white gc's.
+
+Sun Feb 23 19:17:56 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwindow.c: 'gtk_window_size_request' was setting the window
+       hints. This was also being done in 'gtk_window_map', so the
+       instance being done in 'gtk_window_size_request' was removed.
+
+Fri Feb 21 01:04:01 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwidget.c: 'gtk_widget_draw' has to use the widgets allocated
+       position for the drawing rectangle when the widget has the
+       GTK_NO_WINDOW flag set.
+
+       * gtkwidget.c: In 'gtk_widget_init' the visual and colormap were
+       being directly compared against 'default_visual' and
+       'default_colormap' instead of calling
+       'gtk_widget_get_default_{visual,colormap}'.
+
+       * gdkrectangle.c: Amazing! There was a bug in the
+       'gtk_rectangle_intersect' logic. Its been there for near eternity
+       and I never noticed.
+
+       * gtkpreview.c:
+       * gtkpreview.h: Created preview widget which allows drawing to an
+       rgb or grayscale buffer which is automatically displayed on the
+       screen. Performs dithering as necessary.
+
+Thu Feb 20 20:33:21 1997  Peter Mattis  <pmattis@localhost>
+
+       * gdkwindow.c: Modified the logic in 'gdk_window_new' which
+       determined when to add a window to the WM_COLORMAP_WINDOWS
+       property.
+
+Wed Feb 19 19:55:29 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkruler.c: 'gtk_ruler_make_pixmap' was always destroying the
+       old backing store and creating a new one even when it would create
+       a new one of exactly the same size as the old one.
+
+Tue Feb 18 18:32:10 1997  Peter Mattis  <pmattis@localhost>
+
+       * gmem.c: 'g_mem_chunk_alloc' was incorrectly modifying the mem
+       areas free mem field when reallocating a previously freed
+       atom. This caused a fairly severe memory leak.
+
+       * gtkmenushell.c: 'gtk_menu_shell_button_release' had a bug in the
+       logic for deciding whether to initiate an X pointer grab or not
+       when the mouse button was released. It now only initiates a grab
+       if the mouse is released within an active menu item.
+
+Fri Feb 14 00:57:40 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtknotebook.c: Changed the look of notebook tabs slightly.
+
+       * gtkentry.c:
+       * gtkentry.h: Deleting an entry widget which is holding the X
+       selection presents some difficulties. The X selection must be
+       released, but the widget can't be destroyed until the
+       SELECTION_CLEAR event is received that the X server will send in
+       response to clearing the X selection. There are probably still
+       bugs in the current method of entry widget deletion when the X
+       selection is held.
+
+       * gtkmain.c: 'gtk_propagate_event' was not properly destroying the
+       toplevel window when receiving a key press event.
+
+       * gtkwidget.c: Setting a widget insensitive did not cause it to
+       redraw. It now does.
+
+Thu Feb 13 16:59:07 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkviewport.c: 'gtk_viewport_size_allocate' was allocating its
+       child widget an adjusted allocation. Since the actual scrolling
+       has handled by a subwindow this caused the child to be double
+       scrolled. Modified to always set the child allocations origin to
+       (0, 0).
+
+Wed Feb 12 01:06:48 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkentry.c: Text is now centered vertically. Previously it was
+       pushed up against the top. This problem was only evident when the
+       widget was allocated more vertical space than it requested.
+
+       * gtkfilesel.c: 'gtk_file_selection_key_press' was previously only
+       a stub for tab completion. The actual tab completion call had been
+       left out. (Oops!)
+
+Tue Feb 11 01:43:08 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtksignal.c: 'gtk_signal_disconnect_by_data' was going into a
+       loop and crashing. Bad logic. Fixed.
+
+       * gtkmain.c: An idle function which returns FALSE will be removed
+       from the list of idle functions. This makes the functioning of
+       idle functions and timeouts more similar.
+
+       * gtkentry.c: 'gtk_entry_get_text' now returns an empty string
+       when the actual text is NULL. This allows "stupid" programs to use
+       the value returned by 'gtk_entry_get_text' blindly (without
+       checking to see if its NULL).
+
+       * gtkradiobutton.c: Modified 'gtk_radio_button_clicked' so that
+       'gtk_toggle_button_toggled' is called _after_ the widget state is
+       changed.
+
+       * gtksignal.c:
+       * gtksignal.h: Added 'gtk_signal_name' which returns the character
+       string name for a given signal number.
+
+       * gtkwidget.c: 'gtk_widget_set_parent' checks to see if the widget
+       is now "anchored" through the parent chain to a widget which is
+       GTK_ANCHORED. If it is, then it changes the widgets style using
+       'gtk_rc_get_style' and recursively performs the same operation on
+       the widgets children. This is necessary is 'gtk_rc_get_style' only
+       works properly on "anchored" widgets.
+
+       * gtkwindow.c: Modified GTK_WIN_POS logic so that it is only used
+       immediately after the window has been shown.
+
+       * gtkmenu.c: 'gtk_menu_key_press'. Can now change menu item
+       accelerator keys on the fly. Why? Why not. Cool/useless feature of
+       the day.
+
+       * gtkmenuitem.c: Accelerator key drawing. Somehow that never got
+       finished. (Oops!)
+
+       * gtkdrawingarea.c: 'gtk_drawing_area_size_allocate' was not
+       actually installed during 'gtk_drawing_area_class_init'. (Oops!)
+
+       * gtkframe.c: 'gtk_frame_size_request' fixed size requisition
+       problem caused by unsigned arithmetic.
+
+       * gtkwindow.c: Modified window widget so that it only uses the
+       widget uposition auxiliary information immediately after it has
+       been shown. This prevents the annoying bug which can cause a
+       uposition'ed window to jump back to its original position after
+       the user moves it.
+
+       * gtkwidget.c: Need to ref and unref style in
+       'gtk_widget_{push,pop}_style' to make sure that a style on the
+       style stack is not destroyed.
+
+       * gtktogglebutton.c: 'gtk_toggle_button_set_state' now calls
+       gtk_button_clicked to actually change the state of the
+       button. In this way, radio buttons can now perform the appropriate
+       actions when the toggle button state is set.
+
+Mon Feb 10 00:27:39 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtklist.c: 'gtk_list_select_item' and 'gtk_list_unselect_item'
+       were casting a GList* variable to a a GtkWidget* variable. Bad bad
+       bad. (Tim Janik).
+
+       * gtksignal.c: Modified 'gtk_signal_connect' and
+       'gtk_signal_connect_object' to warn when a signal type cannot be
+       found.
+
+Sun Feb  9 00:15:30 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkoptionmenu.c:
+       * gtkoptionmenu.h: Changed option menus back to being derived from
+       buttons. This fixes up some screwiness with their user
+       interaction.
+
+       * gtkwindow.c: Modified key press handler to support focus
+       traversal.
+
+       * gtkcontainer.c:
+       * gtkcontainer.h: Added default focus traversal back in.
+
+Sat Feb  8 10:44:38 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkviewport.h:
+       * gtkviewport.c: Massively sped up viewport scrolling. Used to be
+       reallocating child's size (offset) each time a scrollbar
+       moved. Now a subwindow is moved. All the children are moved
+       automatically by moving the subwindow. Much much much faster.
+
+Tue Feb  4 00:20:44 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtree.c: Changed 'g_tree_node_search' to use a loop instead of
+       recursion.
+
+Mon Feb  3 11:30:03 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkbutton.c: Removed 'parent_destroy' global and replaced it
+       with 'parent_class' global to reflect style used in other
+       widgets.
+
+       * gtknotebook.c: Tab labels were being allocated less than their
+       requested size.
+
+       * gtkrange.c:
+       * gtkrange.h: Moved the "digits" field of scales into the range
+       type. The adjustment value for scales is truncated to the number
+       of visible digits instead of being left untouched.
+
+       * gtree.c: Fixed a bug in the AVL tree implementation. Single
+       rotations were always being performed during insertion. It is
+       sometimes necessary to perform a double rotation.
+
+       * gtklabel.c: Modified 'gtk_label_expose' to only draw the label
+       when the allocated space is greater than or equal to the requested
+       space.
+
+       * gtklabel.c: Added call to 'gtk_widget_unmap' to
+       'gtk_label_destroy' in order for the label to redraw correctly
+       (erase itself) when destroyed.
+
+       * gtklabel.c: Added 'gtk_label_unmap' call which erases the labels
+       allocation when it gets unmapped.
+
+       * *.h: Removed a few remaining instances of using "class" as a
+       parameter name. (Causes problems for C++).
+
+Fri Jan 31 12:26:50 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkcontainer.c: 'gtk_container_enable_resize' needs to call
+       'gtk_container_check_resize' instead of
+       'gtk_container_need_resize'.
+
+       * gtkwidget.c: 'gtk_real_widget_show' now maps the widget if its
+       parent is mapped.
+
+       * gtkscrolledwindow.c: Fixed size allocation when the scrollbar
+       policy's are GTK_POLICY_AUTOMATIC. Doing it correctly is harder
+       than I originally thought.
+
+       * gtklist.c: Added 'gtk_list_child_position' to determine the
+       integer position in a list of a child. Filled in the
+       'gtk_list_item_select' and 'gtk_list_item_unselect' stubs.
+
+Thu Jan 30 16:08:06 1997  Peter Mattis  <pmattis@localhost>
+
+       * gmem.c: Changed the implementation of G_ALLOC_AND_FREE mem
+       chunks. They used to allocate SIZEOF_VOID_P extra bytes per atom
+       in order to keep track of which mem area they were allocated
+       from. Now the mem area is determined by searching through an AVL
+       tree of the mem areas for a mem chunk and comparing memory
+       locations. A little slower, but makes G_ALLOC_AND_FREE mem chunks
+       much more attractive.
+
+       * gtree.c: Added an AVL tree implementation to glib.
+
+       * gtksignal.c:
+       * gstring.c: va_arg (arg_list, {char, short}) is
+       invalid. Arguments passed in a variable argument list are
+       promoted. ({char, short}->int). Seemed to work ok before under
+       Linux. Crashed under FreeBSD.
+
+Tue Jan 28 02:27:51 1997  Peter Mattis  <pmattis@localhost>
+
+       * gdkwindow.c: Fixed a major slowdown apparent in the file
+       selection dialog which was caused by calling
+       'gtk_window_add_colormap_windows' way way way too often.
+
+       * *.c: Many widgets called 'gtk_container_need_resize' when
+       something internal changed which would cause the widget to grow or
+       shrink. The assumption was made that the widget would change size
+       and an expose event would be generated. This happens "most" of the
+       time. But its possible for certain widgets to change size without
+       generating expose events, or for its internal geometry to change
+       without a change of size which would mean no expose event was
+       generated. So a wrapper function called
+       'gtk_container_check_resize' was created and
+       'gtk_container_need_resize' was modified so that it returns FALSE
+       if a resize was actually generated and TRUE if nothing
+       changed. This allows 'gtk_container_check_resize' to initiate a
+       'gtk_widget_size_allocate' and 'gtk_widget_draw' to emulate the
+       expose event.
+
+Sat Jan 25 14:17:44 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmain.c: Fixed a bug with propogating key press events. The
+       events were sent 2 times to the toplevel windows which caused the
+       focus widget to be activated twice when the space bar was pressed.
+
+       * */configure.in:
+       * */Makefile.am: Added support for libtool and removed the old
+       shared library configuration craziness.
+
+Fri Jan 24 12:59:22 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtktext.c:
+       * gtktext.h: Josh's fixes and additions to the text widget.
+
+       * gtkfill.c:
+       * gtkfill.h: Filler widget useful for filling space in a
+       table. Can specify a minimum size. Used by the canvas widget.
+
+       * gtknotebook.c:
+       * gtknotebook.h: Made outline of notebook widget.
+
+       * gtkcanvas.c:
+       * gtkcanvas.h: Started canvas widget. A composite of 2 rulers (w/
+       an origin), 2 scrolllbars. Guides, grids, snap to.
+
+Sun Jan 19 18:26:45 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkdialog.c:
+       * gtkdialog.h: Created dialog widget which creates a standard
+       looking dialog with buttons along the button and a separator.
+
+       * gtkxid.c: Generalized the window table code for looking up a gdk
+       window based on an XID to work for any XID and a piece of
+       data. Can now look up gdk fonts based on their XID.
+
+       * gtkruler.c:
+       * gtkruler.h:
+       * gtkhruler.c:
+       * gtkhruler.h:
+       * gtkvruler.c:
+       * gtkvruler.h: Started conversion of the ruler widget.
+
+       * gtktext.c:
+       * gtktext.h: Started conversion of the text widget. Scrolling
+       doesn't work.
+
+       * gtkmain.c: Fixed a fairly major bug. The event widget needs to
+       be in a call for the entire duration of handling an event. Not
+       just for when the event widget itself is handling the event.
+
+       * gtkfilesel.c: Fixed up some bugs with resizing.
+
+Fri Jan 10 14:18:03 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwidget.c:
+       * gtkwidget.h:
+       * gtkentry.c:
+       * gtkentry.h: Support for selections.
+
+       * gdkselection.c:
+       * gdk.c:
+       * gdktypes.h:
+       * gdk.h: Gdk support for X selections. Currently only text
+       selections are supported.
+
+       * gtksignal.c: Fixed a major bug which occurred when destroying an
+       object. Memory was being written to after it was freed.
+
+       * gtkfilesel.c:
+       * gtkfilesel.h: Hooked up more functionality to the file selection
+       dialog.
+
+Wed Jan  8 18:13:53 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkfilesel.c:
+       * gtkfilesel.h: Mostly converted old file selection dialog
+       widget. The widget is derived from the GtkWindow class and is
+       quite a bit simpler in the widget code.
+
+       * gtkwidget.c: Fixed 'gtk_widget_grab_focus' and
+       'gtk_widget_grab_default' to check that the toplevel widget is a
+       type of window (which includes classes derived from windows).
+
+Tue Jan  7 01:12:32 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkwindow.c: Was calling 'gtk_window_resize' twice in a
+       row...why?
+
+       * gtksignal.c:
+       * gtksignal.h:
+       * *.c: Changed 'gtk_signal_new' so that the class function that is
+       called when the signal is emitted can be called either before,
+       after or both before and after the calling of any signal
+       handlers.
+
+       * gtkobject.c:
+       * gtkobject.h: Added 'object_data' mechanism for storing data
+       associated with a character string key in objects. Removed
+       'user_data' field of objects and changed
+       'gtk_object_{get,set}_user_data' to use the object data
+       mechanism. Removed 'handlers' field of objects.
+
+       * gtkwidget.c:
+       * gtkwidget.h:
+       * gtkwindow.c: Modified aux info mechanism to use object data
+       mechanism.
+
+       * gtksignal.c: Modified signal mechanism to use object data
+       mechanism instead of 'handlers' field.
+
+
+Mon Jan  6 15:10:16 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenushell.c: Fixed up button press handling so as to conform
+       more closely to that used by Motif.
+
+Wed Jan  1 21:27:17 1997  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenu.c:
+       * gtkmenu.h:
+       * gtkmenubar.c:
+       * gtkmenubar.h:
+       * gtkmenushell.c:
+       * gtkmenushell.h: Reorganization of menu-ing code so that code
+       duplication is reduced. The menu shell now contains most of the
+       code for menu-ing interaction while menus and menubars simply layout
+       their child menu items in the appropriate place.
+
+Sun Dec 29 17:48:18 1996  Peter Mattis  <pmattis@localhost>
+
+       * gtkmenu.c:
+       * gtkmenubar.c:
+       * gtkmenuitem.h:
+       * gtkmenuitem.c: Modifications so that menu item accelerators and
+       the submenu indicator are drawn correctly and the correct amount
+       of space is allocated.
+
+Sat Dec 28 00:32:13 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtkmenufactory.h:
+       * gtkmenufactory.c: Started menu factories as an easy method to
+       create and manipulate menus.
+
+Fri Dec 27 13:17:34 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtkmenu.c:
+       * gtkmenu.h:
+       * gtkmenubar.c:
+       * gtkmenubar.h:
+       * gtkmenuitem.c:
+       * gtkmenuitem.h:
+       * gtkmenushell.c:
+       * gtkmenushell.h: Implemented basic menu functionality. Menubars
+       and popup menus work. Submenus work. (Much left to be done).
+
+Wed Dec 18 15:27:05 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtktypeutils.h:
+       * gtktypeutils.c: Added 'gtk_type_from_name' which returns a type
+       identifier given a type name. Implemented using a second hash
+       table keyed by type names.
+
+       * gtkbutton.c:
+       * gtktogglebutton.c: Fixed very small messed-up drawing bug when a
+       button loses its focus.
+
+       * gtkwidget.h:
+       * gtkwidget.c:
+       * gtkbutton.c:
+       * gtkwindow.c: Added default button handling. Default buttons now
+       draw correctly and pressing return or enter causes the default
+       button (if one exists) to be activated.
+
+Tue Dec 17 19:32:21 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtkhscale.c:
+       * gtkvscale.c: Overrode 'draw_slider' method of ranges in order to
+       draw the slider of scales with a line in them so as to be closer
+       to the Motif look-and-feel.
+
+       * gtkwindow.c: Modified 'gtk_window_focus_in_event' so that focus
+       in events are only handled when the window is visible. Fixes a bug
+       where spurious focus in events get sent when a window is being
+       hidden.
+
+       * gtkwidget.h: Added 'activate_signal' field to the GtkWidgetClass
+       structure. Added 'gtk_widget_activate' call to emit the activate
+       signal for a widget if it is non-zero.
+
+Tue Dec 10 15:59:45 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * gtkwidget.c: 'gtk_widget_set_name' oops in strdup'ing the old
+       "widget->name" instead of the new one we are setting.
+
+       * gtkrc.c: 'gtk_rc_widget_path' changed to use
+       'gtk_widget_get_name' instead of accessing the "widget->name"
+       field directly.
+
+       * gtkwidget.c: Added 'gtk_widget_get_name' function which returns
+       the widgets name if it exists and the widgets type name if it does
+       not.
+
+       * gtkcheckbutton.c: Added 'gtk_check_button_draw'
+       function. Modified 'gtk_check_button_expose' to pass an expose
+       event to child instead of callings its draw function.
+
+       * gtkentry.c: 'gtk_entry_draw_text' why was "+1" being added to
+       the font->ascent to calculate the font position? This was wrong
+       and caused some characters in fonts to be clipped. (Notably "g").
+
+       * gtkentry.c: 'gtk_entry_realize' specify GTK_BUTTON1_MOTION_MASK
+       and GTK_POINTER_MOTION_HINT_MASK for _both_ windows.
+
+       * gtkmain.c: 'gtk_propagate_event' needs to set the GTK_IN_CALL
+       flag for the object before calling 'gtk_widget_event' and needs to
+       destroy the object if necessary after 'gtk_widget_event' returns.
+
+       * gtkradiobutton.c: 'gtk_radio_button_clicked' needs to call
+       'gtk_toggle_button_toggled' when the currently active button is
+       toggled.
+
+       * gtkwidget.c: 'gtk_real_widget_hide' needs to call
+       'gtk_widget_unmap' if the widget is currently mapped.
+
+       * gtkwindow.c: Prevent automatic resizing after the user has
+       specified a new window size. Add 'handling_resize' flag to
+       windows.
+
+       * gtkscrolledwindow.c: Implement the GTK_POLICY_AUTOMATIC
+       scrollbar policy. Need to connect to the adjustments 'changed'
+       signal and notice when the scrollbars aren't in use.
+
+       * gtkcontainer.c: 'gtk_container_init' must set 'auto_resize' and
+       'need_resize' fields to TRUE and FALSE respectively.
+
+       * gtkwidget.c: 'gtk_widget_set_parent' must all set a widgets state
+       to its parents state.
+
+Sun Dec  1 01:31:01 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * Started ChangeLog
diff --git a/INSTALL b/INSTALL
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..8f24c51
--- /dev/null
@@ -0,0 +1,30 @@
+## Process this file with automake to produce Makefile.in
+
+SRC_SUBDIRS = glib gdk gtk
+SUBDIRS = $(SRC_SUBDIRS) docs
+
+EXTRA_DIST = gtk+.prj makecopyright TODO 
+
+.PHONY: files populate checkin release
+
+files:
+       @files=`ls $(DISTFILES) 2> /dev/null `; for p in $$files; do \
+         echo $$p; \
+       done
+       @for subdir in $(SUBDIRS); do \
+         files=`cd $$subdir; $(MAKE) files | grep -v "make\[[1-9]\]"`; \
+         for file in $$files; do \
+           echo $$subdir/$$file; \
+         done; \
+       done
+
+populate:
+       @echo "populating project"
+       @files=`$(MAKE) files | grep -v "make\[[1-9]\]"`; prcs populate -d gtk+.prj $$files
+
+checkin: populate
+       @echo "checking in project"
+       @prcs checkin
+
+release:
+       $(MAKE) dist distdir=$(PACKAGE)`date +"%y%m%d"`
diff --git a/NEWS b/NEWS
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..728cf38
--- /dev/null
+++ b/README
@@ -0,0 +1,17 @@
+
+The official ftp site is:
+  ftp://ftp.gimp.org/pub/gtk
+
+Patches can be uploaded to:
+  ftp://ftp.gimp.org/incoming
+
+Anonymous CVS access for gtk+ (as well as 'gimp', 'gimp-data', and
+'gnome') is available via
+  CVSROOT=:pserver:anonymous@cvs.gnome.org:/home/cvs
+with an empty password.
+
+A mailing list is located at:
+  gtk-list@redhat.com
+
+To subscribe: mail -s subscribe gtk-list-request@redhat.com < /dev/null
+(Send mail to gtk-list-request@redhat.com with the subject "subscribe")
diff --git a/TODO b/TODO
new file mode 100644 (file)
index 0000000..8c1af4d
--- /dev/null
+++ b/TODO
@@ -0,0 +1,36 @@
+Now
+---
+
+3. Fix focus activation of list items. Does list item activation have to be
+   completely reorganized?
+
+4. Lists should scroll to center the recently selected item if it isn't
+   visible.
+
+
+The Future
+----------
+
+-Documentation
+
+-Tree widget
+
+-Text widget (needs to be finished)
+
+-Widget redrawing when the window resizes sometimes messes up.
+
+-Make sure a widget added to a list is a list item and a widget added
+ to a menu is a menu item, etc...
+
+-More dialogs? Print, font, etc?
+
+-Multiple document interface (MDI)?
+
+-Support another widget style? Should be possible using GtkStyle's, but
+ there may be some work needed to remove any style dependencies in widget
+ code. Maybe GtkStyle's should have 'draw_push_button', 'draw_check_button',
+ etc, functions to draw the various widgets.
+
+-OffiX drag and drop support
+
+-Make all widget attributes configurable after the widget is created.
diff --git a/acconfig.h b/acconfig.h
new file mode 100644 (file)
index 0000000..be2cb54
--- /dev/null
@@ -0,0 +1,47 @@
+/* acconfig.h
+   This file is in the public domain.
+
+   Descriptive text for the C preprocessor macros that
+   the distributed Autoconf macros can define.
+   No software package will use all of them; autoheader copies the ones
+   your configure.in uses into your configuration header file templates.
+
+   The entries are in sort -df order: alphabetical, case insensitive,
+   ignoring punctuation (such as underscores).  Although this order
+   can split up related entries, it makes it easier to check whether
+   a given entry is in the file.
+
+   Leave the following blank line there!!  Autoheader needs it.  */
+\f
+
+/* Other stuff */
+#undef HAVE_IPC_H
+#undef HAVE_SHM_H
+#undef HAVE_XPM
+#undef HAVE_XSHM_H
+#undef HAVE_SYS_SELECT_H
+
+#undef IPC_RMID_DEFERRED_RELEASE
+
+#undef NO_FD_SET
+
+#undef RESOURCE_BASE
+
+#undef XINPUT_NONE
+#undef XINPUT_GXI
+#undef XINPUT_XFREE
+
+/* Define as the return type of signal handlers (int or void).  */
+#undef RETSIGTYPE
+
+/* Most machines will be happy with int or void.  IRIX requires '...' */
+#undef SIGNAL_ARG_TYPE
+
+/* #undef PACKAGE */
+/* #undef VERSION */
+
+\f
+/* Leave that blank line there!!  Autoheader needs it.
+   If you're adding to this file, keep in mind:
+   The entries are in sort -df order: alphabetical, case insensitive,
+   ignoring punctuation (such as underscores).  */
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644 (file)
index 0000000..9f99ab8
--- /dev/null
@@ -0,0 +1,395 @@
+dnl aclocal.m4 generated automatically by aclocal 1.2
+
+# Do all the work for Automake.  This macro actually does too much --
+# some checks are only needed if your package does certain things.
+# But this isn't really a big deal.
+
+# serial 1
+
+dnl Usage:
+dnl AM_INIT_AUTOMAKE(package,version, [no-define])
+
+AC_DEFUN(AM_INIT_AUTOMAKE,
+[AC_REQUIRE([AM_PROG_INSTALL])
+PACKAGE=[$1]
+AC_SUBST(PACKAGE)
+VERSION=[$2]
+AC_SUBST(VERSION)
+dnl test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+  AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+ifelse([$3],,
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE")
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION"))
+AM_SANITY_CHECK
+AC_ARG_PROGRAM
+dnl FIXME This is truly gross.
+missing_dir=`cd $ac_aux_dir && pwd`
+AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
+AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
+AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
+AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
+AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
+AC_PROG_MAKE_SET])
+
+
+# serial 1
+
+AC_DEFUN(AM_PROG_INSTALL,
+[AC_REQUIRE([AC_PROG_INSTALL])
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+AC_SUBST(INSTALL_SCRIPT)dnl
+])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+AC_DEFUN(AM_SANITY_CHECK,
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+   if test "$@" = "X"; then
+      # -L didn't work.
+      set X `ls -t $srcdir/configure conftestfile`
+   fi
+   test "[$]2" = conftestfile
+   )
+then
+   # Ok.
+   :
+else
+   AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+rm -f conftest*
+AC_MSG_RESULT(yes)])
+
+dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
+dnl The program must properly implement --version.
+AC_DEFUN(AM_MISSING_PROG,
+[AC_MSG_CHECKING(for working $2)
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if ($2 --version) < /dev/null > /dev/null 2>&1; then
+   $1=$2
+   AC_MSG_RESULT(found)
+else
+   $1="$3/missing $2"
+   AC_MSG_RESULT(missing)
+fi
+AC_SUBST($1)])
+
+# Like AC_CONFIG_HEADER, but automatically create stamp file.
+
+AC_DEFUN(AM_CONFIG_HEADER,
+[AC_PREREQ([2.12])
+AC_CONFIG_HEADER([$1])
+dnl When config.status generates a header, we must update the stamp-h file.
+dnl This file resides in the same directory as the config header
+dnl that is generated.  We must strip everything past the first ":",
+dnl and everything past the last "/".
+AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl
+ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>,
+<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>,
+<<am_indx=1
+for am_file in <<$1>>; do
+  case " <<$>>CONFIG_HEADERS " in
+  *" <<$>>am_file "*<<)>>
+    echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx
+    ;;
+  esac
+  am_indx=`expr "<<$>>am_indx" + 1`
+done<<>>dnl>>)
+changequote([,]))])
+
+
+# serial 17 AM_PROG_LIBTOOL
+AC_DEFUN(AM_PROG_LIBTOOL,
+[AC_REQUIRE([AC_CANONICAL_HOST])
+AC_REQUIRE([AC_PROG_RANLIB])
+AC_REQUIRE([AC_PROG_CC])
+AC_REQUIRE([AM_PROG_LD])
+AC_REQUIRE([AM_PROG_NM])
+AC_REQUIRE([AC_PROG_LN_S])
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)
+
+dnl Allow the --disable-shared flag to stop us from building shared libs.
+AC_ARG_ENABLE(shared,
+[  --enable-shared         build shared libraries [default=yes]],
+[if test "$enableval" = no; then
+  libtool_enable_shared=no
+else
+  libtool_enable_shared=yes
+fi])
+test -n "$libtool_enable_shared" && enable_shared="$libtool_enable_shared"
+libtool_shared=
+test "$enable_shared" = no && libtool_shared=" --disable-shared"
+
+dnl Allow the --disable-static flag to stop us from building static libs.
+AC_ARG_ENABLE(static,
+[  --enable-static         build static libraries [default=yes]],
+[if test "$enableval" = no; then
+  libtool_enable_static=no
+else
+  libtool_enable_static=yes
+fi])
+test -n "$libtool_enable_static" && enable_static="$libtool_enable_static"
+libtool_static=
+test "$enable_static" = no && libtool_static=" --disable-static"
+
+libtool_flags="$libtool_shared$libtool_static"
+test "$silent" = yes && libtool_flags="$libtool_flags --silent"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+[case "$host" in
+*-*-irix6*)
+  ac_save_CFLAGS="$CFLAGS"
+  flag_passed=no
+  for f in -32 -64 -n32 ABI -cckr -mips1 -mips2 -mips3 -mips4; do
+    case "$f" in
+    ABI)
+      test -n "$SGI_ABI" && flag_passed=yes
+      if test "$flag_passed" = no && test "$ac_cv_prog_gcc" = yes; then
+       # Choose the ABI flag according to GCC's specs.
+       if $CC -dumpspecs 2>&1 | sed '/^\*link:$/,/^$/!d' | egrep -e '[         ]-32' >/dev/null; then
+         LD="${LD-ld} -32"
+       else
+         LD="${LD-ld} -n32"
+       fi
+      fi
+      ;;
+
+    *)
+      if echo " $CC $CFLAGS " | egrep -e "[    ]$f[     ]" > /dev/null; then
+       flag_passed=yes
+       LD="${LD-ld} $f"
+      fi
+      ;;
+    esac
+  done
+  CFLAGS="$ac_save_CFLAGS"
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  CFLAGS="$CFLAGS -belf"
+  ;;
+esac]
+
+# Actually configure libtool.  ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" NM="$NM" RANLIB="$RANLIB" LN_S="$LN_S" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+|| AC_MSG_ERROR([libtool configure failed])
+])
+
+# AM_PROG_LD - find the path to the GNU or non-GNU linker
+AC_DEFUN(AM_PROG_LD,
+[AC_ARG_WITH(gnu-ld,
+[  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  AC_MSG_CHECKING([for ld used by GCC])
+  ac_prog=`($CC -print-prog-name=ld) 2>&5`
+  case "$ac_prog" in
+  # Accept absolute paths.
+  /*)
+    test -z "$LD" && LD="$ac_prog"
+    ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  AC_MSG_CHECKING([for GNU ld])
+else
+  AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(ac_cv_path_LD,
+[if test -z "$LD"; then
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog"; then
+      ac_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some GNU ld's only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+       test "$with_gnu_ld" != no && break
+      else
+        test "$with_gnu_ld" != yes && break
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+else
+  ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+  AC_MSG_RESULT($LD)
+else
+  AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_SUBST(LD)
+AM_PROG_LD_GNU
+])
+
+AC_DEFUN(AM_PROG_LD_GNU,
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  ac_cv_prog_gnu_ld=yes
+else
+  ac_cv_prog_gnu_ld=no
+fi])
+])
+
+# AM_PROG_NM - find the path to a BSD-compatible name lister
+AC_DEFUN(AM_PROG_NM,
+[AC_MSG_CHECKING([for BSD-compatible nm])
+AC_CACHE_VAL(ac_cv_path_NM,
+[case "$NM" in
+/*)
+  ac_cv_path_NM="$NM" # Let the user override the test with a path.
+  ;;
+*)
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in /usr/ucb $PATH /bin; do
+    test -z "$ac_dir" && dir=.
+    if test -f $ac_dir/nm; then
+      # Check to see if the nm accepts a BSD-compat flag.
+      if ($ac_dir/nm -B /dev/null 2>&1; exit 0) | grep /dev/null >/dev/null; then
+        ac_cv_path_NM="$ac_dir/nm -B"
+      elif ($ac_dir/nm -p /dev/null 2>&1; exit 0) | grep /dev/null >/dev/null; then
+        ac_cv_path_NM="$ac_dir/nm -p"
+      else
+        ac_cv_path_NM="$ac_dir/nm"
+      fi
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+  ;;
+esac])
+NM="$ac_cv_path_NM"
+AC_MSG_RESULT([$NM])
+AC_SUBST(NM)
+])
+
+# Add --enable-maintainer-mode option to configure.
+# From Jim Meyering
+
+# serial 1
+
+AC_DEFUN(AM_MAINTAINER_MODE,
+[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+  dnl maintainer-mode is disabled by default
+  AC_ARG_ENABLE(maintainer-mode,
+[  --enable-maintainer-mode enable make rules and dependencies not useful
+                          (and sometimes confusing) to the casual installer],
+      USE_MAINTAINER_MODE=$enableval,
+      USE_MAINTAINER_MODE=no)
+  AC_MSG_RESULT($USE_MAINTAINER_MODE)
+  if test $USE_MAINTAINER_MODE = yes; then
+    MAINT=
+  else
+    MAINT='#M#'
+  fi
+  AC_SUBST(MAINT)dnl
+]
+)
+
+
+# serial 1
+
+# @defmac AC_PROG_CC_STDC
+# @maindex PROG_CC_STDC
+# @ovindex CC
+# If the C compiler in not in ANSI C mode by default, try to add an option
+# to output variable @code{CC} to make it so.  This macro tries various
+# options that select ANSI C on some system or another.  It considers the
+# compiler to be in ANSI C mode if it defines @code{__STDC__} to 1 and
+# handles function prototypes correctly.
+#
+# If you use this macro, you should check after calling it whether the C
+# compiler has been set to accept ANSI C; if not, the shell variable
+# @code{am_cv_prog_cc_stdc} is set to @samp{no}.  If you wrote your source
+# code in ANSI C, you can make an un-ANSIfied copy of it by using the
+# program @code{ansi2knr}, which comes with Ghostscript.
+# @end defmac
+
+AC_DEFUN(AM_PROG_CC_STDC,
+[AC_REQUIRE([AC_PROG_CC])
+AC_BEFORE([$0], [AC_C_INLINE])
+AC_BEFORE([$0], [AC_C_CONST])
+AC_MSG_CHECKING(for ${CC-cc} option to accept ANSI C)
+AC_CACHE_VAL(am_cv_prog_cc_stdc,
+[am_cv_prog_cc_stdc=no
+ac_save_CC="$CC"
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX                  -qlanglvl=ansi
+# Ultrix and OSF/1     -std1
+# HP-UX                        -Aa -D_HPUX_SOURCE
+# SVR4                 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  AC_TRY_COMPILE(
+[#if !defined(__STDC__) || __STDC__ != 1
+choke me
+#endif
+/* DYNIX/ptx V4.1.3 can't compile sys/stat.h with -Xc -D__EXTENSIONS__. */
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/stat.h>
+#endif
+], [
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};],
+[am_cv_prog_cc_stdc="$ac_arg"; break])
+done
+CC="$ac_save_CC"
+])
+if test -z "$am_cv_prog_cc_stdc"; then
+  AC_MSG_RESULT([none needed])
+else
+  AC_MSG_RESULT($am_cv_prog_cc_stdc)
+fi
+case "x$am_cv_prog_cc_stdc" in
+  x|xno) ;;
+  *) CC="$CC $am_cv_prog_cc_stdc" ;;
+esac
+])
+
diff --git a/config.guess b/config.guess
new file mode 100755 (executable)
index 0000000..413ed41
--- /dev/null
@@ -0,0 +1,883 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Written by Per Bothner <bothner@cygnus.com>.
+# The master version of this file is at the FSF in /home/gd/gnu/lib.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit system type (host/target name).
+#
+# Only a few systems have been added to this list; please add others
+# (but try to keep the structure clean).
+#
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 8/24/94.)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+       PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    alpha:OSF1:*:*)
+       if test $UNAME_RELEASE = "V4.0"; then
+               UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+       fi
+       # A Vn.n version is a released version.
+       # A Tn.n version is a released field test version.
+       # A Xn.n version is an unreleased experimental baselevel.
+       # 1.2 uses "1.2" for uname -r.
+       cat <<EOF >dummy.s
+       .globl main
+       .ent main
+main:
+       .frame \$30,0,\$26,0
+       .prologue 0
+       .long 0x47e03d80 # implver $0
+       lda \$2,259
+       .long 0x47e20c21 # amask $2,$1
+       srl \$1,8,\$2
+       sll \$2,2,\$2
+       sll \$0,3,\$0
+       addl \$1,\$0,\$0
+       addl \$2,\$0,\$0
+       ret \$31,(\$26),1
+       .end main
+EOF
+       ${CC-cc} dummy.s -o dummy 2>/dev/null
+       if test "$?" = 0 ; then
+               ./dummy
+               case "$?" in
+                       7)
+                               UNAME_MACHINE="alpha"
+                               ;;
+                       15)
+                               UNAME_MACHINE="alphaev5"
+                               ;;
+                       14)
+                               UNAME_MACHINE="alphaev56"
+                               ;;
+                       10)
+                               UNAME_MACHINE="alphapca56"
+                               ;;
+                       16)
+                               UNAME_MACHINE="alphaev6"
+                               ;;
+               esac
+       fi
+       rm -f dummy.s dummy
+       echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr [[A-Z]] [[a-z]]`
+       exit 0 ;;
+    21064:Windows_NT:50:3)
+       echo alpha-dec-winnt3.5
+       exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+       echo m68k-cbm-sysv4
+       exit 0;;
+    amiga:NetBSD:*:*)
+      echo m68k-cbm-netbsd${UNAME_RELEASE}
+      exit 0 ;;
+    amiga:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    arc64:OpenBSD:*:*)
+       echo mips64el-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    arc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    hkmips:OpenBSD:*:*)
+       echo mips-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    pmax:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    sgi:OpenBSD:*:*)
+       echo mips-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    wgrisc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+       echo arm-acorn-riscix${UNAME_RELEASE}
+       exit 0;;
+    arm32:NetBSD:*:*)
+       echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+       exit 0 ;;
+    SR2?01:HI-UX/MPP:*:*)
+       echo hppa1.1-hitachi-hiuxmpp
+       exit 0;;
+    Pyramid*:OSx*:*:*|MIS*:OSx*:*:*)
+       # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+       if test "`(/bin/universe) 2>/dev/null`" = att ; then
+               echo pyramid-pyramid-sysv3
+       else
+               echo pyramid-pyramid-bsd
+       fi
+       exit 0 ;;
+    NILE:*:*:dcosx)
+       echo pyramid-pyramid-svr4
+       exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+       echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    i86pc:SunOS:5.*:*)
+       echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:6*:*)
+       # According to config.sub, this is the proper way to canonicalize
+       # SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+       # it's likely to be more like Solaris than SunOS4.
+       echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:*:*)
+       case "`/usr/bin/arch -k`" in
+           Series*|S4*)
+               UNAME_RELEASE=`uname -v`
+               ;;
+       esac
+       # Japanese Language versions have a version number like `4.1.3-JL'.
+       echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+       exit 0 ;;
+    sun3*:SunOS:*:*)
+       echo m68k-sun-sunos${UNAME_RELEASE}
+       exit 0 ;;
+    sun*:*:4.2BSD:*)
+       UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+       test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+       case "`/bin/arch`" in
+           sun3)
+               echo m68k-sun-sunos${UNAME_RELEASE}
+               ;;
+           sun4)
+               echo sparc-sun-sunos${UNAME_RELEASE}
+               ;;
+       esac
+       exit 0 ;;
+    aushp:SunOS:*:*)
+       echo sparc-auspex-sunos${UNAME_RELEASE}
+       exit 0 ;;
+    atari*:NetBSD:*:*)
+       echo m68k-atari-netbsd${UNAME_RELEASE}
+       exit 0 ;;
+    atari*:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    sun3*:NetBSD:*:*)
+       echo m68k-sun-netbsd${UNAME_RELEASE}
+       exit 0 ;;
+    sun3*:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mac68k:NetBSD:*:*)
+       echo m68k-apple-netbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mac68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+       echo m88k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    powerpc:machten:*:*)
+       echo powerpc-apple-machten${UNAME_RELEASE}
+       exit 0 ;;
+    RISC*:Mach:*:*)
+       echo mips-dec-mach_bsd4.3
+       exit 0 ;;
+    RISC*:ULTRIX:*:*)
+       echo mips-dec-ultrix${UNAME_RELEASE}
+       exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+       echo vax-dec-ultrix${UNAME_RELEASE}
+       exit 0 ;;
+    2020:CLIX:*:*)
+       echo clipper-intergraph-clix${UNAME_RELEASE}
+       exit 0 ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+       sed 's/^        //' << EOF >dummy.c
+       int main (argc, argv) int argc; char **argv; {
+       #if defined (host_mips) && defined (MIPSEB)
+       #if defined (SYSTYPE_SYSV)
+         printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_SVR4)
+         printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+         printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+       #endif
+       #endif
+         exit (-1);
+       }
+EOF
+       ${CC-cc} dummy.c -o dummy \
+         && ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+         && rm dummy.c dummy && exit 0
+       rm -f dummy.c dummy
+       echo mips-mips-riscos${UNAME_RELEASE}
+       exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+       echo powerpc-harris-powerunix
+       exit 0 ;;
+    m88k:CX/UX:7*:*)
+       echo m88k-harris-cxux7
+       exit 0 ;;
+    m88k:*:4*:R4*)
+       echo m88k-motorola-sysv4
+       exit 0 ;;
+    m88k:*:3*:R3*)
+       echo m88k-motorola-sysv3
+       exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+        if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then
+       if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
+            -o ${TARGET_BINARY_INTERFACE}x = x ] ; then
+               echo m88k-dg-dgux${UNAME_RELEASE}
+       else
+               echo m88k-dg-dguxbcs${UNAME_RELEASE}
+       fi
+        else echo i586-dg-dgux${UNAME_RELEASE}
+        fi
+       exit 0 ;;
+    M88*:DolphinOS:*:*)        # DolphinOS (SVR3)
+       echo m88k-dolphin-sysv3
+       exit 0 ;;
+    M88*:*:R3*:*)
+       # Delta 88k system running SVR3
+       echo m88k-motorola-sysv3
+       exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+       echo m88k-tektronix-sysv3
+       exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+       echo m68k-tektronix-bsd
+       exit 0 ;;
+    *:IRIX*:*:*)
+       echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+       exit 0 ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+       echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+       exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i?86:AIX:*:*)
+       echo i386-ibm-aix
+       exit 0 ;;
+    *:AIX:2:3)
+       if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+               sed 's/^                //' << EOF >dummy.c
+               #include <sys/systemcfg.h>
+
+               main()
+                       {
+                       if (!__power_pc())
+                               exit(1);
+                       puts("powerpc-ibm-aix3.2.5");
+                       exit(0);
+                       }
+EOF
+               ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
+               rm -f dummy.c dummy
+               echo rs6000-ibm-aix3.2.5
+       elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+               echo rs6000-ibm-aix3.2.4
+       else
+               echo rs6000-ibm-aix3.2
+       fi
+       exit 0 ;;
+    *:AIX:*:4)
+       if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then
+               IBM_ARCH=rs6000
+       else
+               IBM_ARCH=powerpc
+       fi
+       if [ -x /usr/bin/oslevel ] ; then
+               IBM_REV=`/usr/bin/oslevel`
+       else
+               IBM_REV=4.${UNAME_RELEASE}
+       fi
+       echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+       exit 0 ;;
+    *:AIX:*:*)
+       echo rs6000-ibm-aix
+       exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+       echo romp-ibm-bsd4.4
+       exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC NetBSD and
+       echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+       exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+       echo rs6000-bull-bosx
+       exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+       echo m68k-bull-sysv3
+       exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+       echo m68k-hp-bsd
+       exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+       echo m68k-hp-bsd4.4
+       exit 0 ;;
+    9000/[3478]??:HP-UX:*:*)
+       case "${UNAME_MACHINE}" in
+           9000/31? )            HP_ARCH=m68000 ;;
+           9000/[34]?? )         HP_ARCH=m68k ;;
+           9000/7?? | 9000/8?[1679] ) HP_ARCH=hppa1.1 ;;
+           9000/8?? )            HP_ARCH=hppa1.0 ;;
+       esac
+       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+       echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+       exit 0 ;;
+    3050*:HI-UX:*:*)
+       sed 's/^        //' << EOF >dummy.c
+       #include <unistd.h>
+       int
+       main ()
+       {
+         long cpu = sysconf (_SC_CPU_VERSION);
+         /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+            true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+            results, however.  */
+         if (CPU_IS_PA_RISC (cpu))
+           {
+             switch (cpu)
+               {
+                 case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+                 default: puts ("hppa-hitachi-hiuxwe2"); break;
+               }
+           }
+         else if (CPU_IS_HP_MC68K (cpu))
+           puts ("m68k-hitachi-hiuxwe2");
+         else puts ("unknown-hitachi-hiuxwe2");
+         exit (0);
+       }
+EOF
+       ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
+       rm -f dummy.c dummy
+       echo unknown-hitachi-hiuxwe2
+       exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+       echo hppa1.1-hp-bsd
+       exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+       echo hppa1.0-hp-bsd
+       exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+       echo hppa1.1-hp-osf
+       exit 0 ;;
+    hp8??:OSF1:*:*)
+       echo hppa1.0-hp-osf
+       exit 0 ;;
+    i?86:OSF1:*:*)
+       if [ -x /usr/sbin/sysversion ] ; then
+           echo ${UNAME_MACHINE}-unknown-osf1mk
+       else
+           echo ${UNAME_MACHINE}-unknown-osf1
+       fi
+       exit 0 ;;
+    parisc*:Lites*:*:*)
+       echo hppa1.1-hp-lites
+       exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+       echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+       echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+       echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+       echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*X-MP:*:*:*)
+       echo xmp-cray-unicos
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+       echo ymp-cray-unicos${UNAME_RELEASE}
+       exit 0 ;;
+    CRAY*[A-Z]90:*:*:*)
+       echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+       | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+             -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
+       exit 0 ;;
+    CRAY*TS:*:*:*)
+       echo t90-cray-unicos${UNAME_RELEASE}
+       exit 0 ;;
+    CRAY-2:*:*:*)
+       echo cray2-cray-unicos
+        exit 0 ;;
+    F300:UNIX_System_V:*:*)
+        FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit 0 ;;
+    F301:UNIX_System_V:*:*)
+       echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
+       exit 0 ;;
+    hp3[0-9][05]:NetBSD:*:*)
+       echo m68k-hp-netbsd${UNAME_RELEASE}
+       exit 0 ;;
+    hp300:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    i?86:BSD/386:*:* | *:BSD/OS:*:*)
+       echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    *:FreeBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+       exit 0 ;;
+    *:NetBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+       exit 0 ;;
+    *:OpenBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+       exit 0 ;;
+    i*:CYGWIN*:*)
+       echo i386-pc-cygwin32
+       exit 0 ;;
+    i*:MINGW*:*)
+       echo i386-pc-mingw32
+       exit 0 ;;
+    p*:CYGWIN*:*)
+       echo powerpcle-unknown-cygwin32
+       exit 0 ;;
+    prep*:SunOS:5.*:*)
+       echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    *:GNU:*:*)
+       echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+       exit 0 ;;
+    *:Linux:*:*)
+       # The BFD linker knows what the default object file format is, so
+       # first see if it will tell us.
+       ld_help_string=`ld --help 2>&1`
+       ld_supported_emulations=`echo $ld_help_string \
+                        | sed -ne '/supported emulations:/!d
+                                   s/[         ][      ]*/ /g
+                                   s/.*supported emulations: *//
+                                   s/ .*//
+                                   p'`
+        case "$ld_supported_emulations" in
+         i?86linux)  echo "${UNAME_MACHINE}-pc-linux-gnuaout"      ; exit 0 ;;
+         i?86coff)   echo "${UNAME_MACHINE}-pc-linux-gnucoff"      ; exit 0 ;;
+         sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+         m68klinux)  echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+         elf32ppc)   echo "powerpc-unknown-linux-gnu"              ; exit 0 ;;
+       esac
+
+       if test "${UNAME_MACHINE}" = "alpha" ; then
+               sed 's/^        //'  <<EOF >dummy.s
+               .globl main
+               .ent main
+       main:
+               .frame \$30,0,\$26,0
+               .prologue 0
+               .long 0x47e03d80 # implver $0
+               lda \$2,259
+               .long 0x47e20c21 # amask $2,$1
+               srl \$1,8,\$2
+               sll \$2,2,\$2
+               sll \$0,3,\$0
+               addl \$1,\$0,\$0
+               addl \$2,\$0,\$0
+               ret \$31,(\$26),1
+               .end main
+EOF
+               LIBC=""
+               ${CC-cc} dummy.s -o dummy 2>/dev/null
+               if test "$?" = 0 ; then
+                       ./dummy
+                       case "$?" in
+                       7)
+                               UNAME_MACHINE="alpha"
+                               ;;
+                       15)
+                               UNAME_MACHINE="alphaev5"
+                               ;;
+                       14)
+                               UNAME_MACHINE="alphaev56"
+                               ;;
+                       10)
+                               UNAME_MACHINE="alphapca56"
+                               ;;
+                       16)
+                               UNAME_MACHINE="alphaev6"
+                               ;;
+                       esac    
+
+                       objdump --private-headers dummy | \
+                         grep ld.so.1 > /dev/null
+                       if test "$?" = 0 ; then
+                               LIBC="libc1"
+                       fi
+               fi      
+               rm -f dummy.s dummy
+               echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0
+       elif test "${UNAME_MACHINE}" = "mips" ; then
+         cat >dummy.c <<EOF
+main(argc, argv)
+     int argc;
+     char *argv[];
+{
+#ifdef __MIPSEB__
+  printf ("%s-unknown-linux-gnu\n", argv[1]);
+#endif
+#ifdef __MIPSEL__
+  printf ("%sel-unknown-linux-gnu\n", argv[1]);
+#endif
+  return 0;
+}
+EOF
+         ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
+         rm -f dummy.c dummy
+       else
+         # Either a pre-BFD a.out linker (linux-gnuoldld)
+         # or one that does not give us useful --help.
+         # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout.
+         # If ld does not provide *any* "supported emulations:"
+         # that means it is gnuoldld.
+         echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:"
+         test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
+
+         case "${UNAME_MACHINE}" in
+         i?86)
+           VENDOR=pc;
+           ;;
+         *)
+           VENDOR=unknown;
+           ;;
+         esac
+         # Determine whether the default compiler is a.out or elf
+         cat >dummy.c <<EOF
+#include <features.h>
+main(argc, argv)
+     int argc;
+     char *argv[];
+{
+#ifdef __ELF__
+# ifdef __GLIBC__
+#  if __GLIBC__ >= 2
+    printf ("%s-${VENDOR}-linux-gnu\n", argv[1]);
+#  else
+    printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+#  endif
+# else
+   printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
+#else
+  printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]);
+#endif
+  return 0;
+}
+EOF
+         ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
+         rm -f dummy.c dummy
+       fi ;;
+# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.  earlier versions
+# are messed up and put the nodename in both sysname and nodename.
+    i?86:DYNIX/ptx:4*:*)
+       echo i386-sequent-sysv4
+       exit 0 ;;
+    i?86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+       # I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+       echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+       exit 0 ;;
+    i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
+       if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+               echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
+       else
+               echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
+       fi
+       exit 0 ;;
+    i?86:*:3.2:*)
+       if test -f /usr/options/cb.name; then
+               UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+               echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+       elif /bin/uname -X 2>/dev/null >/dev/null ; then
+               UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+               (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+               (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+                       && UNAME_MACHINE=i586
+               echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+       else
+               echo ${UNAME_MACHINE}-pc-sysv32
+       fi
+       exit 0 ;;
+    pc:*:*:*)
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+       echo i386-pc-msdosdjgpp
+        exit 0 ;;
+    Intel:Mach:3*:*)
+       echo i386-pc-mach3
+       exit 0 ;;
+    paragon:*:*:*)
+       echo i860-intel-osf1
+       exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+       if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+         echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+       else # Add other i860-SVR4 vendors below as they are discovered.
+         echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+       fi
+       exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+       # "miniframe"
+       echo m68010-convergent-sysv
+       exit 0 ;;
+    M68*:*:R3V[567]*:*)
+       test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+       OS_REL=''
+       test -r /etc/.relid \
+       && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+       /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+         && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+       /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+         && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:*)
+       echo m68k-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+       echo m68k-atari-sysv4
+       exit 0 ;;
+    i?86:LynxOS:2.*:*)
+       echo i386-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+       echo sparc-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*)
+       echo rs6000-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+       echo mips-dde-sysv${UNAME_RELEASE}
+       exit 0 ;;
+    RM*:SINIX-*:*:*)
+       echo mips-sni-sysv4
+       exit 0 ;;
+    *:SINIX-*:*:*)
+       if uname -p 2>/dev/null >/dev/null ; then
+               UNAME_MACHINE=`(uname -p) 2>/dev/null`
+               echo ${UNAME_MACHINE}-sni-sysv4
+       else
+               echo ns32k-sni-sysv
+       fi
+       exit 0 ;;
+    PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                           # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+       # From Gerald Hewes <hewes@openmarket.com>.
+       # How about differentiating between stratus architectures? -djm
+       echo hppa1.1-stratus-sysv4
+       exit 0 ;;
+    *:*:*:FTX*)
+       # From seanf@swdc.stratus.com.
+       echo i860-stratus-sysv4
+       exit 0 ;;
+    mc68*:A/UX:*:*)
+       echo m68k-apple-aux${UNAME_RELEASE}
+       exit 0 ;;
+    news*:NEWS-OS:*:6*)
+       echo mips-sony-newsos6
+       exit 0 ;;
+    R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:*)
+       if [ -d /usr/nec ]; then
+               echo mips-nec-sysv${UNAME_RELEASE}
+       else
+               echo mips-unknown-sysv${UNAME_RELEASE}
+       fi
+        exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+cat >dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+         ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+       printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+       printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+#if !defined (ultrix)
+  printf ("vax-dec-bsd\n"); exit (0);
+#else
+  printf ("vax-dec-ultrix\n"); exit (0);
+#endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0
+rm -f dummy.c dummy
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+       echo c1-convex-bsd
+       exit 0 ;;
+    c2*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+       exit 0 ;;
+    c34*)
+       echo c34-convex-bsd
+       exit 0 ;;
+    c38*)
+       echo c38-convex-bsd
+       exit 0 ;;
+    c4*)
+       echo c4-convex-bsd
+       exit 0 ;;
+    esac
+fi
+
+#echo '(Unable to guess system type)' 1>&2
+
+exit 1
diff --git a/config.h.in b/config.h.in
new file mode 100644 (file)
index 0000000..d190ec4
--- /dev/null
@@ -0,0 +1,36 @@
+/* config.h.in.  Generated automatically from configure.in by autoheader.  */
+
+/* Define to empty if the keyword does not work.  */
+#undef const
+
+/* Define as the return type of signal handlers (int or void).  */
+#undef RETSIGTYPE
+
+/* Define if you have the ANSI C header files.  */
+#undef STDC_HEADERS
+
+/* Define if the X Window System is missing or not being used.  */
+#undef X_DISPLAY_MISSING
+
+/* Other stuff */
+#undef HAVE_IPC_H
+#undef HAVE_SHM_H
+#undef HAVE_XPM
+#undef HAVE_XSHM_H
+#undef HAVE_SYS_SELECT_H
+
+#undef IPC_RMID_DEFERRED_RELEASE
+
+#undef NO_FD_SET
+
+#undef RESOURCE_BASE
+
+#undef XINPUT_NONE
+#undef XINPUT_GXI
+#undef XINPUT_XFREE
+
+/* Define as the return type of signal handlers (int or void).  */
+#undef RETSIGTYPE
+
+/* #undef PACKAGE */
+/* #undef VERSION */
diff --git a/config.sub b/config.sub
new file mode 100755 (executable)
index 0000000..213a6d4
--- /dev/null
@@ -0,0 +1,954 @@
+#! /bin/sh
+# Configuration validation subroutine script, version 1.1.
+#   Copyright (C) 1991, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#      CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#      CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+if [ x$1 = x ]
+then
+       echo Configuration name missing. 1>&2
+       echo "Usage: $0 CPU-MFR-OPSYS" 1>&2
+       echo "or     $0 ALIAS" 1>&2
+       echo where ALIAS is a recognized configuration type. 1>&2
+       exit 1
+fi
+
+# First pass through any local machine types.
+case $1 in
+       *local*)
+               echo $1
+               exit 0
+               ;;
+       *)
+       ;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  linux-gnu*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+       -sun*os*)
+               # Prevent following clause from handling this invalid input.
+               ;;
+       -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+       -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+       -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+       -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+       -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+       -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+       -apple)
+               os=
+               basic_machine=$1
+               ;;
+       -hiux*)
+               os=-hiuxwe2
+               ;;
+       -sco5)
+               os=sco3.2v5
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco4)
+               os=-sco3.2v4
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2.[4-9]*)
+               os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2v[4-9]*)
+               # Don't forget version if it is 3.2v4 or newer.
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco*)
+               os=-sco3.2v2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -isc)
+               os=-isc2.2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -clix*)
+               basic_machine=clipper-intergraph
+               ;;
+       -isc*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -lynx*)
+               os=-lynxos
+               ;;
+       -ptx*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+               ;;
+       -windowsnt*)
+               os=`echo $os | sed -e 's/windowsnt/winnt/'`
+               ;;
+       -psos*)
+               os=-psos
+               ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+       # Recognize the basic CPU types without company name.
+       # Some are omitted here because they have special meanings below.
+       tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
+               | arme[lb] | pyramid | mn10200 | mn10300 \
+               | tron | a29k | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 \
+               | alpha | alphaev5 | alphaev56 | we32k | ns16k | clipper \
+               | i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \
+               | mips64 | mipsel | mips64el | mips64orion | mips64orionel \
+               | mipstx39 | mipstx39el \
+               | sparc | sparclet | sparclite | sparc64 | v850)
+               basic_machine=$basic_machine-unknown
+               ;;
+       # We use `pc' rather than `unknown'
+       # because (1) that's what they normally are, and
+       # (2) the word "unknown" tends to confuse beginning users.
+       i[3456]86)
+         basic_machine=$basic_machine-pc
+         ;;
+       # Object if more than one company name word.
+       *-*-*)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+       # Recognize the basic CPU types with company name.
+       vax-* | tahoe-* | i[3456]86-* | i860-* | m32r-* | m68k-* | m68000-* \
+             | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
+             | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
+             | power-* | none-* | 580-* | cray2-* | h8300-* | i960-* \
+             | xmp-* | ymp-* | hppa-* | hppa1.0-* | hppa1.1-* \
+             | alpha-* | alphaev5-* | alphaev56-* | we32k-* | cydra-* \
+             | ns16k-* | pn-* | np1-* | xps100-* | clipper-* | orion-* \
+             | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
+             | sparc64-* | mips64-* | mipsel-* \
+             | mips64el-* | mips64orion-* | mips64orionel-*  \
+             | mipstx39-* | mipstx39el-* \
+             | f301-*)
+               ;;
+       # Recognize the various machine names and aliases which stand
+       # for a CPU type and a company and sometimes even an OS.
+       3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+               basic_machine=m68000-att
+               ;;
+       3b*)
+               basic_machine=we32k-att
+               ;;
+       alliant | fx80)
+               basic_machine=fx80-alliant
+               ;;
+       altos | altos3068)
+               basic_machine=m68k-altos
+               ;;
+       am29k)
+               basic_machine=a29k-none
+               os=-bsd
+               ;;
+       amdahl)
+               basic_machine=580-amdahl
+               os=-sysv
+               ;;
+       amiga | amiga-*)
+               basic_machine=m68k-cbm
+               ;;
+       amigaos | amigados)
+               basic_machine=m68k-cbm
+               os=-amigaos
+               ;;
+       amigaunix | amix)
+               basic_machine=m68k-cbm
+               os=-sysv4
+               ;;
+       apollo68)
+               basic_machine=m68k-apollo
+               os=-sysv
+               ;;
+       aux)
+               basic_machine=m68k-apple
+               os=-aux
+               ;;
+       balance)
+               basic_machine=ns32k-sequent
+               os=-dynix
+               ;;
+       convex-c1)
+               basic_machine=c1-convex
+               os=-bsd
+               ;;
+       convex-c2)
+               basic_machine=c2-convex
+               os=-bsd
+               ;;
+       convex-c32)
+               basic_machine=c32-convex
+               os=-bsd
+               ;;
+       convex-c34)
+               basic_machine=c34-convex
+               os=-bsd
+               ;;
+       convex-c38)
+               basic_machine=c38-convex
+               os=-bsd
+               ;;
+       cray | ymp)
+               basic_machine=ymp-cray
+               os=-unicos
+               ;;
+       cray2)
+               basic_machine=cray2-cray
+               os=-unicos
+               ;;
+       [ctj]90-cray)
+               basic_machine=c90-cray
+               os=-unicos
+               ;;
+       crds | unos)
+               basic_machine=m68k-crds
+               ;;
+       da30 | da30-*)
+               basic_machine=m68k-da30
+               ;;
+       decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+               basic_machine=mips-dec
+               ;;
+       delta | 3300 | motorola-3300 | motorola-delta \
+             | 3300-motorola | delta-motorola)
+               basic_machine=m68k-motorola
+               ;;
+       delta88)
+               basic_machine=m88k-motorola
+               os=-sysv3
+               ;;
+       dpx20 | dpx20-*)
+               basic_machine=rs6000-bull
+               os=-bosx
+               ;;
+       dpx2* | dpx2*-bull)
+               basic_machine=m68k-bull
+               os=-sysv3
+               ;;
+       ebmon29k)
+               basic_machine=a29k-amd
+               os=-ebmon
+               ;;
+       elxsi)
+               basic_machine=elxsi-elxsi
+               os=-bsd
+               ;;
+       encore | umax | mmax)
+               basic_machine=ns32k-encore
+               ;;
+       fx2800)
+               basic_machine=i860-alliant
+               ;;
+       genix)
+               basic_machine=ns32k-ns
+               ;;
+       gmicro)
+               basic_machine=tron-gmicro
+               os=-sysv
+               ;;
+       h3050r* | hiux*)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       h8300hms)
+               basic_machine=h8300-hitachi
+               os=-hms
+               ;;
+       harris)
+               basic_machine=m88k-harris
+               os=-sysv3
+               ;;
+       hp300-*)
+               basic_machine=m68k-hp
+               ;;
+       hp300bsd)
+               basic_machine=m68k-hp
+               os=-bsd
+               ;;
+       hp300hpux)
+               basic_machine=m68k-hp
+               os=-hpux
+               ;;
+       hp9k2[0-9][0-9] | hp9k31[0-9])
+               basic_machine=m68000-hp
+               ;;
+       hp9k3[2-9][0-9])
+               basic_machine=m68k-hp
+               ;;
+       hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7)
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[0-9][0-9] | hp8[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hppa-next)
+               os=-nextstep3
+               ;;
+       i370-ibm* | ibm*)
+               basic_machine=i370-ibm
+               os=-mvs
+               ;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+       i[3456]86v32)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv32
+               ;;
+       i[3456]86v4*)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv4
+               ;;
+       i[3456]86v)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv
+               ;;
+       i[3456]86sol2)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-solaris2
+               ;;
+       iris | iris4d)
+               basic_machine=mips-sgi
+               case $os in
+                   -irix*)
+                       ;;
+                   *)
+                       os=-irix4
+                       ;;
+               esac
+               ;;
+       isi68 | isi)
+               basic_machine=m68k-isi
+               os=-sysv
+               ;;
+       m88k-omron*)
+               basic_machine=m88k-omron
+               ;;
+       magnum | m3230)
+               basic_machine=mips-mips
+               os=-sysv
+               ;;
+       merlin)
+               basic_machine=ns32k-utek
+               os=-sysv
+               ;;
+       miniframe)
+               basic_machine=m68000-convergent
+               ;;
+       mipsel*-linux*)
+               basic_machine=mipsel-unknown
+               os=-linux-gnu
+               ;;
+       mips*-linux*)
+               basic_machine=mips-unknown
+               os=-linux-gnu
+               ;;
+       mips3*-*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+               ;;
+       mips3*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+               ;;
+       ncr3000)
+               basic_machine=i486-ncr
+               os=-sysv4
+               ;;
+       news | news700 | news800 | news900)
+               basic_machine=m68k-sony
+               os=-newsos
+               ;;
+       news1000)
+               basic_machine=m68030-sony
+               os=-newsos
+               ;;
+       news-3600 | risc-news)
+               basic_machine=mips-sony
+               os=-newsos
+               ;;
+       next | m*-next )
+               basic_machine=m68k-next
+               case $os in
+                   -nextstep* )
+                       ;;
+                   -ns2*)
+                     os=-nextstep2
+                       ;;
+                   *)
+                     os=-nextstep3
+                       ;;
+               esac
+               ;;
+       nh3000)
+               basic_machine=m68k-harris
+               os=-cxux
+               ;;
+       nh[45]000)
+               basic_machine=m88k-harris
+               os=-cxux
+               ;;
+       nindy960)
+               basic_machine=i960-intel
+               os=-nindy
+               ;;
+       np1)
+               basic_machine=np1-gould
+               ;;
+       pa-hitachi)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       paragon)
+               basic_machine=i860-intel
+               os=-osf
+               ;;
+       pbd)
+               basic_machine=sparc-tti
+               ;;
+       pbb)
+               basic_machine=m68k-tti
+               ;;
+        pc532 | pc532-*)
+               basic_machine=ns32k-pc532
+               ;;
+       pentium | p5)
+               basic_machine=i586-intel
+               ;;
+       pentiumpro | p6)
+               basic_machine=i686-intel
+               ;;
+       pentium-* | p5-*)
+               basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentiumpro-* | p6-*)
+               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       k5)
+               # We don't have specific support for AMD's K5 yet, so just call it a Pentium
+               basic_machine=i586-amd
+               ;;
+       nexen)
+               # We don't have specific support for Nexgen yet, so just call it a Pentium
+               basic_machine=i586-nexgen
+               ;;
+       pn)
+               basic_machine=pn-gould
+               ;;
+       power)  basic_machine=rs6000-ibm
+               ;;
+       ppc)    basic_machine=powerpc-unknown
+               ;;
+       ppc-*)  basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppcle | powerpclittle | ppc-le | powerpc-little)
+               basic_machine=powerpcle-unknown
+               ;;
+       ppcle-* | powerpclittle-*)
+               basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ps2)
+               basic_machine=i386-ibm
+               ;;
+       rm[46]00)
+               basic_machine=mips-siemens
+               ;;
+       rtpc | rtpc-*)
+               basic_machine=romp-ibm
+               ;;
+       sequent)
+               basic_machine=i386-sequent
+               ;;
+       sh)
+               basic_machine=sh-hitachi
+               os=-hms
+               ;;
+       sps7)
+               basic_machine=m68k-bull
+               os=-sysv2
+               ;;
+       spur)
+               basic_machine=spur-unknown
+               ;;
+       sun2)
+               basic_machine=m68000-sun
+               ;;
+       sun2os3)
+               basic_machine=m68000-sun
+               os=-sunos3
+               ;;
+       sun2os4)
+               basic_machine=m68000-sun
+               os=-sunos4
+               ;;
+       sun3os3)
+               basic_machine=m68k-sun
+               os=-sunos3
+               ;;
+       sun3os4)
+               basic_machine=m68k-sun
+               os=-sunos4
+               ;;
+       sun4os3)
+               basic_machine=sparc-sun
+               os=-sunos3
+               ;;
+       sun4os4)
+               basic_machine=sparc-sun
+               os=-sunos4
+               ;;
+       sun4sol2)
+               basic_machine=sparc-sun
+               os=-solaris2
+               ;;
+       sun3 | sun3-*)
+               basic_machine=m68k-sun
+               ;;
+       sun4)
+               basic_machine=sparc-sun
+               ;;
+       sun386 | sun386i | roadrunner)
+               basic_machine=i386-sun
+               ;;
+       symmetry)
+               basic_machine=i386-sequent
+               os=-dynix
+               ;;
+       tx39)
+               basic_machine=mipstx39-unknown
+               ;;
+       tx39el)
+               basic_machine=mipstx39el-unknown
+               ;;
+       tower | tower-32)
+               basic_machine=m68k-ncr
+               ;;
+       udi29k)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       ultra3)
+               basic_machine=a29k-nyu
+               os=-sym1
+               ;;
+       vaxv)
+               basic_machine=vax-dec
+               os=-sysv
+               ;;
+       vms)
+               basic_machine=vax-dec
+               os=-vms
+               ;;
+       vpp*|vx|vx-*)
+               basic_machine=f301-fujitsu
+               ;;
+       vxworks960)
+               basic_machine=i960-wrs
+               os=-vxworks
+               ;;
+       vxworks68)
+               basic_machine=m68k-wrs
+               os=-vxworks
+               ;;
+       vxworks29k)
+               basic_machine=a29k-wrs
+               os=-vxworks
+               ;;
+       xmp)
+               basic_machine=xmp-cray
+               os=-unicos
+               ;;
+        xps | xps100)
+               basic_machine=xps100-honeywell
+               ;;
+       none)
+               basic_machine=none-none
+               os=-none
+               ;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+       mips)
+               if [ x$os = x-linux-gnu ]; then
+                       basic_machine=mips-unknown
+               else
+                       basic_machine=mips-mips
+               fi
+               ;;
+       romp)
+               basic_machine=romp-ibm
+               ;;
+       rs6000)
+               basic_machine=rs6000-ibm
+               ;;
+       vax)
+               basic_machine=vax-dec
+               ;;
+       pdp11)
+               basic_machine=pdp11-dec
+               ;;
+       we32k)
+               basic_machine=we32k-att
+               ;;
+       sparc)
+               basic_machine=sparc-sun
+               ;;
+        cydra)
+               basic_machine=cydra-cydrome
+               ;;
+       orion)
+               basic_machine=orion-highlevel
+               ;;
+       orion105)
+               basic_machine=clipper-highlevel
+               ;;
+       *)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+       *-digital*)
+               basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+               ;;
+       *-commodore*)
+               basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+               ;;
+       *)
+               ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+       # -solaris* is a basic system type, with this one exception.
+       -solaris1 | -solaris1.*)
+               os=`echo $os | sed -e 's|solaris1|sunos4|'`
+               ;;
+       -solaris)
+               os=-solaris2
+               ;;
+       -svr4*)
+               os=-sysv4
+               ;;
+       -unixware*)
+               os=-sysv4.2uw
+               ;;
+       -gnu/linux*)
+               os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+               ;;
+       # First accept the basic system types.
+       # The portable systems comes first.
+       # Each alternative MUST END IN A *, to match a version number.
+       # -sysv* is not here because it comes later, after sysvr4.
+       -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+             | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+             | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+             | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+             | -aos* \
+             | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+             | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+             | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+             | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \
+             | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+             | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+             | -cygwin32* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+             | -mingw32* | -linux-gnu* | -uxpv*)
+       # Remember, each alternative MUST END IN *, to match a version number.
+               ;;
+       -linux*)
+               os=`echo $os | sed -e 's|linux|linux-gnu|'`
+               ;;
+       -sunos5*)
+               os=`echo $os | sed -e 's|sunos5|solaris2|'`
+               ;;
+       -sunos6*)
+               os=`echo $os | sed -e 's|sunos6|solaris3|'`
+               ;;
+       -osfrose*)
+               os=-osfrose
+               ;;
+       -osf*)
+               os=-osf
+               ;;
+       -utek*)
+               os=-bsd
+               ;;
+       -dynix*)
+               os=-bsd
+               ;;
+       -acis*)
+               os=-aos
+               ;;
+       -ctix* | -uts*)
+               os=-sysv
+               ;;
+       -ns2 )
+               os=-nextstep2
+               ;;
+       # Preserve the version number of sinix5.
+       -sinix5.*)
+               os=`echo $os | sed -e 's|sinix|sysv|'`
+               ;;
+       -sinix*)
+               os=-sysv4
+               ;;
+       -triton*)
+               os=-sysv3
+               ;;
+       -oss*)
+               os=-sysv3
+               ;;
+       -svr4)
+               os=-sysv4
+               ;;
+       -svr3)
+               os=-sysv3
+               ;;
+       -sysvr4)
+               os=-sysv4
+               ;;
+       # This must come after -sysvr4.
+       -sysv*)
+               ;;
+       -xenix)
+               os=-xenix
+               ;;
+       -none)
+               ;;
+       *)
+               # Get rid of the `-' at the beginning of $os.
+               os=`echo $os | sed 's/[^-]*-//'`
+               echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+       *-acorn)
+               os=-riscix1.2
+               ;;
+       arm*-semi)
+               os=-aout
+               ;;
+        pdp11-*)
+               os=-none
+               ;;
+       *-dec | vax-*)
+               os=-ultrix4.2
+               ;;
+       m68*-apollo)
+               os=-domain
+               ;;
+       i386-sun)
+               os=-sunos4.0.2
+               ;;
+       m68000-sun)
+               os=-sunos3
+               # This also exists in the configure program, but was not the
+               # default.
+               # os=-sunos4
+               ;;
+       *-tti)  # must be before sparc entry or we get the wrong os.
+               os=-sysv3
+               ;;
+       sparc-* | *-sun)
+               os=-sunos4.1.1
+               ;;
+       *-ibm)
+               os=-aix
+               ;;
+       *-hp)
+               os=-hpux
+               ;;
+       *-hitachi)
+               os=-hiux
+               ;;
+       i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+               os=-sysv
+               ;;
+       *-cbm)
+               os=-amigaos
+               ;;
+       *-dg)
+               os=-dgux
+               ;;
+       *-dolphin)
+               os=-sysv3
+               ;;
+       m68k-ccur)
+               os=-rtu
+               ;;
+       m88k-omron*)
+               os=-luna
+               ;;
+       *-next )
+               os=-nextstep
+               ;;
+       *-sequent)
+               os=-ptx
+               ;;
+       *-crds)
+               os=-unos
+               ;;
+       *-ns)
+               os=-genix
+               ;;
+       i370-*)
+               os=-mvs
+               ;;
+       *-next)
+               os=-nextstep3
+               ;;
+        *-gould)
+               os=-sysv
+               ;;
+        *-highlevel)
+               os=-bsd
+               ;;
+       *-encore)
+               os=-bsd
+               ;;
+        *-sgi)
+               os=-irix
+               ;;
+        *-siemens)
+               os=-sysv4
+               ;;
+       *-masscomp)
+               os=-rtu
+               ;;
+       f301-fujitsu)
+               os=-uxpv
+               ;;
+       *)
+               os=-none
+               ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+       *-unknown)
+               case $os in
+                       -riscix*)
+                               vendor=acorn
+                               ;;
+                       -sunos*)
+                               vendor=sun
+                               ;;
+                       -aix*)
+                               vendor=ibm
+                               ;;
+                       -hpux*)
+                               vendor=hp
+                               ;;
+                       -hiux*)
+                               vendor=hitachi
+                               ;;
+                       -unos*)
+                               vendor=crds
+                               ;;
+                       -dgux*)
+                               vendor=dg
+                               ;;
+                       -luna*)
+                               vendor=omron
+                               ;;
+                       -genix*)
+                               vendor=ns
+                               ;;
+                       -mvs*)
+                               vendor=ibm
+                               ;;
+                       -ptx*)
+                               vendor=sequent
+                               ;;
+                       -vxsim* | -vxworks*)
+                               vendor=wrs
+                               ;;
+                       -aux*)
+                               vendor=apple
+                               ;;
+               esac
+               basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+               ;;
+esac
+
+echo $basic_machine$os
diff --git a/configure.in b/configure.in
new file mode 100644 (file)
index 0000000..faa57ed
--- /dev/null
@@ -0,0 +1,214 @@
+# Process this file with autoconf to produce a configure script.
+AC_INIT(gdk/gdktypes.h)
+
+# Configure glib
+AC_CONFIG_SUBDIRS(glib)
+
+dnl Initialize automake stuff
+AM_INIT_AUTOMAKE(gtk+, 971109)
+
+# Specify a configuration file
+AM_CONFIG_HEADER(config.h)
+
+dnl Initialize libtool
+AM_PROG_LIBTOOL
+
+dnl Initialize maintainer mode
+AM_MAINTAINER_MODE
+
+AC_CANONICAL_HOST
+
+AC_ARG_ENABLE(shm, [  --enable-shm            support shared memory if available [default=yes]],
+                  echo $enable_shm, enable_shm="yes")
+AC_ARG_ENABLE(debug, [  --enable-debug          turn on debugging [default=no]],
+if eval "test x$enable_debug = xyes"; then
+  DEBUGFLAG="-g"
+fi)
+AC_ARG_ENABLE(ansi, [  --enable-ansi           turn on strict ansi [default=no]],
+                   , enable_ansi=no)
+
+AC_ARG_WITH(xinput, [  --with-xinput[=no/gxi/xfree] support XInput ])
+
+if test -n "$DEBUGFLAG"; then
+  CFLAGS="$DEBUGFLAG"
+else
+  CFLAGS="$CFLAGS -DNDEBUG"
+fi
+
+# Build time sanity check...
+AM_SANITY_CHECK
+
+# Checks for programs.
+AC_PROG_CC
+AM_PROG_CC_STDC
+AC_PROG_INSTALL
+AC_PROG_MAKE_SET
+
+if eval "test x$GCC = xyes"; then
+  test `echo "$CFLAGS" | grep "\-Wall" > /dev/null 2> /dev/null`
+  if test ! $?; then
+    CFLAGS="$CFLAGS -Wall"
+  fi
+
+  if eval "test x$enable_ansi = xyes"; then
+    test `echo "$CFLAGS" | grep "\-ansi" > /dev/null 2> /dev/null`
+    if test ! $?; then
+      CFLAGS="$CFLAGS -ansi"
+    fi
+
+    test `echo "$CFLAGS" | grep "\-pedantic" > /dev/null 2> /dev/null`
+    if test ! $?; then
+      CFLAGS="$CFLAGS -pedantic"
+    fi
+  fi
+fi
+
+# Find the X11 include and library directories
+AC_PATH_X
+AC_PATH_XTRA
+
+if test "x$x_includes" = "x"; then
+  x_includes="/usr/include"
+fi
+
+saved_cflags="$CFLAGS"
+saved_ldflags="$LDFLAGS"
+
+CFLAGS="$X_CFLAGS"
+LDFLAGS="$X_LDFLAGS $X_LIBS"
+
+# Checks for libraries.
+# Check for the X11 library
+AC_CHECK_LIB(X11, XOpenDisplay, x_libs="-lX11 $X_EXTRA_LIBS", no_x11_lib=yes, $X_EXTRA_LIBS)
+
+if eval "test x$enable_shm = xyes"; then
+  # Check for the Xext library (needed for XShm extention)
+  AC_CHECK_LIB(Xext, XShmAttach, x_libs="-lXext $x_libs", no_xext_lib=yes, $x_libs)
+fi
+
+x_cflags="$X_CFLAGS"
+x_ldflags="$X_LDFLAGS $X_LIBS"
+
+# set up things for XInput
+
+if eval "test x$with_xinput = xgxi -o x$with_xinput = xyes"; then
+  AC_DEFINE(XINPUT_GXI)
+  xinput_progs=gxid
+  x_libs="-lXi $x_libs"
+elif eval "test x$with_xinput = xxfree"; then
+  AC_DEFINE(XINPUT_XFREE)
+  x_libs="-lXi $x_libs"
+else
+  AC_DEFINE(XINPUT_NONE)
+fi
+
+
+AC_SUBST(x_cflags)
+AC_SUBST(x_includes)
+AC_SUBST(x_ldflags)
+AC_SUBST(x_libs)
+AC_SUBST(xinput_progs)
+
+CFLAGS="$saved_cflags"
+LDFLAGS="$saved_ldflags"
+
+if eval "test x$enable_shm = xyes"; then
+  # Check for shared memory
+  AC_CHECK_HEADER(sys/ipc.h, AC_DEFINE(HAVE_IPC_H), no_sys_ipc=yes)
+  AC_CHECK_HEADER(sys/shm.h, AC_DEFINE(HAVE_SHM_H), no_sys_shm=yes)
+
+  # Check whether shmctl IPC_RMID allowes subsequent attaches
+  if test "$ac_cv_header_sys_shm_h" = "yes"; then
+    AC_MSG_CHECKING(whether shmctl IPC_RMID allowes subsequent attaches)
+    AC_TRY_RUN([
+          #include <sys/types.h>
+          #include <sys/ipc.h>
+          #include <sys/shm.h>
+          int main()
+          {
+            int id;
+            char *shmaddr;
+          id = shmget (IPC_PRIVATE, 4, IPC_CREAT | 0777);
+          if (id == -1)
+            exit (2);
+            shmaddr = shmat (id, 0, 0);
+            shmctl (id, IPC_RMID, 0);
+            if ((char*) shmat (id, 0, 0) == (char*) -1)
+            {
+              shmdt (shmaddr);
+              exit (1);
+            }
+            shmdt (shmaddr);
+            shmdt (shmaddr);
+            exit (0);
+          }
+      ],
+      AC_DEFINE(IPC_RMID_DEFERRED_RELEASE)
+        AC_MSG_RESULT(yes),
+      AC_MSG_RESULT(no),
+      AC_MSG_RESULT(assuming no))
+  fi
+
+  # Check for the X shared memory extension header file
+  AC_MSG_CHECKING(X11/extensions/XShm.h)
+  if eval "test x$no_ext_lib = xyes"; then
+    AC_MSG_RESULT(no)
+    no_xshm=yes
+  else
+    if eval "test -f $x_includes/X11/extensions/XShm.h"; then
+      AC_MSG_RESULT(yes)
+      AC_DEFINE(HAVE_XSHM_H)
+    else
+      AC_MSG_RESULT(no)
+      no_xshm=yes
+    fi
+  fi
+fi
+
+# Check for private display resource base variable
+AC_MSG_CHECKING(resource base field in XDisplay)
+AC_CACHE_VAL(gtk_cv_display_resource_base,
+[AC_TRY_RUN([
+#define XLIB_ILLEGAL_ACCESS
+#include <X11/Xlib.h>
+
+int
+main ()
+{
+  Display *display;
+
+  return 0;
+
+  display->resource_base;
+}],
+gtk_cv_display_resource_base="resource_base",
+gtk_cv_display_resource_base="private3")])
+AC_MSG_RESULT($gtk_cv_display_resource_base)
+AC_DEFINE_UNQUOTED(RESOURCE_BASE, gdk_display->$gtk_cv_display_resource_base)
+
+# Checks for header files.
+AC_HEADER_STDC
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+
+# Checks for library functions.
+AC_TYPE_SIGNAL
+
+# Check for sys/select.h
+
+AC_MSG_CHECKING([fd_set and sys/select])
+AC_TRY_COMPILE([#include <sys/types.h>],
+        [fd_set readMask, writeMask;], gtk_ok=yes, gtk_ok=no)
+if test $gtk_ok = no; then
+    AC_HEADER_EGREP(fd_mask, sys/select.h, gtk_ok=yes)
+    if test $gtk_ok = yes; then
+        AC_DEFINE(HAVE_SYS_SELECT_H)
+    fi
+fi
+AC_MSG_RESULT($gtk_ok)
+if test $gtk_ok = no; then
+    AC_DEFINE(NO_FD_SET)
+fi
+
+AC_OUTPUT(Makefile gtk+.xconfig docs/Makefile gdk/Makefile gtk/Makefile)
diff --git a/docs/.cvsignore b/docs/.cvsignore
new file mode 100644 (file)
index 0000000..f3c7a7c
--- /dev/null
@@ -0,0 +1 @@
+Makefile
diff --git a/docs/Makefile.am b/docs/Makefile.am
new file mode 100644 (file)
index 0000000..f4df2f3
--- /dev/null
@@ -0,0 +1,10 @@
+## Process this file with automake to produce Makefile.in
+
+info_TEXINFOS = gdk.texi gtk.texi
+
+EXTRA_DIST = texinfo.tex macros.texi
+
+files:
+       @files=`ls $(DISTFILES) 2> /dev/null `; for p in $$files; do \
+         echo $$p; \
+       done
diff --git a/docs/gdk.texi b/docs/gdk.texi
new file mode 100644 (file)
index 0000000..4942fe2
--- /dev/null
@@ -0,0 +1,326 @@
+\input texinfo @c -*-texinfo-*-
+@c %**start of header
+@setfilename gdk.info
+@settitle GDK
+@setchapternewpage odd
+@c %**end of header
+
+@set edition 1.0
+@set update-date 16 May 1996
+@set update-month May 1996
+
+@ifinfo
+This file documents GDK, the General Drawing Kit
+
+Copyright (C) 1996 Peter Mattis
+
+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
+
+@ignore
+Permission is granted to process this file throught TeX and print the
+results, provided the printed document carries copying permission notice
+identical to this one except for the removal of this paragraph (this
+paragraph not being relevant to the printed manual).
+
+@end ignore
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided 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 manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation
+approved by Peter Mattis.
+@end ifinfo
+
+@titlepage
+@title The General Drawing Kit
+@subtitle Version 1.0
+@subtitle @value{update-month}
+@author by Peter Mattis
+
+@page
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1996 Peter Mattis
+
+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
+manual under the conditions for verbatim copying, provided 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 manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation
+approved by Peter Mattis.
+@end titlepage
+
+@dircategory User Interface Toolkit
+@direntry
+* GDK: (gdk).          The General Drawing Kit
+@end direntry
+
+@node Top, Copying, (dir), (dir)
+@top The General Drawing Kit
+@ifinfo
+This is edition @value{edition} of the GDK documentation,
+@w{@value{update-date}}.
+@end ifinfo
+
+@menu
+* Copying::                     Your rights.
+* Overview::                    What is GDK?
+* Initialization::              Initialization and exit.
+* Events::                      Event handling.
+* Visuals::                     Understanding and using visuals.
+* Windows::                     Creating and using windows.
+* Graphics Contexts::           Creating and modifying GCs.
+* Pixmaps::                     Creating pixmaps.
+* Images::                      Creating images.
+* Color::                       Specifying color.
+* Fonts::                       Creating fonts.
+* Drawing::                     Drawing commands.
+* XInput Support::              Using extended devices.
+* Miscellany::                  Other stuff.
+* Examples::                    Using GDK.
+* Function Index::              Index of functions
+* Concept Index::               Index of concepts
+@end menu
+
+@node Copying, Overview, Top, Top
+@comment node-name, next, previous, up
+@chapter Copying
+
+GDK is @dfn{free}; this means that everyone is free to use it and free
+to redestribute it on a free basis. GDK is not in the public domain; it
+is copyrighted and there are restrictions on its distribution, but these
+restrictions are designed to permit everything that a good cooperating
+citizen would want to do. What is not allowed is to try to prevent
+others from further sharing any version of GDK that they might get from
+you.
+
+Specifically, we want to make sure that you have the right to give away
+copies of GDK, that you receive source code or else can get it if you
+want it, that you can change GDK or use pieces of it in new free
+programs, and that you know you can do these things.
+
+To make sure that everyone has such rights, we have to forbid you to
+deprive anyone else of these rights. For example, if you distribute
+copies of GDK, you must give the recipients all the rights that you
+have. You must make sure that they, too, receive or can get the source
+code. And you must tell them their rights.
+
+Also, for my own protection, we must make certain that everyone finds
+out that there is no warranty for GDK. If GDK is modified by someone
+else and passed on, we want their recipients to know that what they have
+is not what we distributed, so that any problems introduced by others
+will no reflect on our reputation.
+
+The precise conditions of the licenses for GDK are found in the General
+Public Licenses that accompanies it.
+
+
+@node Overview, Initialization, Copying, Top
+@comment node-name, next, previous, up
+@chapter What is GDK?
+@cindex Overview
+
+GDK is designed as a wrapper library that lies on top of Xlib. It
+performs many common and desired operations for a programmer instead
+of the programmer having to explicitly ask for such functionality from
+Xlib directly. For example, GDK provides a common interface to both
+regular and shared memory XImage types. By doing so, an application
+can nearly transparently use the fastest image type available. GDK
+also provides routines for determining the best available color depth
+and the best available visual which is not always the default visual
+for a screen.
+
+@node Initialization, Events, Overview, Top
+@comment node-name, next, previous, up
+@chapter Initialization and exit
+@cindex Initialization
+@cindex Exit
+
+Initializing GDK is easy. Simply call @code{gdk_init} passing in the
+@var{argc} and @var{argv} parameters. Exit is similarly easy. Just
+call @code{gdk_exit}.
+
+@deftypefun void gdk_init (int *@var{argc}, char ***@var{argv})
+Initializes the GDK library. The arguments @var{argc} and @var{argv}
+are scanned and any arguments that GDK recognizes are handled and
+removed. The @var{argc} and @var{argv} parameters are the values
+passed to @code{main} upon program invocation.
+@end deftypefun
+
+@deftypefun void gdk_exit (int @var{errorcode})
+Exit GDK and perform any necessary cleanup. @code{gdk_exit} will call
+the systems @code{exit} function passing @var{errorcode} as the
+parameter.
+@end deftypefun
+
+@example
+int
+main (int argc, char *argv[])
+@{
+  /* Initialize GDK. */
+  gdk_init (&argc, &argv);
+
+  /* Exit from GDK...this call will never return. */
+  gdk_exit (0);
+
+  /* Keep compiler from issuing a warning */
+  return 0;
+@}
+@end example
+
+
+@node Events, Visuals, Initialization, Top
+@comment node-name, next, previous, up
+@chapter Event handling
+@cindex Events
+
+Events are the means by which GDK lets the programmer know of user
+interaction. An event is normally a button or key press or some other
+indirect user action, such as a the mouse cursor entering or leaving a
+window.
+
+There exist only a few functions for getting events and event
+information. These are @code{gdk_events_pending},
+@code{gdk_event_get}, @code{gdk_events_record} and
+@code{gdk_events_playback}. The latter two functions are useful for
+automatic testing of a software package and should normally not be
+needed in a program.
+
+@deftypefun gint gdk_events_pending (void)
+Returns the number of events pending on the event queue.
+@end deftypefun
+
+@deftypefun gint gdk_event_get (GdkEvent *@var{event})
+Return the next available event in the @var{event}
+structure. @code{gdk_event_get} will return @code{TRUE} on success and
+@code{FALSE} on failure. Success and failure is determined by whether
+an event arrived before the timeout period expired.
+@end deftypefun
+
+@deftypefun void gdk_events_record (char *@var{filename})
+Turn on recording of events. User events and certain system events will
+be saved in the file named by the variable @var{filename}. This stream
+of events can later be played back and ``should'' produce the same
+results as when the original events were handled. However, the
+programmer does need to be careful in that the state of the program must
+be the same when @code{gdk_events_record} is called and when
+@code{gdk_events_playback} is called. For this reason,
+@code{gdk_events_record} is normally not called directly, but is instead
+invoked indirectly by specifying the ``-record'' command line option.
+@end deftypefun
+
+@deftypefun void gdk_events_playback (char *@var{filename})
+Start playback of events from a file. (See the above description of
+@code{gdk_events_record}). Normally this function is not called directly
+but is invoked by the ``-playback'' command line option.
+@end deftypefun
+
+@deftypefun void gdk_events_stop (void)
+Stop recording and playback of events.
+@end deftypefun
+
+@example
+void
+handle_event ()
+@{
+  GdkEvent event;
+
+  if (gdk_event_get (&event))
+    @{
+      switch (event.type)
+       @{
+         @dots{}
+       @}
+    @}
+@}
+@end example
+
+
+@node Visuals, Windows, Events, Top
+@comment node-name, next, previous, up
+@chapter Understanding and using visuals
+@cindex Visuals
+
+@node Windows, Graphics Contexts, Visuals, Top
+@comment node-name, next, previous, up
+@chapter Creating and using windows
+@cindex Windows
+
+@node Graphics Contexts, Pixmaps, Windows, Top
+@comment node-name, next, previous, up
+@chapter Creating and modifying GCs
+@cindex Graphics Contexts
+@cindex GC
+
+@node Pixmaps, Images, Graphics Contexts, Top
+@comment node-name, next, previous, up
+@chapter Creating pixmaps
+@cindex Pixmaps
+
+@node Images, Color, Pixmaps, Top
+@comment node-name, next, previous, up
+@chapter Creating images
+@cindex Images
+
+@node Color, Fonts, Images, Top
+@comment node-name, next, previous, up
+@chapter Specifying color
+@cindex Color
+
+@node Fonts, Drawing, Color, Top
+@comment node-name, next, previous, up
+@chapter Creating Fonts
+@cindex Fonts
+
+@node Drawing, XInput Support, Fonts, Top
+@comment node-name, next, previous, up
+@chapter Drawing Commands
+@cindex Drawing
+
+@node XInput Support, Miscellany, Drawing, Top
+@comment node-name, next, previous, up
+@chapter Using extended devices
+@cindex Overview
+@cindex Using extended device capabilities
+@cindex Controlling extended devices
+
+@node Miscellany, Examples, XInput Support, Top
+@comment node-name, next, previous, up
+@chapter Other stuff
+@cindex Timers
+@cindex Debugging
+@cindex Miscellaneous
+
+
+@node Examples, Function Index, Miscellany, Top
+@comment node-name, next, previous, up
+@chapter Using GDK
+@cindex Examples
+
+
+@node Function Index, Concept Index, Examples, Top
+@comment node-name, next, previous, up
+@unnumbered Variable Index
+
+@printindex fn
+
+@node Concept Index, , Function Index, Top
+@comment node-name, next, previous, up
+@unnumbered Concept Index
+
+@printindex cp
+
+@summarycontents
+@contents
+@bye
diff --git a/docs/gtk.texi b/docs/gtk.texi
new file mode 100644 (file)
index 0000000..93daf5b
--- /dev/null
@@ -0,0 +1,3285 @@
+\input texinfo @c -*-texinfo-*-
+@c Copyright (C) 1996 by Peter Mattis. All rights reserved.
+@c
+@c %**start of header
+@setfilename gtk.info
+@settitle GTK
+@setchapternewpage odd
+@include macros.texi
+@c %**end of header
+
+@set edition 1.0
+@set update-date 9 April 1997
+@set update-month April 1997
+
+@ifinfo
+This file documents GTK, the General Toolkit
+
+Copyright (C) 1996 Peter Mattis
+Copyright (C) 1997 Peter Mattis
+
+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
+
+@ignore
+Permission is granted to process this file throught TeX and print the
+results, provided the printed document carries copying permission notice
+identical to this one except for the removal of this paragraph (this
+paragraph not being relevant to the printed manual).
+
+@end ignore
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided 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 manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation
+approved by Peter Mattis.
+@end ifinfo
+
+@titlepage
+@title The General Toolkit
+@subtitle Version @value{edition}
+@subtitle @value{update-month}
+@author by Peter Mattis
+
+@page
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1996 Peter Mattis
+Copyright @copyright{} 1997 Peter Mattis
+
+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
+manual under the conditions for verbatim copying, provided 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 manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation
+approved by Peter Mattis.
+@end titlepage
+
+@dircategory User Interface Toolkit
+@direntry
+* GTK: (gtk).          The General Toolkit
+@end direntry
+
+@node Top, Copying, (dir), (dir)
+@top The General Toolkit
+@ifinfo
+This is edition @value{edition} of the GTK documentation,
+@w{@value{update-date}}.
+@end ifinfo
+
+@menu
+* Copying::                     Your rights.
+* Overview::                    What is GTK?
+* Objects::                     Object overview.
+* Signals::                     Signals overview.
+* Widgets::                     Widget overview.
+* Other Objects::               Utility objects.
+* Miscellaneous::               Initialization, exit and other features.
+* Examples::                    Using GTK.
+* Object Implementation::       Object internals.
+* Signal Implementation::       Signal internals.
+* Widget Implementation::       Widget internals.
+* Function Index::              Index of functions.
+* Concept Index::               Index of concepts.
+@end menu
+
+@node Copying, Overview, Top, Top
+@comment node-name, next, previous, up
+@chapter Copying
+
+GTK is @dfn{free}; this means that everyone is free to use it and free
+to redestribute it on a free basis. GTK is not in the public domain; it
+is copyrighted and there are restrictions on its distribution, but
+these restrictions are designed to permit everything that a good
+cooperating citizen would want to do. What is not allowed is to try to
+prevent others from further sharing any version of GTK that they might
+get from you.
+
+Specifically, we want to make sure that you have the right to give away
+copies of GTK, that you receive source code or else can get it if you
+want it, that you can change GTK or use pieces of it in new free
+programs, and that you know you can do these things.
+
+To make sure that everyone has such rights, we have to forbid you to
+deprive anyone else of these rights. For example, if you distribute
+copies of GTK, you must give the recipients all the rights that you
+have. You must make sure that they, too, receive or can get the source
+code. And you must tell them their rights.
+
+Also, for my own protection, we must make certain that everyone finds
+out that there is no warranty for GTK. If GTK is modified by someone
+else and passed on, we want their recipients to know that what they have
+is not what we distributed, so that any problems introduced by others
+will no reflect on our reputation.
+
+The precise conditions of the licenses for GTK are found in the General
+Public Licenses that accompanies it.
+
+
+@node Overview, Objects, Copying, Top
+@comment node-name, next, previous, up
+@chapter What is GTK?
+@cindex Overview
+
+GTK is a library for creating graphical user interfaces similar to the
+Motif ``look and feel''. It is designed to be small and efficient, but
+still flexible enough to allow the programmer freedom in the interfaces
+created. GTK allows the programmer to use a variety of standard user
+interface widgets (@pxref{Widgets}) such as push, radio and check
+buttons, menus, lists and frames. It also provides several ``container''
+widgets which can be used to control the layout of the user interface
+elements.
+
+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.
+
+
+@node Objects, Signals, Overview, Top
+@comment node-name, next, previous, up
+@chapter Object Overview
+@cindex Objects
+
+GTK implements a semi-simple class mechanism and an associated class
+hierarchy for widgets and several other useful objects. The GtkObject
+type is the root of the class hierarchy. It provides a few items needed
+by all classes, the foundation for the signal (@pxref{Signals})
+mechanism and the ``destroy'' method.
+
+The class hierarchy is defined by a type hierarchy. This hierarchy
+allows queries to be made in regards to a type. The basic query that can
+be performed is asking whether a given type has an ``is a'' relation
+with another type. For instance, it is common to ask whether a general
+widget pointer is a type of specific widget so that runtime sanity
+checks can be made.
+
+@section Type utility functions
+
+The @code{GtkTypeInfo} structure is used to communicate information to
+@code{gtk_type_unique} as opposed to passing in large numbers of
+parameters.
+
+@example
+typedef struct _GtkTypeInfo GtkTypeInfo;
+
+struct _GtkTypeInfo
+@{
+  gchar *type_name;
+  guint object_size;
+  guint class_size;
+  GtkClassInitFunc class_init_func;
+  GtkObjectInitFunc object_init_func;
+  GtkValueInitFunc value_init_func;
+@}
+@end example
+
+@itemize @bullet
+@item
+The @code{type_name} field refers to the name of the type. It is
+convention for the type name to be the same as the C structure type. For
+example, the type name of the @code{GtkObject} structure is
+``GtkObject''.
+
+@item
+The @code{object_size} field refers to the size in bytes of the C
+structure. The easiest (and portable) means of computing this size is by
+using the C @code{sizeof} operator. For instance, the sizeof of the
+@code{GtkObject} structure is computed by doing @code{sizeof
+(GtkObject)}.
+
+@item
+The @code{class_size} field refers to the size in bytes of the C
+structure for the class. Again, the @code{sizeof} operator should be
+used to compute this value.
+
+@item
+The @code{class_init_func} field is a callback which is used by the type
+mechanism to initialize class specific fields. The single argument this
+function takes is a pointer to a class structure.
+
+@item
+The @code{object_init_func} field is a callback which is used by the
+type mechanism to initialize object specific fields. The single argument
+this functions takes is a pointer to an object structure.
+
+@item
+The @code{value_init_func} field is a callback which is used by the type
+mechanism to initialize object stack value types. (FIXME: unfinished).
+@end itemize
+
+@deftypefun guint gtk_type_unique (guint @var{parent_type}, GtkTypeInfo *@var{type_info})
+The @var{parent_type} is simply the value of the new types parent
+type. If @var{parent_type} is 0, then the new type is the root of the
+type hierarchy. @var{type_info} is a pointer to a structure which
+contains necessary information for construction of the new
+type. Specifically, the @code{type_name}, @code{object_size} and
+@code{class_size} fields are required. The @code{class_init_func},
+@code{object_init_func} and @code{value_init_func} fields may be NULL.
+@end deftypefun
+
+@deftypefun gchar* gtk_type_name (guint @var{type})
+The returned string is the name of @var{type} as specified to
+@code{gtk_type_unique}.
+@end deftypefun
+
+@deftypefun guint gtk_type_from_name (guchar *@var{name})
+Return the type associated with @var{name}. If there is no type
+associated with @var{name}, then 0 will be returned.
+@end deftypefun
+
+@deftypefun guint gtk_type_parent (guint @var{type})
+Returns the parent type of @var{type} or 0 if @var{type} is the root of
+the type hierarchy.
+@end deftypefun
+
+@deftypefun gpointer gtk_type_class (guint @var{type})
+Returns the initialized class structure for @var{type}. The class
+structure is actually created and initialized the first time it is
+needed. If creation and initialization occurs, the @code{class_size}
+field of the @code{GtkTypeInfo} structure used to initialize this type
+is used to determine how large the class structure is. The
+@code{class_init_func} field from the @code{GtkTypeInfo} structure is
+called for all the members in the types ancestry, including the
+type. The order of this invocation proceeds from the root on down. For
+example, the @code{GtkWidgetClass} is first initialized as an
+@code{GtkObjectClass} by the object class initialization routine and
+then by the widget class initialization routine. This allows the widget
+class initialization routine to override values set by the object class
+initialization routine. The returned structure is shared by all objects
+of @var{type} and, as such, should not be modified.
+@end deftypefun
+
+@deftypefun gpointer gtk_type_new (guint @var{type})
+Returns a new instance of an @var{type} object. The object structure is
+created and initialized similarly to the class structure (as described
+above). The @code{object_size} and @code{object_init_func} fields of the
+@code{GtkTypeInfo} structure are used to determine the objects allocated
+size and the object specific initialization routine. Similarly to the
+class initialization, all the object initialization routines from the
+root on down to the particular type being created are invoked.
+@end deftypefun
+
+@deftypefun void gtk_type_describe_heritage (guint @var{type})
+Prints the type heritage for @var{type}. The heritage for a type
+includes the type and all its parent types up the type tree.
+@end deftypefun
+
+@deftypefun void gtk_type_describe_tree (guint @var{type}, gint @var{show_size})
+Prints the type tree which starts at @var{type}. @var{show_size} is a
+boolean which determines whether type sizes are printed.
+@end deftypefun
+
+@deftypefun gint gtk_type_is_a (guint @var{type}, guint @var{is_a_type})
+A predicate function which determines whether the relation @var{type}
+is_a @var{is_a_type} is true.
+@end deftypefun
+
+@section Object functions
+
+The GtkObject type is the root of the type hierarchy used by GTK. It
+provides a minimal set of fields used to implement the actual
+object, class and signal mechanisms, as well as several utility routines
+which make dealing with objects easier.
+
+For the adventurous, see @ref{Object Implementation}.
+
+@deftypefun guint gtk_object_get_type (void)
+Returns the @code{GtkObject} type identifier.
+@end deftypefun
+
+@deftypefun void gtk_object_class_add_signals (GtkObjectClass *@var{class}, gint *@var{signals}, gint @var{nsignals})
+Adds @var{signals} to the @code{signals} field in the GtkObjectClass
+structure @var{class}. @xref{Signals}.
+@end deftypefun
+
+@deftypefun void gtk_object_destroy (GtkObject *@var{object})
+Performs checks to make sure it is alright to destroy @var{object} and
+then emits the @code{destroy} signal. The check which is performed is to
+make sure @var{object} is not already processing another signal. If this
+were the case then destroying the object immediately would undoubtedly
+cause problems as the other signal would not be able to tell the object
+was destroyed. The solution is that if @var{object} is processing another
+signal we mark @var{object} is needing to be destroyed. When we finish
+processing of the other signal we check whether the object needs to be
+destroyed.
+@end deftypefun
+
+The GtkObject type provides a mechanism for associating arbitrary
+amounts of data with an object. The data is associated with the object
+using a character string key. The functions @code{gtk_object_set_data},
+@code{gtk_object_get_data}, and @code{gtk_object_remove_data} are the
+interface to this mechanism. Two other routines,
+@code{gtk_object_set_user_data} and @code{gtk_object_get_user_data},
+exist as convenience functions which simply use the same mechanism.
+
+@deftypefun void gtk_object_set_data (GtkObject *@var{object}, const char *@var{key}, gpointer @var{data})
+Associate @var{data} with @var{key} in the data list of @var{object}.
+@end deftypefun
+
+@deftypefun gpointer gtk_object_get_data (GtkObject *@var{object}, const char *@var{key})
+Retrieve the data associated with @var{key} in the data list of @var{object}.
+@end deftypefun
+
+@deftypefun void gtk_object_remove_data (GtkObject *@var{object}, const char *@var{key})
+Remove the data associated with @var{key} in the data list of @var{object}.
+@end deftypefun
+
+@deftypefun void gtk_object_set_user_data (GtkObject *@var{object}, gpointer @var{data})
+Sets @var{data} into the @code{user_data} field of @var{object}.
+@end deftypefun
+
+@deftypefun gpointer gtk_object_get_user_data (GtkObject *@var{object})
+Returns the @code{user_data} field of @var{object}.
+@end deftypefun
+
+The GtkObject type also provides a mechanism for specifying
+initialization values for fields. This general mechanism is called
+object value stacks. The reason for using value stacks is that they can
+simplify the life of the programmer. For instance, by default widgets
+are non-visible when created. However, the ``visible'' value for widgets
+may be specified so that widgets are made visible when created. (FIXME:
+unfinished).
+
+@deftypefun void gtk_object_value_stack_new (guint @var{object_type}, const gchar *@var{value_id}, GtkParamType @var{value_type})
+@end deftypefun
+
+@deftypefun void gtk_object_push_value (guint @var{object_type}, const gchar *@var{value_id}, @dots{})
+Push a value on the value stack specified by @var{object_type} and
+@var{value_id}. The type of value is implicitly given in the context of
+@var{object_type} and @var{value_id}. (That is, it is not specified
+explicitly in the function call). Only a single extra argument is
+expected which is the data which is to be placed on the stack.
+@end deftypefun
+
+@deftypefun void gtk_object_pop_value (guint @var{object_type}, const gchar *@var{value_id})
+Pop a value of the value stack specified by @var{object_type} and
+@var{value_id}.
+@end deftypefun
+
+@deftypefun gint gtk_object_peek_value (guint @var{object_type}, const gchar *@var{value_id}, gpointer @var{data})
+Peek at the value on the top of the value stack specified by
+@var{object_type} and @var{value_id}. The @var{data} argument is
+interpreted as the location of where to place the ``peeked'' data. For
+instance, if the peeked data is of type @code{GTK_PARAM_POINTER}, then
+@var{data} will be a pointer to a pointer. If the value stack is empty
+or does not exist or an error occurs, @code{gtk_object_peek_value} will
+return @code{FALSE}. On success it will return @code{TRUE}.
+@end deftypefun
+
+
+@node Signals, Widgets, Objects, Top
+@comment node-name, next, previous, up
+@chapter Signals Overview
+@cindex Signals
+
+Signals are GTK's method for objects to perform callbacks. A signal is
+an event which occurs upon an object. The programmer can connect to a
+signal of an object which involves specifying a function to be called
+when that signal is emitted in the specified object.
+
+When a signal is emitted, both the class function associated with the
+signal (when it was defined) and all signal handlers installed for that
+signal on the particular object emitting the signal are called. The
+widget programmer can specify whether the class function is to be called
+before after or both before and after the signal handlers installed by
+the widget user. The widget user can, however, specify that their signal
+handler is to be run after the class function (using the ``_after''
+signal connection routines). Any signal handling function can emit the
+same signal on the same object while it is running causing that signal
+emittion to either restart or to run recursively. Additionally, signal
+emittion can be terminated prematurely. While both such abilities are
+rarely used, they do allow for greater flexibility in regards to
+signals. For instance, a programmer can attach to the key press event
+signal and intercept all tab key presses from a widget. This particular
+example is used in the file selection dialog to implement tab completion
+of filenames and prevent the entry widget from inserting the tab into
+its buffer.
+
+Signals are selected using either an integer identifier or a character
+string name. It is convention to name the signal the same as the class
+function which is associated with it. There are two versions of most of
+the signal functions, one which takes an integer identifier and one
+which takes a character string name for the signal.
+
+@deftypefun gint gtk_signal_new (gchar *@var{name}, GtkSignalRunType @var{run_type}, gint @var{object_type}, gint @var{function_offset}, GtkSignalMarsahller @var{marshaller}, GtkParamType @var{return_val}, gint @var{nparams}, @dots{})
+Create a new signal and give it the character string identifier
+@var{name}. @var{name} needs to be unique in the context of
+@var{object_type}'s branch of the class hierarchy. That is,
+@var{object_type} cannot create a signal type with the same name as a
+signal type created by one of its parent types.
+
+@var{run_type} specifies whether the class function should be run before
+(@code{GTK_RUN_FIRST}), after (@code{GTK_RUN_LAST}) or both before and
+after normal signal handlers (@code{GTK_RUN_BOTH}). Additionally, the
+@code{GTK_RUN_NO_RECURSE} value can be or'ed with any of those values to
+specify that the signal should not be recursive. By default, emitting
+the same signal on the same widget will cause the signal to be emitted
+twice. However, if the @code{GTK_RUN_NO_RECURSE} flag is specified,
+emitting the same signal on the same widget will cause the current
+signal emittion to be restarted. This allows the widget programmer to
+specify the semantics of signal emittion on a per signal
+basis. (The @code{GTK_RUN_NO_RECURSE} flag is used by the GtkAdjustment
+widget).
+
+The @var{function_offset} is the byte offset from the start of the class
+structure to the class function field within the class structure. The
+easiest means to compute this offset is by using the
+@code{GTK_SIGNAL_OFFSET} macro which takes the class structure type as
+the first argument and the field as the second argument. For example,
+@code{GTK_SIGNAL_OFFSET (GtkObjectClass, destroy)} will give the offset
+of the @code{destroy} class function within the
+@code{GtkObjectClass}. Note: An offset is specified instead of an
+absolute location since there will be multiple instances of a class
+structure being referenced. (The @code{GtkWidgetClass} structure ``is
+a'' @code{GtkObjectClass} structure, etc.)
+
+The @var{marshaller} function is used to invoke a signal handler. Since
+signal handlers may take different parameters and return values and a
+general mechanism for invoking them is not apparent, the approach of
+making the signal creator responsible for invoking the signal handler
+was taken. (FIXME: unfinished).
+
+The @var{return_val} and @var{nparams} and the remaining arguments
+specify the return value and the arguments to the signal handler
+respectively. Note: There is an implicit first argument to every signal
+handler which is the widget the signal has been emitted from. The
+variable argument list (@var{@dots{}}) specifies the types of the
+arguments. These can be one of @code{GTK_PARAM_CHAR},
+@code{GTK_PARAM_SHORT}, @code{GTK_PARAM_INT}, @code{GTK_PARAM_LONG},
+@code{GTK_PARAM_POINTER} or @code{GTK_PARAM_FUNCTION}. It is undefined
+to specify @code{GTK_PARAM_NONE} as an argument type, however it is ok
+to use @code{GTK_PARAM_NONE} for @var{return_val}. (This corresponds to
+returning a @code{void}).
+
+@code{gtk_signal_new} returns the integer identifier of the newly
+created signal. Signal identifiers start numbering at 1 and increase
+upwards. A value of -1 will be returned if an error occurs.
+
+@strong{Note:} @code{gtk_signal_new} is only needed by widget writers. A
+normal user of GTK will never needed to invoke this function.
+@end deftypefun
+
+@deftypefun gint gtk_signal_lookup (gchar *@var{name}, gint @var{object_type})
+Returns the integer identifier for the signal referenced by @var{name}
+and @var{object_type}. If @var{object_type} does not define the signal
+@var{name}, then the signal is looked for in @var{object_type}'s parent
+type recursively.
+@end deftypefun
+
+@deftypefun gint gtk_signal_emit (GtkObject *@var{object}, gint @var{signal_type}, @dots{})
+Emit the signal specified by the integer identifier @var{signal_type}
+from @var{object}. If an error occurs, @code{gtk_signal_emit} will
+return @code{FALSE} and will return @code{TRUE} on success. The signal
+definition determines the parameters passed in the variable argument
+list (@code{@dots{}}). For example, if the signal is defined as:
+
+@example
+  gint (* event) (GtkWidget *widget, GdkEvent *event);
+@end example
+
+Then a call to emit the ``event'' signal would look like:
+
+@example
+  GdkEvent event;
+  gint return_val;
+  @dots{}
+  gtk_signal_emit (some_object,
+                   gtk_signal_lookup ("event",
+                     GTK_OBJECT_TYPE (some_object)),
+                   &event, &return_val);
+@end example
+
+Notice that the @code{widget} argument is implicit in that the first
+argument to every signal is a type derived from @code{GtkObject}. The
+@var{return_val} argument is actually a pointer to the return value type
+since the signal mechanism needs to be able to place the return value in
+an actual location. And lastly, the @code{gtk_signal_lookup} call is
+normally avoided by using the @code{gtk_signal_emit_by_name} function
+instead. @code{gtk_signal_emit} is normally used internally by widgets
+which know the signal identifier (since they defined the signal) and can
+therefore side-step the cost of calling @code{gtk_signal_lookup}.
+@end deftypefun
+
+@deftypefun gint gtk_signal_emit_by_name (GtkObject *@var{object}, gchar *@var{name}, @dots{})
+Similar to @code{gtk_signal_emit} except that the signal is referenced
+by @var{name} instead of by its integer identifier.
+@end deftypefun
+
+@deftypefun void gtk_signal_emit_stop (GtkObject *@var{object}, gint @var{signal_type})
+Stop the emission of the signal @var{signal_type} on
+@var{object}. @var{signal_type} is the integer identifier for the signal
+and can be determined using the function
+@code{gtk_signal_lookup}. Alternatively, the function
+@code{gtk_signal_emit_stop_by_name} can be used to refer to the signal
+by name. Attempting to stop the emission of a signal that isn't being
+emitted does nothing.
+@end deftypefun
+
+@deftypefun void gtk_signal_emit_stop_by_name (GtkObject *@var{object}, gchar *@var{name})
+Similar to @code{gtk_signal_emit_stop} except that the signal is
+referenced by @var{name} instead of by its integer identifier.
+@end deftypefun
+
+@deftypefun gint gtk_signal_connect (GtkObject *@var{object}, gchar *@var{name}, GtkSignalFunc @var{func}, gpointer @var{func_data})
+Connects a signal handling function to a signal emitting
+object. @var{func} is connected to the signal @var{name} emitted by
+@var{object}. The arguments and returns type of @var{func} should match
+the arguments and return type of the signal @var{name}. However,
+@var{func} may take the extra argument of @var{func_data}. Due to the C
+calling convention it is ok to ignore the extra argument. (It is ok to
+ignore all the arguments in fact).
+
+@code{gtk_signal_connect} returns an integer identifier for the
+connection which can be used to refer to it in the future. Specifically
+it is useful for removing the connection and/or blocking it from being
+used.
+@end deftypefun
+
+@deftypefun gint gtk_signal_connect_after (GtkObject *@var{object}, gchar *@var{name}, GtkSignalFunc @var{func}, gpointer @var{func_data})
+Similar to @code{gtk_signal_connect} except the signal handler is
+connected in the ``after'' slot. This allows a signal handler to be
+guaranteed to run after other signal handlers connected to the same
+signal on the same object and after the class function associated with
+the signal.
+
+Like @code{gtk_signal_connect}, @code{gtk_signal_connect_after} returns
+an integer identifier which can be used to refer to the connection.
+@end deftypefun
+
+@deftypefun gint gtk_signal_connect_object (GtkObject *@var{object}, gchar *@var{name}, GtkSignalFunc @var{func}, GtkObject *@var{slot_object})
+Connects @var{func} to the signal @var{name} emitted by
+@var{object}. Similar to @code{gtk_signal_connect} with the difference
+that @var{slot_object} is passed as the first parameter to @var{func}
+instead of the signal emitting object. This can be useful for connecting
+a signal emitted by one object to a signal in another object. A common
+usage is to connect the ``destroy'' signal of dialog to the ``clicked''
+signal emitted by a ``close'' button in the dialog. That is, the
+``clicked'' signal emitted by the button will caused the ``destroy''
+signal to be emitted for the dialog. This is also the ``right'' way to
+handle closing of a dialog since the ``destroy'' signal will be sent if
+the dialog is deleted using a window manager function and this enables
+the two methods of closing the window to be handled by the same
+mechanism. Returns an integer identifier which can be used to refer to
+the connection.
+@end deftypefun
+
+@deftypefun gint gtk_signal_connect_object_after (GtkObject *@var{object}, gchar *@var{name}, GtkSignalFunc @var{func}, GtkObject *@var{slot_object})
+Similar to @code{gtk_signal_connect_object} except the signal handler is
+connected in the ``after'' slot. This allows a signal handler to be
+guaranteed to run after other signal handlers connected to the same
+signal on the same object and after the class function associated with
+the signal. Returns an integer identifier which can be used to refer to
+the connection.
+@end deftypefun
+
+@deftypefun void gtk_signal_disconnect (GtkObject *@var{object}, gint @var{id})
+Disconnects a signal handler from an object. The signal handler is
+identified by the integer @var{id} which is returned by the
+@code{gtk_signal_connect*} family of functions.
+@end deftypefun
+
+@deftypefun void gtk_signal_disconnect_by_data (GtkObject *@var{object}, gpointer @var{data})
+Disconnects a signal handler from an object. The signal handler is
+identified by the @var{data} argument specified as the @var{func_data}
+argument to the @code{gtk_signal_connect*} family of functions. For the
+@code{gtk_signal_connect_object*} functions, @var{data} refers to the
+@var{slot_object}.
+
+@strong{Note:} This will remove all signal handlers connected to
+@var{object} which were connected using @var{data} as their
+@var{func_data} argument. Multiple signal handlers may be disconnected
+with this call.
+@end deftypefun
+
+@deftypefun void gtk_signal_handler_block (GtkObject *@var{object}, gint @var{id})
+Blocks calling of a signal handler during signal emission. The signal
+handler is identified by the integer @var{id} which is returned by the
+@code{gtk_signal_connect*} family of functions. If the signal is already
+blocked no change is made.
+@end deftypefun
+
+@deftypefun void gtk_signal_handler_block_by_data (GtkObject *@var{object}, gint @var{data})
+Blocks calling of a signal handler during signal emission. The signal
+handler is identified by the @var{data} argument specified as the
+@var{func_data} argument to the @code{gtk_signal_connect*} family of
+functions. For the @code{gtk_signal_connect_object*} functions,
+@var{data} refers to the @var{slot_object}. If the signal is already
+blocked no change is made.
+
+@strong{Note:} This will block all signal handlers connected to
+@var{object} which were connected using @var{data} as their
+@var{func_data} argument. Multiple signal handlers may be blocked
+with this call.
+@end deftypefun
+
+@deftypefun void gtk_signal_handler_unblock (GtkObject *@var{object}, gint @var{id})
+Unblocks calling of a signal handler during signal emission. The signal
+handler is identified by the integer @var{id} which is returned by the
+@code{gtk_signal_connect*} family of functions. If the signal is already
+unblocked no change is made.
+@end deftypefun
+
+@deftypefun void gtk_signal_handler_unblock_by_data (GtkObject *@var{object}, gint @var{data})
+Unblocks calling of a signal handler during signal emission. The signal
+handler is identified by the @var{data} argument specified as the
+@var{func_data} argument to the @code{gtk_signal_connect*} family of
+functions. For the @code{gtk_signal_connect_object*} functions,
+@var{data} refers to the @var{slot_object}. If the signal is already
+unblocked no change is made.
+
+@strong{Note:} This will unblock all signal handlers connected to
+@var{object} which were connected using @var{data} as their
+@var{func_data} argument. Multiple signal handlers may be unblocked
+with this call.
+@end deftypefun
+
+@deftypefun void gtk_signal_handlers_destroy (GtkObject *@var{object})
+Destroy all of the signal handlers connected to @var{object}. There
+should normally never be reason to call this function as it is called
+automatically when @var{object} is destroyed.
+@end deftypefun
+
+@deftypefun void gtk_signal_default_marshaller (GtkObject *@var{object}, GtkSignalFunc @var{func}, gpointer @var{func_data}, GtkSignalParam *@var{params})
+@code{gtk_signal_new} requires a callback in order to actually call a
+signal handler for a particular signal. The vast majority of signals are
+of the particular form:
+
+@example
+  (* std_signal) (gpointer std_arg);
+@end example
+
+@code{gtk_signal_default_marshaller} is a signal marshaller which
+marshals arguments for a signal of that form.
+@end deftypefun
+
+
+@node Widgets, Other Objects, Signals, Top
+@comment node-name, next, previous, up
+@chapter Widget Overview
+@cindex Widgets
+
+
+Widgets are the general term used to describe user interface objects. A
+widget defines a class interface that all user interface objects conform
+to. This interface allows a uniform method for dealing with operations
+common to all objects such as hiding and showing, size requisition and
+allocation and events.
+
+The common interface that widgets must adhere to is described by the
+GtkWidget and GtkWidgetClass structure. For the purposes of using GTK
+these structures can be considered read-only and, for the most part,
+opaque.
+
+All widget creation routines in GTK return pointers to GtkWidget
+structures. In reality, all widget creation routines create structures
+that can be viewed as equivalent to the GtkWidget structure, but often
+have contain additional information. @xref{Object Implementation}
+
+The widgets available for use are implemented in a hierarchy. Several
+widgets exist solely as common bases for more specific widgets. For
+example, it is not possible to create a ruler widget itself, but the
+ruler widget provides a base and functionality common to the horizontal
+and vertical rulers.
+
+The available widgets (in alphabetical order):
+
+@menu
+* GtkAlignment::                The alignment widget.
+* GtkArrow::                    The arrow widget.
+* GtkBin::                      The bin widget.
+* GtkBox::                      The box widget.
+* GtkButton::                   The button widget.
+* GtkCheckButton::              The check button widget.
+* GtkCheckMenuItem::            The check menu item widget.
+* GtkContainer::                The container widget.
+* GtkDialog::                   The dialog widget.
+* GtkDrawingArea::              The drawing area widget.
+* GtkEntry::                    The entry widget.
+* GtkFileSelection::            The file selection dialog widget.
+* GtkFrame::                    The frame widget.
+* GtkHBox::                     The horizontal box widget.
+* GtkHRuler::                   The horizontal ruler widget.
+* GtkHScale::                   The horizontal scale widget.
+* GtkHScrollbar::               The horizontal scrollbar widget.
+* GtkHSeparator::               The horizontal separator widget.
+* GtkImage::                    The image widget.
+* GtkItem::                     The item widget.
+* GtkLabel::                    The label widget.
+* GtkList::                     The list widget.
+* GtkListItem::                 The list item widget.
+* GtkMenu::                     The menu widget.
+* GtkMenuBar::                  The menu bar widget.
+* GtkMenuItem::                 The menu item widget.
+* GtkMenuShell::                The menu shell widget.
+* GtkMisc::                     The misc widget.
+* GtkNotebook::                 The notebook widget.
+* GtkOptionMenu::               The option menu widget.
+* GtkPixmap::                   The pixmap widget.
+* GtkPreview::                  The preview widget.
+* GtkProgressBar::              The progress bar widget.
+* GtkRadioButton::              The radio button widget.
+* GtkRadioMenuItem::            The radio menu item widget.
+* GtkRange::                    The range widget.
+* GtkRuler::                    The ruler widget.
+* GtkScale::                    The scale widget.
+* GtkScrollbar::                The scrollbar widget.
+* GtkScrolledWindow::           The scrolled window widget.
+* GtkSeparator::                The separator widget.
+* GtkTable::                    The table widget.
+* GtkText::                     The text widget.
+* GtkToggleButton::             The toggle button widget.
+* GtkTree::                     The tree widget.
+* GtkTreeItem::                 The tree item widget.
+* GtkVBox::                     The vertical box widget.
+* GtkViewport::                 The viewport widget.
+* GtkVRuler::                   The vertical ruler widget.
+* GtkVScale::                   The vertical scale widget.
+* GtkVScrollbar::               The vertical scrollbar widget.
+* GtkVSeparator::               The vertical separator widget.
+* GtkWidget::                   The base widget type.
+* GtkWindow::                   The window widget.
+@end menu
+
+
+@node GtkAlignment, GtkArrow, Widgets, Widgets
+@comment node-name, next, previous, up
+@section The alignment widget
+
+
+@subsection Description
+
+The alignment widget is a container (@pxref{GtkContainer}) derived from
+the bin widget (@pxref{GtkBin}). Its entire purpose is to give the
+programmer flexibility in how the child it manages is positioned when a
+window is resized.
+
+Normally, a widget is allocated at least as much size as it
+requests. (@pxref{GtkContainer} for a discussion of geometry
+management). When a widget is allocated more size than it requests there
+is a question of how the widget should expand. By convention, most GTK
+widgets expand to fill their allocated space. Sometimes this behavior is
+not desired. The alignment widget allows the programmer to specify how a
+widget should expand and position itself to fill the area it is
+allocated.
+
+@subsection Options
+
+@defopt xscale
+@defoptx yscale
+The @var{xscale} and @var{yscale} options specify how to scale the child
+widget. If the scale value is 0.0, the child widget is allocated exactly
+the size it requested in that dimension. If the scale value is 1.0, the
+child widget is allocated all of the space in a dimension. A scale value
+of 1.0 for both x and y is equivalent to not using an alignment widget.
+@end defopt
+
+@defopt xalign
+@defoptx yalign
+The @var{xalign} and @var{yalign} options specify how to position the
+child widget when it is not allocated all the space available to it
+(because the @var{xscale} and/or @var{yscale} options are less than
+1.0). If an alignment value is 0.0 the widget is positioned to the left
+(or top) of its allocated space. An alignment value of 1.0 positions the
+widget to the right (or bottom) of its allocated space. A common usage
+is to specify @var{xalign} and @var{yalign} to be 0.5 which causes the
+widget to be centered within its allocated area.
+@end defopt
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_alignment_get_type (void)
+Returns the @code{GtkAlignment} type identifier.
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_alignment_new (gfloat @var{xalign}, gfloat @var{yalign}, gfloat @var{xscale}, gfloat @var{yscale})
+Create a new @code{GtkAlignment} object and initialize it with the
+values @var{xalign}, @var{yalign}, @var{xscale} and @var{yscale}. The
+new widget is returned as a pointer to a @code{GtkWidget}
+object. @code{NULL} is returned on failure.
+@end deftypefun
+
+@deftypefun void gtk_alignment_set (GtkAlignment *@var{alignment}, gfloat @var{xalign}, gfloat @var{yalign}, gfloat @var{xscale}, gfloat @var{yscale})
+Set the @var{xalign}, @var{yalign}, @var{xscale} and @var{yscale} options
+of an alignment widget. It is important to not set the fields of the
+@code{GtkAlignment} structure directly (or, for that matter, any type
+derived from @code{GtkObject}).
+@end deftypefun
+
+@gtkstdmacros{Alignment, ALIGNMENT}
+
+
+@page
+@node GtkArrow, GtkBin, GtkAlignment, Widgets
+@comment node-name, next, previous, up
+@section The arrow widget
+
+@subsection Description
+
+The arrow widget is derived from the misc widget (@pxref{GtkMisc}) and
+is intended for use where a directional arrow (in one of the four
+cardinal directions) is desired. As such, it has very limited
+functionality and basically only draws itself in a particular direction
+and with a particular shadow type. The arrow widget will expand to fill
+all the space it is allocated.
+
+@subsection Options
+
+@defopt arrow_type
+The @var{arrow_type} option specifies which direction the arrow will
+point. It can be one of @code{GTK_ARROW_UP}, @code{GTK_ARROW_DOWN},
+@code{GTK_ARROW_LEFT} or @code{GTK_ARROW_RIGHT}.
+@end defopt
+
+@defopt shadow_type
+The @var{shadow_type} option specifies how to draw the shadow for the
+arrow. Currently, only the @code{GTK_SHADOW_IN} and
+@code{GTK_SHADOW_OUT} shadow types are supported for drawing
+arrows. Other shadow types will cause nothing to be drawn.
+@end defopt
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_arrow_get_type (void)
+Returns the @code{GtkArrow} type identifier.
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_arrow_new (GtkArrowType @var{arrow_type}, GtkShadowType @var{shadow_type})
+Create a new @code{GtkArrow} object and initialize it with the values
+@var{arrow_type} and @var{shadow_type}. The new widget is returned as a
+pointer to a @code{GtkWidget} object. @code{NULL} is returned on
+failure.
+@end deftypefun
+
+@deftypefun void gtk_arrow_set (GtkArrow *@var{arrow}, GtkArrowType @var{arrow_type}, GtkShadowType @var{shadow_type})
+Set the @var{arrow_type} and @var{shadow_type} options of an arrow
+widget. It is important to not set the fields of the @code{GtkArrow}
+structure directly (or, for that matter, any type derived from
+@code{GtkObject}).
+@end deftypefun
+
+@gtkstdmacros{Arrow, ARROW}
+
+
+@page
+@node GtkBin, GtkBox, GtkArrow, Widgets
+@comment node-name, next, previous, up
+@section The bin widget
+
+@subsection Description
+
+The bin widget is a container (@pxref{GtkContainer}) derived from the
+container widget. It is an abstract base class. That is, it is not
+possible to create an actual bin widget. It exists only to provide a
+base of functionality for other widgets. Specifically, the bin widget
+provides a base for several other widgets that contain only a single
+child. These widgets include alignments (@pxref{GtkAlignment}), frames
+(@pxref{GtkFrame}), items (@pxref{GtkItem}), viewports
+(@pxref{GtkViewport}) and windows (@pxref{GtkWindow})
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_bin_get_type (void)
+Returns the @code{GtkBin} type identifier.
+@end deftypefun
+
+@gtkstdmacros{Bin, BIN}
+
+
+@page
+@node GtkBox, GtkButton, GtkBin, Widgets
+@comment node-name, next, previous, up
+@section The box widget
+
+
+@subsection Description
+
+The box widget is a container (@pxref{GtkContainer}) derived from the
+container widget. It is an abstract base class used by the horizontal
+box (@pxref{GtkHBox}) and vertical box (@pxref{GtkVBox}) widgets to
+provide a base of common functionality.
+
+A box provides an abstraction for organizing the position and size of
+widgets. Widgets in a box are layed out horizontally or vertically. By
+using a box widget appropriately, a programmer can control how widgets
+are positioned and how they will be allocated space when a window gets
+resized.
+
+The key attribute of boxes is that they position their children in a
+single row (horizontal boxes) or column (vertical boxes). In the case of
+horizontal boxes, all children are stretched vertically. The vertical
+size of the box is determined by the largest vertical requisition of all
+of its children. Similarly, a vertical box streches all of its children
+horizontally. The horizontal size (of the vertical box) is determined by
+the largest horizontal requisition of all of its children. An alignment
+widget (@pxref{GtkAlignment}) can be used to control child allocation
+more precisely on a per child basis.
+
+The second attribute of boxes is how they expand children. In the case
+of a horizontal box, the main control is over how children are expanded
+horizontally to fill the allocated area. (The rest of this discussion
+will focus on horizontal boxes but it applies to vertical boxes as
+well).
+
+There are two flags which can be set controlling how a widget is
+expanded horizontally in a horizontal box. These are the @code{expand}
+and @code{fill}. There operation is fairly simple. If @code{expand} is
+set, the childs potentially allocated area will expand to fill available
+space. If @code{fill} is set, the childs actual allocated area will be
+its potentially allocated area. There is a difference between
+the potentially area (which is the area the box widget sets aside for
+the child) and the actual allocated area (which is the area the box
+widget actual allocates for the widget via
+@code{gtk_widget_size_allocate}).
+
+The allocation of space to children occurs as follows (for horizontal
+boxes):
+@enumerate
+@item
+All children are allocated at least their requested size horizontally
+and the maximum requested child size vertically.
+
+@item
+Any child with the @code{expand} flag set is allocated @code{extra_width
+/ nexpand_children} extra pixels horizontally. If the @code{homogeneous}
+flag was set, all children are considered to have the @code{expand} flag
+set. That is, all children will be allocated the same area.The
+horizontal box is a fair widget and, as such, divides up any extra
+allocated space evenly among the ``expand'' children. (Those children
+which have the @code{expand} flag set). The exception occurs when
+@code{extra_width / nexpand_children} does not divide cleanly. The extra
+space is given to the last widget.
+
+@item
+@code{spacing} number of pixels separate each child. Note: The
+separation is between the potentially allocated area for each child and
+not the actual allocated area. The @code{padding} value associated with
+each child causes that many pixels to be left empty to each side of the
+child.
+
+@item
+If a child has the @code{fill} flag set it is allocated its potentially
+allocated area. If it does not, it is allocated its requested size
+horizontally and centered within its potentially allocated area. Its
+vertical allocation is still the maximum requested size of any child.
+
+@item
+Children placed at the start of the box are placed in order of addition
+to the box from left to right in the boxes allocated area.. Children
+placed at the end of the box are placed in order of addition from right
+to left in the boxes allocated area.
+@end enumerate
+
+@xref{GtkHBox}, and @ref{GtkVBox}, for code examples of using horizontal
+and vertical boxes.
+
+@subsection Options
+
+@c FIXME: options for GtkBox
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_box_get_type (void)
+Returns the @code{GtkBox} type identifier.
+@end deftypefun
+
+@deftypefun void gtk_box_pack_start (GtkBox *@var{box}, GtkWidget *@var{child}, gint @var{expand}, gint @var{fill}, gint @var{padding})
+Add @var{child} to the front of @var{box}. The flags @var{expand} and
+@var{fill} and the padding value of @var{padding} are associated with
+@var{child}.
+@end deftypefun
+
+@deftypefun void gtk_box_pack_end (GtkBox *@var{box}, GtkWidget *@var{child}, gint @var{expand}, gint @var{fill}, gint @var{padding})
+Add @var{child} to the end of @var{box}. The flags @var{expand} and
+@var{fill} and the padding value of @var{padding} are associated with
+@var{child}.
+@end deftypefun
+
+@deftypefun void gtk_box_pack_start_defaults (GtkBox *@var{box}, GtkWidget *@var{widget})
+A convenience function which is equivalent to the following:
+
+@example
+  gtk_box_pack_start (@var{box}, @var{widget}, TRUE, TRUE, 0);
+@end example
+@end deftypefun
+
+@deftypefun void gtk_box_pack_end_defaults (GtkBox *@var{box}, GtkWidget *@var{widget})
+A convenience function which is equivalent to the following:
+
+@example
+  gtk_box_pack_start (@var{box}, @var{widget}, TRUE, TRUE, 0);
+@end example
+@end deftypefun
+
+@gtkstdmacros{Box, BOX}
+
+
+@page
+@node GtkButton, GtkCheckButton, GtkBox, Widgets
+@comment node-name, next, previous, up
+@section The button widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@deftypefn Signal void GtkButton::pressed (GtkButton *@var{button})
+@end deftypefn
+
+@deftypefn Signal void GtkButton::released (GtkButton *@var{button})
+@end deftypefn
+
+@deftypefn Signal void GtkButton::clicked (GtkButton *@var{button})
+@end deftypefn
+
+@deftypefn Signal void GtkButton::enter (GtkButton *@var{button})
+@end deftypefn
+
+@deftypefn Signal void GtkButton::leave (GtkButton *@var{button})
+@end deftypefn
+
+@subsection Functions
+
+@deftypefun guint gtk_button_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_button_new (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_button_new_with_label (gchar *@var{label})
+@end deftypefun
+
+@deftypefun void gtk_button_pressed (GtkButton *@var{button})
+@end deftypefun
+
+@deftypefun void gtk_button_released (GtkButton *@var{button})
+@end deftypefun
+
+@deftypefun void gtk_button_clicked (GtkButton *@var{button})
+@end deftypefun
+
+@deftypefun void gtk_button_enter (GtkButton *@var{button})
+@end deftypefun
+
+@deftypefun void gtk_button_leave (GtkButton *@var{button})
+@end deftypefun
+
+@gtkstdmacros{Button, BUTTON}
+
+
+@page
+@node GtkCheckButton, GtkCheckMenuItem, GtkButton, Widgets
+@comment node-name, next, previous, up
+@section The check button widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_check_button_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_check_button_new (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_check_button_new_with_label (gchar *@var{label})
+@end deftypefun
+
+@deftypefun GtkCheckButton* GTK_CHECK_BUTTON (gpointer @var{obj})
+@end deftypefun
+
+@deftypefun GtkCheckButtonClass* GTK_CHECK_BUTTON_CLASS (gpointer @var{class})
+@end deftypefun
+
+@deftypefun gint GTK_IS_CHECK_BUTTON (gpointer @var{obj})
+@end deftypefun
+
+@gtkstdmacros{CheckButton, CHECK_BUTTON}
+
+
+@page
+@node GtkCheckMenuItem, GtkContainer, GtkCheckButton, Widgets,
+@comment node-name, next, previous, up
+@section The check menu item widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@deftypefn Signal void GtkCheckMenuItem::toggled (GtkCheckMenuItem *@var{check_menu_item})
+@end deftypefn
+
+@subsection Functions
+
+@deftypefun guint gtk_check_menu_item_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_check_menu_item_new (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_check_menu_item_new_with_label (gchar *@var{label})
+@end deftypefun
+
+@deftypefun void gtk_check_menu_item_set_state (GtkCheckMenuItem *@var{check_menu_item}, gint @var{state})
+@end deftypefun
+
+@deftypefun void gtk_check_menu_item_toggled (GtkCheckMenuItem *@var{check_menu_item})
+@end deftypefun
+
+@gtkstdmacros{CheckMenuItem, CHECK_MENU_ITEM}
+
+
+@page
+@node GtkContainer, GtkDialog, GtkCheckMenuItem, Widgets
+@comment node-name, next, previous, up
+@section The container widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@deftypefn Signal void GtkContainer::add (GtkContainer *@var{container}, GtkWidget *@var{widget})
+@end deftypefn
+
+@deftypefn Signal void GtkContainer::remove (GtkContainer *@var{container}, GtkWidget *@var{widget})
+@end deftypefn
+
+@deftypefn Signal void GtkContainer::need_resize (GtkContainer *@var{container}, GtkWidget *@var{widget})
+@end deftypefn
+
+@deftypefn Signal void GtkContainer::foreach (GtkContainer *@var{container}, GtkCallback @var{callback}, gpointer @var{callback_data})
+@end deftypefn
+
+@deftypefn Signal gint GtkContainer::focus (GtkContainer *@var{container}, GtkDirectionType @var{direction})
+@end deftypefn
+
+@subsection Functions
+
+@deftypefun guint gtk_container_get_type (void)
+@end deftypefun
+
+@deftypefun void gtk_container_border_width (GtkContainer *@var{container}, gint @var{border_width})
+@end deftypefun
+
+@deftypefun void gtk_container_add (GtkContainer *@var{container}, GtkWidget *@var{widget})
+@end deftypefun
+
+@deftypefun void gtk_container_remove (GtkContainer *@var{container}, GtkWidget *@var{widget})
+@end deftypefun
+
+@deftypefun void gtk_container_disable_resize (GtkContainer *@var{container})
+@end deftypefun
+
+@deftypefun void gtk_container_enable_resize (GtkContainer *@var{container})
+@end deftypefun
+
+@deftypefun void gtk_container_block_resize (GtkContainer *@var{container})
+@end deftypefun
+
+@deftypefun void gtk_container_unblock_resize (GtkContainer *@var{container})
+@end deftypefun
+
+@deftypefun gint gtk_container_need_resize (GtkContainer *@var{container}, GtkWidget *@var{widget})
+@end deftypefun
+
+@deftypefun void gtk_container_check_resize (GtkContainer *@var{container}, GtkWidget *@var{widget})
+@end deftypefun
+
+@deftypefun void gtk_container_foreach (GtkContainer *@var{container}, GtkCallback @var{callback}, gpointer @var{callback_data})
+@end deftypefun
+
+@deftypefun void gtk_container_focus (GtkContainer *@var{container}, GtkDirectionType @var{direction})
+@end deftypefun
+
+@deftypefun GList* gtk_container_children (GtkContainer @var{container})
+@end deftypefun
+
+@gtkstdmacros{Container, CONTAINER}
+
+
+@page
+@node GtkDialog, GtkDrawingArea, GtkContainer, Widgets
+@comment node-name, next, previous, up
+@section The dialog widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_dialog_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_dialog_new (void)
+@end deftypefun
+
+@gtkstdmacros{Dialog, DIALOG}
+
+
+@page
+@node GtkDrawingArea, GtkEntry, GtkDialog, Widgets
+@comment node-name, next, previous, up
+@section The drawing area widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_drawing_area_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_drawing_area_new (void)
+@end deftypefun
+
+@deftypefun void gtk_drawing_area_size (GtkDrawingArea *@var{darea}, gint @var{width}, gint @var{height})
+@end deftypefun
+
+@gtkstdmacros{DrawingArea, DRAWING_AREA}
+
+
+@page
+@node GtkEntry, GtkFileSelection, GtkDrawingArea, Widgets
+@comment node-name, next, previous, up
+@section The entry widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@deftypefn Signal void GtkEntry::insert (GtkEntry *@var{entry}, gchar *@var{text}, gint @var{length}, gint *@var{position})
+@end deftypefn
+
+@deftypefn Signal void GtkEntry::delete (GtkEntry *@var{entry}, gint @var{start_pos}, gint @var{end_pos})
+@end deftypefn
+
+@deftypefn Signal void GtkEntry::changed (GtkEntry *@var{entry})
+@end deftypefn
+
+@subsection Functions
+
+@deftypefun guint gtk_entry_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_entry_new (void)
+@end deftypefun
+
+@deftypefun void gtk_entry_set_text (GtkEntry *@var{entry}, gchar *@var{text})
+@end deftypefun
+
+@deftypefun void gtk_entry_append_text (GtkEntry *@var{entry}, gchar *@var{text})
+@end deftypefun
+
+@deftypefun void gtk_entry_prepend_text (GtkEntry *@var{entry}, gchar *@var{text})
+@end deftypefun
+
+@deftypefun void gtk_entry_set_position (GtkEntry *@var{entry}, gint @var{position})
+@end deftypefun
+
+@deftypefun gchar* gtk_entry_get_text (GtkEntry *@var{entry})
+@end deftypefun
+
+@gtkstdmacros{Entry, ENTRY}
+
+
+@page
+@node GtkFileSelection, GtkFrame, GtkEntry, Widgets
+@comment node-name, next, previous, up
+@section The file selection dialog widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_file_selection_get_Type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_file_selection_new (gchar *@var{title})
+@end deftypefun
+
+@deftypefun void gtk_file_selection_set_filename (GtkFileSelection *@var{filesel}, gchar *@var{filename})
+@end deftypefun
+
+@deftypefun gchar* gtk_file_selection_get_filename (GtkFileSelection *@var{filesel})
+@end deftypefun
+
+@gtkstdmacros{FileSelection, FILE_SELECTION}
+
+
+@page
+@node GtkFrame, GtkHBox, GtkFileSelection, Widgets
+@comment node-name, next, previous, up
+@section The frame widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_frame_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_frame_new (gchar *@var{label})
+@end deftypefun
+
+@deftypefun void gtk_frame_set_label (GtkFrame *@var{frame}, gchar *@var{label})
+@end deftypefun
+
+@deftypefun void gtk_frame_set_label_align (GtkFrame *@var{frame}, gfloat @var{xalign}, gfloat @var{yalign})
+@end deftypefun
+
+@deftypefun void gtk_frame_set_shadow_type (GtkFrame *@var{frame}, GtkShadowType @var{type})
+@end deftypefun
+
+@gtkstdmacros{Frame, FRAME}
+
+
+@page
+@node GtkHBox, GtkHRuler, GtkFrame, Widgets
+@comment node-name, next, previous, up
+@section The horizontal box widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_hbox_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_hbox_new (gint @var{homogeneous}, gint @var{spacing})
+@end deftypefun
+
+@gtkstdmacros{HBox, HBOX}
+
+
+@page
+@node GtkHRuler, GtkHScale, GtkHBox, Widgets
+@comment node-name, next, previous, up
+@section The horizontal ruler widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_hruler_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_hruler_new (void)
+@end deftypefun
+
+@gtkstdmacros{HRuler, HRULER}
+
+
+@page
+@node GtkHScale, GtkHScrollbar, GtkHRuler, Widgets
+@comment node-name, next, previous, up
+@section The horizontal scale widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_hscale_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_hscale_new (GtkAdjustment *@var{adjustment})
+@end deftypefun
+
+@gtkstdmacros{HScale, HSCALE}
+
+
+@page
+@node GtkHScrollbar, GtkHSeparator, GtkHScale, Widgets
+@comment node-name, next, previous, up
+@section The horizontal scrollbar widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_hscrollbar_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_hscrollbar_new (GtkAdjustment *@var{adjustment})
+@end deftypefun
+
+@gtkstdmacros{HScrollbar, HSCROLLBAR}
+
+
+@page
+@node GtkHSeparator, GtkImage, GtkHScrollbar, Widgets
+@comment node-name, next, previous, up
+@section The horizontal separator widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_hseparator_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_hseparator_new (void)
+@end deftypefun
+
+@gtkstdmacros{HSeparator, HSEPARATOR}
+
+
+@page
+@node GtkImage, GtkItem, GtkHSeparator, Widgets
+@comment node-name, next, previous, up
+@section The image widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_image_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_image_new (GdkImage *@var{val})
+@end deftypefun
+
+@deftypefun void gtk_image_set (GtkImage *@var{image}, GdkImage *@var{val})
+@end deftypefun
+
+@deftypefun void gtk_image_get (GtkImage *@var{image}, GdkImage **@var{val})
+@end deftypefun
+
+@gtkstdmacros{Image, IMAGE}
+
+
+@page
+@node GtkItem, GtkLabel, GtkImage, Widgets
+@comment node-name, next, previous, up
+@section The item widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@deftypefn Signal void GtkItem::select (GtkItem *@var{item})
+@end deftypefn
+
+@deftypefn Signal void GtkItem::deselect (GtkItem *@var{item})
+@end deftypefn
+
+@deftypefn Signal void GtkItem::toggle (GtkItem *@var{toggle})
+@end deftypefn
+
+@subsection Functions
+
+@deftypefun guint gtk_item_get_type (void)
+@end deftypefun
+
+@deftypefun void gtk_item_select (GtkItem *@var{item})
+@end deftypefun
+
+@deftypefun void gtk_item_deselect (GtkItem *@var{item})
+@end deftypefun
+
+@deftypefun void gtk_item_toggle (GtkItem *@var{item})
+@end deftypefun
+
+@gtkstdmacros{Item, ITEM}
+
+
+@page
+@node GtkLabel, GtkList, GtkItem, Widgets
+@comment node-name, next, previous, up
+@section The label widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_label_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_label_new (GtkLabel *@var{label}, gchar *@var{str})
+@end deftypefun
+
+@deftypefun void gtk_label_set (GtkLabel *@var{label}, gchar *@var{str})
+@end deftypefun
+
+@deftypefun void gtk_label_get (GtkLabel *@var{label}, gchar **@var{str})
+@end deftypefun
+
+@gtkstdmacros{Label, LABEL}
+
+
+@page
+@node GtkList, GtkListItem, GtkLabel, Widgets
+@comment node-name, next, previous, up
+@section The list widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@deftypefn Signal void GtkList::selection_changed (GtkList *@var{list})
+@end deftypefn
+
+@deftypefn Signal void GtkList::select_child (GtkList *@var{list}, GtkWidget *@var{child})
+@end deftypefn
+
+@deftypefn Signal void GtkList::unselect_child (GtkList *@var{list}, GtkWidget *@var{child})
+@end deftypefn
+
+@subsection Functions
+
+@deftypefun guint gtk_list_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_list_new (void)
+@end deftypefun
+
+@deftypefun void gtk_list_insert_items (GtkList *@var{list}, GList *@var{items}, gint @var{position})
+@end deftypefun
+
+@deftypefun void gtk_list_append_items (GtkList *@var{list}, GList *@var{items})
+@end deftypefun
+
+@deftypefun void gtk_list_prepend_items (GtkList *@var{list}, GList *@var{items})
+@end deftypefun
+
+@deftypefun void gtk_list_remove_items (GtkList *@var{list}, GList *@var{items})
+@end deftypefun
+
+@deftypefun void gtk_list_clear_items (GtkList *@var{list}, gint @var{start}, gint @var{end})
+@end deftypefun
+
+@deftypefun void gtk_list_select_item (GtkList *@var{list}, gint @var{item})
+@end deftypefun
+
+@deftypefun void gtk_list_unselect_item (GtkList *@var{list}, gint @var{item})
+@end deftypefun
+
+@deftypefun void gtk_list_select_child (GtkList *@var{list}, GtkWidget *@var{child})
+@end deftypefun
+
+@deftypefun void gtk_list_unselect_child (GtkList *@var{list}, GtkWidget *@var{child})
+@end deftypefun
+
+@deftypefun gint gtk_list_child_position (GtkList *@var{list}, GtkWidget *@var{child})
+@end deftypefun
+
+@deftypefun void gtk_list_set_selection_mode (GtkList *@var{list}, GtkSelectionMode @var{mode})
+@end deftypefun
+
+@gtkstdmacros{List, LIST}
+
+
+@page
+@node GtkListItem, GtkMenu, GtkList, Widgets
+@comment node-name, next, previous, up
+@section The list item widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_list_item_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_list_item_new (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_list_item_new_with_label (gchar *@var{label})
+@end deftypefun
+
+@deftypefun void gtk_list_item_select (GtkListItem *@var{list_item})
+@end deftypefun
+
+@deftypefun void gtk_list_item_deselect (GtkListItem *@var{list_item})
+@end deftypefun
+
+@gtkstdmacros{ListItem, LIST_ITEM}
+
+
+@page
+@node GtkMenu, GtkMenuBar, GtkListItem, Widgets
+@comment node-name, next, previous, up
+@section The menu widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_menu_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_menu_new (void)
+@end deftypefun
+
+@deftypefun void gtk_menu_append (GtkMenu *@var{menu}, GtkWidget *@var{child})
+@end deftypefun
+
+@deftypefun void gtk_menu_prepend (GtkMenu *@var{menu}, GtkWidget *@var{child})
+@end deftypefun
+
+@deftypefun void gtk_menu_insert (GtkMenu *@var{menu}, GtkWidget *@var{child}, gint @var{position})
+@end deftypefun
+
+@deftypefun void gtk_menu_popup (GtkMenu *@var{menu}, GtkWidget *@var{parent_menu_shell}, GtkWidget *@var{parent_menu_item}, GtkMenuPositionFunc @var{func}, gpointer @var{data}, gint @var{button})
+@end deftypefun
+
+@deftypefun void gtk_menu_popdown (GtkMenu *@var{menu})
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_menu_get_active (GtkMenu *@var{menu})
+@end deftypefun
+
+@deftypefun void gtk_menu_set_active (GtkMenu *@var{menu})
+@end deftypefun
+
+@deftypefun void gtk_menu_set_accelerator_table (GtkMenu *@var{menu}, GtkAcceleratorTable *@var{table})
+@end deftypefun
+
+@gtkstdmacros{Menu, MENU}
+
+
+@page
+@node GtkMenuBar, GtkMenuItem, GtkMenu, Widgets
+@comment node-name, next, previous, up
+@section The menu bar widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_menu_bar_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_menu_bar_new (void)
+@end deftypefun
+
+@deftypefun void gtk_menu_bar_append (GtkMenuBar *@var{menu_bar}, GtkWidget *@var{child})
+@end deftypefun
+
+@deftypefun void gtk_menu_bar_prepend (GtkMenuBar *@var{menu_bar}, GtkWidget *@var{child})
+@end deftypefun
+
+@deftypefun void gtk_menu_bar_insert (GtkMenuBar *@var{menu_bar}, GtkWidget *@var{child}, gint @var{position})
+@end deftypefun
+
+@gtkstdmacros{MenuBar, MENU_BAR}
+
+
+@page
+@node GtkMenuItem, GtkMenuShell, GtkMenuBar, Widgets
+@comment node-name, next, previous, up
+@section The menu item widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@deftypefn Signal void GtkMenuItem::activate (GtkMenuItem *@var{menu_item})
+@end deftypefn
+
+@subsection Functions
+
+@deftypefun guint gtk_menu_item_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_menu_item_new (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_menu_item_new_with_label (gchar *@var{label})
+@end deftypefun
+
+@deftypefun void gtk_menu_item_set_submenu (GtkMenuItem *@var{menu_item}, GtkWidget *@var{submenu})
+@end deftypefun
+
+@deftypefun void gtk_menu_item_set_placement (GtkMenuItem *@var{menu_item}, GtkSubmenuPlacement @var{placement})
+@end deftypefun
+
+@deftypefun void gtk_menu_item_accelerator_size (GtkMenuItem *@var{menu_item})
+@end deftypefun
+
+@deftypefun void gtk_menu_item_accelerator_text (GtkMenuItem *@var{menu_item}, gchar *@var{buffer})
+@end deftypefun
+
+@deftypefun void gtk_menu_item_configure (GtkMenuItem *@var{menu_item}, gint @var{show_toggle_indicator}, gint @var{show_submenu_indicator})
+@end deftypefun
+
+@deftypefun void gtk_menu_item_select (GtkMenuItem *@var{menu_item})
+@end deftypefun
+
+@deftypefun void gtk_menu_item_deselect (GtkMenuItem *@var{menu_item})
+@end deftypefun
+
+@deftypefun void gtk_menu_item_activate (GtkMenuItem *@var{menu_item})
+@end deftypefun
+
+@gtkstdmacros{MenuItem, MENU_ITEM}
+
+
+@page
+@node GtkMenuShell, GtkMisc, GtkMenuItem, Widgets
+@comment node-name, next, previous, up
+@section The menu shell widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@deftypefn Signal void GtkMenuShell::deactivate (GtkMenuShell *@var{menu_shell})
+@end deftypefn
+
+@subsection Functions
+
+@deftypefun guint gtk_menu_shell_get_type (void)
+@end deftypefun
+
+@deftypefun void gtk_menu_shell_append (GtkMenuShell *@var{menu_shell}, GtkWidget *@var{child})
+@end deftypefun
+
+@deftypefun void gtk_menu_shell_prepend (GtkMenuShell *@var{menu_shell}, GtkWidget *@var{child})
+@end deftypefun
+
+@deftypefun void gtk_menu_shell_insert (GtkMenuShell *@var{menu_shell}, GtkWidget *@var{child}, gint @var{position})
+@end deftypefun
+
+@deftypefun void gtk_menu_shell_deactivate (GtkMenuShell *@var{menu_shell})
+@end deftypefun
+
+@gtkstdmacros{MenuShell, MENU_SHELL}
+
+
+@page
+@node GtkMisc, GtkNotebook, GtkMenuShell, Widgets
+@comment node-name, next, previous, up
+@section The misc widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_misc_get_type (void)
+@end deftypefun
+
+@deftypefun void gtk_misc_set_alignment (GtkMisc *@var{misc}, gfloat @var{xalign}, gfloat @var{yalign})
+@end deftypefun
+
+@deftypefun void gtk_misc_set_padding (GtkMisc *@var{misc}, gint @var{xpad}, gint @var{ypad})
+@end deftypefun
+
+@gtkstdmacros{Misc, MISC}
+
+
+@page
+@node GtkNotebook, GtkOptionMenu, GtkMisc, Widgets
+@comment node-name, next, previous, up
+@section The notebook widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_notebook_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_notebook_new (void)
+@end deftypefun
+
+@deftypefun void gtk_notebook_append_page (GtkNotebook *@var{notebook}, GtkWidget *@var{child}, GtkWidget *@var{tab_label})
+@end deftypefun
+
+@deftypefun void gtk_notebook_prepend_page (GtkNotebook *@var{notebook}, GtkWidget *@var{child}, GtkWidget *@var{tab_label})
+@end deftypefun
+
+@deftypefun void gtk_notebook_insert_page (GtkNotebook *@var{notebook}, GtkWidget *@var{child}, GtkWidget *@var{tab_label}, gint @var{position})
+@end deftypefun
+
+@deftypefun void gtk_notebook_remove_page (GtkNotebook *@var{notebook}, gint @var{page_num})
+@end deftypefun
+
+@deftypefun void gtk_notebook_set_page (GtkNotebook *@var{notebook}, gint @var{page_num})
+@end deftypefun
+
+@deftypefun void gtk_notebook_next_page (GtkNotebook *@var{notebook})
+@end deftypefun
+
+@deftypefun void gtk_notebook_prev_page (GtkNotebook *@var{notebook})
+@end deftypefun
+
+@deftypefun void gtk_notebook_set_tab_pos (GtkNotebook *@var{notebook}, GtkPositionType @var{pos})
+@end deftypefun
+
+@deftypefun void gtk_notebook_set_show_tabs (GtkNotebook *@var{notebook}, gint @var{show_tabs})
+@end deftypefun
+
+@deftypefun void gtk_notebook_set_show_border (GtkNotebook *@var{notebook}, gint @var{show_border})
+@end deftypefun
+
+@gtkstdmacros{Notebook, NOTEBOOK}
+
+
+@page
+@node GtkOptionMenu, GtkPixmap, GtkNotebook, Widgets
+@comment node-name, next, previous, up
+@section The option menu widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_option_menu_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_option_menu_new (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_option_menu_get_menu (GtkOptionMenu *@var{option_menu})
+@end deftypefun
+
+@deftypefun void gtk_option_menu_set_menu (GtkOptionMenu *@var{option_menu}, GtkWidget *@var{menu})
+@end deftypefun
+
+@deftypefun void gtk_option_menu_remove_menu (GtkOptionMenu *@var{option_menu})
+@end deftypefun
+
+@deftypefun void gtk_option_menu_set_history (GtkOptionMenu *@var{option_menu}, gint @var{index})
+@end deftypefun
+
+@gtkstdmacros{OptionMenu, OPTION_MENU}
+
+
+@page
+@node GtkPixmap, GtkPreview, GtkOptionMenu, Widgets
+@comment node-name, next, previous, up
+@section The pixmap widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_pixmap_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_pixmap_new (GdkPixmap *@var{normal}, GdkPixmap *@var{active}, GdkPixmap *@var{prelight}, GdkPixmap *@var{selected}, GdkPixmap *@var{insensitive})
+@end deftypefun
+
+@deftypefun void gtk_pixmap_set (GtkPixmap *@var{pixmap}, GdkPixmap *@var{val}, GtkStateType @var{state})
+@end deftypefun
+
+@deftypefun void gtk_pixmap_get (GtkPixmap *@var{pixmap}, GdkPixmap **@var{val}, GtkStateType @var{state})
+@end deftypefun
+
+@gtkstdmacros{Pixmap, PIXMAP}
+
+
+@page
+@node GtkPreview, GtkProgressBar, GtkPixmap, Widgets
+@comment node-name, next, previous, up
+@section The preview widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_preview_get_type (void)
+@end deftypefun
+
+@deftypefun void gtk_preview_uninit (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_preview_new (GtkPreviewType @var{type})
+@end deftypefun
+
+@deftypefun void gtk_preview_size (GtkPreview *@var{preview}, gint @var{width}, gint @var{height})
+@end deftypefun
+
+@deftypefun void gtk_preview_put (GtkPreview *@var{preview}, GdkWindow *@var{window}, GdkGC *@var{gc}, gint @var{srcx}, gint @var{srcy}, gint @var{destx}, gint @var{desty}, gint @var{width}, gint @var{height})
+@end deftypefun
+
+@deftypefun void gtk_preview_put_row (GtkPreview *@var{preview}, guchar *@var{src}, guchar *@var{dest}, gint @var{x}, gint @var{y}, gint @var{w})
+@end deftypefun
+
+@deftypefun void gtk_preview_draw_row (GtkPreview *@var{preview}, guchar @var{data}, gint @var{x}, gint @var{y}, gint @var{w})
+@end deftypefun
+
+@deftypefun void gtk_preview_set_expand (GtkPreview *@var{preview}, gint @var{expand})
+@end deftypefun
+
+@deftypefun void gtk_preview_set_gamma (double @var{gamma})
+@end deftypefun
+
+@deftypefun void gtk_preview_set_color_cube (guint @var{nred_shades}, guint @var{ngreen_shades}, guint @var{nblue_shades}, guint @var{ngray_shades})
+@end deftypefun
+
+@deftypefun void gtk_preview_set_install_cmap (gint @var{install_cmap})
+@end deftypefun
+
+@deftypefun void gtk_preview_set_reserved (gint @var{nreserved})
+@end deftypefun
+
+@deftypefun GdkVisual* gtk_preview_get_visual (void)
+@end deftypefun
+
+@deftypefun GdkColormap* gtk_preview_get_cmap (void)
+@end deftypefun
+
+@deftypefun GtkPreviewInfo* gtk_preview_get_info (void)
+@end deftypefun
+
+@gtkstdmacros{Preview, PREVIEW}
+
+
+@page
+@node GtkProgressBar, GtkRadioButton, GtkPreview, Widgets
+@comment node-name, next, previous, up
+@section The progress bar widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_progress_bar_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_progress_bar_new (void)
+@end deftypefun
+
+@deftypefun void gtk_progress_bar_update (GtkProgressBar *@var{pbar}, gfloat @var{percentage})
+@end deftypefun
+
+@gtkstdmacros{ProgressBar, PROGRESS_BAR}
+
+
+@page
+@node GtkRadioButton, GtkRadioMenuItem, GtkProgressBar, Widgets
+@comment node-name, next, previous, up
+@section The radio button widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_radio_button_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_radio_button_new (GSList *@var{group})
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_radio_button_new_with_label (GSList *@var{group}, gchar *@var{label})
+@end deftypefun
+
+@deftypefun GSList* gtk_radio_button_group (GtkRadioButton *@var{radio_button})
+@end deftypefun
+
+@gtkstdmacros{RadioButton, RADIO_BUTTON}
+
+
+@page
+@node GtkRadioMenuItem, GtkRange, GtkRadioButton, Widgets
+@comment node-name, next, previous, up
+@section The radio button widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_radio_menu_item_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_radio_menu_item_new (GSList *@var{group})
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_radio_menu_item_new_with_label (GSList *@var{group}, gchar *@var{label})
+@end deftypefun
+
+@deftypefun GSList* gtk_radio_menu_item_group (GtkRadioMenuItem *@var{radio_menu_item})
+@end deftypefun
+
+@gtkstdmacros{RadioMenuItem, RADIO_MENU_ITEM}
+
+
+@page
+@node GtkRange, GtkRuler, GtkRadioMenuItem, Widgets
+@comment node-name, next, previous, up
+@section The range widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_range_get_type (void)
+@end deftypefun
+
+@deftypefun GtkAdjustment* gtk_range_get_adjustment (GtkRange *@var{range})
+@end deftypefun
+
+@deftypefun void gtk_range_set_update_policy (GtkRange *@var{range}, GtkUpdatePolicy @var{policy})
+@end deftypefun
+
+@deftypefun void gtk_range_set_adjustment (GtkRange *@var{range}, GtkAdjustment *@var{adjustment})
+@end deftypefun
+
+@deftypefun void gtk_range_draw_background (GtkRange *@var{range})
+@end deftypefun
+
+@deftypefun void gtk_range_draw_trough (GtkRange *@var{range})
+@end deftypefun
+
+@deftypefun void gtk_range_draw_slider (GtkRange *@var{range})
+@end deftypefun
+
+@deftypefun void gtk_range_draw_step_forw (GtkRange *@var{range})
+@end deftypefun
+
+@deftypefun void gtk_range_draw_step_back (GtkRange *@var{range})
+@end deftypefun
+
+@deftypefun void gtk_range_slider_update (GtkRange *@var{range})
+@end deftypefun
+
+@deftypefun gint gtk_range_trough_click (GtkRange *@var{range}, gint @var{x}, gint @var{y})
+@end deftypefun
+
+@deftypefun void gtk_range_default_hslider_update (GtkRange *@var{range})
+@end deftypefun
+
+@deftypefun void gtk_range_default_vslider_update (GtkRange *@var{range})
+@end deftypefun
+
+@deftypefun gint gtk_range_default_htrough_click (GtkRange *@var{range}, gint @var{x}, gint @var{y})
+@end deftypefun
+
+@deftypefun gint gtk_range_default_vtrough_click (GtkRange *@var{range}, gint @var{x}, gint @var{y})
+@end deftypefun
+
+@deftypefun void gtk_range_default_hmotion (GtkRange *@var{range}, gint @var{xdelta}, gint @var{ydelta})
+@end deftypefun
+
+@deftypefun void gtk_range_default_vmotion (GtkRange *@var{range}, gint @var{xdelta}, gint @var{ydelta})
+@end deftypefun
+
+@deftypefun gfloat gtk_range_calc_value (GtkRange *@var{ragne}, gint @var{position})
+@end deftypefun
+
+@gtkstdmacros{Range, RANGE}
+
+
+@page
+@node GtkRuler, GtkScale, GtkRange, Widgets
+@comment node-name, next, previous, up
+@section The ruler widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_ruler_get_type (void)
+@end deftypefun
+
+@deftypefun void gtk_ruler_set_metric (GtkRuler *@var{ruler}, GtkMetricType @var{metric})
+@end deftypefun
+
+@deftypefun void gtk_ruler_set_range (GtkRuler *@var{ruler}, gfloat @var{lower}, gfloat @var{upper}, gfloat @var{position}, gfloat @var{max_size})
+@end deftypefun
+
+@deftypefun void gtk_ruler_draw_ticks (GtkRuler *@var{ruler})
+@end deftypefun
+
+@deftypefun void gtk_ruler_draw_pos (GtkRuler *@var{ruler})
+@end deftypefun
+
+@gtkstdmacros{Ruler, RULER}
+
+
+@page
+@node GtkScale, GtkScrollbar, GtkRuler, Widgets
+@comment node-name, next, previous, up
+@section The scale widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_scale_get_type (void)
+@end deftypefun
+
+@deftypefun void gtk_scale_set_digits (GtkScale *@var{scale}, gint @var{digits})
+@end deftypefun
+
+@deftypefun void gtk_scale_set_draw_value (GtkScale *@var{scale}, gint @var{draw_value})
+@end deftypefun
+
+@deftypefun void gtk_scale_set_value_pos (GtkScale *@var{scale}, gint @var{pos})
+@end deftypefun
+
+@deftypefun gint gtk_scale_value_width (GtkScale *@var{scale})
+@end deftypefun
+
+@deftypefun void gtk_scale_draw_value (GtkScale *@var{scale})
+@end deftypefun
+
+@gtkstdmacros{Scale, SCALE}
+
+
+@page
+@node GtkScrollbar, GtkScrolledWindow, GtkScale, Widgets
+@comment node-name, next, previous, up
+@section The scrollbar widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_scrollbar_get_type (void)
+@end deftypefun
+
+@gtkstdmacros{Scrollbar, SCROLLBAR}
+
+
+@page
+@node GtkScrolledWindow, GtkSeparator, GtkScrollbar, Widgets
+@comment node-name, next, previous, up
+@section The scrolled window widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_scrolled_window_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_scrolled_window_new (GtkAdjustment *@var{hadjustment}, GtkAdjustment *@var{vadjustment})
+@end deftypefun
+
+@deftypefun GtkAdjustment* gtk_scrolled_window_get_hadjustment (GtkScrolledWindow *@var{scrolled_window})
+@end deftypefun
+
+@deftypefun GtkAdjustment* gtk_scrolled_window_get_vadjustment (GtkScrolledWindow *@var{scrolled_window})
+@end deftypefun
+
+@deftypefun void gtk_scrolled_window_set_policy (GtkScrolledWindow *@var{scrolled_window}, GtkPolicyType @var{hscrollbar_policy}, GtkPolicyType @var{vscrollbar_policy})
+@end deftypefun
+
+@gtkstdmacros{ScrolledWindow, SCROLLED_WINDOW}
+
+
+@page
+@node GtkSeparator, GtkTable, GtkScrolledWindow, Widgets
+@comment node-name, next, previous, up
+@section The separator widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_separator_get_type (void)
+@end deftypefun
+
+@gtkstdmacros{Separator, SEPARATOR}
+
+
+@page
+@node GtkTable, GtkText, GtkSeparator, Widgets
+@comment node-name, next, previous, up
+@section The table widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_table_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_table_new (gint @var{rows}, gint @var{columns}, gint @var{homogeneous})
+@end deftypefun
+
+@deftypefun void gtk_table_attach (GtkTable *@var{table}, GtkWidget *@var{child}, gint @var{left_attach}, gint @var{right_attach}, gint @var{top_attach}, gint @var{bottom_attach}, gint @var{xoptions}, gint @var{yoptions}, gint @var{xpadding}, gint @var{ypadding})
+@end deftypefun
+
+@deftypefun void gtk_table_attach_defaults (GtkTable *@var{table}, GtkWidget *@var{widget}, gint @var{left_attach}, gint @var{right_attach}, gint @var{top_attach}, gint @var{bottom_attach})
+@end deftypefun
+
+@deftypefun void gtk_table_set_row_spacing (GtkTable *@var{table}, gint @var{row}, gint @var{spacing})
+@end deftypefun
+
+@deftypefun void gtk_table_set_col_spacing (GtkTable *@var{table}, gint @var{col}, gint @var{spacing})
+@end deftypefun
+
+@deftypefun void gtk_table_set_row_spacings (GtkTable *@var{table}, gint @var{spacing})
+@end deftypefun
+
+@deftypefun void gtk_table_set_col_spacings (GtkTable *@var{table}, gint @var{spacing})
+@end deftypefun
+
+@gtkstdmacros{Table, TABLE}
+
+
+@page
+@node GtkText, GtkToggleButton, GtkTable, Widgets
+@comment node-name, next, previous, up
+@section The text widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_text_get_type (void)
+@end deftypefun
+
+@gtkstdmacros{Text, TEXT}
+
+
+@page
+@node GtkToggleButton, GtkTree, GtkText, Widgets
+@comment node-name, next, previous, up
+@section The toggle button widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@deftypefn Signal void GtkToggleButton::toggled (GtkToggleButton *@var{toggle_button})
+@end deftypefn
+
+@subsection Functions
+
+@deftypefun guint gtk_toggle_button_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_toggle_button_new (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_toggle_button_new_with_label (gchar *@var{label})
+@end deftypefun
+
+@deftypefun void gtk_toggle_button_set_mode (GtkToggleButton *@var{toggle_button}, gint @var{draw_indicator})
+@end deftypefun
+
+@deftypefun void gtk_toggle_button_set_state (GtkToggleButton *@var{toggle_button}, gint @var{state})
+@end deftypefun
+
+@deftypefun void gtk_toggle_button_toggled (GtkToggleButotn *@var{toggle_button})
+@end deftypefun
+
+@gtkstdmacros{ToggleButton, TOGGLE_BUTTON}
+
+
+@page
+@node GtkTree, GtkTreeItem, GtkToggleButton, Widgets
+@comment node-name, next, previous, up
+@section The tree widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_tree_get_type (void)
+@end deftypefun
+
+@gtkstdmacros{Tree, TREE}
+
+
+@page
+@node GtkTreeItem, GtkVBox, GtkTree, Widgets
+@comment node-name, next, previous, up
+@section The tree item widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_tree_item_get_type (void)
+@end deftypefun
+
+@gtkstdmacros{TreeItem, TREE_ITEM}
+
+
+@page
+@node GtkVBox, GtkViewport, GtkTreeItem, Widgets
+@comment node-name, next, previous, up
+@section The vertical box widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_vbox_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_vbox_new (gint @var{homogeneous}, gint @var{spacing})
+@end deftypefun
+
+@gtkstdmacros{VBox, VBOX}
+
+
+@page
+@node GtkViewport, GtkVRuler, GtkVBox, Widgets
+@comment node-name, next, previous, up
+@section The viewport widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_viewport_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_viewport_new (GtkAdjustment *@var{hadjustment}, GtkAdjustment *@var{vadjustment})
+@end deftypefun
+
+@deftypefun GtkAdjustment* gtk_viewport_get_hadjustment (GtkViewport *@var{viewport})
+@end deftypefun
+
+@deftypefun GtkAdjustment* gtk_viewport_get_vadjustment (GtkViewport *@var{viewport})
+@end deftypefun
+
+@deftypefun void gtk_viewport_set_hadjustment (GtkViewport *@var{viewport}, GtkAdjustment *@var{adjustment})
+@end deftypefun
+
+@deftypefun void gtk_viewport_set_vadjustment (GtkViewport *@var{viewport}, GtkAdjustment *@var{adjustment})
+@end deftypefun
+
+@deftypefun void gtk_viewport_set_shadow_type (GtkViewport *@var{viewport}, GtkShadowType @var{type})
+@end deftypefun
+
+@gtkstdmacros{Viewport, VIEWPORT}
+
+
+@page
+@node GtkVRuler, GtkVScale, GtkViewport, Widgets
+@comment node-name, next, previous, up
+@section The vertical ruler widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_vruler_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_vruler_new (void)
+@end deftypefun
+
+@gtkstdmacros{VRuler, VRULER}
+
+
+@page
+@node GtkVScale, GtkVScrollbar, GtkVRuler, Widgets
+@comment node-name, next, previous, up
+@section The vertical ruler widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_vscale_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_vscale_new (GtkAdjustment *@var{adjustment})
+@end deftypefun
+
+@gtkstdmacros{VScale, VSCALE}
+
+
+@page
+@node GtkVScrollbar, GtkVSeparator, GtkVScale, Widgets
+@comment node-name, next, previous, up
+@section The vertical scrollbar widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_vscrollbar_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_vscrollbar_new (GtkAdjustment *@var{adjustment})
+@end deftypefun
+
+@gtkstdmacros{VScrollbar, VSCROLLBAR}
+
+
+@page
+@node GtkVSeparator, GtkWidget, GtkVScrollbar, Widgets
+@comment node-name, next, previous, up
+@section The vertical separator widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@subsection Functions
+
+@deftypefun guint gtk_vseparator_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_vseparator_new (void)
+@end deftypefun
+
+@gtkstdmacros{VSeparator, VSEPARATOR}
+
+
+@page
+@node GtkWidget, GtkWindow, GtkVSeparator, Widgets
+@comment node-name, next, previous, up
+@section The base widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@deftypefn Signal void GtkWidget::show (GtkWidget *@var{widget})
+@end deftypefn
+
+@deftypefn Signal void GtkWidget::hide (GtkWidget *@var{widget})
+@end deftypefn
+
+@deftypefn Signal void GtkWidget::map (GtkWidget *@var{widget})
+@end deftypefn
+
+@deftypefn Signal void GtkWidget::unmap (GtkWidget *@var{widget})
+@end deftypefn
+
+@deftypefn Signal void GtkWidget::realize (GtkWidget *@var{widget})
+@end deftypefn
+
+@deftypefn Signal void GtkWidget::unrealize (GtkWidget *@var{widget})
+@end deftypefn
+
+@deftypefn Signal void GtkWidget::draw (GtkWidget *@var{widget}, GdkRectangle *@var{area})
+@end deftypefn
+
+@deftypefn Signal void GtkWidget::draw_focus (GtkWidget *@var{widget})
+@end deftypefn
+
+@deftypefn Signal void GtkWidget::draw_default (GtkWidget *@var{widget})
+@end deftypefn
+
+@deftypefn Signal void GtkWidget::size_request (GtkWidget *@var{widget}, GtkRequisition *@var{requisition})
+@end deftypefn
+
+@deftypefn Signal void GtkWidget::size_allocate (GtkWidget *@var{widget}, GtkAllocation *@var{allocation})
+@end deftypefn
+
+@deftypefn Signal void GtkWidget::state_changed (GtkWidget *@var{widget})
+@end deftypefn
+
+@deftypefn Signal gint GtkWidget::install_accelerator (GtkWidget *@var{widget}, gchar *@var{signal_name}, gchar @var{key}, guint8 @var{modifiers})
+@end deftypefn
+
+@deftypefn Signal void GtkWidget::remove_accelerator (GtkWidget *@var{widget}, gchar *@var{signal_name})
+@end deftypefn
+
+@deftypefn Signal gint GtkWidget::event (GtkWidget *@var{widget}, GdkEvent *@var{event})
+@end deftypefn
+
+@deftypefn Signal gint GtkWidget::button_press_event (GtkWidget *@var{widget}, GdkEventButton *@var{event})
+@end deftypefn
+
+@deftypefn Signal gint GtkWidget::button_release_event (GtkWidget *@var{widget}, GdkEventButton *@var{event})
+@end deftypefn
+
+@deftypefn Signal gint GtkWidget::motion_notify_event (GtkWidget *@var{widget}, GdkEventMotion *@var{event})
+@end deftypefn
+
+@deftypefn Signal gint GtkWidget::delete_event (GtkWidget *@var{widget}, GdkEventAny *@var{event})
+@end deftypefn
+
+@deftypefn Signal gint GtkWidget::destroy_event (GtkWidget *@var{widget}, GdkEventAny *@var{event})
+@end deftypefn
+
+@deftypefn Signal gint GtkWidget::expose_event (GtkWidget *@var{widget}, GdkEventExpose *@var{event})
+@end deftypefn
+
+@deftypefn Signal gint GtkWidget::key_press_event (GtkWidget *@var{widget}, GdkEventKey *@var{event})
+@end deftypefn
+
+@deftypefn Signal gint GtkWidget::key_release_event (GtkWidget *@var{widget}, GdkEventKey *@var{event})
+@end deftypefn
+
+@deftypefn Signal gint GtkWidget::enter_notify_event (GtkWidget *@var{widget}, GdkEventCrossing *@var{event})
+@end deftypefn
+
+@deftypefn Signal gint GtkWidget::leave_notify_event (GtkWidget *@var{widget}, GdkEventCrossing *@var{event})
+@end deftypefn
+
+@deftypefn Signal gint GtkWidget::configure_event (GtkWidget *@var{widget}, GdkEventConfigure *@var{event})
+@end deftypefn
+
+@deftypefn Signal gint GtkWidget::focus_in_event (GtkWidget *@var{widget}, GdkEventFocus *@var{event})
+@end deftypefn
+
+@deftypefn Signal gint GtkWidget::focus_out_event (GtkWidget *@var{widget}, GdkEventFocus *@var{event})
+@end deftypefn
+
+@deftypefn Signal gint GtkWidget::map_event (GtkWidget *@var{widget}, GdkEventAny *@var{event})
+@end deftypefn
+
+@deftypefn Signal gint GtkWidget::unmap_event (GtkWidget *@var{widget}, GdkEventAny *@var{event})
+@end deftypefn
+
+@deftypefn Signal gint GtkWidget::property_notify_event (GtkWidget *@var{widget}, GdkEventProperty *@var{event})
+@end deftypefn
+
+@deftypefn Signal gint GtkWidget::selection_clear_event (GtkWidget *@var{widget}, GdkEventSelection *@var{event})
+@end deftypefn
+
+@deftypefn Signal gint GtkWidget::selection_request_event (GtkWidget *@var{widget}, GdkEventSelection *@var{event})
+@end deftypefn
+
+@deftypefn Signal gint GtkWidget::selection_notify_event (GtkWidget *@var{widget}, GdkEventSelection *@var{event})
+@end deftypefn
+
+@deftypefn Signal gint GtkWidget::drop_event (GtkWidget *@var{widget}, GdkEventDrop *@var{event})
+@end deftypefn
+
+@deftypefn Signal gint GtkWidget::drag_begin_event (GtkWidget *@var{widget}, GdkEventDragBegin *@var{event})
+@end deftypefn
+
+@deftypefn Signal gint GtkWidget::other_event (GtkWidget *@var{widget}, GdkEventOther *@var{event})
+@end deftypefn
+
+@subsection Functions
+
+@deftypefun guint gtk_widget_get_type (void)
+@end deftypefun
+
+@deftypefun void gtk_widget_class_init (GtkWidgetClass *@var{class})
+@end deftypefun
+
+@deftypefun void gtk_widget_init (GtkWidget *@var{widget})
+@end deftypefun
+
+@deftypefun void gtk_widget_destroy (GtkWidget *@var{widget})
+@end deftypefun
+
+@deftypefun void gtk_widget_show (GtkWidget *@var{widget})
+@end deftypefun
+
+@deftypefun void gtk_widget_hide (GtkWidget *@var{widget})
+@end deftypefun
+
+@deftypefun void gtk_widget_map (GtkWidget *@var{widget})
+@end deftypefun
+
+@deftypefun void gtk_widget_unmap (GtkWidget *@var{widget})
+@end deftypefun
+
+@deftypefun void gtk_widget_realize (GtkWidget *@var{widget})
+@end deftypefun
+
+@deftypefun void gtk_widget_unrealize (GtkWidget *@var{widget})
+@end deftypefun
+
+@deftypefun void gtk_widget_draw (GtkWidget *@var{widget}, GdkRectangle *@var{area})
+@end deftypefun
+
+@deftypefun void gtk_widget_draw_focus (GtkWidget *@var{widget})
+@end deftypefun
+
+@deftypefun void gtk_widget_draw_children (GtkWidget *@var{widget})
+@end deftypefun
+
+@deftypefun void gtk_widget_size_request (GtkWidget *@var{widget}, GtkRequisition *@var{requisition})
+@end deftypefun
+
+@deftypefun void gtk_widget_size_allocate (GtkWidget *@var{widget}, GtkAllocation *@var{allocation})
+@end deftypefun
+
+@deftypefun void gtk_widget_install_accelerator (GtkWidget *@var{widget}, GtkAcceleratorTable *@var{table}, gchar *@var{signal_name}, gchar @var{key}, guint8 @var{modifiers})
+@end deftypefun
+
+@deftypefun void gtk_widget_remove_accelerator (GtkWidget *@var{widget}, GtkAcceleratorTable *@var{table}, gchar *@var{signal_name})
+@end deftypefun
+
+@deftypefun gint gtk_widget_event (GtkWidget *@var{widget}, GdkEvent *@var{event})
+@end deftypefun
+
+@deftypefun void gtk_widget_reparent (GtkWidget *@var{widget}, GtkWidget *@var{new_parent})
+@end deftypefun
+
+@deftypefun void gtk_widget_popup (GtkWidget *@var{widget}, gint @var{x}, gint @var{y})
+@end deftypefun
+
+@deftypefun gint gtk_widget_intersect (GtkWidget *@var{widget}, GdkRectangle *@var{area}, GdkRectangle *@var{intersection})
+@end deftypefun
+
+@deftypefun void gtk_widget_grab_focus (GtkWidget *@var{widget})
+@end deftypefun
+
+@deftypefun void gtk_widget_grab_default (GtkWidget *@var{widget})
+@end deftypefun
+
+@deftypefun void gtk_widget_restore_state (GtkWidget *@var{widget})
+@end deftypefun
+
+@deftypefun void gtk_widget_set_name (GtkWidget *@var{widget}, gchar *@var{name})
+@end deftypefun
+
+@deftypefun void gtk_widget_set_state (GtkWidget *@var{widget}, GtkStateType @var{state})
+@end deftypefun
+
+@deftypefun void gtk_widget_set_sensitive (GtkWidget *@var{widget}, gint sensitive)
+@end deftypefun
+
+@deftypefun void gtk_widget_set_parent (GtkWidget *@var{widget}, GtkWidget *@var{parent})
+@end deftypefun
+
+@deftypefun void gtk_widget_set_style (GtkWidget *@var{widget}, GtkStyle *@var{style})
+@end deftypefun
+
+@deftypefun void gtk_widget_set_uposition (GtkWidget *@var{widget}, gint @var{x}, gint @var{y})
+@end deftypefun
+
+@deftypefun void gtk_widget_set_usize (GtkWidget *@var{widget}, gint @var{width}, gint @var{height})
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_widget_get_toplevel (GtkWidget *@var{widget})
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_widget_get_ancestor (GtkWidget *@var{widget}, gint @var{type})
+@end deftypefun
+
+@deftypefun GdkColormap* gtk_widget_get_colormap (GtkWidget *@var{widget})
+@end deftypefun
+
+@deftypefun GdkVisual* gtk_widget_get_visual (GtkWidget *@var{visual})
+@end deftypefun
+
+@deftypefun GtkStyle* gtk_widget_get_style (GtkWidget *@var{style})
+@end deftypefun
+
+@gtkstdmacros{Widget, WIDGET}
+
+
+@page
+@node GtkWindow, , GtkWidget, Widgets
+@comment node-name, next, previous, up
+@section The window widget
+
+
+@subsection Description
+
+@subsection Signals
+
+@deftypefn Signal void GtkWindow::move_resize (GtkWindow *@var{window}, gint *@var{x}, gint *@var{y}, gint @var{width}, gint @var{height})
+@end deftypefn
+
+@subsection Functions
+
+@deftypefun guint gtk_window_get_type (void)
+@end deftypefun
+
+@deftypefun GtkWidget* gtk_window_new (GtkWindowType @var{type})
+@end deftypefun
+
+@deftypefun void gtk_window_set_title (GtkWindow *@var{window}, gchar *@var{title})
+@end deftypefun
+
+@deftypefun void gtk_window_set_focus (GtkWindow *@var{window}, GtkWidget *@var{focus})
+@end deftypefun
+
+@deftypefun void gtk_window_set_default (GtkWindow *@var{window}, GtkWidget *@var{defaultw})
+@end deftypefun
+
+@deftypefun void gtk_window_set_policy (GtkWindow *@var{window}, gint @var{allow_shrink}, gint @var{allow_grow}, gint @var{auto_shrink})
+@end deftypefun
+
+@deftypefun void gtk_window_add_accelerator_table (GtkWindow *@var{window}, GtkAcceleratorTable *@var{table})
+@end deftypefun
+
+@deftypefun void gtk_window_remove_accelerator_table (GtkWindow *@var{window}, GtkAcceleratorTable *@var{table})
+@end deftypefun
+
+@deftypefun void gtk_window_position (GtkWindow *@var{window}, GtkWindowPosition @var{position})
+@end deftypefun
+
+@gtkstdmacros{Window, WINDOW}
+
+
+@node Other Objects, Miscellaneous, Widgets, Top
+@comment node-name, next, previous, up
+@chapter Utility objects
+
+
+@menu
+* GtkAdjustment::               The adjustment object.
+* GtkData::                     The data object.
+@end menu
+
+
+@node GtkAdjustment, GtkData, Other Objects, Other Objects
+@comment node-name, next, previous, up
+@section The adjustment object
+
+
+@node GtkData, , GtkAdjustment, Other Objects
+@comment node-name, next, previous, up
+@section The data object
+
+
+@node Miscellaneous, Examples, Other Objects, Top
+@comment node-name, next, previous, up
+@chapter Initialization, exit and other features
+
+
+@menu
+* Initialization and exit::     Initializing and exiting GTK.
+* Menu Factories::              Simplified menu creation.
+* Tree Factories::              Simplified tree creation.
+* Tool Tips::                   Pop up help mechanism.
+* Resource Files::              Resource files.
+* Standard Macros::             Macros defined by all objects.
+@end menu
+
+
+@node Initialization and exit, Menu Factories, Miscellaneous, Miscellaneous
+@comment node-name, next, previous, up
+@section Initializing and exiting GTK
+
+
+@node Menu Factories, Tree Factories, Initialization and exit, Miscellaneous
+@comment node-name, next, previous, up
+@section Simplified menu creation
+
+
+@node Tree Factories, Tool Tips, Menu Factories, Miscellaneous
+@comment node-name, next, previous, up
+@section Simplified tree creation
+
+
+@node Tool Tips, Resource Files, Tree Factories, Miscellaneous
+@comment node-name, next, previous, up
+@section Pop up help mechanism
+
+
+@node Resource Files, Standard Macros, Tool Tips, Miscellaneous
+@comment node-name, next, previous, up
+@section Pop up help mechanism
+
+
+@node Standard Macros, , Resource Files, Miscellaneous
+@comment node-name, next, previous, up
+@section Macros defined by all objects
+
+There are three macros that are defined by all object types. The first
+two are used for performing casts and the last is for querying whether
+an object is of a particular type. These macros are both conveniences
+and debugging tools. If the GTK library was compiled with @code{NDEBUG}
+defined as a preprocessor symbol (via the -DNDEBUG to cc), then the
+macros check the object type and emit a warning if the cast is
+invalid. Doing such checking is fairly expensive since the cast macros
+are used everywhere in GTK and would normally be turned off in a public
+release of a product. Note: The functions below are indeed macros, but
+they may be considered functions for most purposes.
+
+@deftypefun Gtk<ObjectType>* GTK_<OBJECT_TYPE> (gpointer @var{obj})
+Cast a generic pointer to @code{Gtk<ObjectType>*}. This function is
+provided in order to be able to provide checking during development
+stages of code development since it is possible to examine the actual
+type of object (using @code{gtk_type_is_a}) before performing the cast.
+@end deftypefun
+
+@deftypefun Gtk<ObjectType>Class* GTK_<OBJECT_TYPE>_CLASS (gpointer @var{class})
+Cast a generic pointer to @code{Gtk<ObjectType>Class*}. Like
+@code{GTK_<ObjectType>}, this function is, in reality, a macro.
+@end deftypefun
+
+@deftypefun gint GTK_IS_<ObjectType> (gpointer @var{obj})
+Determine if a generic pointer refers to a @code{Gtk<ObjectType>}
+object. This function is, in reality, a macro wrapper around the
+@code{gtk_type_is_a} function (@pxref{Objects}).
+@end deftypefun
+
+
+@node Examples, Object Implementation, Miscellaneous, Top
+@comment node-name, next, previous, up
+@chapter Using GTK
+
+
+@menu
+* Simple::                      The simplest GTK program.
+* Hello World::                 Hello world in GTK.
+* Hello World II::              An enhanced hello world.
+* Hello World III::             Making Hello World II robust.
+@end menu
+
+
+@node Simple, Hello World, Examples, Examples
+@comment node-name, next, previous, up
+@section The simplest GTK program
+
+
+The 16 line GTK program shown below is just about the simplest possible
+program which uses GTK. (Well, technically, you don't have to create the
+window and it would still be a program which uses GTK). The program,
+when compiled and run, will create a single window 200x200 pixels in
+size. The program does not exit until its is explicitly killed using the
+shell or a window manager function.
+
+@example
+#include <gtk/gtk.h>
+
+int
+main (int argc, char *argv[])
+@{
+  GtkWidget *window;
+
+  gtk_init (&argc, &argv);
+
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_widget_show (window);
+
+  gtk_main ();
+
+  return 0;
+@}
+@end example
+
+The first point of interest in this program is the standard
+initialization line.
+
+@example
+  gtk_init (&argc, &argv);
+@end example
+
+Almost every GTK program will contain such a line. GTK will initialize
+itself and GDK and remove any command line arguments it recognizes from
+@var{argc} and @var{argv}.
+
+The next two lines of code create and display a window.
+
+@example
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_widget_show (window);
+@end example
+
+The @code{GTK_WINDOW_TOPLEVEL} argument specifies that we want the
+window to undergo window manager decoration and placement. One might be
+lead to think that the window, since it has no children, would be 0x0
+pixels in size. But, this is not the case because a window that has no
+children defaults to 200x200 pixels in size. Mainly because 0x0 windows
+are annoying to manipulate or even see in some cases.
+
+The last line enters the GTK main processing loop.
+
+@example
+  gtk_main ();
+@end example
+
+Normally, @code{gtk_main} is called once and the program should exit
+when it returns. @xref{Initialization and exit}.
+
+
+@node Hello World, Hello World II, Simple, Examples
+@comment node-name, next, previous, up
+@section Hello world in GTK
+
+
+@example
+#include <gtk/gtk.h>
+
+int
+main (int argc, char *argv[])
+@{
+  GtkWidget *window;
+  GtkWidget *label;
+
+  gtk_init (&argc, &argv);
+
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_container_border_width (GTK_CONTAINER (window), 10);
+
+  label = gtk_label_new ("Hello World");
+  gtk_container_add (GTK_CONTAINER (window), label);
+  gtk_widget_show (label);
+
+  gtk_widget_show (window);
+
+  gtk_main ();
+
+  return 0;
+@}
+@end example
+
+
+@node Hello World II, Hello World III, Hello World, Examples
+@comment node-name, next, previous, up
+@section An enhanced hello world
+
+
+@example
+#include "gtk.h"
+
+void
+hello (void)
+@{
+  g_print ("Hello World\n");
+  gtk_exit (0);
+@}
+
+int
+main (int argc, char *argv[])
+@{
+  GtkWidget *window;
+  GtkWidget *button;
+
+  gtk_init (&argc, &argv);
+
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_container_border_width (GTK_CONTAINER (window), 10);
+
+  button = gtk_button_new_with_label ("Hello World");
+  gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                     GTK_SIGNAL_FUNC (hello), NULL);
+  gtk_container_add (GTK_CONTAINER (window), button);
+  gtk_widget_show (button);
+
+  gtk_widget_show (window);
+
+  gtk_main ();
+
+  return 0;
+@}
+@end example
+
+
+@node Hello World III, , Hello World II, Examples
+@comment node-name, next, previous, up
+@section Making Hello World II robust
+
+
+@example
+#include "gtk.h"
+
+void
+hello (void)
+@{
+  g_print ("Hello World\n");
+  gtk_exit (0);
+@}
+
+void
+destroy (void)
+@{
+  gtk_exit (0);
+@}
+
+int
+main (int argc, char *argv[])
+@{
+  GtkWidget *window;
+  GtkWidget *button;
+
+  gtk_init (&argc, &argv);
+
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                     GTK_SIGNAL_FUNC (destroy), NULL);
+  gtk_container_border_width (GTK_CONTAINER (window), 10);
+
+  button = gtk_button_new_with_label ("Hello World");
+  gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                     GTK_SIGNAL_FUNC (hello), NULL);
+  gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                            GTK_SIGNAL_FUNC (gtk_widget_destroy),
+                            GTK_OBJECT (window));
+  gtk_container_add (GTK_CONTAINER (window), button);
+  gtk_widget_show (button);
+
+  gtk_widget_show (window);
+
+  gtk_main ();
+
+  return 0;
+@}
+@end example
+
+
+@node Object Implementation, Signal Implementation, Examples, Top
+@comment node-name, next, previous, up
+@chapter Object internals
+@cindex Object Implementaton
+
+Objects (or the @code{GtkObject} type) and the class hierarchy in
+general is implemented via a hierarchy of structs and type casting. Be
+aware that when classes are mentioned it is the conceptual idea of
+classes that is being referred to. GTK is written entirely in C which
+provides no direct support for classes.
+
+The first part to the class mechanism is the object fields. These are
+fields that will be used on a per object basis. For example, the widget
+type contains a field for the widgets parent. Every derived type needs a
+reference to its parent type. A descendant class of @code{GtkObject}
+would define itself like:
+
+@example
+struct Descendant
+@{
+  GtkObject object;
+
+  @dots{}
+@};
+@end example
+
+It is important to note that the @code{GtkObject} field needs to appear
+first in the descendant type structure. This allows pointers to objects
+of type @code{Descendant} to be cast to pointers to @code{GtkObjects}'s
+and vice-versa.
+
+The second part to the class mechanism is the class fields. These fields
+are defined on a per class basis. In the case of widgets, the class
+fields are all the ``virtual'' functions for widgets. The
+@code{GtkObject} class defines the @code{destroy} virtual function and
+the necessary fields for the signal mechanism as well as a field for
+determining the runtime type of an object. A virtual function is
+semantically the same as it is in C++. That is, the actual function that
+is called is determined based on the type of the object. Or, more
+specifically, the actual function call depends on the class structure
+that is pointed to by the @code{klass} field of the @code{GtkObject}
+structure.
+
+To see how the class fields work it is necessary to see the object
+fields for a @code{GtkObject}. The @code{GtkObject} type is defined as
+follows:
+
+@example
+typedef struct _GtkObject GtkObject;
+
+struct _GtkObject
+@{
+  guint32 flags;
+  GtkObjectClass *klass;
+  gpointer object_data;
+@};
+@end example
+
+The @code{class} field actually points to a class structure derived from
+@code{GtkObjectClass}. By convention, each new type defines its own
+class structure even if it is unnecessary. As an example, the
+hypothetical @code{Descendant} class would define its class structure
+as:
+
+@example
+struct DescendantClass
+@{
+  GtkObjectClass parent_class;
+
+  @dots{}
+@};
+@end example
+
+It is convention to name the parent class field (@code{GtkObjectClass}
+in this case), @code{parent_class}. For the same reason as stated above
+for the object structure, the parent class field must be the first field
+in the class structure.
+
+@strong{Note:} GTK assumes that the first field in a structure will be
+placed by the compiler at the start of the structure. This is certainly
+true for gcc, however, from my precursory reading of the C standard I
+was unable to come to a definite conclusion as to whether this was
+required or simply done for simplicity. I'm not too worried about this
+assumption, though, as every C compiler I've ever encountered would work
+with GTK.
+
+The @code{flags} field of the @code{GtkObject} structure is used to keep
+track of a relatively few object flags and is also used by the
+@code{GtkWidget} type to store additional flags. At this time, the upper
+16 bits of the flags field are reserved but unused.
+
+The @code{object_data} field of the @code{GtkObject} structure is an
+opaque pointer used by the object data mechanism. In truth, it is a
+pointer to the beginning of the data list which is composed of the
+following structures.
+
+@example
+typedef struct _GtkObjectData GtkObjectData;
+
+struct _GtkObjectData
+@{
+  guint id;
+  gpointer data;
+  GtkObjectData *next;
+@};
+@end example
+
+The data mechanism allows arbitrary data to be associated with a
+character string key in any object. A hash table is used to transform
+the character string key into the data id and then a search through the
+list is made to see if the data exists. The assumption being that the
+data list will usually be short and therefore a linear search is
+ok. Future work on the data mechanism might make use of a resizable
+array instead of a linked list. This would shrink the overhead of the
+@code{GtkObjectData} structure by 4 bytes on 32 bit architectures.
+
+
+@node Signal Implementation, Widget Implementation, Object Implementation, Top
+@comment node-name, next, previous, up
+@chapter Signal internals
+@cindex Signal Implementation
+
+
+@node Widget Implementation, Function Index, Signal Implementation, Top
+@comment node-name, next, previous, up
+@chapter Widget internals
+@cindex Widget Implementation
+
+
+@node Function Index, Concept Index, Widget Implementation, Top
+@comment node-name, next, previous, up
+@unnumbered Function Index
+
+@printindex fn
+
+
+@node Concept Index, , Function Index, Top
+@comment node-name, next, previous, up
+@unnumbered Concept Index
+
+@printindex cp
+
+
+@summarycontents
+@contents
+@bye
diff --git a/docs/macros.texi b/docs/macros.texi
new file mode 100644 (file)
index 0000000..f8df89a
--- /dev/null
@@ -0,0 +1,18 @@
+@macro gtkstdmacros {p, q}
+
+@deftypefun Gtk\p\* GTK_\q\ (gpointer @var{obj})
+Cast a generic pointer to @code{Gtk\p\*}. @xref{Standard Macros}, for
+more info.
+@end deftypefun
+
+@deftypefun Gtk\p\Class* GTK_\q\_CLASS (gpointer @var{class})
+Cast a generic pointer to @code{Gtk\p\Class*}. @xref{Standard Macros},
+for more info.
+@end deftypefun
+
+@deftypefun gint GTK_IS_\q\ (gpointer @var{obj})
+Determine if a generic pointer refers to a @code{Gtk\p\}
+object. @xref{Standard Macros}, for more info.
+@end deftypefun
+
+@end macro
diff --git a/docs/texinfo.tex b/docs/texinfo.tex
new file mode 100644 (file)
index 0000000..7d62f26
--- /dev/null
@@ -0,0 +1,4692 @@
+%% TeX macros to handle texinfo files
+
+%  Copyright (C) 1985, 86, 88, 90, 91, 92, 93,
+%                94, 95, 1996 Free Software Foundation, Inc.
+
+%This texinfo.tex file is free software; you can redistribute it and/or
+%modify it under the terms of the GNU General Public License as
+%published by the Free Software Foundation; either version 2, or (at
+%your option) any later version.
+
+%This texinfo.tex file is distributed in the hope that it will be
+%useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+%of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%General Public License for more details.
+
+%You should have received a copy of the GNU General Public License
+%along with this texinfo.tex file; see the file COPYING.  If not, write
+%to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+%Boston, MA 02111-1307, USA.
+
+
+%In other words, you are welcome to use, share and improve this program.
+%You are forbidden to forbid anyone else to use, share and improve
+%what you give them.   Help stamp out software-hoarding!
+
+
+% Send bug reports to bug-texinfo@prep.ai.mit.edu.
+% Please include a *precise* test case in each bug report.
+
+
+% Make it possible to create a .fmt file just by loading this file:
+% if the underlying format is not loaded, start by loading it now.
+% Added by gildea November 1993.
+\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
+
+% This automatically updates the version number based on RCS.
+\def\deftexinfoversion$#1: #2 ${\def\texinfoversion{#2}}
+\deftexinfoversion$Revision$
+\message{Loading texinfo package [Version \texinfoversion]:}
+
+% If in a .fmt file, print the version number
+% and turn on active characters that we couldn't do earlier because
+% they might have appeared in the input file name.
+\everyjob{\message{[Texinfo version \texinfoversion]}\message{}
+  \catcode`+=\active \catcode`\_=\active}
+
+% Save some parts of plain tex whose names we will redefine.
+
+\let\ptexb=\b
+\let\ptexbullet=\bullet
+\let\ptexc=\c
+\let\ptexcomma=\,
+\let\ptexdot=\.
+\let\ptexdots=\dots
+\let\ptexend=\end
+\let\ptexequiv = \equiv
+\let\ptexi=\i
+\let\ptexlbrace=\{
+\let\ptexrbrace=\}
+\let\ptexstar=\*
+\let\ptext=\t
+\let\ptextilde=\~
+
+% Be sure we're in horizontal mode when doing a tie, since we make space
+% equivalent to this in @example-like environments. Otherwise, a space
+% at the beginning of a line will start with \penalty -- and
+% since \penalty is valid in vertical mode, we'd end up putting the
+% penalty on the vertical list instead of in the new paragraph.
+{\catcode`@ = 11
+ % Avoid using \@M directly, because that causes trouble
+ % if the definition is written into an index file.
+ \global\let\tiepenalty = \@M
+ \gdef\tie{\leavevmode\penalty\tiepenalty\ }
+}
+\let\~ = \tie                  % And make it available as @~.
+
+
+\message{Basics,}
+\chardef\other=12
+
+% If this character appears in an error message or help string, it
+% starts a new line in the output.
+\newlinechar = `^^J
+
+% Set up fixed words for English.
+\ifx\putwordChapter\undefined{\gdef\putwordChapter{Chapter}}\fi%
+\def\putwordInfo{Info}%
+\ifx\putwordSee\undefined{\gdef\putwordSee{See}}\fi%
+\ifx\putwordsee\undefined{\gdef\putwordsee{see}}\fi%
+\ifx\putwordfile\undefined{\gdef\putwordfile{file}}\fi%
+\ifx\putwordpage\undefined{\gdef\putwordpage{page}}\fi%
+\ifx\putwordsection\undefined{\gdef\putwordsection{section}}\fi%
+\ifx\putwordSection\undefined{\gdef\putwordSection{Section}}\fi%
+\ifx\putwordTableofContents\undefined{\gdef\putwordTableofContents{Table of Contents}}\fi%
+\ifx\putwordShortContents\undefined{\gdef\putwordShortContents{Short Contents}}\fi%
+\ifx\putwordAppendix\undefined{\gdef\putwordAppendix{Appendix}}\fi%
+
+% Ignore a token.
+%
+\def\gobble#1{}
+
+\hyphenation{ap-pen-dix}
+\hyphenation{mini-buf-fer mini-buf-fers}
+\hyphenation{eshell}
+
+% Margin to add to right of even pages, to left of odd pages.
+\newdimen \bindingoffset  
+\newdimen \normaloffset   
+\newdimen\pagewidth \newdimen\pageheight
+
+% Sometimes it is convenient to have everything in the transcript file
+% and nothing on the terminal.  We don't just call \tracingall here,
+% since that produces some useless output on the terminal.
+%
+\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}%
+\def\loggingall{\tracingcommands2 \tracingstats2
+   \tracingpages1 \tracingoutput1 \tracinglostchars1
+   \tracingmacros2 \tracingparagraphs1 \tracingrestores1
+   \showboxbreadth\maxdimen\showboxdepth\maxdimen
+}%
+
+%---------------------Begin change-----------------------
+%
+%%%% For @cropmarks command.
+% Dimensions to add cropmarks at corners Added by P. A. MacKay, 12 Nov. 1986
+%
+\newdimen\cornerlong \newdimen\cornerthick
+\newdimen \topandbottommargin
+\newdimen \outerhsize \newdimen \outervsize
+\cornerlong=1pc\cornerthick=.3pt        % These set size of cropmarks
+\outerhsize=7in
+%\outervsize=9.5in
+% Alternative @smallbook page size is 9.25in
+\outervsize=9.25in
+\topandbottommargin=.75in
+%
+%---------------------End change-----------------------
+
+% \onepageout takes a vbox as an argument.  Note that \pagecontents
+% does insertions, but you have to call it yourself.
+\chardef\PAGE=255  \output={\onepageout{\pagecontents\PAGE}}
+\def\onepageout#1{%
+  \hoffset=\normaloffset
+  \ifodd\pageno  \advance\hoffset by \bindingoffset
+  \else \advance\hoffset by -\bindingoffset\fi
+  {%
+    \escapechar = `\\ % use backslash in output files.
+    \indexdummies
+    \shipout\vbox{%
+      {\let\hsize=\pagewidth \makeheadline}%
+      \pagebody{#1}%
+      {\let\hsize=\pagewidth \makefootline}%
+    }%
+  }%
+  \advancepageno
+  \ifnum\outputpenalty>-20000 \else\dosupereject\fi
+}
+
+%%%% For @cropmarks command %%%%
+
+% Here is a modification of the main output routine for Near East Publications
+% This provides right-angle cropmarks at all four corners.
+% The contents of the page are centerlined into the cropmarks,
+% and any desired binding offset is added as an \hskip on either
+% site of the centerlined box.  (P. A. MacKay, 12 November, 1986)
+%
+\def\croppageout#1{\hoffset=0pt % make sure this doesn't mess things up
+{\escapechar=`\\\relax % makes sure backslash is used in output files.
+                 \shipout
+                 \vbox to \outervsize{\hsize=\outerhsize
+                 \vbox{\line{\ewtop\hfill\ewtop}}
+                 \nointerlineskip
+                 \line{\vbox{\moveleft\cornerthick\nstop}
+                       \hfill
+                       \vbox{\moveright\cornerthick\nstop}}
+                 \vskip \topandbottommargin
+                 \centerline{\ifodd\pageno\hskip\bindingoffset\fi
+                        \vbox{
+                        {\let\hsize=\pagewidth \makeheadline}
+                        \pagebody{#1}
+                        {\let\hsize=\pagewidth \makefootline}}
+                        \ifodd\pageno\else\hskip\bindingoffset\fi}
+                 \vskip \topandbottommargin plus1fill minus1fill
+                 \boxmaxdepth\cornerthick
+                 \line{\vbox{\moveleft\cornerthick\nsbot}
+                       \hfill
+                       \vbox{\moveright\cornerthick\nsbot}}
+                 \nointerlineskip
+                 \vbox{\line{\ewbot\hfill\ewbot}}
+        }}
+  \advancepageno
+  \ifnum\outputpenalty>-20000 \else\dosupereject\fi}
+%
+% Do @cropmarks to get crop marks
+\def\cropmarks{\let\onepageout=\croppageout }
+
+\newinsert\margin \dimen\margin=\maxdimen
+
+\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}}
+{\catcode`\@ =11
+\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi
+% marginal hacks, juha@viisa.uucp (Juha Takala)
+\ifvoid\margin\else % marginal info is present
+  \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi
+\dimen@=\dp#1 \unvbox#1
+\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi
+\ifr@ggedbottom \kern-\dimen@ \vfil \fi}
+}
+
+%
+% Here are the rules for the cropmarks.  Note that they are
+% offset so that the space between them is truly \outerhsize or \outervsize
+% (P. A. MacKay, 12 November, 1986)
+%
+\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong}
+\def\nstop{\vbox
+  {\hrule height\cornerthick depth\cornerlong width\cornerthick}}
+\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong}
+\def\nsbot{\vbox
+  {\hrule height\cornerlong depth\cornerthick width\cornerthick}}
+
+% Parse an argument, then pass it to #1.  The argument is the rest of
+% the input line (except we remove a trailing comment).  #1 should be a
+% macro which expects an ordinary undelimited TeX argument.
+%
+\def\parsearg#1{%
+  \let\next = #1%
+  \begingroup
+    \obeylines
+    \futurelet\temp\parseargx
+}
+
+% If the next token is an obeyed space (from an @example environment or
+% the like), remove it and recurse.  Otherwise, we're done.
+\def\parseargx{%
+  % \obeyedspace is defined far below, after the definition of \sepspaces.
+  \ifx\obeyedspace\temp
+    \expandafter\parseargdiscardspace
+  \else
+    \expandafter\parseargline
+  \fi
+}
+
+% Remove a single space (as the delimiter token to the macro call).
+{\obeyspaces %
+ \gdef\parseargdiscardspace {\futurelet\temp\parseargx}}
+
+{\obeylines %
+  \gdef\parseargline#1^^M{%
+    \endgroup % End of the group started in \parsearg.
+    %
+    % First remove any @c comment, then any @comment.
+    % Result of each macro is put in \toks0.
+    \argremovec #1\c\relax %
+    \expandafter\argremovecomment \the\toks0 \comment\relax %
+    %
+    % Call the caller's macro, saved as \next in \parsearg.
+    \expandafter\next\expandafter{\the\toks0}%
+  }%
+}
+
+% Since all \c{,omment} does is throw away the argument, we can let TeX
+% do that for us.  The \relax here is matched by the \relax in the call
+% in \parseargline; it could be more or less anything, its purpose is
+% just to delimit the argument to the \c.
+\def\argremovec#1\c#2\relax{\toks0 = {#1}}
+\def\argremovecomment#1\comment#2\relax{\toks0 = {#1}}
+
+% \argremovec{,omment} might leave us with trailing spaces, though; e.g.,
+%    @end itemize  @c foo
+% will have two active spaces as part of the argument with the
+% `itemize'.  Here we remove all active spaces from #1, and assign the
+% result to \toks0.
+%
+% This loses if there are any *other* active characters besides spaces
+% in the argument -- _ ^ +, for example -- since they get expanded.
+% Fortunately, Texinfo does not define any such commands.  (If it ever
+% does, the catcode of the characters in questionwill have to be changed
+% here.)  But this means we cannot call \removeactivespaces as part of
+% \argremovec{,omment}, since @c uses \parsearg, and thus the argument
+% that \parsearg gets might well have any character at all in it.
+%
+\def\removeactivespaces#1{%
+  \begingroup
+    \ignoreactivespaces
+    \edef\temp{#1}%
+    \global\toks0 = \expandafter{\temp}%
+  \endgroup
+}
+
+% Change the active space to expand to nothing.
+%
+\begingroup
+  \obeyspaces
+  \gdef\ignoreactivespaces{\obeyspaces\let =\empty}
+\endgroup
+
+
+\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next}
+
+%% These are used to keep @begin/@end levels from running away
+%% Call \inENV within environments (after a \begingroup)
+\newif\ifENV \ENVfalse \def\inENV{\ifENV\relax\else\ENVtrue\fi}
+\def\ENVcheck{%
+\ifENV\errmessage{Still within an environment.  Type Return to continue.}
+\endgroup\fi} % This is not perfect, but it should reduce lossage
+
+% @begin foo  is the same as @foo, for now.
+\newhelp\EMsimple{Type <Return> to continue.}
+
+\outer\def\begin{\parsearg\beginxxx}
+
+\def\beginxxx #1{%
+\expandafter\ifx\csname #1\endcsname\relax
+{\errhelp=\EMsimple \errmessage{Undefined command @begin #1}}\else
+\csname #1\endcsname\fi}
+
+% @end foo executes the definition of \Efoo.
+%
+\def\end{\parsearg\endxxx}
+\def\endxxx #1{%
+  \removeactivespaces{#1}%
+  \edef\endthing{\the\toks0}%
+  %
+  \expandafter\ifx\csname E\endthing\endcsname\relax
+    \expandafter\ifx\csname \endthing\endcsname\relax
+      % There's no \foo, i.e., no ``environment'' foo.
+      \errhelp = \EMsimple
+      \errmessage{Undefined command `@end \endthing'}%
+    \else
+      \unmatchedenderror\endthing
+    \fi
+  \else
+    % Everything's ok; the right environment has been started.
+    \csname E\endthing\endcsname
+  \fi
+}
+
+% There is an environment #1, but it hasn't been started.  Give an error.
+%
+\def\unmatchedenderror#1{%
+  \errhelp = \EMsimple
+  \errmessage{This `@end #1' doesn't have a matching `@#1'}%
+}
+
+% Define the control sequence \E#1 to give an unmatched @end error.
+%
+\def\defineunmatchedend#1{%
+  \expandafter\def\csname E#1\endcsname{\unmatchedenderror{#1}}%
+}
+
+
+% Single-spacing is done by various environments (specifically, in
+% \nonfillstart and \quotations).
+\newskip\singlespaceskip \singlespaceskip = 12.5pt
+\def\singlespace{%
+  % Why was this kern here?  It messes up equalizing space above and below
+  % environments.  --karl, 6may93
+  %{\advance \baselineskip by -\singlespaceskip
+  %\kern \baselineskip}%
+  \setleading \singlespaceskip
+}
+
+%% Simple single-character @ commands
+
+% @@ prints an @
+% Kludge this until the fonts are right (grr).
+\def\@{{\tt \char '100}}
+
+% This is turned off because it was never documented
+% and you can use @w{...} around a quote to suppress ligatures.
+%% Define @` and @' to be the same as ` and '
+%% but suppressing ligatures.
+%\def\`{{`}}
+%\def\'{{'}}
+
+% Used to generate quoted braces.
+\def\mylbrace {{\tt \char '173}}
+\def\myrbrace {{\tt \char '175}}
+\let\{=\mylbrace
+\let\}=\myrbrace
+\begingroup
+  % Definitions to produce actual \{ & \} command in an index.
+  \catcode`\{ = 12 \catcode`\} = 12
+  \catcode`\[ = 1 \catcode`\] = 2
+  \catcode`\@ = 0 \catcode`\\ = 12
+  @gdef@lbracecmd[\{]%
+  @gdef@rbracecmd[\}]%
+@endgroup
+
+% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent
+% Others are defined by plain TeX: @` @' @" @^ @~ @= @v @H.
+\let\, = \c
+\let\dotaccent = \.
+\def\ringaccent#1{{\accent23 #1}}
+\let\tieaccent = \t
+\let\ubaraccent = \b
+\let\udotaccent = \d
+
+% Other special characters: @questiondown @exclamdown
+% Plain TeX defines: @AA @AE @O @OE @L (and lowercase versions) @ss.
+\def\questiondown{?`}
+\def\exclamdown{!`}
+
+% Dotless i and dotless j, used for accents.
+\def\imacro{i}
+\def\jmacro{j}
+\def\dotless#1{%
+  \def\temp{#1}%
+  \ifx\temp\imacro \ptexi
+  \else\ifx\temp\jmacro \j
+  \else \errmessage{@dotless can be used only with i or j}%
+  \fi\fi
+}
+
+% @: forces normal size whitespace following.
+\def\:{\spacefactor=1000 }
+
+% @* forces a line break.
+\def\*{\hfil\break\hbox{}\ignorespaces}
+
+% @. is an end-of-sentence period.
+\def\.{.\spacefactor=3000 }
+
+% @enddots{} is an end-of-sentence ellipsis.
+\gdef\enddots{$\mathinner{\ldotp\ldotp\ldotp\ldotp}$\spacefactor=3000}
+
+% @! is an end-of-sentence bang.
+\gdef\!{!\spacefactor=3000 }
+
+% @? is an end-of-sentence query.
+\gdef\?{?\spacefactor=3000 }
+
+% @w prevents a word break.  Without the \leavevmode, @w at the
+% beginning of a paragraph, when TeX is still in vertical mode, would
+% produce a whole line of output instead of starting the paragraph.
+\def\w#1{\leavevmode\hbox{#1}}
+
+% @group ... @end group forces ... to be all on one page, by enclosing
+% it in a TeX vbox.  We use \vtop instead of \vbox to construct the box
+% to keep its height that of a normal line.  According to the rules for
+% \topskip (p.114 of the TeXbook), the glue inserted is
+% max (\topskip - \ht (first item), 0).  If that height is large,
+% therefore, no glue is inserted, and the space between the headline and
+% the text is small, which looks bad.
+%
+\def\group{\begingroup
+  \ifnum\catcode13=\active \else
+    \errhelp = \groupinvalidhelp
+    \errmessage{@group invalid in context where filling is enabled}%
+  \fi
+  %
+  % The \vtop we start below produces a box with normal height and large
+  % depth; thus, TeX puts \baselineskip glue before it, and (when the
+  % next line of text is done) \lineskip glue after it.  (See p.82 of
+  % the TeXbook.)  Thus, space below is not quite equal to space
+  % above.  But it's pretty close.
+  \def\Egroup{%
+    \egroup           % End the \vtop.
+    \endgroup         % End the \group.
+  }%
+  %
+  \vtop\bgroup
+    % We have to put a strut on the last line in case the @group is in
+    % the midst of an example, rather than completely enclosing it.
+    % Otherwise, the interline space between the last line of the group
+    % and the first line afterwards is too small.  But we can't put the
+    % strut in \Egroup, since there it would be on a line by itself.
+    % Hence this just inserts a strut at the beginning of each line.
+    \everypar = {\strut}%
+    %
+    % Since we have a strut on every line, we don't need any of TeX's
+    % normal interline spacing.
+    \offinterlineskip
+    %
+    % OK, but now we have to do something about blank
+    % lines in the input in @example-like environments, which normally
+    % just turn into \lisppar, which will insert no space now that we've
+    % turned off the interline space.  Simplest is to make them be an
+    % empty paragraph.
+    \ifx\par\lisppar
+      \edef\par{\leavevmode \par}%
+      %
+      % Reset ^^M's definition to new definition of \par.
+      \obeylines
+    \fi
+    %
+    % Do @comment since we are called inside an environment such as
+    % @example, where each end-of-line in the input causes an
+    % end-of-line in the output.  We don't want the end-of-line after
+    % the `@group' to put extra space in the output.  Since @group
+    % should appear on a line by itself (according to the Texinfo
+    % manual), we don't worry about eating any user text.
+    \comment
+}
+%
+% TeX puts in an \escapechar (i.e., `@') at the beginning of the help
+% message, so this ends up printing `@group can only ...'.
+%
+\newhelp\groupinvalidhelp{%
+group can only be used in environments such as @example,^^J%
+where each line of input produces a line of output.}
+
+% @need space-in-mils
+% forces a page break if there is not space-in-mils remaining.
+
+\newdimen\mil  \mil=0.001in
+
+\def\need{\parsearg\needx}
+
+% Old definition--didn't work.
+%\def\needx #1{\par %
+%% This method tries to make TeX break the page naturally
+%% if the depth of the box does not fit.
+%{\baselineskip=0pt%
+%\vtop to #1\mil{\vfil}\kern -#1\mil\penalty 10000
+%\prevdepth=-1000pt
+%}}
+
+\def\needx#1{%
+  % Go into vertical mode, so we don't make a big box in the middle of a
+  % paragraph.
+  \par
+  %
+  % Don't add any leading before our big empty box, but allow a page
+  % break, since the best break might be right here.
+  \allowbreak
+  \nointerlineskip
+  \vtop to #1\mil{\vfil}%
+  %
+  % TeX does not even consider page breaks if a penalty added to the
+  % main vertical list is 10000 or more.  But in order to see if the
+  % empty box we just added fits on the page, we must make it consider
+  % page breaks.  On the other hand, we don't want to actually break the
+  % page after the empty box.  So we use a penalty of 9999.
+  %
+  % There is an extremely small chance that TeX will actually break the
+  % page at this \penalty, if there are no other feasible breakpoints in
+  % sight.  (If the user is using lots of big @group commands, which
+  % almost-but-not-quite fill up a page, TeX will have a hard time doing
+  % good page breaking, for example.)  However, I could not construct an
+  % example where a page broke at this \penalty; if it happens in a real
+  % document, then we can reconsider our strategy.
+  \penalty9999
+  %
+  % Back up by the size of the box, whether we did a page break or not.
+  \kern -#1\mil
+  %
+  % Do not allow a page break right after this kern.
+  \nobreak
+}
+
+% @br   forces paragraph break
+
+\let\br = \par
+
+% @dots{}  output some dots
+
+\def\dots{$\ldots$}
+
+% @page    forces the start of a new page
+
+\def\page{\par\vfill\supereject}
+
+% @exdent text....
+% outputs text on separate line in roman font, starting at standard page margin
+
+% This records the amount of indent in the innermost environment.
+% That's how much \exdent should take out.
+\newskip\exdentamount
+
+% This defn is used inside fill environments such as @defun.
+\def\exdent{\parsearg\exdentyyy}
+\def\exdentyyy #1{{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}}
+
+% This defn is used inside nofill environments such as @example.
+\def\nofillexdent{\parsearg\nofillexdentyyy}
+\def\nofillexdentyyy #1{{\advance \leftskip by -\exdentamount
+\leftline{\hskip\leftskip{\rm#1}}}}
+
+% @inmargin{TEXT} puts TEXT in the margin next to the current paragraph.
+
+\def\inmargin#1{%
+\strut\vadjust{\nobreak\kern-\strutdepth
+  \vtop to \strutdepth{\baselineskip\strutdepth\vss
+  \llap{\rightskip=\inmarginspacing \vbox{\noindent #1}}\null}}}
+\newskip\inmarginspacing \inmarginspacing=1cm
+\def\strutdepth{\dp\strutbox}
+
+%\hbox{{\rm#1}}\hfil\break}}
+
+% @include file    insert text of that file as input.
+% Allow normal characters that  we make active in the argument (a file name).
+\def\include{\begingroup
+  \catcode`\\=12
+  \catcode`~=12
+  \catcode`^=12
+  \catcode`_=12
+  \catcode`|=12
+  \catcode`<=12
+  \catcode`>=12
+  \catcode`+=12
+  \parsearg\includezzz}
+% Restore active chars for included file.
+\def\includezzz#1{\endgroup\begingroup
+  % Read the included file in a group so nested @include's work.
+  \def\thisfile{#1}%
+  \input\thisfile
+\endgroup}
+
+\def\thisfile{}
+
+% @center line   outputs that line, centered
+
+\def\center{\parsearg\centerzzz}
+\def\centerzzz #1{{\advance\hsize by -\leftskip
+\advance\hsize by -\rightskip
+\centerline{#1}}}
+
+% @sp n   outputs n lines of vertical space
+
+\def\sp{\parsearg\spxxx}
+\def\spxxx #1{\vskip #1\baselineskip}
+
+% @comment ...line which is ignored...
+% @c is the same as @comment
+% @ignore ... @end ignore  is another way to write a comment
+
+\def\comment{\catcode 64=\other \catcode 123=\other \catcode 125=\other%
+\parsearg \commentxxx}
+
+\def\commentxxx #1{\catcode 64=0 \catcode 123=1 \catcode 125=2 }
+
+\let\c=\comment
+
+% @paragraphindent  is defined for the Info formatting commands only.
+\let\paragraphindent=\comment
+
+% Prevent errors for section commands.
+% Used in @ignore and in failing conditionals.
+\def\ignoresections{%
+\let\chapter=\relax
+\let\unnumbered=\relax
+\let\top=\relax
+\let\unnumberedsec=\relax
+\let\unnumberedsection=\relax
+\let\unnumberedsubsec=\relax
+\let\unnumberedsubsection=\relax
+\let\unnumberedsubsubsec=\relax
+\let\unnumberedsubsubsection=\relax
+\let\section=\relax
+\let\subsec=\relax
+\let\subsubsec=\relax
+\let\subsection=\relax
+\let\subsubsection=\relax
+\let\appendix=\relax
+\let\appendixsec=\relax
+\let\appendixsection=\relax
+\let\appendixsubsec=\relax
+\let\appendixsubsection=\relax
+\let\appendixsubsubsec=\relax
+\let\appendixsubsubsection=\relax
+\let\contents=\relax
+\let\smallbook=\relax
+\let\titlepage=\relax
+}
+
+% Used in nested conditionals, where we have to parse the Texinfo source
+% and so want to turn off most commands, in case they are used
+% incorrectly.
+%
+\def\ignoremorecommands{%
+  \let\defcodeindex = \relax
+  \let\defcv = \relax
+  \let\deffn = \relax
+  \let\deffnx = \relax
+  \let\defindex = \relax
+  \let\defivar = \relax
+  \let\defmac = \relax
+  \let\defmethod = \relax
+  \let\defop = \relax
+  \let\defopt = \relax
+  \let\defspec = \relax
+  \let\deftp = \relax
+  \let\deftypefn = \relax
+  \let\deftypefun = \relax
+  \let\deftypevar = \relax
+  \let\deftypevr = \relax
+  \let\defun = \relax
+  \let\defvar = \relax
+  \let\defvr = \relax
+  \let\ref = \relax
+  \let\xref = \relax
+  \let\printindex = \relax
+  \let\pxref = \relax
+  \let\settitle = \relax
+  \let\setchapternewpage = \relax
+  \let\setchapterstyle = \relax
+  \let\everyheading = \relax
+  \let\evenheading = \relax
+  \let\oddheading = \relax
+  \let\everyfooting = \relax
+  \let\evenfooting = \relax
+  \let\oddfooting = \relax
+  \let\headings = \relax
+  \let\include = \relax
+  \let\lowersections = \relax
+  \let\down = \relax
+  \let\raisesections = \relax
+  \let\up = \relax
+  \let\set = \relax
+  \let\clear = \relax
+  \let\item = \relax
+}
+
+% Ignore @ignore ... @end ignore.
+%
+\def\ignore{\doignore{ignore}}
+
+% Also ignore @ifinfo, @ifhtml, @html, @menu, and @direntry text.
+%
+\def\ifinfo{\doignore{ifinfo}}
+\def\ifhtml{\doignore{ifhtml}}
+\def\html{\doignore{html}}
+\def\menu{\doignore{menu}}
+\def\direntry{\doignore{direntry}}
+
+% Also ignore @macro ... @end macro.  The user must run texi2dvi,
+% which runs makeinfo to do macro expansion.  Ignore @unmacro, too.
+\def\macro{\doignore{macro}}
+\let\unmacro = \comment
+
+
+% @dircategory CATEGORY  -- specify a category of the dir file
+% which this file should belong to.  Ignore this in TeX.
+\let\dircategory = \comment
+
+% Ignore text until a line `@end #1'.
+%
+\def\doignore#1{\begingroup
+  % Don't complain about control sequences we have declared \outer.
+  \ignoresections
+  %
+  % Define a command to swallow text until we reach `@end #1'.
+  \long\def\doignoretext##1\end #1{\enddoignore}%
+  %
+  % Make sure that spaces turn into tokens that match what \doignoretext wants.
+  \catcode32 = 10
+  %
+  % And now expand that command.
+  \doignoretext
+}
+
+% What we do to finish off ignored text.
+%
+\def\enddoignore{\endgroup\ignorespaces}%
+
+\newif\ifwarnedobs\warnedobsfalse
+\def\obstexwarn{%
+  \ifwarnedobs\relax\else
+  % We need to warn folks that they may have trouble with TeX 3.0.
+  % This uses \immediate\write16 rather than \message to get newlines.
+    \immediate\write16{}
+    \immediate\write16{***WARNING*** for users of Unix TeX 3.0!}
+    \immediate\write16{This manual trips a bug in TeX version 3.0 (tex hangs).}
+    \immediate\write16{If you are running another version of TeX, relax.}
+    \immediate\write16{If you are running Unix TeX 3.0, kill this TeX process.}
+    \immediate\write16{  Then upgrade your TeX installation if you can.}
+    \immediate\write16{  (See ftp://ftp.gnu.ai.mit.edu/pub/gnu/TeX.README.)}
+    \immediate\write16{If you are stuck with version 3.0, run the}
+    \immediate\write16{  script ``tex3patch'' from the Texinfo distribution}
+    \immediate\write16{  to use a workaround.}
+    \immediate\write16{}
+    \global\warnedobstrue
+    \fi
+}
+
+% **In TeX 3.0, setting text in \nullfont hangs tex.  For a
+% workaround (which requires the file ``dummy.tfm'' to be installed),
+% uncomment the following line:
+%%%%%\font\nullfont=dummy\let\obstexwarn=\relax
+
+% Ignore text, except that we keep track of conditional commands for
+% purposes of nesting, up to an `@end #1' command.
+%
+\def\nestedignore#1{%
+  \obstexwarn
+  % We must actually expand the ignored text to look for the @end
+  % command, so that nested ignore constructs work.  Thus, we put the
+  % text into a \vbox and then do nothing with the result.  To minimize
+  % the change of memory overflow, we follow the approach outlined on
+  % page 401 of the TeXbook: make the current font be a dummy font.
+  %
+  \setbox0 = \vbox\bgroup
+    % Don't complain about control sequences we have declared \outer.
+    \ignoresections
+    %
+    % Define `@end #1' to end the box, which will in turn undefine the
+    % @end command again.
+    \expandafter\def\csname E#1\endcsname{\egroup\ignorespaces}%
+    %
+    % We are going to be parsing Texinfo commands.  Most cause no
+    % trouble when they are used incorrectly, but some commands do
+    % complicated argument parsing or otherwise get confused, so we
+    % undefine them.
+    %
+    % We can't do anything about stray @-signs, unfortunately;
+    % they'll produce `undefined control sequence' errors.
+    \ignoremorecommands
+    %
+    % Set the current font to be \nullfont, a TeX primitive, and define
+    % all the font commands to also use \nullfont.  We don't use
+    % dummy.tfm, as suggested in the TeXbook, because not all sites
+    % might have that installed.  Therefore, math mode will still
+    % produce output, but that should be an extremely small amount of
+    % stuff compared to the main input.
+    %
+    \nullfont
+    \let\tenrm = \nullfont  \let\tenit = \nullfont  \let\tensl = \nullfont
+    \let\tenbf = \nullfont  \let\tentt = \nullfont  \let\smallcaps = \nullfont
+    \let\tensf = \nullfont
+    % Similarly for index fonts (mostly for their use in
+    % smallexample)
+    \let\indrm = \nullfont  \let\indit = \nullfont  \let\indsl = \nullfont
+    \let\indbf = \nullfont  \let\indtt = \nullfont  \let\indsc = \nullfont
+    \let\indsf = \nullfont
+    %
+    % Don't complain when characters are missing from the fonts.
+    \tracinglostchars = 0
+    %
+    % Don't bother to do space factor calculations.
+    \frenchspacing
+    %
+    % Don't report underfull hboxes.
+    \hbadness = 10000
+    %
+    % Do minimal line-breaking.
+    \pretolerance = 10000
+    %
+    % Do not execute instructions in @tex
+    \def\tex{\doignore{tex}}
+}
+
+% @set VAR sets the variable VAR to an empty value.
+% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE.
+%
+% Since we want to separate VAR from REST-OF-LINE (which might be
+% empty), we can't just use \parsearg; we have to insert a space of our
+% own to delimit the rest of the line, and then take it out again if we
+% didn't need it.  Make sure the catcode of space is correct to avoid
+% losing inside @example, for instance.
+%
+\def\set{\begingroup\catcode` =10 \parsearg\setxxx}
+\def\setxxx#1{\setyyy#1 \endsetyyy}
+\def\setyyy#1 #2\endsetyyy{%
+  \def\temp{#2}%
+  \ifx\temp\empty \global\expandafter\let\csname SET#1\endcsname = \empty
+  \else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted.
+  \fi
+  \endgroup
+}
+% Can't use \xdef to pre-expand #2 and save some time, since \temp or
+% \next or other control sequences that we've defined might get us into
+% an infinite loop. Consider `@set foo @cite{bar}'.
+\def\setzzz#1#2 \endsetzzz{\expandafter\gdef\csname SET#1\endcsname{#2}}
+
+% @clear VAR clears (i.e., unsets) the variable VAR.
+%
+\def\clear{\parsearg\clearxxx}
+\def\clearxxx#1{\global\expandafter\let\csname SET#1\endcsname=\relax}
+
+% @value{foo} gets the text saved in variable foo.
+%
+\def\value#1{\expandafter
+                \ifx\csname SET#1\endcsname\relax
+                        {\{No value for ``#1''\}}
+                \else \csname SET#1\endcsname \fi}
+
+% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined
+% with @set.
+%
+\def\ifset{\parsearg\ifsetxxx}
+\def\ifsetxxx #1{%
+  \expandafter\ifx\csname SET#1\endcsname\relax
+    \expandafter\ifsetfail
+  \else
+    \expandafter\ifsetsucceed
+  \fi
+}
+\def\ifsetsucceed{\conditionalsucceed{ifset}}
+\def\ifsetfail{\nestedignore{ifset}}
+\defineunmatchedend{ifset}
+
+% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been
+% defined with @set, or has been undefined with @clear.
+%
+\def\ifclear{\parsearg\ifclearxxx}
+\def\ifclearxxx #1{%
+  \expandafter\ifx\csname SET#1\endcsname\relax
+    \expandafter\ifclearsucceed
+  \else
+    \expandafter\ifclearfail
+  \fi
+}
+\def\ifclearsucceed{\conditionalsucceed{ifclear}}
+\def\ifclearfail{\nestedignore{ifclear}}
+\defineunmatchedend{ifclear}
+
+% @iftex always succeeds; we read the text following, through @end
+% iftex).  But `@end iftex' should be valid only after an @iftex.
+%
+\def\iftex{\conditionalsucceed{iftex}}
+\defineunmatchedend{iftex}
+
+% We can't just want to start a group at @iftex (for example) and end it
+% at @end iftex, since then @set commands inside the conditional have no
+% effect (they'd get reverted at the end of the group).  So we must
+% define \Eiftex to redefine itself to be its previous value.  (We can't
+% just define it to fail again with an ``unmatched end'' error, since
+% the @ifset might be nested.)
+%
+\def\conditionalsucceed#1{%
+  \edef\temp{%
+    % Remember the current value of \E#1.
+    \let\nece{prevE#1} = \nece{E#1}%
+    %
+    % At the `@end #1', redefine \E#1 to be its previous value.
+    \def\nece{E#1}{\let\nece{E#1} = \nece{prevE#1}}%
+  }%
+  \temp
+}
+
+% We need to expand lots of \csname's, but we don't want to expand the
+% control sequences after we've constructed them.
+%
+\def\nece#1{\expandafter\noexpand\csname#1\endcsname}
+
+% @asis just yields its argument.  Used with @table, for example.
+%
+\def\asis#1{#1}
+
+% @math means output in math mode.
+% We don't use $'s directly in the definition of \math because control
+% sequences like \math are expanded when the toc file is written.  Then,
+% we read the toc file back, the $'s will be normal characters (as they
+% should be, according to the definition of Texinfo).  So we must use a
+% control sequence to switch into and out of math mode.
+%
+% This isn't quite enough for @math to work properly in indices, but it
+% seems unlikely it will ever be needed there.
+%
+\let\implicitmath = $
+\def\math#1{\implicitmath #1\implicitmath}
+
+% @bullet and @minus need the same treatment as @math, just above.
+\def\bullet{\implicitmath\ptexbullet\implicitmath}
+\def\minus{\implicitmath-\implicitmath}
+
+\def\node{\ENVcheck\parsearg\nodezzz}
+\def\nodezzz#1{\nodexxx [#1,]}
+\def\nodexxx[#1,#2]{\gdef\lastnode{#1}}
+\let\nwnode=\node
+\let\lastnode=\relax
+
+\def\donoderef{\ifx\lastnode\relax\else
+\expandafter\expandafter\expandafter\setref{\lastnode}\fi
+\global\let\lastnode=\relax}
+
+\def\unnumbnoderef{\ifx\lastnode\relax\else
+\expandafter\expandafter\expandafter\unnumbsetref{\lastnode}\fi
+\global\let\lastnode=\relax}
+
+\def\appendixnoderef{\ifx\lastnode\relax\else
+\expandafter\expandafter\expandafter\appendixsetref{\lastnode}\fi
+\global\let\lastnode=\relax}
+
+% @refill is a no-op.
+\let\refill=\relax
+
+% @setfilename is done at the beginning of every texinfo file.
+% So open here the files we need to have open while reading the input.
+% This makes it possible to make a .fmt file for texinfo.
+\def\setfilename{%
+   \readauxfile
+   \opencontents
+   \openindices
+   \fixbackslash  % Turn off hack to swallow `\input texinfo'.
+   \global\let\setfilename=\comment % Ignore extra @setfilename cmds.
+   \comment % Ignore the actual filename.
+}
+
+% @bye.
+\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend}
+
+% \def\macro#1{\begingroup\ignoresections\catcode`\#=6\def\macrotemp{#1}\parsearg\macroxxx}
+% \def\macroxxx#1#2 \end macro{%
+% \expandafter\gdef\macrotemp#1{#2}%
+% \endgroup}
+
+%\def\linemacro#1{\begingroup\ignoresections\catcode`\#=6\def\macrotemp{#1}\parsearg\linemacroxxx}
+%\def\linemacroxxx#1#2 \end linemacro{%
+%\let\parsearg=\relax
+%\edef\macrotempx{\csname M\butfirst\expandafter\string\macrotemp\endcsname}%
+%\expandafter\xdef\macrotemp{\parsearg\macrotempx}%
+%\expandafter\gdef\macrotempx#1{#2}%
+%\endgroup}
+
+%\def\butfirst#1{}
+
+
+\message{fonts,}
+
+% Font-change commands.
+
+% Texinfo supports the sans serif font style, which plain TeX does not.
+% So we set up a \sf analogous to plain's \rm, etc.
+\newfam\sffam
+\def\sf{\fam=\sffam \tensf}
+\let\li = \sf % Sometimes we call it \li, not \sf.
+
+% We don't need math for this one.
+\def\ttsl{\tenttsl}
+
+%% Try out Computer Modern fonts at \magstephalf
+\let\mainmagstep=\magstephalf
+
+% Set the font macro #1 to the font named #2, adding on the
+% specified font prefix (normally `cm').
+% #3 is the font's design size, #4 is a scale factor
+\def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4}
+
+% Use cm as the default font prefix.
+% To specify the font prefix, you must define \fontprefix
+% before you read in texinfo.tex.
+\ifx\fontprefix\undefined
+\def\fontprefix{cm}
+\fi
+% Support font families that don't use the same naming scheme as CM.
+\def\rmshape{r}
+\def\rmbshape{bx}               %where the normal face is bold
+\def\bfshape{b}
+\def\bxshape{bx}
+\def\ttshape{tt}
+\def\ttbshape{tt}
+\def\ttslshape{sltt}
+\def\itshape{ti}
+\def\itbshape{bxti}
+\def\slshape{sl}
+\def\slbshape{bxsl}
+\def\sfshape{ss}
+\def\sfbshape{ss}
+\def\scshape{csc}
+\def\scbshape{csc}
+
+\ifx\bigger\relax
+\let\mainmagstep=\magstep1
+\setfont\textrm\rmshape{12}{1000}
+\setfont\texttt\ttshape{12}{1000}
+\else
+\setfont\textrm\rmshape{10}{\mainmagstep}
+\setfont\texttt\ttshape{10}{\mainmagstep}
+\fi
+% Instead of cmb10, you many want to use cmbx10.
+% cmbx10 is a prettier font on its own, but cmb10
+% looks better when embedded in a line with cmr10.
+\setfont\textbf\bfshape{10}{\mainmagstep}
+\setfont\textit\itshape{10}{\mainmagstep}
+\setfont\textsl\slshape{10}{\mainmagstep}
+\setfont\textsf\sfshape{10}{\mainmagstep}
+\setfont\textsc\scshape{10}{\mainmagstep}
+\setfont\textttsl\ttslshape{10}{\mainmagstep}
+\font\texti=cmmi10 scaled \mainmagstep
+\font\textsy=cmsy10 scaled \mainmagstep
+
+% A few fonts for @defun, etc.
+\setfont\defbf\bxshape{10}{\magstep1} %was 1314
+\setfont\deftt\ttshape{10}{\magstep1}
+\def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf}
+
+% Fonts for indices and small examples (9pt).
+% We actually use the slanted font rather than the italic,
+% because texinfo normally uses the slanted fonts for that.
+% Do not make many font distinctions in general in the index, since they
+% aren't very useful.
+\setfont\ninett\ttshape{9}{1000}
+\setfont\indrm\rmshape{9}{1000}
+\setfont\indit\slshape{9}{1000}
+\let\indsl=\indit
+\let\indtt=\ninett
+\let\indttsl=\ninett
+\let\indsf=\indrm
+\let\indbf=\indrm
+\setfont\indsc\scshape{10}{900}
+\font\indi=cmmi9
+\font\indsy=cmsy9
+
+% Chapter (and unnumbered) fonts (17.28pt).
+\setfont\chaprm\rmbshape{12}{\magstep2}
+\setfont\chapit\itbshape{10}{\magstep3}
+\setfont\chapsl\slbshape{10}{\magstep3}
+\setfont\chaptt\ttbshape{12}{\magstep2}
+\setfont\chapttsl\ttslshape{10}{\magstep3}
+\setfont\chapsf\sfbshape{12}{\magstep2}
+\let\chapbf=\chaprm
+\setfont\chapsc\scbshape{10}{\magstep3}
+\font\chapi=cmmi12 scaled \magstep2
+\font\chapsy=cmsy10 scaled \magstep3
+
+% Section fonts (14.4pt).
+\setfont\secrm\rmbshape{12}{\magstep1}
+\setfont\secit\itbshape{10}{\magstep2}
+\setfont\secsl\slbshape{10}{\magstep2}
+\setfont\sectt\ttbshape{12}{\magstep1}
+\setfont\secttsl\ttslshape{10}{\magstep2}
+\setfont\secsf\sfbshape{12}{\magstep1}
+\let\secbf\secrm
+\setfont\secsc\scbshape{10}{\magstep2}
+\font\seci=cmmi12 scaled \magstep1
+\font\secsy=cmsy10 scaled \magstep2
+
+% \setfont\ssecrm\bxshape{10}{\magstep1}    % This size an font looked bad.
+% \setfont\ssecit\itshape{10}{\magstep1}    % The letters were too crowded.
+% \setfont\ssecsl\slshape{10}{\magstep1}
+% \setfont\ssectt\ttshape{10}{\magstep1}
+% \setfont\ssecsf\sfshape{10}{\magstep1}
+
+%\setfont\ssecrm\bfshape{10}{1315}      % Note the use of cmb rather than cmbx.
+%\setfont\ssecit\itshape{10}{1315}      % Also, the size is a little larger than
+%\setfont\ssecsl\slshape{10}{1315}      % being scaled magstep1.
+%\setfont\ssectt\ttshape{10}{1315}
+%\setfont\ssecsf\sfshape{10}{1315}
+
+%\let\ssecbf=\ssecrm
+
+% Subsection fonts (13.15pt).
+\setfont\ssecrm\rmbshape{12}{\magstephalf}
+\setfont\ssecit\itbshape{10}{1315}
+\setfont\ssecsl\slbshape{10}{1315}
+\setfont\ssectt\ttbshape{12}{\magstephalf}
+\setfont\ssecttsl\ttslshape{10}{\magstep1}
+\setfont\ssecsf\sfbshape{12}{\magstephalf}
+\let\ssecbf\ssecrm
+\setfont\ssecsc\scbshape{10}{\magstep1}
+\font\sseci=cmmi12 scaled \magstephalf
+\font\ssecsy=cmsy10 scaled \magstep1
+% The smallcaps and symbol fonts should actually be scaled \magstep1.5,
+% but that is not a standard magnification.
+
+% Fonts for title page:
+\setfont\titlerm\rmbshape{12}{\magstep3}
+\let\authorrm = \secrm
+
+% In order for the font changes to affect most math symbols and letters,
+% we have to define the \textfont of the standard families.  Since
+% texinfo doesn't allow for producing subscripts and superscripts, we
+% don't bother to reset \scriptfont and \scriptscriptfont (which would
+% also require loading a lot more fonts).
+%
+\def\resetmathfonts{%
+  \textfont0 = \tenrm \textfont1 = \teni \textfont2 = \tensy
+  \textfont\itfam = \tenit \textfont\slfam = \tensl \textfont\bffam = \tenbf
+  \textfont\ttfam = \tentt \textfont\sffam = \tensf
+}
+
+
+% The font-changing commands redefine the meanings of \tenSTYLE, instead
+% of just \STYLE.  We do this so that font changes will continue to work
+% in math mode, where it is the current \fam that is relevant in most
+% cases, not the current font.  Plain TeX does \def\bf{\fam=\bffam
+% \tenbf}, for example.  By redefining \tenbf, we obviate the need to
+% redefine \bf itself.
+\def\textfonts{%
+  \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl
+  \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc
+  \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy \let\tenttsl=\textttsl
+  \resetmathfonts}
+\def\chapfonts{%
+  \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl
+  \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc
+  \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy \let\tenttsl=\chapttsl
+  \resetmathfonts \setleading{19pt}}
+\def\secfonts{%
+  \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl
+  \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc
+  \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy \let\tenttsl=\secttsl
+  \resetmathfonts \setleading{16pt}}
+\def\subsecfonts{%
+  \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl
+  \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc
+  \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy \let\tenttsl=\ssecttsl
+  \resetmathfonts \setleading{15pt}}
+\let\subsubsecfonts = \subsecfonts % Maybe make sssec fonts scaled magstephalf?
+\def\indexfonts{%
+  \let\tenrm=\indrm \let\tenit=\indit \let\tensl=\indsl
+  \let\tenbf=\indbf \let\tentt=\indtt \let\smallcaps=\indsc
+  \let\tensf=\indsf \let\teni=\indi \let\tensy=\indsy \let\tenttsl=\indttsl
+  \resetmathfonts \setleading{12pt}}
+
+% Set up the default fonts, so we can use them for creating boxes.
+%
+\textfonts
+
+% Count depth in font-changes, for error checks
+\newcount\fontdepth \fontdepth=0
+
+% Fonts for short table of contents.
+\setfont\shortcontrm\rmshape{12}{1000}
+\setfont\shortcontbf\bxshape{12}{1000}
+\setfont\shortcontsl\slshape{12}{1000}
+
+%% Add scribe-like font environments, plus @l for inline lisp (usually sans
+%% serif) and @ii for TeX italic
+
+% \smartitalic{ARG} outputs arg in italics, followed by an italic correction
+% unless the following character is such as not to need one.
+\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else\/\fi\fi\fi}
+\def\smartitalic#1{{\sl #1}\futurelet\next\smartitalicx}
+
+\let\i=\smartitalic
+\let\var=\smartitalic
+\let\dfn=\smartitalic
+\let\emph=\smartitalic
+\let\cite=\smartitalic
+
+\def\b#1{{\bf #1}}
+\let\strong=\b
+
+% We can't just use \exhyphenpenalty, because that only has effect at
+% the end of a paragraph.  Restore normal hyphenation at the end of the
+% group within which \nohyphenation is presumably called.
+%
+\def\nohyphenation{\hyphenchar\font = -1  \aftergroup\restorehyphenation}
+\def\restorehyphenation{\hyphenchar\font = `- }
+
+\def\t#1{%
+  {\tt \rawbackslash \frenchspacing #1}%
+  \null
+}
+\let\ttfont=\t
+\def\samp #1{`\tclose{#1}'\null}
+\setfont\smallrm\rmshape{8}{1000}
+\font\smallsy=cmsy9
+\def\key#1{{\smallrm\textfont2=\smallsy \leavevmode\hbox{%
+  \raise0.4pt\hbox{$\langle$}\kern-.08em\vtop{%
+    \vbox{\hrule\kern-0.4pt
+     \hbox{\raise0.4pt\hbox{\vphantom{$\langle$}}#1}}%
+    \kern-0.4pt\hrule}%
+  \kern-.06em\raise0.4pt\hbox{$\rangle$}}}}
+% The old definition, with no lozenge:
+%\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null}
+\def\ctrl #1{{\tt \rawbackslash \hat}#1}
+
+\let\file=\samp
+\let\url=\samp % perhaps include a hypertex \special eventually
+\def\email#1{$\langle${\tt #1}$\rangle$}
+
+% @code is a modification of @t,
+% which makes spaces the same size as normal in the surrounding text.
+\def\tclose#1{%
+  {%
+    % Change normal interword space to be same as for the current font.
+    \spaceskip = \fontdimen2\font
+    %
+    % Switch to typewriter.
+    \tt
+    %
+    % But `\ ' produces the large typewriter interword space.
+    \def\ {{\spaceskip = 0pt{} }}%
+    %
+    % Turn off hyphenation.
+    \nohyphenation
+    %
+    \rawbackslash
+    \frenchspacing
+    #1%
+  }%
+  \null
+}
+
+% We *must* turn on hyphenation at `-' and `_' in \code.
+% Otherwise, it is too hard to avoid overfull hboxes
+% in the Emacs manual, the Library manual, etc.
+
+% Unfortunately, TeX uses one parameter (\hyphenchar) to control
+% both hyphenation at - and hyphenation within words.
+% We must therefore turn them both off (\tclose does that)
+% and arrange explicitly to hyphenate at a dash.
+%  -- rms.
+{
+\catcode`\-=\active
+\catcode`\_=\active
+\global\def\code{\begingroup \catcode`\-=\active \let-\codedash \catcode`\_=\active \let_\codeunder \codex}
+% The following is used by \doprintindex to insure that long function names
+% wrap around.  It is necessary for - and _ to be active before the index is
+% read from the file, as \entry parses the arguments long before \code is
+% ever called.  -- mycroft
+\global\def\indexbreaks{\catcode`\-=\active \let-\realdash \catcode`\_=\active \let_\realunder}
+}
+
+\def\realdash{-}
+\def\realunder{_}
+\def\codedash{-\discretionary{}{}{}}
+\def\codeunder{\normalunderscore\discretionary{}{}{}}
+\def\codex #1{\tclose{#1}\endgroup}
+
+%\let\exp=\tclose  %Was temporary
+
+% @kbd is like @code, except that if the argument is just one @key command,
+% then @kbd has no effect.
+%
+\def\xkey{\key}
+\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}%
+\ifx\one\xkey\ifx\threex\three \key{#2}%
+\else{\tclose{\ttsl\look}}\fi
+\else{\tclose{\ttsl\look}}\fi}
+
+% Check if we are currently using a typewriter font.  Since all the
+% Computer Modern typewriter fonts have zero interword stretch (and
+% shrink), and it is reasonable to expect all typewriter fonts to have
+% this property, we can check that font parameter.
+% 
+\def\ifmonospace{\ifdim\fontdimen3\font=0pt }
+
+% Typeset a dimension, e.g., `in' or `pt'.  The only reason for the
+% argument is to make the input look right: @dmn{pt} instead of
+% @dmn{}pt.
+%
+\def\dmn#1{\thinspace #1}
+
+\def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par}
+
+% @l was never documented to mean ``switch to the Lisp font'',
+% and it is not used as such in any manual I can find.  We need it for
+% Polish suppressed-l.  --karl, 22sep96.
+%\def\l#1{{\li #1}\null}
+
+\def\r#1{{\rm #1}}              % roman font
+% Use of \lowercase was suggested.
+\def\sc#1{{\smallcaps#1}}       % smallcaps font
+\def\ii#1{{\it #1}}             % italic font
+
+% @pounds{} is a sterling sign.
+\def\pounds{{\it\$}}
+
+
+\message{page headings,}
+
+\newskip\titlepagetopglue \titlepagetopglue = 1.5in
+\newskip\titlepagebottomglue \titlepagebottomglue = 2pc
+
+% First the title page.  Must do @settitle before @titlepage.
+\def\titlefont#1{{\titlerm #1}}
+
+\newif\ifseenauthor
+\newif\iffinishedtitlepage
+
+\def\shorttitlepage{\parsearg\shorttitlepagezzz}
+\def\shorttitlepagezzz #1{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}%
+        \endgroup\page\hbox{}\page}
+
+\def\titlepage{\begingroup \parindent=0pt \textfonts
+   \let\subtitlerm=\tenrm
+% I deinstalled the following change because \cmr12 is undefined.
+% This change was not in the ChangeLog anyway.  --rms.
+%   \let\subtitlerm=\cmr12
+   \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}%
+   %
+   \def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines}%
+   %
+   % Leave some space at the very top of the page.
+   \vglue\titlepagetopglue
+   %
+   % Now you can print the title using @title.
+   \def\title{\parsearg\titlezzz}%
+   \def\titlezzz##1{\leftline{\titlefont{##1}}
+                    % print a rule at the page bottom also.
+                    \finishedtitlepagefalse
+                    \vskip4pt \hrule height 4pt width \hsize \vskip4pt}%
+   % No rule at page bottom unless we print one at the top with @title.
+   \finishedtitlepagetrue
+   %
+   % Now you can put text using @subtitle.
+   \def\subtitle{\parsearg\subtitlezzz}%
+   \def\subtitlezzz##1{{\subtitlefont \rightline{##1}}}%
+   %
+   % @author should come last, but may come many times.
+   \def\author{\parsearg\authorzzz}%
+   \def\authorzzz##1{\ifseenauthor\else\vskip 0pt plus 1filll\seenauthortrue\fi
+      {\authorfont \leftline{##1}}}%
+   %
+   % Most title ``pages'' are actually two pages long, with space
+   % at the top of the second.  We don't want the ragged left on the second.
+   \let\oldpage = \page
+   \def\page{%
+      \iffinishedtitlepage\else
+         \finishtitlepage
+      \fi
+      \oldpage
+      \let\page = \oldpage
+      \hbox{}}%
+%   \def\page{\oldpage \hbox{}}
+}
+
+\def\Etitlepage{%
+   \iffinishedtitlepage\else
+      \finishtitlepage
+   \fi
+   % It is important to do the page break before ending the group,
+   % because the headline and footline are only empty inside the group.
+   % If we use the new definition of \page, we always get a blank page
+   % after the title page, which we certainly don't want.
+   \oldpage
+   \endgroup
+   \HEADINGSon
+}
+
+\def\finishtitlepage{%
+   \vskip4pt \hrule height 2pt width \hsize
+   \vskip\titlepagebottomglue
+   \finishedtitlepagetrue
+}
+
+%%% Set up page headings and footings.
+
+\let\thispage=\folio
+
+\newtoks \evenheadline    % Token sequence for heading line of even pages
+\newtoks \oddheadline     % Token sequence for heading line of odd pages
+\newtoks \evenfootline    % Token sequence for footing line of even pages
+\newtoks \oddfootline     % Token sequence for footing line of odd pages
+
+% Now make Tex use those variables
+\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline
+                            \else \the\evenheadline \fi}}
+\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline
+                            \else \the\evenfootline \fi}\HEADINGShook}
+\let\HEADINGShook=\relax
+
+% Commands to set those variables.
+% For example, this is what  @headings on  does
+% @evenheading @thistitle|@thispage|@thischapter
+% @oddheading @thischapter|@thispage|@thistitle
+% @evenfooting @thisfile||
+% @oddfooting ||@thisfile
+
+\def\evenheading{\parsearg\evenheadingxxx}
+\def\oddheading{\parsearg\oddheadingxxx}
+\def\everyheading{\parsearg\everyheadingxxx}
+
+\def\evenfooting{\parsearg\evenfootingxxx}
+\def\oddfooting{\parsearg\oddfootingxxx}
+\def\everyfooting{\parsearg\everyfootingxxx}
+
+{\catcode`\@=0 %
+
+\gdef\evenheadingxxx #1{\evenheadingyyy #1@|@|@|@|\finish}
+\gdef\evenheadingyyy #1@|#2@|#3@|#4\finish{%
+\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\gdef\oddheadingxxx #1{\oddheadingyyy #1@|@|@|@|\finish}
+\gdef\oddheadingyyy #1@|#2@|#3@|#4\finish{%
+\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\gdef\everyheadingxxx #1{\everyheadingyyy #1@|@|@|@|\finish}
+\gdef\everyheadingyyy #1@|#2@|#3@|#4\finish{%
+\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}
+\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\gdef\evenfootingxxx #1{\evenfootingyyy #1@|@|@|@|\finish}
+\gdef\evenfootingyyy #1@|#2@|#3@|#4\finish{%
+\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\gdef\oddfootingxxx #1{\oddfootingyyy #1@|@|@|@|\finish}
+\gdef\oddfootingyyy #1@|#2@|#3@|#4\finish{%
+\global\oddfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\gdef\everyfootingxxx #1{\everyfootingyyy #1@|@|@|@|\finish}
+\gdef\everyfootingyyy #1@|#2@|#3@|#4\finish{%
+\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}
+\global\oddfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+%
+}% unbind the catcode of @.
+
+% @headings double      turns headings on for double-sided printing.
+% @headings single      turns headings on for single-sided printing.
+% @headings off         turns them off.
+% @headings on          same as @headings double, retained for compatibility.
+% @headings after       turns on double-sided headings after this page.
+% @headings doubleafter turns on double-sided headings after this page.
+% @headings singleafter turns on single-sided headings after this page.
+% By default, they are off at the start of a document,
+% and turned `on' after @end titlepage.
+
+\def\headings #1 {\csname HEADINGS#1\endcsname}
+
+\def\HEADINGSoff{
+\global\evenheadline={\hfil} \global\evenfootline={\hfil}
+\global\oddheadline={\hfil} \global\oddfootline={\hfil}}
+\HEADINGSoff
+% When we turn headings on, set the page number to 1.
+% For double-sided printing, put current file name in lower left corner,
+% chapter name on inside top of right hand pages, document
+% title on inside top of left hand pages, and page numbers on outside top
+% edge of all pages.
+\def\HEADINGSdouble{
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
+}
+\let\contentsalignmacro = \chappager
+
+% For single-sided printing, chapter title goes across top left of page,
+% page number on top right.
+\def\HEADINGSsingle{
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
+}
+\def\HEADINGSon{\HEADINGSdouble}
+
+\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex}
+\let\HEADINGSdoubleafter=\HEADINGSafter
+\def\HEADINGSdoublex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
+}
+
+\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex}
+\def\HEADINGSsinglex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
+}
+
+% Subroutines used in generating headings
+% Produces Day Month Year style of output.
+\def\today{\number\day\space
+\ifcase\month\or
+January\or February\or March\or April\or May\or June\or
+July\or August\or September\or October\or November\or December\fi
+\space\number\year}
+
+% Use this if you want the Month Day, Year style of output.
+%\def\today{\ifcase\month\or
+%January\or February\or March\or April\or May\or June\or
+%July\or August\or September\or October\or November\or December\fi
+%\space\number\day, \number\year}
+
+% @settitle line...  specifies the title of the document, for headings
+% It generates no output of its own
+
+\def\thistitle{No Title}
+\def\settitle{\parsearg\settitlezzz}
+\def\settitlezzz #1{\gdef\thistitle{#1}}
+
+
+\message{tables,}
+
+% @tabs -- simple alignment
+
+% These don't work.  For one thing, \+ is defined as outer.
+% So these macros cannot even be defined.
+
+%\def\tabs{\parsearg\tabszzz}
+%\def\tabszzz #1{\settabs\+#1\cr}
+%\def\tabline{\parsearg\tablinezzz}
+%\def\tablinezzz #1{\+#1\cr}
+%\def\&{&}
+
+% Tables -- @table, @ftable, @vtable, @item(x), @kitem(x), @xitem(x).
+
+% default indentation of table text
+\newdimen\tableindent \tableindent=.8in
+% default indentation of @itemize and @enumerate text
+\newdimen\itemindent  \itemindent=.3in
+% margin between end of table item and start of table text.
+\newdimen\itemmargin  \itemmargin=.1in
+
+% used internally for \itemindent minus \itemmargin
+\newdimen\itemmax
+
+% Note @table, @vtable, and @vtable define @item, @itemx, etc., with
+% these defs.
+% They also define \itemindex
+% to index the item name in whatever manner is desired (perhaps none).
+
+\newif\ifitemxneedsnegativevskip
+
+\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi}
+
+\def\internalBitem{\smallbreak \parsearg\itemzzz}
+\def\internalBitemx{\itemxpar \parsearg\itemzzz}
+
+\def\internalBxitem "#1"{\def\xitemsubtopix{#1} \smallbreak \parsearg\xitemzzz}
+\def\internalBxitemx "#1"{\def\xitemsubtopix{#1} \itemxpar \parsearg\xitemzzz}
+
+\def\internalBkitem{\smallbreak \parsearg\kitemzzz}
+\def\internalBkitemx{\itemxpar \parsearg\kitemzzz}
+
+\def\kitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \lastfunction}}%
+                 \itemzzz {#1}}
+
+\def\xitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \xitemsubtopic}}%
+                 \itemzzz {#1}}
+
+\def\itemzzz #1{\begingroup %
+  \advance\hsize by -\rightskip
+  \advance\hsize by -\tableindent
+  \setbox0=\hbox{\itemfont{#1}}%
+  \itemindex{#1}%
+  \nobreak % This prevents a break before @itemx.
+  %
+  % Be sure we are not still in the middle of a paragraph.
+  %{\parskip = 0in
+  %\par
+  %}%
+  %
+  % If the item text does not fit in the space we have, put it on a line
+  % by itself, and do not allow a page break either before or after that
+  % line.  We do not start a paragraph here because then if the next
+  % command is, e.g., @kindex, the whatsit would get put into the
+  % horizontal list on a line by itself, resulting in extra blank space.
+  \ifdim \wd0>\itemmax
+    %
+    % Make this a paragraph so we get the \parskip glue and wrapping,
+    % but leave it ragged-right.
+    \begingroup
+      \advance\leftskip by-\tableindent
+      \advance\hsize by\tableindent
+      \advance\rightskip by0pt plus1fil
+      \leavevmode\unhbox0\par
+    \endgroup
+    %
+    % We're going to be starting a paragraph, but we don't want the
+    % \parskip glue -- logically it's part of the @item we just started.
+    \nobreak \vskip-\parskip
+    %
+    % Stop a page break at the \parskip glue coming up.  Unfortunately
+    % we can't prevent a possible page break at the following
+    % \baselineskip glue.
+    \nobreak
+    \endgroup
+    \itemxneedsnegativevskipfalse
+  \else
+    % The item text fits into the space.  Start a paragraph, so that the
+    % following text (if any) will end up on the same line.  Since that
+    % text will be indented by \tableindent, we make the item text be in
+    % a zero-width box.
+    \noindent
+    \rlap{\hskip -\tableindent\box0}\ignorespaces%
+    \endgroup%
+    \itemxneedsnegativevskiptrue%
+  \fi
+}
+
+\def\item{\errmessage{@item while not in a table}}
+\def\itemx{\errmessage{@itemx while not in a table}}
+\def\kitem{\errmessage{@kitem while not in a table}}
+\def\kitemx{\errmessage{@kitemx while not in a table}}
+\def\xitem{\errmessage{@xitem while not in a table}}
+\def\xitemx{\errmessage{@xitemx while not in a table}}
+
+%% Contains a kludge to get @end[description] to work
+\def\description{\tablez{\dontindex}{1}{}{}{}{}}
+
+\def\table{\begingroup\inENV\obeylines\obeyspaces\tablex}
+{\obeylines\obeyspaces%
+\gdef\tablex #1^^M{%
+\tabley\dontindex#1        \endtabley}}
+
+\def\ftable{\begingroup\inENV\obeylines\obeyspaces\ftablex}
+{\obeylines\obeyspaces%
+\gdef\ftablex #1^^M{%
+\tabley\fnitemindex#1        \endtabley
+\def\Eftable{\endgraf\afterenvbreak\endgroup}%
+\let\Etable=\relax}}
+
+\def\vtable{\begingroup\inENV\obeylines\obeyspaces\vtablex}
+{\obeylines\obeyspaces%
+\gdef\vtablex #1^^M{%
+\tabley\vritemindex#1        \endtabley
+\def\Evtable{\endgraf\afterenvbreak\endgroup}%
+\let\Etable=\relax}}
+
+\def\dontindex #1{}
+\def\fnitemindex #1{\doind {fn}{\code{#1}}}%
+\def\vritemindex #1{\doind {vr}{\code{#1}}}%
+
+{\obeyspaces %
+\gdef\tabley#1#2 #3 #4 #5 #6 #7\endtabley{\endgroup%
+\tablez{#1}{#2}{#3}{#4}{#5}{#6}}}
+
+\def\tablez #1#2#3#4#5#6{%
+\aboveenvbreak %
+\begingroup %
+\def\Edescription{\Etable}% Necessary kludge.
+\let\itemindex=#1%
+\ifnum 0#3>0 \advance \leftskip by #3\mil \fi %
+\ifnum 0#4>0 \tableindent=#4\mil \fi %
+\ifnum 0#5>0 \advance \rightskip by #5\mil \fi %
+\def\itemfont{#2}%
+\itemmax=\tableindent %
+\advance \itemmax by -\itemmargin %
+\advance \leftskip by \tableindent %
+\exdentamount=\tableindent
+\parindent = 0pt
+\parskip = \smallskipamount
+\ifdim \parskip=0pt \parskip=2pt \fi%
+\def\Etable{\endgraf\afterenvbreak\endgroup}%
+\let\item = \internalBitem %
+\let\itemx = \internalBitemx %
+\let\kitem = \internalBkitem %
+\let\kitemx = \internalBkitemx %
+\let\xitem = \internalBxitem %
+\let\xitemx = \internalBxitemx %
+}
+
+% This is the counter used by @enumerate, which is really @itemize
+
+\newcount \itemno
+
+\def\itemize{\parsearg\itemizezzz}
+
+\def\itemizezzz #1{%
+  \begingroup % ended by the @end itemsize
+  \itemizey {#1}{\Eitemize}
+}
+
+\def\itemizey #1#2{%
+\aboveenvbreak %
+\itemmax=\itemindent %
+\advance \itemmax by -\itemmargin %
+\advance \leftskip by \itemindent %
+\exdentamount=\itemindent
+\parindent = 0pt %
+\parskip = \smallskipamount %
+\ifdim \parskip=0pt \parskip=2pt \fi%
+\def#2{\endgraf\afterenvbreak\endgroup}%
+\def\itemcontents{#1}%
+\let\item=\itemizeitem}
+
+% Set sfcode to normal for the chars that usually have another value.
+% These are `.?!:;,'
+\def\frenchspacing{\sfcode46=1000 \sfcode63=1000 \sfcode33=1000
+  \sfcode58=1000 \sfcode59=1000 \sfcode44=1000 }
+
+% \splitoff TOKENS\endmark defines \first to be the first token in
+% TOKENS, and \rest to be the remainder.
+%
+\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}%
+
+% Allow an optional argument of an uppercase letter, lowercase letter,
+% or number, to specify the first label in the enumerated list.  No
+% argument is the same as `1'.
+%
+\def\enumerate{\parsearg\enumeratezzz}
+\def\enumeratezzz #1{\enumeratey #1  \endenumeratey}
+\def\enumeratey #1 #2\endenumeratey{%
+  \begingroup % ended by the @end enumerate
+  %
+  % If we were given no argument, pretend we were given `1'.
+  \def\thearg{#1}%
+  \ifx\thearg\empty \def\thearg{1}\fi
+  %
+  % Detect if the argument is a single token.  If so, it might be a
+  % letter.  Otherwise, the only valid thing it can be is a number.
+  % (We will always have one token, because of the test we just made.
+  % This is a good thing, since \splitoff doesn't work given nothing at
+  % all -- the first parameter is undelimited.)
+  \expandafter\splitoff\thearg\endmark
+  \ifx\rest\empty
+    % Only one token in the argument.  It could still be anything.
+    % A ``lowercase letter'' is one whose \lccode is nonzero.
+    % An ``uppercase letter'' is one whose \lccode is both nonzero, and
+    %   not equal to itself.
+    % Otherwise, we assume it's a number.
+    %
+    % We need the \relax at the end of the \ifnum lines to stop TeX from
+    % continuing to look for a <number>.
+    %
+    \ifnum\lccode\expandafter`\thearg=0\relax
+      \numericenumerate % a number (we hope)
+    \else
+      % It's a letter.
+      \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax
+        \lowercaseenumerate % lowercase letter
+      \else
+        \uppercaseenumerate % uppercase letter
+      \fi
+    \fi
+  \else
+    % Multiple tokens in the argument.  We hope it's a number.
+    \numericenumerate
+  \fi
+}
+
+% An @enumerate whose labels are integers.  The starting integer is
+% given in \thearg.
+%
+\def\numericenumerate{%
+  \itemno = \thearg
+  \startenumeration{\the\itemno}%
+}
+
+% The starting (lowercase) letter is in \thearg.
+\def\lowercaseenumerate{%
+  \itemno = \expandafter`\thearg
+  \startenumeration{%
+    % Be sure we're not beyond the end of the alphabet.
+    \ifnum\itemno=0
+      \errmessage{No more lowercase letters in @enumerate; get a bigger
+                  alphabet}%
+    \fi
+    \char\lccode\itemno
+  }%
+}
+
+% The starting (uppercase) letter is in \thearg.
+\def\uppercaseenumerate{%
+  \itemno = \expandafter`\thearg
+  \startenumeration{%
+    % Be sure we're not beyond the end of the alphabet.
+    \ifnum\itemno=0
+      \errmessage{No more uppercase letters in @enumerate; get a bigger
+                  alphabet}
+    \fi
+    \char\uccode\itemno
+  }%
+}
+
+% Call itemizey, adding a period to the first argument and supplying the
+% common last two arguments.  Also subtract one from the initial value in
+% \itemno, since @item increments \itemno.
+%
+\def\startenumeration#1{%
+  \advance\itemno by -1
+  \itemizey{#1.}\Eenumerate\flushcr
+}
+
+% @alphaenumerate and @capsenumerate are abbreviations for giving an arg
+% to @enumerate.
+%
+\def\alphaenumerate{\enumerate{a}}
+\def\capsenumerate{\enumerate{A}}
+\def\Ealphaenumerate{\Eenumerate}
+\def\Ecapsenumerate{\Eenumerate}
+
+% Definition of @item while inside @itemize.
+
+\def\itemizeitem{%
+\advance\itemno by 1
+{\let\par=\endgraf \smallbreak}%
+\ifhmode \errmessage{\in hmode at itemizeitem}\fi
+{\parskip=0in \hskip 0pt
+\hbox to 0pt{\hss \itemcontents\hskip \itemmargin}%
+\vadjust{\penalty 1200}}%
+\flushcr}
+
+% @multitable macros
+% Amy Hendrickson, 8/18/94, 3/6/96
+%
+% @multitable ... @end multitable will make as many columns as desired.
+% Contents of each column will wrap at width given in preamble.  Width
+% can be specified either with sample text given in a template line,
+% or in percent of \hsize, the current width of text on page.
+
+% Table can continue over pages but will only break between lines.
+
+% To make preamble:
+%
+% Either define widths of columns in terms of percent of \hsize: 
+%   @multitable @columnfractions .25 .3 .45
+%   @item ...
+%
+%   Numbers following @columnfractions are the percent of the total
+%   current hsize to be used for each column. You may use as many
+%   columns as desired.
+
+
+% Or use a template:
+%   @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+%   @item ...
+%   using the widest term desired in each column.
+%
+% For those who want to use more than one line's worth of words in
+% the preamble, break the line within one argument and it
+% will parse correctly, i.e.,
+%
+%     @multitable {Column 1 template} {Column 2 template} {Column 3 
+%      template}
+% Not:
+%     @multitable {Column 1 template} {Column 2 template} 
+%      {Column 3 template}
+
+% Each new table line starts with @item, each subsequent new column 
+% starts with @tab. Empty columns may be produced by supplying @tab's
+% with nothing between them for as many times as empty columns are needed,
+% ie, @tab@tab@tab will produce two empty columns.
+
+% @item, @tab, @multitable or @end multitable do not need to be on their
+% own lines, but it will not hurt if they are.
+
+% Sample multitable:
+
+%   @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+%   @item first col stuff @tab second col stuff @tab third col
+%   @item 
+%   first col stuff 
+%   @tab 
+%   second col stuff 
+%   @tab 
+%   third col 
+%   @item first col stuff @tab second col stuff 
+%   @tab Many paragraphs of text may be used in any column.
+%     
+%         They will wrap at the width determined by the template.
+%   @item@tab@tab This will be in third column.
+%   @end multitable
+
+% Default dimensions may be reset by user.
+% @multitableparskip is vertical space between paragraphs in table.
+% @multitableparindent is paragraph indent in table.
+% @multitablecolmargin is horizontal space to be left between columns.
+% @multitablelinespace is space to leave between table items, baseline
+%                                                            to baseline.
+%   0pt means it depends on current normal line spacing.
+
+%%%%
+% Dimensions 
+
+\newskip\multitableparskip
+\newskip\multitableparindent
+\newdimen\multitablecolspace
+\newskip\multitablelinespace
+\multitableparskip=0pt
+\multitableparindent=6pt
+\multitablecolspace=12pt
+\multitablelinespace=0pt
+
+%%%%
+% Macros used to set up halign preamble:
+\let\endsetuptable\relax
+\def\xendsetuptable{\endsetuptable}
+\let\columnfractions\relax
+\def\xcolumnfractions{\columnfractions}
+\newif\ifsetpercent
+
+%% 2/1/96, to allow fractions to be given with more than one digit.
+\def\pickupwholefraction#1 {\global\advance\colcount by1 %
+\expandafter\xdef\csname col\the\colcount\endcsname{.#1\hsize}%
+\setuptable}
+
+\newcount\colcount
+\def\setuptable#1{\def\firstarg{#1}%
+\ifx\firstarg\xendsetuptable\let\go\relax%
+\else
+  \ifx\firstarg\xcolumnfractions\global\setpercenttrue%
+  \else
+    \ifsetpercent
+       \let\go\pickupwholefraction   % In this case arg of setuptable
+                                     % is the decimal point before the
+                                     % number given in percent of hsize.
+                                     % We don't need this so we don't use it.
+    \else
+       \global\advance\colcount by1
+       \setbox0=\hbox{#1 }% Add a normal word space as a separator;
+                          % typically that is always in the input, anyway.
+       \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}%
+    \fi%
+  \fi%
+\ifx\go\pickupwholefraction\else\let\go\setuptable\fi%
+\fi\go}
+
+%%%%
+% multitable syntax
+\def\tab{&\hskip1sp\relax} % 2/2/96
+                           % tiny skip here makes sure this column space is
+                           % maintained, even if it is never used.
+
+
+%%%%
+% @multitable ... @end multitable definitions:
+
+\def\multitable{\parsearg\dotable}
+
+\def\dotable#1{\bgroup
+\let\item\cr
+\tolerance=9500
+\hbadness=9500
+\setmultitablespacing
+\parskip=\multitableparskip
+\parindent=\multitableparindent
+\overfullrule=0pt
+\global\colcount=0\relax%
+\def\Emultitable{\global\setpercentfalse\global\everycr{}\cr\egroup\egroup}%
+ % To parse everything between @multitable and @item :
+\setuptable#1 \endsetuptable
+ % Need to reset this to 0 after \setuptable.
+\global\colcount=0\relax% 
+ %
+ % This preamble sets up a generic column definition, which will
+ % be used as many times as user calls for columns.
+ % \vtop will set a single line and will also let text wrap and 
+ % continue for many paragraphs if desired.
+\halign\bgroup&\global\advance\colcount by 1\relax%
+\multistrut\vtop{\hsize=\expandafter\csname col\the\colcount\endcsname
+ % In order to keep entries from bumping into each other
+ % we will add a \leftskip of \multitablecolspace to all columns after
+ % the first one.
+ %  If a template has been used, we will add \multitablecolspace 
+ % to the width of each template entry.
+ %  If user has set preamble in terms of percent of \hsize
+ % we will use that dimension as the width of the column, and
+ % the \leftskip will keep entries from bumping into each other.
+ % Table will start at left margin and final column will justify at
+ % right margin.
+\ifnum\colcount=1
+\else
+  \ifsetpercent
+  \else
+   % If user has <not> set preamble in terms of percent of \hsize
+   % we will advance \hsize by \multitablecolspace 
+  \advance\hsize by \multitablecolspace
+  \fi
+ % In either case we will make \leftskip=\multitablecolspace:
+\leftskip=\multitablecolspace
+\fi
+\noindent##\multistrut}\cr%
+ % \everycr will reset column counter, \colcount, at the end of
+ % each line. Every column  entry will cause \colcount to advance by one. 
+ % The table preamble
+ % looks at the current \colcount to find the correct column width.
+\global\everycr{\noalign{%
+\filbreak%% keeps underfull box messages off when table breaks over pages.
+\global\colcount=0\relax}}
+}
+
+\def\setmultitablespacing{% test to see if user has set \multitablelinespace.
+% If so, do nothing. If not, give it an appropriate dimension based on
+% current baselineskip.
+\ifdim\multitablelinespace=0pt
+%% strut to put in table in case some entry doesn't have descenders,
+%% to keep lines equally spaced
+\let\multistrut = \strut
+%% Test to see if parskip is larger than space between lines of
+%% table. If not, do nothing. 
+%%        If so, set to same dimension as multitablelinespace.
+\else
+\gdef\multistrut{\vrule height\multitablelinespace depth\dp0
+width0pt\relax} \fi
+\ifdim\multitableparskip>\multitablelinespace
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
+                                      %% than skip between lines in the table.
+\fi%
+\ifdim\multitableparskip=0pt
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
+                                      %% than skip between lines in the table.
+\fi}
+
+
+\message{indexing,}
+% Index generation facilities
+
+% Define \newwrite to be identical to plain tex's \newwrite
+% except not \outer, so it can be used within \newindex.
+{\catcode`\@=11
+\gdef\newwrite{\alloc@7\write\chardef\sixt@@n}}
+
+% \newindex {foo} defines an index named foo.
+% It automatically defines \fooindex such that
+% \fooindex ...rest of line... puts an entry in the index foo.
+% It also defines \fooindfile to be the number of the output channel for
+% the file that accumulates this index.  The file's extension is foo.
+% The name of an index should be no more than 2 characters long
+% for the sake of vms.
+
+\def\newindex #1{
+\expandafter\newwrite \csname#1indfile\endcsname% Define number for output file
+\openout \csname#1indfile\endcsname \jobname.#1 % Open the file
+\expandafter\xdef\csname#1index\endcsname{%     % Define \xxxindex
+\noexpand\doindex {#1}}
+}
+
+% @defindex foo  ==  \newindex{foo}
+
+\def\defindex{\parsearg\newindex}
+
+% Define @defcodeindex, like @defindex except put all entries in @code.
+
+\def\newcodeindex #1{
+\expandafter\newwrite \csname#1indfile\endcsname% Define number for output file
+\openout \csname#1indfile\endcsname \jobname.#1 % Open the file
+\expandafter\xdef\csname#1index\endcsname{%     % Define \xxxindex
+\noexpand\docodeindex {#1}}
+}
+
+\def\defcodeindex{\parsearg\newcodeindex}
+
+% @synindex foo bar    makes index foo feed into index bar.
+% Do this instead of @defindex foo if you don't want it as a separate index.
+\def\synindex #1 #2 {%
+\expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname
+\expandafter\let\csname#1indfile\endcsname=\synindexfoo
+\expandafter\xdef\csname#1index\endcsname{%     % Define \xxxindex
+\noexpand\doindex {#2}}%
+}
+
+% @syncodeindex foo bar   similar, but put all entries made for index foo
+% inside @code.
+\def\syncodeindex #1 #2 {%
+\expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname
+\expandafter\let\csname#1indfile\endcsname=\synindexfoo
+\expandafter\xdef\csname#1index\endcsname{%     % Define \xxxindex
+\noexpand\docodeindex {#2}}%
+}
+
+% Define \doindex, the driver for all \fooindex macros.
+% Argument #1 is generated by the calling \fooindex macro,
+%  and it is "foo", the name of the index.
+
+% \doindex just uses \parsearg; it calls \doind for the actual work.
+% This is because \doind is more useful to call from other macros.
+
+% There is also \dosubind {index}{topic}{subtopic}
+% which makes an entry in a two-level index such as the operation index.
+
+\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer}
+\def\singleindexer #1{\doind{\indexname}{#1}}
+
+% like the previous two, but they put @code around the argument.
+\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer}
+\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}}
+
+\def\indexdummies{%
+% Take care of the plain tex accent commands.
+\def\"{\realbackslash "}%
+\def\`{\realbackslash `}%
+\def\'{\realbackslash '}%
+\def\^{\realbackslash ^}%
+\def\~{\realbackslash ~}%
+\def\={\realbackslash =}%
+\def\b{\realbackslash b}%
+\def\c{\realbackslash c}%
+\def\d{\realbackslash d}%
+\def\u{\realbackslash u}%
+\def\v{\realbackslash v}%
+\def\H{\realbackslash H}%
+% Take care of the plain tex special European modified letters.
+\def\oe{\realbackslash oe}%
+\def\ae{\realbackslash ae}%
+\def\aa{\realbackslash aa}%
+\def\OE{\realbackslash OE}%
+\def\AE{\realbackslash AE}%
+\def\AA{\realbackslash AA}%
+\def\o{\realbackslash o}%
+\def\O{\realbackslash O}%
+\def\l{\realbackslash l}%
+\def\L{\realbackslash L}%
+\def\ss{\realbackslash ss}%
+% Take care of texinfo commands likely to appear in an index entry.
+% (Must be a way to avoid doing expansion at all, and thus not have to
+% laboriously list every single command here.)
+\def\@{@}% will be @@ when we switch to @ as escape char.
+%\let\{ = \lbracecmd
+%\let\} = \rbracecmd
+\def\_{{\realbackslash _}}%
+\def\w{\realbackslash w }%
+\def\bf{\realbackslash bf }%
+%\def\rm{\realbackslash rm }%
+\def\sl{\realbackslash sl }%
+\def\sf{\realbackslash sf}%
+\def\tt{\realbackslash tt}%
+\def\gtr{\realbackslash gtr}%
+\def\less{\realbackslash less}%
+\def\hat{\realbackslash hat}%
+%\def\char{\realbackslash char}%
+\def\TeX{\realbackslash TeX}%
+\def\dots{\realbackslash dots }%
+\def\copyright{\realbackslash copyright }%
+\def\tclose##1{\realbackslash tclose {##1}}%
+\def\code##1{\realbackslash code {##1}}%
+\def\dotless##1{\realbackslash dotless {##1}}%
+\def\samp##1{\realbackslash samp {##1}}%
+\def\,##1{\realbackslash ,{##1}}%
+\def\t##1{\realbackslash t {##1}}%
+\def\r##1{\realbackslash r {##1}}%
+\def\i##1{\realbackslash i {##1}}%
+\def\b##1{\realbackslash b {##1}}%
+\def\cite##1{\realbackslash cite {##1}}%
+\def\key##1{\realbackslash key {##1}}%
+\def\file##1{\realbackslash file {##1}}%
+\def\var##1{\realbackslash var {##1}}%
+\def\kbd##1{\realbackslash kbd {##1}}%
+\def\dfn##1{\realbackslash dfn {##1}}%
+\def\emph##1{\realbackslash emph {##1}}%
+\unsepspaces
+}
+
+% If an index command is used in an @example environment, any spaces
+% therein should become regular spaces in the raw index file, not the
+% expansion of \tie (\\leavevmode \penalty \@M \ ).
+{\obeyspaces
+ \gdef\unsepspaces{\obeyspaces\let =\space}}
+
+% \indexnofonts no-ops all font-change commands.
+% This is used when outputting the strings to sort the index by.
+\def\indexdummyfont#1{#1}
+\def\indexdummytex{TeX}
+\def\indexdummydots{...}
+
+\def\indexnofonts{%
+% Just ignore accents.
+\let\,=\indexdummyfont
+\let\"=\indexdummyfont
+\let\`=\indexdummyfont
+\let\'=\indexdummyfont
+\let\^=\indexdummyfont
+\let\~=\indexdummyfont
+\let\==\indexdummyfont
+\let\b=\indexdummyfont
+\let\c=\indexdummyfont
+\let\d=\indexdummyfont
+\let\u=\indexdummyfont
+\let\v=\indexdummyfont
+\let\H=\indexdummyfont
+\let\dotless=\indexdummyfont
+% Take care of the plain tex special European modified letters.
+\def\oe{oe}%
+\def\ae{ae}%
+\def\aa{aa}%
+\def\OE{OE}%
+\def\AE{AE}%
+\def\AA{AA}%
+\def\o{o}%
+\def\O{O}%
+\def\l{l}%
+\def\L{L}%
+\def\ss{ss}%
+\let\w=\indexdummyfont
+\let\t=\indexdummyfont
+\let\r=\indexdummyfont
+\let\i=\indexdummyfont
+\let\b=\indexdummyfont
+\let\emph=\indexdummyfont
+\let\strong=\indexdummyfont
+\let\cite=\indexdummyfont
+\let\sc=\indexdummyfont
+%Don't no-op \tt, since it isn't a user-level command
+% and is used in the definitions of the active chars like <, >, |...
+%\let\tt=\indexdummyfont
+\let\tclose=\indexdummyfont
+\let\code=\indexdummyfont
+\let\file=\indexdummyfont
+\let\samp=\indexdummyfont
+\let\kbd=\indexdummyfont
+\let\key=\indexdummyfont
+\let\var=\indexdummyfont
+\let\TeX=\indexdummytex
+\let\dots=\indexdummydots
+\def\@{@}%
+}
+
+% To define \realbackslash, we must make \ not be an escape.
+% We must first make another character (@) an escape
+% so we do not become unable to do a definition.
+
+{\catcode`\@=0 \catcode`\\=\other
+@gdef@realbackslash{\}}
+
+\let\indexbackslash=0  %overridden during \printindex.
+
+\let\SETmarginindex=\relax %initialize!
+% workhorse for all \fooindexes
+% #1 is name of index, #2 is stuff to put there
+\def\doind #1#2{%
+  % Put the index entry in the margin if desired.
+  \ifx\SETmarginindex\relax\else
+    \insert\margin{\hbox{\vrule height8pt depth3pt width0pt #2}}%
+  \fi
+  {%
+    \count255=\lastpenalty
+    {%
+      \indexdummies % Must do this here, since \bf, etc expand at this stage
+      \escapechar=`\\
+      {%
+        \let\folio=0 % We will expand all macros now EXCEPT \folio.
+        \def\rawbackslashxx{\indexbackslash}% \indexbackslash isn't defined now
+        % so it will be output as is; and it will print as backslash.
+        %
+        % First process the index-string with all font commands turned off
+        % to get the string to sort by.
+        {\indexnofonts \xdef\indexsorttmp{#2}}%
+        %
+        % Now produce the complete index entry, with both the sort key and the
+        % original text, including any font commands.
+        \toks0 = {#2}%
+        \edef\temp{%
+          \write\csname#1indfile\endcsname{%
+            \realbackslash entry{\indexsorttmp}{\folio}{\the\toks0}}%
+        }%
+        \temp
+      }%
+    }%
+    \penalty\count255
+  }%
+}
+
+\def\dosubind #1#2#3{%
+{\count10=\lastpenalty %
+{\indexdummies % Must do this here, since \bf, etc expand at this stage
+\escapechar=`\\%
+{\let\folio=0%
+\def\rawbackslashxx{\indexbackslash}%
+%
+% Now process the index-string once, with all font commands turned off,
+% to get the string to sort the index by.
+{\indexnofonts
+\xdef\temp1{#2 #3}%
+}%
+% Now produce the complete index entry.  We process the index-string again,
+% this time with font commands expanded, to get what to print in the index.
+\edef\temp{%
+\write \csname#1indfile\endcsname{%
+\realbackslash entry {\temp1}{\folio}{#2}{#3}}}%
+\temp }%
+}\penalty\count10}}
+
+% The index entry written in the file actually looks like
+%  \entry {sortstring}{page}{topic}
+% or
+%  \entry {sortstring}{page}{topic}{subtopic}
+% The texindex program reads in these files and writes files
+% containing these kinds of lines:
+%  \initial {c}
+%     before the first topic whose initial is c
+%  \entry {topic}{pagelist}
+%     for a topic that is used without subtopics
+%  \primary {topic}
+%     for the beginning of a topic that is used with subtopics
+%  \secondary {subtopic}{pagelist}
+%     for each subtopic.
+
+% Define the user-accessible indexing commands
+% @findex, @vindex, @kindex, @cindex.
+
+\def\findex {\fnindex}
+\def\kindex {\kyindex}
+\def\cindex {\cpindex}
+\def\vindex {\vrindex}
+\def\tindex {\tpindex}
+\def\pindex {\pgindex}
+
+\def\cindexsub {\begingroup\obeylines\cindexsub}
+{\obeylines %
+\gdef\cindexsub "#1" #2^^M{\endgroup %
+\dosubind{cp}{#2}{#1}}}
+
+% Define the macros used in formatting output of the sorted index material.
+
+% This is what you call to cause a particular index to get printed.
+% Write
+% @unnumbered Function Index
+% @printindex fn
+
+\def\printindex{\parsearg\doprintindex}
+
+\def\doprintindex#1{\begingroup
+  \dobreak \chapheadingskip{10000}%
+  %
+  \indexfonts \rm
+  \tolerance = 9500
+  \indexbreaks
+  \def\indexbackslash{\rawbackslashxx}%
+  % Index files are almost Texinfo source, but we use \ as the escape
+  % character.  It would be better to use @, but that's too big a change
+  % to make right now.
+  \catcode`\\ = 0
+  \catcode`\@ = 11
+  \escapechar = `\\
+  \begindoublecolumns
+  %
+  % See if the index file exists and is nonempty.
+  \openin 1 \jobname.#1s
+  \ifeof 1
+    % \enddoublecolumns gets confused if there is no text in the index,
+    % and it loses the chapter title and the aux file entries for the
+    % index.  The easiest way to prevent this problem is to make sure
+    % there is some text.
+    (Index is nonexistent)
+  \else
+    %
+    % If the index file exists but is empty, then \openin leaves \ifeof
+    % false.  We have to make TeX try to read something from the file, so
+    % it can discover if there is anything in it.
+    \read 1 to \temp
+    \ifeof 1
+      (Index is empty)
+    \else
+      \input \jobname.#1s
+    \fi
+  \fi
+  \closein 1
+  \enddoublecolumns
+\endgroup}
+
+% These macros are used by the sorted index file itself.
+% Change them to control the appearance of the index.
+
+% Same as \bigskipamount except no shrink.
+% \balancecolumns gets confused if there is any shrink.
+\newskip\initialskipamount \initialskipamount 12pt plus4pt
+
+\def\initial #1{%
+{\let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt
+\ifdim\lastskip<\initialskipamount
+\removelastskip \penalty-200 \vskip \initialskipamount\fi
+\line{\secbf#1\hfill}\kern 2pt\penalty10000}}
+
+% This typesets a paragraph consisting of #1, dot leaders, and then #2
+% flush to the right margin.  It is used for index and table of contents
+% entries.  The paragraph is indented by \leftskip.
+%
+\def\entry #1#2{\begingroup
+  %
+  % Start a new paragraph if necessary, so our assignments below can't
+  % affect previous text.
+  \par
+  %
+  % Do not fill out the last line with white space.
+  \parfillskip = 0in
+  %
+  % No extra space above this paragraph.
+  \parskip = 0in
+  %
+  % Do not prefer a separate line ending with a hyphen to fewer lines.
+  \finalhyphendemerits = 0
+  %
+  % \hangindent is only relevant when the entry text and page number
+  % don't both fit on one line.  In that case, bob suggests starting the
+  % dots pretty far over on the line.  Unfortunately, a large
+  % indentation looks wrong when the entry text itself is broken across
+  % lines.  So we use a small indentation and put up with long leaders.
+  %
+  % \hangafter is reset to 1 (which is the value we want) at the start
+  % of each paragraph, so we need not do anything with that.
+  \hangindent=2em
+  %
+  % When the entry text needs to be broken, just fill out the first line
+  % with blank space.
+  \rightskip = 0pt plus1fil
+  %
+  % Start a ``paragraph'' for the index entry so the line breaking
+  % parameters we've set above will have an effect.
+  \noindent
+  %
+  % Insert the text of the index entry.  TeX will do line-breaking on it.
+  #1%
+  % The following is kludged to not output a line of dots in the index if
+  % there are no page numbers.  The next person who breaks this will be
+  % cursed by a Unix daemon.
+  \def\tempa{{\rm }}%
+  \def\tempb{#2}%
+  \edef\tempc{\tempa}%
+  \edef\tempd{\tempb}%
+  \ifx\tempc\tempd\ \else%
+    %
+    % If we must, put the page number on a line of its own, and fill out
+    % this line with blank space.  (The \hfil is overwhelmed with the
+    % fill leaders glue in \indexdotfill if the page number does fit.)
+    \hfil\penalty50
+    \null\nobreak\indexdotfill % Have leaders before the page number.
+    %
+    % The `\ ' here is removed by the implicit \unskip that TeX does as
+    % part of (the primitive) \par.  Without it, a spurious underfull
+    % \hbox ensues.
+    \ #2% The page number ends the paragraph.
+  \fi%
+  \par
+\endgroup}
+
+% Like \dotfill except takes at least 1 em.
+\def\indexdotfill{\cleaders
+  \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \mkern1.5mu$}\hskip 1em plus 1fill}
+
+\def\primary #1{\line{#1\hfil}}
+
+\newskip\secondaryindent \secondaryindent=0.5cm
+
+\def\secondary #1#2{
+{\parfillskip=0in \parskip=0in
+\hangindent =1in \hangafter=1
+\noindent\hskip\secondaryindent\hbox{#1}\indexdotfill #2\par
+}}
+
+% Define two-column mode, which we use to typeset indexes.
+% Adapted from the TeXbook, page 416, which is to say,
+% the manmac.tex format used to print the TeXbook itself.
+\catcode`\@=11
+
+\newbox\partialpage
+\newdimen\doublecolumnhsize
+
+\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns
+  % Grab any single-column material above us.
+  \output = {\global\setbox\partialpage
+    =\vbox{\unvbox255\kern -\topskip \kern \baselineskip}}%
+  \eject
+  %
+  % Now switch to the double-column output routine.
+  \output={\doublecolumnout}%
+  %
+  % Change the page size parameters.  We could do this once outside this
+  % routine, in each of @smallbook, @afourpaper, and the default 8.5x11
+  % format, but then we repeat the same computation.  Repeating a couple
+  % of assignments once per index is clearly meaningless for the
+  % execution time, so we may as well do it once.
+  %
+  % First we halve the line length, less a little for the gutter between
+  % the columns.  We compute the gutter based on the line length, so it
+  % changes automatically with the paper format.  The magic constant
+  % below is chosen so that the gutter has the same value (well, +- <
+  % 1pt) as it did when we hard-coded it.
+  %
+  % We put the result in a separate register, \doublecolumhsize, so we
+  % can restore it in \pagesofar, after \hsize itself has (potentially)
+  % been clobbered.
+  %
+  \doublecolumnhsize = \hsize
+    \advance\doublecolumnhsize by -.04154\hsize
+    \divide\doublecolumnhsize by 2
+  \hsize = \doublecolumnhsize
+  %
+  % Double the \vsize as well.  (We don't need a separate register here,
+  % since nobody clobbers \vsize.)
+  \vsize = 2\vsize
+}
+\def\doublecolumnout{%
+  \splittopskip=\topskip \splitmaxdepth=\maxdepth
+  % Get the available space for the double columns -- the normal
+  % (undoubled) page height minus any material left over from the
+  % previous page.
+  \dimen@=\pageheight \advance\dimen@ by-\ht\partialpage
+  % box0 will be the left-hand column, box1 the right.
+  \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@
+  \onepageout\pagesofar
+  \unvbox255 \penalty\outputpenalty
+}
+\def\pagesofar{%
+  % The contents of the output page -- any previous material,
+  % followed by the two boxes we just split.
+  \unvbox\partialpage
+  \hsize = \doublecolumnhsize
+  \wd0=\hsize \wd2=\hsize \hbox to\pagewidth{\box0\hfil\box2}%
+}
+\def\enddoublecolumns{%
+  \output={\balancecolumns}\eject % split what we have
+  \endgroup
+  % Back to normal single-column typesetting, but take account of the
+  % fact that we just accumulated some stuff on the output page.
+  \pagegoal=\vsize 
+}
+\def\balancecolumns{%
+  % Called on the last page of the double column material.
+  \setbox0=\vbox{\unvbox255}%
+  \dimen@ = \ht0
+  \advance\dimen@ by \topskip
+  \advance\dimen@ by-\baselineskip
+  \divide\dimen@ by 2
+  \splittopskip = \topskip
+  % Loop until we get a decent breakpoint.
+  {\vbadness=10000 \loop \global\setbox3=\copy0
+    \global\setbox1=\vsplit3 to\dimen@
+    \ifdim\ht3>\dimen@ \global\advance\dimen@ by1pt \repeat}%
+  \setbox0=\vbox to\dimen@{\unvbox1}%
+  \setbox2=\vbox to\dimen@{\unvbox3}%
+  \pagesofar
+}
+\catcode `\@=\other
+
+
+\message{sectioning,}
+% Define chapters, sections, etc.
+
+\newcount \chapno
+\newcount \secno        \secno=0
+\newcount \subsecno     \subsecno=0
+\newcount \subsubsecno  \subsubsecno=0
+
+% This counter is funny since it counts through charcodes of letters A, B, ...
+\newcount \appendixno  \appendixno = `\@
+\def\appendixletter{\char\the\appendixno}
+
+\newwrite \contentsfile
+% This is called from \setfilename.
+\def\opencontents{\openout \contentsfile = \jobname.toc}
+
+% Each @chapter defines this as the name of the chapter.
+% page headings and footings can use it.  @section does likewise
+
+\def\thischapter{} \def\thissection{}
+\def\seccheck#1{\if \pageno<0 %
+\errmessage{@#1 not allowed after generating table of contents}\fi
+%
+}
+
+\def\chapternofonts{%
+\let\rawbackslash=\relax%
+\let\frenchspacing=\relax%
+\def\result{\realbackslash result}
+\def\equiv{\realbackslash equiv}
+\def\expansion{\realbackslash expansion}
+\def\print{\realbackslash print}
+\def\TeX{\realbackslash TeX}
+\def\dots{\realbackslash dots}
+\def\copyright{\realbackslash copyright}
+\def\tt{\realbackslash tt}
+\def\bf{\realbackslash bf }
+\def\w{\realbackslash w}
+\def\less{\realbackslash less}
+\def\gtr{\realbackslash gtr}
+\def\hat{\realbackslash hat}
+\def\char{\realbackslash char}
+\def\tclose##1{\realbackslash tclose {##1}}
+\def\code##1{\realbackslash code {##1}}
+\def\samp##1{\realbackslash samp {##1}}
+\def\r##1{\realbackslash r {##1}}
+\def\b##1{\realbackslash b {##1}}
+\def\key##1{\realbackslash key {##1}}
+\def\file##1{\realbackslash file {##1}}
+\def\kbd##1{\realbackslash kbd {##1}}
+% These are redefined because @smartitalic wouldn't work inside xdef.
+\def\i##1{\realbackslash i {##1}}
+\def\cite##1{\realbackslash cite {##1}}
+\def\var##1{\realbackslash var {##1}}
+\def\emph##1{\realbackslash emph {##1}}
+\def\dfn##1{\realbackslash dfn {##1}}
+}
+
+\newcount\absseclevel % used to calculate proper heading level
+\newcount\secbase\secbase=0 % @raise/lowersections modify this count
+
+% @raisesections: treat @section as chapter, @subsection as section, etc.
+\def\raisesections{\global\advance\secbase by -1}
+\let\up=\raisesections % original BFox name
+
+% @lowersections: treat @chapter as section, @section as subsection, etc.
+\def\lowersections{\global\advance\secbase by 1}
+\let\down=\lowersections % original BFox name
+
+% Choose a numbered-heading macro
+% #1 is heading level if unmodified by @raisesections or @lowersections
+% #2 is text for heading
+\def\numhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1
+\ifcase\absseclevel
+  \chapterzzz{#2}
+\or
+  \seczzz{#2}
+\or
+  \numberedsubseczzz{#2}
+\or
+  \numberedsubsubseczzz{#2}
+\else
+  \ifnum \absseclevel<0
+    \chapterzzz{#2}
+  \else
+    \numberedsubsubseczzz{#2}
+  \fi
+\fi
+}
+
+% like \numhead, but chooses appendix heading levels
+\def\apphead#1#2{\absseclevel=\secbase\advance\absseclevel by #1
+\ifcase\absseclevel
+  \appendixzzz{#2}
+\or
+  \appendixsectionzzz{#2}
+\or
+  \appendixsubseczzz{#2}
+\or
+  \appendixsubsubseczzz{#2}
+\else
+  \ifnum \absseclevel<0
+    \appendixzzz{#2}
+  \else
+    \appendixsubsubseczzz{#2}
+  \fi
+\fi
+}
+
+% like \numhead, but chooses numberless heading levels
+\def\unnmhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1
+\ifcase\absseclevel
+  \unnumberedzzz{#2}
+\or
+  \unnumberedseczzz{#2}
+\or
+  \unnumberedsubseczzz{#2}
+\or
+  \unnumberedsubsubseczzz{#2}
+\else
+  \ifnum \absseclevel<0
+    \unnumberedzzz{#2}
+  \else
+    \unnumberedsubsubseczzz{#2}
+  \fi
+\fi
+}
+
+
+\def\thischaptername{No Chapter Title}
+\outer\def\chapter{\parsearg\chapteryyy}
+\def\chapteryyy #1{\numhead0{#1}} % normally numhead0 calls chapterzzz
+\def\chapterzzz #1{\seccheck{chapter}%
+\secno=0 \subsecno=0 \subsubsecno=0
+\global\advance \chapno by 1 \message{\putwordChapter \the\chapno}%
+\chapmacro {#1}{\the\chapno}%
+\gdef\thissection{#1}%
+\gdef\thischaptername{#1}%
+% We don't substitute the actual chapter name into \thischapter
+% because we don't want its macros evaluated now.
+\xdef\thischapter{\putwordChapter{} \the\chapno: \noexpand\thischaptername}%
+{\chapternofonts%
+\edef\temp{{\realbackslash chapentry {#1}{\the\chapno}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp  %
+\donoderef %
+\global\let\section = \numberedsec
+\global\let\subsection = \numberedsubsec
+\global\let\subsubsection = \numberedsubsubsec
+}}
+
+\outer\def\appendix{\parsearg\appendixyyy}
+\def\appendixyyy #1{\apphead0{#1}} % normally apphead0 calls appendixzzz
+\def\appendixzzz #1{\seccheck{appendix}%
+\secno=0 \subsecno=0 \subsubsecno=0
+\global\advance \appendixno by 1 \message{Appendix \appendixletter}%
+\chapmacro {#1}{\putwordAppendix{} \appendixletter}%
+\gdef\thissection{#1}%
+\gdef\thischaptername{#1}%
+\xdef\thischapter{\putwordAppendix{} \appendixletter: \noexpand\thischaptername}%
+{\chapternofonts%
+\edef\temp{{\realbackslash chapentry
+  {#1}{\putwordAppendix{} \appendixletter}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp  %
+\appendixnoderef %
+\global\let\section = \appendixsec
+\global\let\subsection = \appendixsubsec
+\global\let\subsubsection = \appendixsubsubsec
+}}
+
+% @centerchap is like @unnumbered, but the heading is centered.
+\outer\def\centerchap{\parsearg\centerchapyyy}
+\def\centerchapyyy #1{{\let\unnumbchapmacro=\centerchapmacro \unnumberedyyy{#1}}}
+
+\outer\def\top{\parsearg\unnumberedyyy}
+\outer\def\unnumbered{\parsearg\unnumberedyyy}
+\def\unnumberedyyy #1{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz
+\def\unnumberedzzz #1{\seccheck{unnumbered}%
+\secno=0 \subsecno=0 \subsubsecno=0
+%
+% This used to be simply \message{#1}, but TeX fully expands the
+% argument to \message.  Therefore, if #1 contained @-commands, TeX
+% expanded them.  For example, in `@unnumbered The @cite{Book}', TeX
+% expanded @cite (which turns out to cause errors because \cite is meant
+% to be executed, not expanded).
+%
+% Anyway, we don't want the fully-expanded definition of @cite to appear
+% as a result of the \message, we just want `@cite' itself.  We use
+% \the<toks register> to achieve this: TeX expands \the<toks> only once,
+% simply yielding the contents of the <toks register>.
+\toks0 = {#1}\message{(\the\toks0)}%
+%
+\unnumbchapmacro {#1}%
+\gdef\thischapter{#1}\gdef\thissection{#1}%
+{\chapternofonts%
+\edef\temp{{\realbackslash unnumbchapentry {#1}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp  %
+\unnumbnoderef %
+\global\let\section = \unnumberedsec
+\global\let\subsection = \unnumberedsubsec
+\global\let\subsubsection = \unnumberedsubsubsec
+}}
+
+\outer\def\numberedsec{\parsearg\secyyy}
+\def\secyyy #1{\numhead1{#1}} % normally calls seczzz
+\def\seczzz #1{\seccheck{section}%
+\subsecno=0 \subsubsecno=0 \global\advance \secno by 1 %
+\gdef\thissection{#1}\secheading {#1}{\the\chapno}{\the\secno}%
+{\chapternofonts%
+\edef\temp{{\realbackslash secentry %
+{#1}{\the\chapno}{\the\secno}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\donoderef %
+\penalty 10000 %
+}}
+
+\outer\def\appendixsection{\parsearg\appendixsecyyy}
+\outer\def\appendixsec{\parsearg\appendixsecyyy}
+\def\appendixsecyyy #1{\apphead1{#1}} % normally calls appendixsectionzzz
+\def\appendixsectionzzz #1{\seccheck{appendixsection}%
+\subsecno=0 \subsubsecno=0 \global\advance \secno by 1 %
+\gdef\thissection{#1}\secheading {#1}{\appendixletter}{\the\secno}%
+{\chapternofonts%
+\edef\temp{{\realbackslash secentry %
+{#1}{\appendixletter}{\the\secno}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\appendixnoderef %
+\penalty 10000 %
+}}
+
+\outer\def\unnumberedsec{\parsearg\unnumberedsecyyy}
+\def\unnumberedsecyyy #1{\unnmhead1{#1}} % normally calls unnumberedseczzz
+\def\unnumberedseczzz #1{\seccheck{unnumberedsec}%
+\plainsecheading {#1}\gdef\thissection{#1}%
+{\chapternofonts%
+\edef\temp{{\realbackslash unnumbsecentry{#1}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\unnumbnoderef %
+\penalty 10000 %
+}}
+
+\outer\def\numberedsubsec{\parsearg\numberedsubsecyyy}
+\def\numberedsubsecyyy #1{\numhead2{#1}} % normally calls numberedsubseczzz
+\def\numberedsubseczzz #1{\seccheck{subsection}%
+\gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 %
+\subsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}%
+{\chapternofonts%
+\edef\temp{{\realbackslash subsecentry %
+{#1}{\the\chapno}{\the\secno}{\the\subsecno}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\donoderef %
+\penalty 10000 %
+}}
+
+\outer\def\appendixsubsec{\parsearg\appendixsubsecyyy}
+\def\appendixsubsecyyy #1{\apphead2{#1}} % normally calls appendixsubseczzz
+\def\appendixsubseczzz #1{\seccheck{appendixsubsec}%
+\gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 %
+\subsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}%
+{\chapternofonts%
+\edef\temp{{\realbackslash subsecentry %
+{#1}{\appendixletter}{\the\secno}{\the\subsecno}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\appendixnoderef %
+\penalty 10000 %
+}}
+
+\outer\def\unnumberedsubsec{\parsearg\unnumberedsubsecyyy}
+\def\unnumberedsubsecyyy #1{\unnmhead2{#1}} %normally calls unnumberedsubseczzz
+\def\unnumberedsubseczzz #1{\seccheck{unnumberedsubsec}%
+\plainsubsecheading {#1}\gdef\thissection{#1}%
+{\chapternofonts%
+\edef\temp{{\realbackslash unnumbsubsecentry{#1}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\unnumbnoderef %
+\penalty 10000 %
+}}
+
+\outer\def\numberedsubsubsec{\parsearg\numberedsubsubsecyyy}
+\def\numberedsubsubsecyyy #1{\numhead3{#1}} % normally numberedsubsubseczzz
+\def\numberedsubsubseczzz #1{\seccheck{subsubsection}%
+\gdef\thissection{#1}\global\advance \subsubsecno by 1 %
+\subsubsecheading {#1}
+  {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}%
+{\chapternofonts%
+\edef\temp{{\realbackslash subsubsecentry %
+  {#1}
+  {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}
+  {\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\donoderef %
+\penalty 10000 %
+}}
+
+\outer\def\appendixsubsubsec{\parsearg\appendixsubsubsecyyy}
+\def\appendixsubsubsecyyy #1{\apphead3{#1}} % normally appendixsubsubseczzz
+\def\appendixsubsubseczzz #1{\seccheck{appendixsubsubsec}%
+\gdef\thissection{#1}\global\advance \subsubsecno by 1 %
+\subsubsecheading {#1}
+  {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}%
+{\chapternofonts%
+\edef\temp{{\realbackslash subsubsecentry{#1}%
+  {\appendixletter}
+  {\the\secno}{\the\subsecno}{\the\subsubsecno}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\appendixnoderef %
+\penalty 10000 %
+}}
+
+\outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubsecyyy}
+\def\unnumberedsubsubsecyyy #1{\unnmhead3{#1}} %normally unnumberedsubsubseczzz
+\def\unnumberedsubsubseczzz #1{\seccheck{unnumberedsubsubsec}%
+\plainsubsubsecheading {#1}\gdef\thissection{#1}%
+{\chapternofonts%
+\edef\temp{{\realbackslash unnumbsubsubsecentry{#1}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\unnumbnoderef %
+\penalty 10000 %
+}}
+
+% These are variants which are not "outer", so they can appear in @ifinfo.
+% Actually, they should now be obsolete; ordinary section commands should work.
+\def\infotop{\parsearg\unnumberedzzz}
+\def\infounnumbered{\parsearg\unnumberedzzz}
+\def\infounnumberedsec{\parsearg\unnumberedseczzz}
+\def\infounnumberedsubsec{\parsearg\unnumberedsubseczzz}
+\def\infounnumberedsubsubsec{\parsearg\unnumberedsubsubseczzz}
+
+\def\infoappendix{\parsearg\appendixzzz}
+\def\infoappendixsec{\parsearg\appendixseczzz}
+\def\infoappendixsubsec{\parsearg\appendixsubseczzz}
+\def\infoappendixsubsubsec{\parsearg\appendixsubsubseczzz}
+
+\def\infochapter{\parsearg\chapterzzz}
+\def\infosection{\parsearg\sectionzzz}
+\def\infosubsection{\parsearg\subsectionzzz}
+\def\infosubsubsection{\parsearg\subsubsectionzzz}
+
+% These macros control what the section commands do, according
+% to what kind of chapter we are in (ordinary, appendix, or unnumbered).
+% Define them by default for a numbered chapter.
+\global\let\section = \numberedsec
+\global\let\subsection = \numberedsubsec
+\global\let\subsubsection = \numberedsubsubsec
+
+% Define @majorheading, @heading and @subheading
+
+% NOTE on use of \vbox for chapter headings, section headings, and
+% such:
+%       1) We use \vbox rather than the earlier \line to permit
+%          overlong headings to fold.
+%       2) \hyphenpenalty is set to 10000 because hyphenation in a
+%          heading is obnoxious; this forbids it.
+%       3) Likewise, headings look best if no \parindent is used, and
+%          if justification is not attempted.  Hence \raggedright.
+
+
+\def\majorheading{\parsearg\majorheadingzzz}
+\def\majorheadingzzz #1{%
+{\advance\chapheadingskip by 10pt \chapbreak }%
+{\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+                  \parindent=0pt\raggedright
+                  \rm #1\hfill}}\bigskip \par\penalty 200}
+
+\def\chapheading{\parsearg\chapheadingzzz}
+\def\chapheadingzzz #1{\chapbreak %
+{\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+                  \parindent=0pt\raggedright
+                  \rm #1\hfill}}\bigskip \par\penalty 200}
+
+% @heading, @subheading, @subsubheading.
+\def\heading{\parsearg\plainsecheading}
+\def\subheading{\parsearg\plainsubsecheading}
+\def\subsubheading{\parsearg\plainsubsubsecheading}
+
+% These macros generate a chapter, section, etc. heading only
+% (including whitespace, linebreaking, etc. around it),
+% given all the information in convenient, parsed form.
+
+%%% Args are the skip and penalty (usually negative)
+\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi}
+
+\def\setchapterstyle #1 {\csname CHAPF#1\endcsname}
+
+%%% Define plain chapter starts, and page on/off switching for it
+% Parameter controlling skip before chapter headings (if needed)
+
+\newskip\chapheadingskip
+
+\def\chapbreak{\dobreak \chapheadingskip {-4000}}
+\def\chappager{\par\vfill\supereject}
+\def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi}
+
+\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname}
+
+\def\CHAPPAGoff{
+\global\let\contentsalignmacro = \chappager
+\global\let\pchapsepmacro=\chapbreak
+\global\let\pagealignmacro=\chappager}
+
+\def\CHAPPAGon{
+\global\let\contentsalignmacro = \chappager
+\global\let\pchapsepmacro=\chappager
+\global\let\pagealignmacro=\chappager
+\global\def\HEADINGSon{\HEADINGSsingle}}
+
+\def\CHAPPAGodd{
+\global\let\contentsalignmacro = \chapoddpage
+\global\let\pchapsepmacro=\chapoddpage
+\global\let\pagealignmacro=\chapoddpage
+\global\def\HEADINGSon{\HEADINGSdouble}}
+
+\CHAPPAGon
+
+\def\CHAPFplain{
+\global\let\chapmacro=\chfplain
+\global\let\unnumbchapmacro=\unnchfplain
+\global\let\centerchapmacro=\centerchfplain}
+
+% Plain chapter opening.
+% #1 is the text, #2 the chapter number or empty if unnumbered.
+\def\chfplain#1#2{%
+  \pchapsepmacro
+  {%
+    \chapfonts \rm
+    \def\chapnum{#2}%
+    \setbox0 = \hbox{#2\ifx\chapnum\empty\else\enspace\fi}%
+    \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
+          \hangindent = \wd0 \centerparametersmaybe
+          \unhbox0 #1\par}%
+  }%
+  \nobreak\bigskip % no page break after a chapter title
+  \nobreak
+}
+
+% Plain opening for unnumbered.
+\def\unnchfplain#1{\chfplain{#1}{}}
+
+% @centerchap -- centered and unnumbered.
+\let\centerparametersmaybe = \relax
+\def\centerchfplain#1{{%
+  \def\centerparametersmaybe{%
+    \advance\rightskip by 3\rightskip
+    \leftskip = \rightskip
+    \parfillskip = 0pt
+  }%
+  \chfplain{#1}{}%
+}}
+
+\CHAPFplain % The default
+
+\def\unnchfopen #1{%
+\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+                       \parindent=0pt\raggedright
+                       \rm #1\hfill}}\bigskip \par\penalty 10000 %
+}
+
+\def\chfopen #1#2{\chapoddpage {\chapfonts
+\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}%
+\par\penalty 5000 %
+}
+
+\def\centerchfopen #1{%
+\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+                       \parindent=0pt
+                       \hfill {\rm #1}\hfill}}\bigskip \par\penalty 10000 %
+}
+
+\def\CHAPFopen{
+\global\let\chapmacro=\chfopen
+\global\let\unnumbchapmacro=\unnchfopen
+\global\let\centerchapmacro=\centerchfopen}
+
+
+% Section titles.
+\newskip\secheadingskip
+\def\secheadingbreak{\dobreak \secheadingskip {-1000}}
+\def\secheading#1#2#3{\sectionheading{sec}{#2.#3}{#1}}
+\def\plainsecheading#1{\sectionheading{sec}{}{#1}}
+
+% Subsection titles.
+\newskip \subsecheadingskip
+\def\subsecheadingbreak{\dobreak \subsecheadingskip {-500}}
+\def\subsecheading#1#2#3#4{\sectionheading{subsec}{#2.#3.#4}{#1}}
+\def\plainsubsecheading#1{\sectionheading{subsec}{}{#1}}
+
+% Subsubsection titles.
+\let\subsubsecheadingskip = \subsecheadingskip
+\let\subsubsecheadingbreak = \subsecheadingbreak
+\def\subsubsecheading#1#2#3#4#5{\sectionheading{subsubsec}{#2.#3.#4.#5}{#1}}
+\def\plainsubsubsecheading#1{\sectionheading{subsubsec}{}{#1}}
+
+
+% Print any size section title.
+% 
+% #1 is the section type (sec/subsec/subsubsec), #2 is the section
+% number (maybe empty), #3 the text.
+\def\sectionheading#1#2#3{%
+  {%
+    \expandafter\advance\csname #1headingskip\endcsname by \parskip
+    \csname #1headingbreak\endcsname
+  }%
+  {%
+    % Switch to the right set of fonts.
+    \csname #1fonts\endcsname \rm
+    %
+    % Only insert the separating space if we have a section number.
+    \def\secnum{#2}%
+    \setbox0 = \hbox{#2\ifx\secnum\empty\else\enspace\fi}%
+    %
+    \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
+          \hangindent = \wd0 % zero if no section number
+          \unhbox0 #3}%
+  }%
+  \ifdim\parskip<10pt \nobreak\kern10pt\nobreak\kern-\parskip\fi \nobreak
+}
+
+
+\message{toc printing,}
+% Finish up the main text and prepare to read what we've written
+% to \contentsfile.
+
+\newskip\contentsrightmargin \contentsrightmargin=1in
+\def\startcontents#1{%
+   % If @setchapternewpage on, and @headings double, the contents should
+   % start on an odd page, unlike chapters.  Thus, we maintain
+   % \contentsalignmacro in parallel with \pagealignmacro.
+   % From: Torbjorn Granlund <tege@matematik.su.se>
+   \contentsalignmacro
+   \immediate\closeout \contentsfile
+   \ifnum \pageno>0
+      \pageno = -1              % Request roman numbered pages.
+   \fi
+   % Don't need to put `Contents' or `Short Contents' in the headline.
+   % It is abundantly clear what they are.
+   \unnumbchapmacro{#1}\def\thischapter{}%
+   \begingroup                  % Set up to handle contents files properly.
+      \catcode`\\=0  \catcode`\{=1  \catcode`\}=2  \catcode`\@=11
+      \catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi
+      \raggedbottom             % Worry more about breakpoints than the bottom.
+      \advance\hsize by -\contentsrightmargin % Don't use the full line length.
+}
+
+
+% Normal (long) toc.
+\outer\def\contents{%
+   \startcontents{\putwordTableofContents}%
+      \input \jobname.toc
+   \endgroup
+   \vfill \eject
+}
+
+% And just the chapters.
+\outer\def\summarycontents{%
+   \startcontents{\putwordShortContents}%
+      %
+      \let\chapentry = \shortchapentry
+      \let\unnumbchapentry = \shortunnumberedentry
+      % We want a true roman here for the page numbers.
+      \secfonts
+      \let\rm=\shortcontrm \let\bf=\shortcontbf \let\sl=\shortcontsl
+      \rm
+      \hyphenpenalty = 10000
+      \advance\baselineskip by 1pt % Open it up a little.
+      \def\secentry ##1##2##3##4{}
+      \def\unnumbsecentry ##1##2{}
+      \def\subsecentry ##1##2##3##4##5{}
+      \def\unnumbsubsecentry ##1##2{}
+      \def\subsubsecentry ##1##2##3##4##5##6{}
+      \def\unnumbsubsubsecentry ##1##2{}
+      \input \jobname.toc
+   \endgroup
+   \vfill \eject
+}
+\let\shortcontents = \summarycontents
+
+% These macros generate individual entries in the table of contents.
+% The first argument is the chapter or section name.
+% The last argument is the page number.
+% The arguments in between are the chapter number, section number, ...
+
+% Chapter-level things, for both the long and short contents.
+\def\chapentry#1#2#3{\dochapentry{#2\labelspace#1}{#3}}
+
+% See comments in \dochapentry re vbox and related settings
+\def\shortchapentry#1#2#3{%
+  \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno{#3}}%
+}
+
+% Typeset the label for a chapter or appendix for the short contents.
+% The arg is, e.g. `Appendix A' for an appendix, or `3' for a chapter.
+% We could simplify the code here by writing out an \appendixentry
+% command in the toc file for appendices, instead of using \chapentry
+% for both, but it doesn't seem worth it.
+\setbox0 = \hbox{\shortcontrm \putwordAppendix }
+\newdimen\shortappendixwidth \shortappendixwidth = \wd0
+
+\def\shortchaplabel#1{%
+  % We typeset #1 in a box of constant width, regardless of the text of
+  % #1, so the chapter titles will come out aligned.
+  \setbox0 = \hbox{#1}%
+  \dimen0 = \ifdim\wd0 > \shortappendixwidth \shortappendixwidth \else 0pt \fi
+  %
+  % This space should be plenty, since a single number is .5em, and the
+  % widest letter (M) is 1em, at least in the Computer Modern fonts.
+  % (This space doesn't include the extra space that gets added after
+  % the label; that gets put in by \shortchapentry above.)
+  \advance\dimen0 by 1.1em
+  \hbox to \dimen0{#1\hfil}%
+}
+
+\def\unnumbchapentry#1#2{\dochapentry{#1}{#2}}
+\def\shortunnumberedentry#1#2{\tocentry{#1}{\doshortpageno{#2}}}
+
+% Sections.
+\def\secentry#1#2#3#4{\dosecentry{#2.#3\labelspace#1}{#4}}
+\def\unnumbsecentry#1#2{\dosecentry{#1}{#2}}
+
+% Subsections.
+\def\subsecentry#1#2#3#4#5{\dosubsecentry{#2.#3.#4\labelspace#1}{#5}}
+\def\unnumbsubsecentry#1#2{\dosubsecentry{#1}{#2}}
+
+% And subsubsections.
+\def\subsubsecentry#1#2#3#4#5#6{%
+  \dosubsubsecentry{#2.#3.#4.#5\labelspace#1}{#6}}
+\def\unnumbsubsubsecentry#1#2{\dosubsubsecentry{#1}{#2}}
+
+% This parameter controls the indentation of the various levels.
+\newdimen\tocindent \tocindent = 3pc
+
+% Now for the actual typesetting. In all these, #1 is the text and #2 is the
+% page number.
+%
+% If the toc has to be broken over pages, we want it to be at chapters
+% if at all possible; hence the \penalty.
+\def\dochapentry#1#2{%
+   \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip
+   \begingroup
+     \chapentryfonts
+     \tocentry{#1}{\dopageno{#2}}%
+   \endgroup
+   \nobreak\vskip .25\baselineskip plus.1\baselineskip
+}
+
+\def\dosecentry#1#2{\begingroup
+  \secentryfonts \leftskip=\tocindent
+  \tocentry{#1}{\dopageno{#2}}%
+\endgroup}
+
+\def\dosubsecentry#1#2{\begingroup
+  \subsecentryfonts \leftskip=2\tocindent
+  \tocentry{#1}{\dopageno{#2}}%
+\endgroup}
+
+\def\dosubsubsecentry#1#2{\begingroup
+  \subsubsecentryfonts \leftskip=3\tocindent
+  \tocentry{#1}{\dopageno{#2}}%
+\endgroup}
+
+% Final typesetting of a toc entry; we use the same \entry macro as for
+% the index entries, but we want to suppress hyphenation here.  (We
+% can't do that in the \entry macro, since index entries might consist
+% of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.)
+%
+% \turnoffactive is for the sake of @" used for umlauts.
+\def\tocentry#1#2{\begingroup
+  \vskip 0pt plus1pt % allow a little stretch for the sake of nice page breaks
+  \entry{\turnoffactive #1}{\turnoffactive #2}%
+\endgroup}
+
+% Space between chapter (or whatever) number and the title.
+\def\labelspace{\hskip1em \relax}
+
+\def\dopageno#1{{\rm #1}}
+\def\doshortpageno#1{{\rm #1}}
+
+\def\chapentryfonts{\secfonts \rm}
+\def\secentryfonts{\textfonts}
+\let\subsecentryfonts = \textfonts
+\let\subsubsecentryfonts = \textfonts
+
+
+\message{environments,}
+
+% Since these characters are used in examples, it should be an even number of
+% \tt widths. Each \tt character is 1en, so two makes it 1em.
+% Furthermore, these definitions must come after we define our fonts.
+\newbox\dblarrowbox    \newbox\longdblarrowbox
+\newbox\pushcharbox    \newbox\bullbox
+\newbox\equivbox       \newbox\errorbox
+
+%{\tentt
+%\global\setbox\dblarrowbox = \hbox to 1em{\hfil$\Rightarrow$\hfil}
+%\global\setbox\longdblarrowbox = \hbox to 1em{\hfil$\mapsto$\hfil}
+%\global\setbox\pushcharbox = \hbox to 1em{\hfil$\dashv$\hfil}
+%\global\setbox\equivbox = \hbox to 1em{\hfil$\ptexequiv$\hfil}
+% Adapted from the manmac format (p.420 of TeXbook)
+%\global\setbox\bullbox = \hbox to 1em{\kern.15em\vrule height .75ex width .85ex
+%                                      depth .1ex\hfil}
+%}
+
+% @point{}, @result{}, @expansion{}, @print{}, @equiv{}.
+\def\point{$\star$}
+\def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}}
+\def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}}
+\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}}
+\def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}}
+
+% Adapted from the TeXbook's \boxit.
+{\tentt \global\dimen0 = 3em}% Width of the box.
+\dimen2 = .55pt % Thickness of rules
+% The text. (`r' is open on the right, `e' somewhat less so on the left.)
+\setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt}
+
+\global\setbox\errorbox=\hbox to \dimen0{\hfil
+   \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right.
+   \advance\hsize by -2\dimen2 % Rules.
+   \vbox{
+      \hrule height\dimen2
+      \hbox{\vrule width\dimen2 \kern3pt          % Space to left of text.
+         \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below.
+         \kern3pt\vrule width\dimen2}% Space to right.
+      \hrule height\dimen2}
+    \hfil}
+
+% The @error{} command.
+\def\error{\leavevmode\lower.7ex\copy\errorbox}
+
+% @tex ... @end tex    escapes into raw Tex temporarily.
+% One exception: @ is still an escape character, so that @end tex works.
+% But \@ or @@ will get a plain tex @ character.
+
+\def\tex{\begingroup
+\catcode `\\=0 \catcode `\{=1 \catcode `\}=2
+\catcode `\$=3 \catcode `\&=4 \catcode `\#=6
+\catcode `\^=7 \catcode `\_=8 \catcode `\~=13 \let~=\tie
+\catcode `\%=14
+\catcode 43=12 % plus
+\catcode`\"=12
+\catcode`\==12
+\catcode`\|=12
+\catcode`\<=12
+\catcode`\>=12
+\escapechar=`\\
+%
+\let\,=\ptexcomma
+\let\~=\ptextilde
+\let\{=\ptexlbrace
+\let\}=\ptexrbrace
+\let\.=\ptexdot
+\let\*=\ptexstar
+\let\dots=\ptexdots
+\def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}
+\def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}
+\def\@{@}%
+\let\bullet=\ptexbullet
+\let\b=\ptexb \let\c=\ptexc \let\i=\ptexi \let\t=\ptext
+%
+\let\Etex=\endgroup}
+
+% Define @lisp ... @endlisp.
+% @lisp does a \begingroup so it can rebind things,
+% including the definition of @endlisp (which normally is erroneous).
+
+% Amount to narrow the margins by for @lisp.
+\newskip\lispnarrowing \lispnarrowing=0.4in
+
+% This is the definition that ^^M gets inside @lisp, @example, and other
+% such environments.  \null is better than a space, since it doesn't
+% have any width.
+\def\lisppar{\null\endgraf}
+
+% Make each space character in the input produce a normal interword
+% space in the output.  Don't allow a line break at this space, as this
+% is used only in environments like @example, where each line of input
+% should produce a line of output anyway.
+%
+{\obeyspaces %
+\gdef\sepspaces{\obeyspaces\let =\tie}}
+
+% Define \obeyedspace to be our active space, whatever it is.  This is
+% for use in \parsearg.
+{\sepspaces%
+\global\let\obeyedspace= }
+
+% This space is always present above and below environments.
+\newskip\envskipamount \envskipamount = 0pt
+
+% Make spacing and below environment symmetrical.  We use \parskip here
+% to help in doing that, since in @example-like environments \parskip
+% is reset to zero; thus the \afterenvbreak inserts no space -- but the
+% start of the next paragraph will insert \parskip
+%
+\def\aboveenvbreak{{\advance\envskipamount by \parskip
+\endgraf \ifdim\lastskip<\envskipamount
+\removelastskip \penalty-50 \vskip\envskipamount \fi}}
+
+\let\afterenvbreak = \aboveenvbreak
+
+% \nonarrowing is a flag.  If "set", @lisp etc don't narrow margins.
+\let\nonarrowing=\relax
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \cartouche: draw rectangle w/rounded corners around argument
+\font\circle=lcircle10
+\newdimen\circthick
+\newdimen\cartouter\newdimen\cartinner
+\newskip\normbskip\newskip\normpskip\newskip\normlskip
+\circthick=\fontdimen8\circle
+%
+\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth
+\def\ctr{{\hskip 6pt\circle\char'010}}
+\def\cbl{{\circle\char'012\hskip -6pt}}
+\def\cbr{{\hskip 6pt\circle\char'011}}
+\def\carttop{\hbox to \cartouter{\hskip\lskip
+        \ctl\leaders\hrule height\circthick\hfil\ctr
+        \hskip\rskip}}
+\def\cartbot{\hbox to \cartouter{\hskip\lskip
+        \cbl\leaders\hrule height\circthick\hfil\cbr
+        \hskip\rskip}}
+%
+\newskip\lskip\newskip\rskip
+
+\long\def\cartouche{%
+\begingroup
+        \lskip=\leftskip \rskip=\rightskip
+        \leftskip=0pt\rightskip=0pt %we want these *outside*.
+        \cartinner=\hsize \advance\cartinner by-\lskip
+                          \advance\cartinner by-\rskip
+        \cartouter=\hsize
+        \advance\cartouter by 18pt % allow for 3pt kerns on either
+%                                    side, and for 6pt waste from
+%                                    each corner char
+        \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip
+        % Flag to tell @lisp, etc., not to narrow margin.
+        \let\nonarrowing=\comment
+        \vbox\bgroup
+                \baselineskip=0pt\parskip=0pt\lineskip=0pt
+                \carttop
+                \hbox\bgroup
+                        \hskip\lskip
+                        \vrule\kern3pt
+                        \vbox\bgroup
+                                \hsize=\cartinner
+                                \kern3pt
+                                \begingroup
+                                        \baselineskip=\normbskip
+                                        \lineskip=\normlskip
+                                        \parskip=\normpskip
+                                        \vskip -\parskip
+\def\Ecartouche{%
+                                \endgroup
+                                \kern3pt
+                        \egroup
+                        \kern3pt\vrule
+                        \hskip\rskip
+                \egroup
+                \cartbot
+        \egroup
+\endgroup
+}}
+
+
+% This macro is called at the beginning of all the @example variants,
+% inside a group.
+\def\nonfillstart{%
+  \aboveenvbreak
+  \inENV % This group ends at the end of the body
+  \hfuzz = 12pt % Don't be fussy
+  \sepspaces % Make spaces be word-separators rather than space tokens.
+  \singlespace
+  \let\par = \lisppar % don't ignore blank lines
+  \obeylines % each line of input is a line of output
+  \parskip = 0pt
+  \parindent = 0pt
+  \emergencystretch = 0pt % don't try to avoid overfull boxes
+  % @cartouche defines \nonarrowing to inhibit narrowing
+  % at next level down.
+  \ifx\nonarrowing\relax
+    \advance \leftskip by \lispnarrowing
+    \exdentamount=\lispnarrowing
+    \let\exdent=\nofillexdent
+    \let\nonarrowing=\relax
+  \fi
+}
+
+% To ending an @example-like environment, we first end the paragraph
+% (via \afterenvbreak's vertical glue), and then the group.  That way we
+% keep the zero \parskip that the environments set -- \parskip glue
+% will be inserted at the beginning of the next paragraph in the
+% document, after the environment.
+%
+\def\nonfillfinish{\afterenvbreak\endgroup}%
+
+% This macro is
+\def\lisp{\begingroup
+  \nonfillstart
+  \let\Elisp = \nonfillfinish
+  \tt
+  \rawbackslash % have \ input char produce \ char from current font
+  \gobble
+}
+
+% Define the \E... control sequence only if we are inside the
+% environment, so the error checking in \end will work.
+%
+% We must call \lisp last in the definition, since it reads the
+% return following the @example (or whatever) command.
+%
+\def\example{\begingroup \def\Eexample{\nonfillfinish\endgroup}\lisp}
+\def\smallexample{\begingroup \def\Esmallexample{\nonfillfinish\endgroup}\lisp}
+\def\smalllisp{\begingroup \def\Esmalllisp{\nonfillfinish\endgroup}\lisp}
+
+% @smallexample and @smalllisp.  This is not used unless the @smallbook
+% command is given.  Originally contributed by Pavel@xerox.
+%
+\def\smalllispx{\begingroup
+  \nonfillstart
+  \let\Esmalllisp = \nonfillfinish
+  \let\Esmallexample = \nonfillfinish
+  %
+  % Smaller fonts for small examples.
+  \indexfonts \tt
+  \rawbackslash % make \ output the \ character from the current font (tt)
+  \gobble
+}
+
+% This is @display; same as @lisp except use roman font.
+%
+\def\display{\begingroup
+  \nonfillstart
+  \let\Edisplay = \nonfillfinish
+  \gobble
+}
+
+% This is @format; same as @display except don't narrow margins.
+%
+\def\format{\begingroup
+  \let\nonarrowing = t
+  \nonfillstart
+  \let\Eformat = \nonfillfinish
+  \gobble
+}
+
+% @flushleft (same as @format) and @flushright.
+%
+\def\flushleft{\begingroup
+  \let\nonarrowing = t
+  \nonfillstart
+  \let\Eflushleft = \nonfillfinish
+  \gobble
+}
+\def\flushright{\begingroup
+  \let\nonarrowing = t
+  \nonfillstart
+  \let\Eflushright = \nonfillfinish
+  \advance\leftskip by 0pt plus 1fill
+  \gobble}
+
+% @quotation does normal linebreaking (hence we can't use \nonfillstart)
+% and narrows the margins.
+%
+\def\quotation{%
+  \begingroup\inENV %This group ends at the end of the @quotation body
+  {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip
+  \singlespace
+  \parindent=0pt
+  % We have retained a nonzero parskip for the environment, since we're
+  % doing normal filling. So to avoid extra space below the environment...
+  \def\Equotation{\parskip = 0pt \nonfillfinish}%
+  %
+  % @cartouche defines \nonarrowing to inhibit narrowing at next level down.
+  \ifx\nonarrowing\relax
+    \advance\leftskip by \lispnarrowing
+    \advance\rightskip by \lispnarrowing
+    \exdentamount = \lispnarrowing
+    \let\nonarrowing = \relax
+  \fi
+}
+
+\message{defuns,}
+% Define formatter for defuns
+% First, allow user to change definition object font (\df) internally
+\def\setdeffont #1 {\csname DEF#1\endcsname}
+
+\newskip\defbodyindent \defbodyindent=.4in
+\newskip\defargsindent \defargsindent=50pt
+\newskip\deftypemargin \deftypemargin=12pt
+\newskip\deflastargmargin \deflastargmargin=18pt
+
+\newcount\parencount
+% define \functionparens, which makes ( and ) and & do special things.
+% \functionparens affects the group it is contained in.
+\def\activeparens{%
+\catcode`\(=\active \catcode`\)=\active \catcode`\&=\active
+\catcode`\[=\active \catcode`\]=\active}
+
+% Make control sequences which act like normal parenthesis chars.
+\let\lparen = ( \let\rparen = )
+
+{\activeparens % Now, smart parens don't turn on until &foo (see \amprm)
+
+% Be sure that we always have a definition for `(', etc.  For example,
+% if the fn name has parens in it, \boldbrax will not be in effect yet,
+% so TeX would otherwise complain about undefined control sequence.
+\global\let(=\lparen \global\let)=\rparen
+\global\let[=\lbrack \global\let]=\rbrack
+
+\gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 }
+\gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb}
+% This is used to turn on special parens
+% but make & act ordinary (given that it's active).
+\gdef\boldbraxnoamp{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb\let&=\ampnr}
+
+% Definitions of (, ) and & used in args for functions.
+% This is the definition of ( outside of all parentheses.
+\gdef\oprm#1 {{\rm\char`\(}#1 \bf \let(=\opnested %
+\global\advance\parencount by 1 }
+%
+% This is the definition of ( when already inside a level of parens.
+\gdef\opnested{\char`\(\global\advance\parencount by 1 }
+%
+\gdef\clrm{% Print a paren in roman if it is taking us back to depth of 0.
+% also in that case restore the outer-level definition of (.
+\ifnum \parencount=1 {\rm \char `\)}\sl \let(=\oprm \else \char `\) \fi
+\global\advance \parencount by -1 }
+% If we encounter &foo, then turn on ()-hacking afterwards
+\gdef\amprm#1 {{\rm\&#1}\let(=\oprm \let)=\clrm\ }
+%
+\gdef\normalparens{\boldbrax\let&=\ampnr}
+} % End of definition inside \activeparens
+%% These parens (in \boldbrax) actually are a little bolder than the
+%% contained text.  This is especially needed for [ and ]
+\def\opnr{{\sf\char`\(}} \def\clnr{{\sf\char`\)}} \def\ampnr{\&}
+\def\lbrb{{\bf\char`\[}} \def\rbrb{{\bf\char`\]}}
+
+% First, defname, which formats the header line itself.
+% #1 should be the function name.
+% #2 should be the type of definition, such as "Function".
+
+\def\defname #1#2{%
+% Get the values of \leftskip and \rightskip as they were
+% outside the @def...
+\dimen2=\leftskip
+\advance\dimen2 by -\defbodyindent
+\dimen3=\rightskip
+\advance\dimen3 by -\defbodyindent
+\noindent        %
+\setbox0=\hbox{\hskip \deflastargmargin{\rm #2}\hskip \deftypemargin}%
+\dimen0=\hsize \advance \dimen0 by -\wd0 % compute size for first line
+\dimen1=\hsize \advance \dimen1 by -\defargsindent %size for continuations
+\parshape 2 0in \dimen0 \defargsindent \dimen1     %
+% Now output arg 2 ("Function" or some such)
+% ending at \deftypemargin from the right margin,
+% but stuck inside a box of width 0 so it does not interfere with linebreaking
+{% Adjust \hsize to exclude the ambient margins,
+% so that \rightline will obey them.
+\advance \hsize by -\dimen2 \advance \hsize by -\dimen3
+\rlap{\rightline{{\rm #2}\hskip \deftypemargin}}}%
+% Make all lines underfull and no complaints:
+\tolerance=10000 \hbadness=10000
+\advance\leftskip by -\defbodyindent
+\exdentamount=\defbodyindent
+{\df #1}\enskip        % Generate function name
+}
+
+% Actually process the body of a definition
+% #1 should be the terminating control sequence, such as \Edefun.
+% #2 should be the "another name" control sequence, such as \defunx.
+% #3 should be the control sequence that actually processes the header,
+%    such as \defunheader.
+
+\def\defparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody
+\medbreak %
+% Define the end token that this defining construct specifies
+% so that it will exit this group.
+\def#1{\endgraf\endgroup\medbreak}%
+\def#2{\begingroup\obeylines\activeparens\spacesplit#3}%
+\parindent=0in
+\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent
+\exdentamount=\defbodyindent
+\begingroup %
+\catcode 61=\active % 61 is `='
+\obeylines\activeparens\spacesplit#3}
+
+\def\defmethparsebody #1#2#3#4 {\begingroup\inENV %
+\medbreak %
+% Define the end token that this defining construct specifies
+% so that it will exit this group.
+\def#1{\endgraf\endgroup\medbreak}%
+\def#2##1 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}}}%
+\parindent=0in
+\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent
+\exdentamount=\defbodyindent
+\begingroup\obeylines\activeparens\spacesplit{#3{#4}}}
+
+\def\defopparsebody #1#2#3#4#5 {\begingroup\inENV %
+\medbreak %
+% Define the end token that this defining construct specifies
+% so that it will exit this group.
+\def#1{\endgraf\endgroup\medbreak}%
+\def#2##1 ##2 {\def#4{##1}%
+\begingroup\obeylines\activeparens\spacesplit{#3{##2}}}%
+\parindent=0in
+\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent
+\exdentamount=\defbodyindent
+\begingroup\obeylines\activeparens\spacesplit{#3{#5}}}
+
+% These parsing functions are similar to the preceding ones
+% except that they do not make parens into active characters.
+% These are used for "variables" since they have no arguments.
+
+\def\defvarparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody
+\medbreak %
+% Define the end token that this defining construct specifies
+% so that it will exit this group.
+\def#1{\endgraf\endgroup\medbreak}%
+\def#2{\begingroup\obeylines\spacesplit#3}%
+\parindent=0in
+\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent
+\exdentamount=\defbodyindent
+\begingroup %
+\catcode 61=\active %
+\obeylines\spacesplit#3}
+
+% This is used for \def{tp,vr}parsebody.  It could probably be used for
+% some of the others, too, with some judicious conditionals.
+% 
+\def\parsebodycommon#1#2#3{%
+  \begingroup\inENV %
+  \medbreak %
+  % Define the end token that this defining construct specifies
+  % so that it will exit this group.
+  \def#1{\endgraf\endgroup\medbreak}%
+  \def#2##1 {\begingroup\obeylines\spacesplit{#3{##1}}}%
+  \parindent=0in
+  \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent
+  \exdentamount=\defbodyindent
+  \begingroup\obeylines
+}
+
+\def\defvrparsebody#1#2#3#4 {%
+  \parsebodycommon{#1}{#2}{#3}%
+  \spacesplit{#3{#4}}%
+}
+
+% This loses on `@deftp {Data Type} {struct termios}' -- it thinks the
+% type is just `struct', because we lose the braces in `{struct
+% termios}' when \spacesplit reads its undelimited argument.  Sigh.
+% \let\deftpparsebody=\defvrparsebody
+%
+% So, to get around this, we put \empty in with the type name.  That
+% way, TeX won't find exactly `{...}' as an undelimited argument, and
+% won't strip off the braces.
+%
+\def\deftpparsebody #1#2#3#4 {%
+  \parsebodycommon{#1}{#2}{#3}%
+  \spacesplit{\parsetpheaderline{#3{#4}}}\empty
+}
+
+% Fine, but then we have to eventually remove the \empty *and* the
+% braces (if any).  That's what this does, putting the result in \tptemp.
+% 
+\def\removeemptybraces\empty#1\relax{\def\tptemp{#1}}%
+
+% After \spacesplit has done its work, this is called -- #1 is the final
+% thing to call, #2 the type name (which starts with \empty), and #3
+% (which might be empty) the arguments.
+% 
+\def\parsetpheaderline#1#2#3{%
+  \removeemptybraces#2\relax
+  #1{\tptemp}{#3}%
+}%
+
+\def\defopvarparsebody #1#2#3#4#5 {\begingroup\inENV %
+\medbreak %
+% Define the end token that this defining construct specifies
+% so that it will exit this group.
+\def#1{\endgraf\endgroup\medbreak}%
+\def#2##1 ##2 {\def#4{##1}%
+\begingroup\obeylines\spacesplit{#3{##2}}}%
+\parindent=0in
+\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent
+\exdentamount=\defbodyindent
+\begingroup\obeylines\spacesplit{#3{#5}}}
+
+% Split up #2 at the first space token.
+% call #1 with two arguments:
+%  the first is all of #2 before the space token,
+%  the second is all of #2 after that space token.
+% If #2 contains no space token, all of it is passed as the first arg
+% and the second is passed as empty.
+
+{\obeylines
+\gdef\spacesplit#1#2^^M{\endgroup\spacesplitfoo{#1}#2 \relax\spacesplitfoo}%
+\long\gdef\spacesplitfoo#1#2 #3#4\spacesplitfoo{%
+\ifx\relax #3%
+#1{#2}{}\else #1{#2}{#3#4}\fi}}
+
+% So much for the things common to all kinds of definitions.
+
+% Define @defun.
+
+% First, define the processing that is wanted for arguments of \defun
+% Use this to expand the args and terminate the paragraph they make up
+
+\def\defunargs #1{\functionparens \sl
+% Expand, preventing hyphenation at `-' chars.
+% Note that groups don't affect changes in \hyphenchar.
+\hyphenchar\tensl=0
+#1%
+\hyphenchar\tensl=45
+\ifnum\parencount=0 \else \errmessage{unbalanced parens in @def arguments}\fi%
+\interlinepenalty=10000
+\advance\rightskip by 0pt plus 1fil
+\endgraf\penalty 10000\vskip -\parskip\penalty 10000%
+}
+
+\def\deftypefunargs #1{%
+% Expand, preventing hyphenation at `-' chars.
+% Note that groups don't affect changes in \hyphenchar.
+% Use \boldbraxnoamp, not \functionparens, so that & is not special.
+\boldbraxnoamp
+\tclose{#1}% avoid \code because of side effects on active chars
+\interlinepenalty=10000
+\advance\rightskip by 0pt plus 1fil
+\endgraf\penalty 10000\vskip -\parskip\penalty 10000%
+}
+
+% Do complete processing of one @defun or @defunx line already parsed.
+
+% @deffn Command forward-char nchars
+
+\def\deffn{\defmethparsebody\Edeffn\deffnx\deffnheader}
+
+\def\deffnheader #1#2#3{\doind {fn}{\code{#2}}%
+\begingroup\defname {#2}{#1}\defunargs{#3}\endgroup %
+\catcode 61=\other % Turn off change made in \defparsebody
+}
+
+% @defun == @deffn Function
+
+\def\defun{\defparsebody\Edefun\defunx\defunheader}
+
+\def\defunheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index
+\begingroup\defname {#1}{Function}%
+\defunargs {#2}\endgroup %
+\catcode 61=\other % Turn off change made in \defparsebody
+}
+
+% @deftypefun int foobar (int @var{foo}, float @var{bar})
+
+\def\deftypefun{\defparsebody\Edeftypefun\deftypefunx\deftypefunheader}
+
+% #1 is the data type.  #2 is the name and args.
+\def\deftypefunheader #1#2{\deftypefunheaderx{#1}#2 \relax}
+% #1 is the data type, #2 the name, #3 the args.
+\def\deftypefunheaderx #1#2 #3\relax{%
+\doind {fn}{\code{#2}}% Make entry in function index
+\begingroup\defname {\defheaderxcond#1\relax$$$#2}{Function}%
+\deftypefunargs {#3}\endgroup %
+\catcode 61=\other % Turn off change made in \defparsebody
+}
+
+% @deftypefn {Library Function} int foobar (int @var{foo}, float @var{bar})
+
+\def\deftypefn{\defmethparsebody\Edeftypefn\deftypefnx\deftypefnheader}
+
+% \defheaderxcond#1\relax$$$
+% puts #1 in @code, followed by a space, but does nothing if #1 is null.
+\def\defheaderxcond#1#2$$${\ifx#1\relax\else\code{#1#2} \fi}
+
+% #1 is the classification.  #2 is the data type.  #3 is the name and args.
+\def\deftypefnheader #1#2#3{\deftypefnheaderx{#1}{#2}#3 \relax}
+% #1 is the classification, #2 the data type, #3 the name, #4 the args.
+\def\deftypefnheaderx #1#2#3 #4\relax{%
+\doind {fn}{\code{#3}}% Make entry in function index
+\begingroup
+\normalparens % notably, turn off `&' magic, which prevents
+%               at least some C++ text from working
+\defname {\defheaderxcond#2\relax$$$#3}{#1}%
+\deftypefunargs {#4}\endgroup %
+\catcode 61=\other % Turn off change made in \defparsebody
+}
+
+% @defmac == @deffn Macro
+
+\def\defmac{\defparsebody\Edefmac\defmacx\defmacheader}
+
+\def\defmacheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index
+\begingroup\defname {#1}{Macro}%
+\defunargs {#2}\endgroup %
+\catcode 61=\other % Turn off change made in \defparsebody
+}
+
+% @defspec == @deffn Special Form
+
+\def\defspec{\defparsebody\Edefspec\defspecx\defspecheader}
+
+\def\defspecheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index
+\begingroup\defname {#1}{Special Form}%
+\defunargs {#2}\endgroup %
+\catcode 61=\other % Turn off change made in \defparsebody
+}
+
+% This definition is run if you use @defunx
+% anywhere other than immediately after a @defun or @defunx.
+
+\def\deffnx #1 {\errmessage{@deffnx in invalid context}}
+\def\defunx #1 {\errmessage{@defunx in invalid context}}
+\def\defmacx #1 {\errmessage{@defmacx in invalid context}}
+\def\defspecx #1 {\errmessage{@defspecx in invalid context}}
+\def\deftypefnx #1 {\errmessage{@deftypefnx in invalid context}}
+\def\deftypeunx #1 {\errmessage{@deftypeunx in invalid context}}
+
+% @defmethod, and so on
+
+% @defop {Funny Method} foo-class frobnicate argument
+
+\def\defop #1 {\def\defoptype{#1}%
+\defopparsebody\Edefop\defopx\defopheader\defoptype}
+
+\def\defopheader #1#2#3{%
+\dosubind {fn}{\code{#2}}{on #1}% Make entry in function index
+\begingroup\defname {#2}{\defoptype{} on #1}%
+\defunargs {#3}\endgroup %
+}
+
+% @defmethod == @defop Method
+
+\def\defmethod{\defmethparsebody\Edefmethod\defmethodx\defmethodheader}
+
+\def\defmethodheader #1#2#3{%
+\dosubind {fn}{\code{#2}}{on #1}% entry in function index
+\begingroup\defname {#2}{Method on #1}%
+\defunargs {#3}\endgroup %
+}
+
+% @defcv {Class Option} foo-class foo-flag
+
+\def\defcv #1 {\def\defcvtype{#1}%
+\defopvarparsebody\Edefcv\defcvx\defcvarheader\defcvtype}
+
+\def\defcvarheader #1#2#3{%
+\dosubind {vr}{\code{#2}}{of #1}% Make entry in var index
+\begingroup\defname {#2}{\defcvtype{} of #1}%
+\defvarargs {#3}\endgroup %
+}
+
+% @defivar == @defcv {Instance Variable}
+
+\def\defivar{\defvrparsebody\Edefivar\defivarx\defivarheader}
+
+\def\defivarheader #1#2#3{%
+\dosubind {vr}{\code{#2}}{of #1}% Make entry in var index
+\begingroup\defname {#2}{Instance Variable of #1}%
+\defvarargs {#3}\endgroup %
+}
+
+% These definitions are run if you use @defmethodx, etc.,
+% anywhere other than immediately after a @defmethod, etc.
+
+\def\defopx #1 {\errmessage{@defopx in invalid context}}
+\def\defmethodx #1 {\errmessage{@defmethodx in invalid context}}
+\def\defcvx #1 {\errmessage{@defcvx in invalid context}}
+\def\defivarx #1 {\errmessage{@defivarx in invalid context}}
+
+% Now @defvar
+
+% First, define the processing that is wanted for arguments of @defvar.
+% This is actually simple: just print them in roman.
+% This must expand the args and terminate the paragraph they make up
+\def\defvarargs #1{\normalparens #1%
+\interlinepenalty=10000
+\endgraf\penalty 10000\vskip -\parskip\penalty 10000}
+
+% @defvr Counter foo-count
+
+\def\defvr{\defvrparsebody\Edefvr\defvrx\defvrheader}
+
+\def\defvrheader #1#2#3{\doind {vr}{\code{#2}}%
+\begingroup\defname {#2}{#1}\defvarargs{#3}\endgroup}
+
+% @defvar == @defvr Variable
+
+\def\defvar{\defvarparsebody\Edefvar\defvarx\defvarheader}
+
+\def\defvarheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index
+\begingroup\defname {#1}{Variable}%
+\defvarargs {#2}\endgroup %
+}
+
+% @defopt == @defvr {User Option}
+
+\def\defopt{\defvarparsebody\Edefopt\defoptx\defoptheader}
+
+\def\defoptheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index
+\begingroup\defname {#1}{User Option}%
+\defvarargs {#2}\endgroup %
+}
+
+% @deftypevar int foobar
+
+\def\deftypevar{\defvarparsebody\Edeftypevar\deftypevarx\deftypevarheader}
+
+% #1 is the data type.  #2 is the name.
+\def\deftypevarheader #1#2{%
+\doind {vr}{\code{#2}}% Make entry in variables index
+\begingroup\defname {\defheaderxcond#1\relax$$$#2}{Variable}%
+\interlinepenalty=10000
+\endgraf\penalty 10000\vskip -\parskip\penalty 10000
+\endgroup}
+
+% @deftypevr {Global Flag} int enable
+
+\def\deftypevr{\defvrparsebody\Edeftypevr\deftypevrx\deftypevrheader}
+
+\def\deftypevrheader #1#2#3{\doind {vr}{\code{#3}}%
+\begingroup\defname {\defheaderxcond#2\relax$$$#3}{#1}
+\interlinepenalty=10000
+\endgraf\penalty 10000\vskip -\parskip\penalty 10000
+\endgroup}
+
+% This definition is run if you use @defvarx
+% anywhere other than immediately after a @defvar or @defvarx.
+
+\def\defvrx #1 {\errmessage{@defvrx in invalid context}}
+\def\defvarx #1 {\errmessage{@defvarx in invalid context}}
+\def\defoptx #1 {\errmessage{@defoptx in invalid context}}
+\def\deftypevarx #1 {\errmessage{@deftypevarx in invalid context}}
+\def\deftypevrx #1 {\errmessage{@deftypevrx in invalid context}}
+
+% Now define @deftp
+% Args are printed in bold, a slight difference from @defvar.
+
+\def\deftpargs #1{\bf \defvarargs{#1}}
+
+% @deftp Class window height width ...
+
+\def\deftp{\deftpparsebody\Edeftp\deftpx\deftpheader}
+
+\def\deftpheader #1#2#3{\doind {tp}{\code{#2}}%
+\begingroup\defname {#2}{#1}\deftpargs{#3}\endgroup}
+
+% This definition is run if you use @deftpx, etc
+% anywhere other than immediately after a @deftp, etc.
+
+\def\deftpx #1 {\errmessage{@deftpx in invalid context}}
+
+
+\message{cross reference,}
+% Define cross-reference macros
+\newwrite \auxfile
+
+\newif\ifhavexrefs  % True if xref values are known.
+\newif\ifwarnedxrefs  % True if we warned once that they aren't known.
+
+% @inforef is simple.
+\def\inforef #1{\inforefzzz #1,,,,**}
+\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}},
+  node \samp{\ignorespaces#1{}}}
+
+% \setref{foo} defines a cross-reference point named foo.
+
+\def\setref#1{%
+\dosetq{#1-title}{Ytitle}%
+\dosetq{#1-pg}{Ypagenumber}%
+\dosetq{#1-snt}{Ysectionnumberandtype}}
+
+\def\unnumbsetref#1{%
+\dosetq{#1-title}{Ytitle}%
+\dosetq{#1-pg}{Ypagenumber}%
+\dosetq{#1-snt}{Ynothing}}
+
+\def\appendixsetref#1{%
+\dosetq{#1-title}{Ytitle}%
+\dosetq{#1-pg}{Ypagenumber}%
+\dosetq{#1-snt}{Yappendixletterandtype}}
+
+% \xref, \pxref, and \ref generate cross-references to specified points.
+% For \xrefX, #1 is the node name, #2 the name of the Info
+% cross-reference, #3 the printed node name, #4 the name of the Info
+% file, #5 the name of the printed manual.  All but the node name can be
+% omitted.
+%
+\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]}
+\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]}
+\def\ref#1{\xrefX[#1,,,,,,,]}
+\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup
+  \def\printedmanual{\ignorespaces #5}%
+  \def\printednodename{\ignorespaces #3}%
+  \setbox1=\hbox{\printedmanual}%
+  \setbox0=\hbox{\printednodename}%
+  \ifdim \wd0 = 0pt
+    % No printed node name was explicitly given.
+    \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax
+      % Use the node name inside the square brackets.
+      \def\printednodename{\ignorespaces #1}%
+    \else
+      % Use the actual chapter/section title appear inside
+      % the square brackets.  Use the real section title if we have it.
+      \ifdim \wd1>0pt%
+        % It is in another manual, so we don't have it.
+        \def\printednodename{\ignorespaces #1}%
+      \else
+        \ifhavexrefs
+          % We know the real title if we have the xref values.
+          \def\printednodename{\refx{#1-title}{}}%
+        \else
+          % Otherwise just copy the Info node name.
+          \def\printednodename{\ignorespaces #1}%
+        \fi%
+      \fi
+    \fi
+  \fi
+  %
+  % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not
+  % insert empty discretionaries after hyphens, which means that it will
+  % not find a line break at a hyphen in a node names.  Since some manuals
+  % are best written with fairly long node names, containing hyphens, this
+  % is a loss.  Therefore, we give the text of the node name again, so it
+  % is as if TeX is seeing it for the first time.
+  \ifdim \wd1 > 0pt
+    \putwordsection{} ``\printednodename'' in \cite{\printedmanual}%
+  \else
+    % _ (for example) has to be the character _ for the purposes of the
+    % control sequence corresponding to the node, but it has to expand
+    % into the usual \leavevmode...\vrule stuff for purposes of
+    % printing. So we \turnoffactive for the \refx-snt, back on for the
+    % printing, back off for the \refx-pg.
+    {\turnoffactive \refx{#1-snt}{}}%
+    \space [\printednodename],\space
+    \turnoffactive \putwordpage\tie\refx{#1-pg}{}%
+  \fi
+\endgroup}
+
+% \dosetq is the interface for calls from other macros
+
+% Use \turnoffactive so that punctuation chars such as underscore
+% work in node names.
+\def\dosetq #1#2{{\let\folio=0 \turnoffactive \auxhat%
+\edef\next{\write\auxfile{\internalsetq {#1}{#2}}}%
+\next}}
+
+% \internalsetq {foo}{page} expands into
+% CHARACTERS 'xrdef {foo}{...expansion of \Ypage...}
+% When the aux file is read, ' is the escape character
+
+\def\internalsetq #1#2{'xrdef {#1}{\csname #2\endcsname}}
+
+% Things to be expanded by \internalsetq
+
+\def\Ypagenumber{\folio}
+
+\def\Ytitle{\thissection}
+
+\def\Ynothing{}
+
+\def\Ysectionnumberandtype{%
+\ifnum\secno=0 \putwordChapter\xreftie\the\chapno %
+\else \ifnum \subsecno=0 \putwordSection\xreftie\the\chapno.\the\secno %
+\else \ifnum \subsubsecno=0 %
+\putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno %
+\else %
+\putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno %
+\fi \fi \fi }
+
+\def\Yappendixletterandtype{%
+\ifnum\secno=0 \putwordAppendix\xreftie'char\the\appendixno{}%
+\else \ifnum \subsecno=0 \putwordSection\xreftie'char\the\appendixno.\the\secno %
+\else \ifnum \subsubsecno=0 %
+\putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno %
+\else %
+\putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno %
+\fi \fi \fi }
+
+\gdef\xreftie{'tie}
+
+% Use TeX 3.0's \inputlineno to get the line number, for better error
+% messages, but if we're using an old version of TeX, don't do anything.
+%
+\ifx\inputlineno\thisisundefined
+  \let\linenumber = \empty % Non-3.0.
+\else
+  \def\linenumber{\the\inputlineno:\space}
+\fi
+
+% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME.
+% If its value is nonempty, SUFFIX is output afterward.
+
+\def\refx#1#2{%
+  \expandafter\ifx\csname X#1\endcsname\relax
+    % If not defined, say something at least.
+    $\langle$un\-de\-fined$\rangle$%
+    \ifhavexrefs
+      \message{\linenumber Undefined cross reference `#1'.}%
+    \else
+      \ifwarnedxrefs\else
+        \global\warnedxrefstrue
+        \message{Cross reference values unknown; you must run TeX again.}%
+      \fi
+    \fi
+  \else
+    % It's defined, so just use it.
+    \csname X#1\endcsname
+  \fi
+  #2% Output the suffix in any case.
+}
+
+% Read the last existing aux file, if any.  No error if none exists.
+
+% This is the macro invoked by entries in the aux file.
+\def\xrdef #1#2{
+{\catcode`\'=\other\expandafter \gdef \csname X#1\endcsname {#2}}}
+
+\def\readauxfile{%
+\begingroup
+\catcode `\^^@=\other
+\catcode `\\ 1=\other
+\catcode `\\ 2=\other
+\catcode `\^^C=\other
+\catcode `\^^D=\other
+\catcode `\^^E=\other
+\catcode `\^^F=\other
+\catcode `\^^G=\other
+\catcode `\^^H=\other
+\catcode `\\v=\other
+\catcode `\^^L=\other
+\catcode `\\ e=\other
+\catcode `\\ f=\other
+\catcode `\\10=\other
+\catcode `\\11=\other
+\catcode `\\12=\other
+\catcode `\\13=\other
+\catcode `\\14=\other
+\catcode `\\15=\other
+\catcode `\\16=\other
+\catcode `\\17=\other
+\catcode `\\18=\other
+\catcode `\\19=\other
+\catcode 26=\other
+\catcode `\^^[=\other
+\catcode `\^^\=\other
+\catcode `\^^]=\other
+\catcode `\^^^=\other
+\catcode `\^^_=\other
+\catcode `\@=\other
+\catcode `\^=\other
+\catcode `\~=\other
+\catcode `\[=\other
+\catcode `\]=\other
+\catcode`\"=\other
+\catcode`\_=\other
+\catcode`\|=\other
+\catcode`\<=\other
+\catcode`\>=\other
+\catcode `\$=\other
+\catcode `\#=\other
+\catcode `\&=\other
+% `\+ does not work, so use 43.
+\catcode 43=\other
+% Make the characters 128-255 be printing characters
+{%
+  \count 1=128
+  \def\loop{%
+    \catcode\count 1=\other
+    \advance\count 1 by 1
+    \ifnum \count 1<256 \loop \fi
+  }%
+}%
+% the aux file uses ' as the escape.
+% Turn off \ as an escape so we do not lose on
+% entries which were dumped with control sequences in their names.
+% For example, 'xrdef {$\leq $-fun}{page ...} made by @defun ^^
+% Reference to such entries still does not work the way one would wish,
+% but at least they do not bomb out when the aux file is read in.
+\catcode `\{=1 \catcode `\}=2
+\catcode `\%=\other
+\catcode `\'=0
+\catcode`\^=7 % to make ^^e4 etc usable in xref tags 
+\catcode `\\=\other
+\openin 1 \jobname.aux
+\ifeof 1 \else \closein 1 \input \jobname.aux \global\havexrefstrue
+\global\warnedobstrue
+\fi
+% Open the new aux file.  Tex will close it automatically at exit.
+\openout \auxfile=\jobname.aux
+\endgroup}
+
+
+% Footnotes.
+
+\newcount \footnoteno
+
+% The trailing space in the following definition for supereject is
+% vital for proper filling; pages come out unaligned when you do a
+% pagealignmacro call if that space before the closing brace is
+% removed. (Generally, numeric constants should always be followed by a
+% space to prevent strange expansion errors.)
+\def\supereject{\par\penalty -20000\footnoteno =0 }
+
+% @footnotestyle is meaningful for info output only..
+\let\footnotestyle=\comment
+
+\let\ptexfootnote=\footnote
+
+{\catcode `\@=11
+%
+% Auto-number footnotes.  Otherwise like plain.
+\gdef\footnote{%
+  \global\advance\footnoteno by \@ne
+  \edef\thisfootno{$^{\the\footnoteno}$}%
+  %
+  % In case the footnote comes at the end of a sentence, preserve the
+  % extra spacing after we do the footnote number.
+  \let\@sf\empty
+  \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\/\fi
+  %
+  % Remove inadvertent blank space before typesetting the footnote number.
+  \unskip
+  \thisfootno\@sf
+  \footnotezzz
+}%
+
+% Don't bother with the trickery in plain.tex to not require the
+% footnote text as a parameter.  Our footnotes don't need to be so general.
+%
+\long\gdef\footnotezzz#1{\insert\footins{%
+  % We want to typeset this text as a normal paragraph, even if the
+  % footnote reference occurs in (for example) a display environment.
+  % So reset some parameters.
+  \interlinepenalty\interfootnotelinepenalty
+  \splittopskip\ht\strutbox % top baseline for broken footnotes
+  \splitmaxdepth\dp\strutbox
+  \floatingpenalty\@MM
+  \leftskip\z@skip
+  \rightskip\z@skip
+  \spaceskip\z@skip
+  \xspaceskip\z@skip
+  \parindent\defaultparindent
+  %
+  % Hang the footnote text off the number.
+  \hang
+  \textindent{\thisfootno}%
+  %
+  % Don't crash into the line above the footnote text.  Since this
+  % expands into a box, it must come within the paragraph, lest it
+  % provide a place where TeX can split the footnote.
+  \footstrut
+  #1\strut}%
+}
+
+}%end \catcode `\@=11
+
+% Set the baselineskip to #1, and the lineskip and strut size
+% correspondingly.  There is no deep meaning behind these magic numbers
+% used as factors; they just match (closely enough) what Knuth defined.
+%
+\def\lineskipfactor{.08333}
+\def\strutheightpercent{.70833}
+\def\strutdepthpercent {.29167}
+%
+\def\setleading#1{%
+  \normalbaselineskip = #1\relax
+  \normallineskip = \lineskipfactor\normalbaselineskip
+  \normalbaselines
+  \setbox\strutbox =\hbox{%
+    \vrule width0pt height\strutheightpercent\baselineskip
+                    depth \strutdepthpercent \baselineskip
+  }%
+}
+
+% @| inserts a changebar to the left of the current line.  It should
+% surround any changed text.  This approach does *not* work if the
+% change spans more than two lines of output.  To handle that, we would
+% have adopt a much more difficult approach (putting marks into the main
+% vertical list for the beginning and end of each change).
+%
+\def\|{%
+  % \vadjust can only be used in horizontal mode.
+  \leavevmode
+  %
+  % Append this vertical mode material after the current line in the output.
+  \vadjust{%
+    % We want to insert a rule with the height and depth of the current
+    % leading; that is exactly what \strutbox is supposed to record.
+    \vskip-\baselineskip
+    %
+    % \vadjust-items are inserted at the left edge of the type.  So
+    % the \llap here moves out into the left-hand margin.
+    \llap{%
+      %
+      % For a thicker or thinner bar, change the `1pt'.
+      \vrule height\baselineskip width1pt
+      %
+      % This is the space between the bar and the text.
+      \hskip 12pt
+    }%
+  }%
+}
+
+% For a final copy, take out the rectangles
+% that mark overfull boxes (in case you have decided
+% that the text looks ok even though it passes the margin).
+%
+\def\finalout{\overfullrule=0pt}
+
+
+% End of control word definitions.
+
+\message{and turning on texinfo input format.}
+
+\def\openindices{%
+   \newindex{cp}%
+   \newcodeindex{fn}%
+   \newcodeindex{vr}%
+   \newcodeindex{tp}%
+   \newcodeindex{ky}%
+   \newcodeindex{pg}%
+}
+
+% Set some numeric style parameters, for 8.5 x 11 format.
+
+\hsize = 6in
+\hoffset = .25in
+\newdimen\defaultparindent \defaultparindent = 15pt
+\parindent = \defaultparindent
+\parskip 3pt plus 2pt minus 1pt
+\setleading{13.2pt}
+\advance\topskip by 1.2cm
+
+\chapheadingskip = 15pt plus 4pt minus 2pt
+\secheadingskip = 12pt plus 3pt minus 2pt
+\subsecheadingskip = 9pt plus 2pt minus 2pt
+
+% Prevent underfull vbox error messages.
+\vbadness=10000
+
+% Following George Bush, just get rid of widows and orphans.
+\widowpenalty=10000
+\clubpenalty=10000
+
+% Use TeX 3.0's \emergencystretch to help line breaking, but if we're
+% using an old version of TeX, don't do anything.  We want the amount of
+% stretch added to depend on the line length, hence the dependence on
+% \hsize.  This makes it come to about 9pt for the 8.5x11 format.
+%
+\ifx\emergencystretch\thisisundefined
+  % Allow us to assign to \emergencystretch anyway.
+  \def\emergencystretch{\dimen0}%
+\else
+  \emergencystretch = \hsize
+  \divide\emergencystretch by 45
+\fi
+
+% Use @smallbook to reset parameters for 7x9.5 format  (or else 7x9.25)
+\def\smallbook{
+  \global\chapheadingskip = 15pt plus 4pt minus 2pt
+  \global\secheadingskip = 12pt plus 3pt minus 2pt
+  \global\subsecheadingskip = 9pt plus 2pt minus 2pt
+  %
+  \global\lispnarrowing = 0.3in
+  \setleading{12pt}
+  \advance\topskip by -1cm
+  \global\parskip 2pt plus 1pt
+  \global\hsize = 5in
+  \global\vsize=7.5in
+  \global\tolerance=700
+  \global\hfuzz=1pt
+  \global\contentsrightmargin=0pt
+  \global\deftypemargin=0pt
+  \global\defbodyindent=.5cm
+  %
+  \global\pagewidth=\hsize
+  \global\pageheight=\vsize
+  %
+  \global\let\smalllisp=\smalllispx
+  \global\let\smallexample=\smalllispx
+  \global\def\Esmallexample{\Esmalllisp}
+}
+
+% Use @afourpaper to print on European A4 paper.
+\def\afourpaper{
+\global\tolerance=700
+\global\hfuzz=1pt
+\setleading{12pt}
+\global\parskip 15pt plus 1pt
+
+\global\vsize= 53\baselineskip
+\advance\vsize by \topskip
+%\global\hsize=   5.85in     % A4 wide 10pt
+\global\hsize=  6.5in
+\global\outerhsize=\hsize
+\global\advance\outerhsize by 0.5in
+\global\outervsize=\vsize
+\global\advance\outervsize by 0.6in
+
+\global\pagewidth=\hsize
+\global\pageheight=\vsize
+}
+
+\bindingoffset=0pt
+\normaloffset=\hoffset
+\pagewidth=\hsize
+\pageheight=\vsize
+
+% Allow control of the text dimensions.  Parameters in order: textheight;
+% textwidth; voffset; hoffset; binding offset; topskip.
+% All require a dimension;
+% header is additional; added length extends the bottom of the page.
+
+\def\changepagesizes#1#2#3#4#5#6{
+ \global\vsize= #1
+ \global\topskip= #6
+ \advance\vsize by \topskip
+ \global\voffset= #3
+ \global\hsize= #2
+ \global\outerhsize=\hsize
+ \global\advance\outerhsize by 0.5in
+ \global\outervsize=\vsize
+ \global\advance\outervsize by 0.6in
+ \global\pagewidth=\hsize
+ \global\pageheight=\vsize
+ \global\normaloffset= #4
+ \global\bindingoffset= #5}
+
+% A specific text layout, 24x15cm overall, intended for A4 paper.  Top margin
+% 29mm, hence bottom margin 28mm, nominal side margin 3cm.
+\def\afourlatex
+        {\global\tolerance=700
+        \global\hfuzz=1pt
+        \setleading{12pt}
+        \global\parskip 15pt plus 1pt
+        \advance\baselineskip by 1.6pt
+        \changepagesizes{237mm}{150mm}{3.6mm}{3.6mm}{3mm}{7mm}
+        }
+
+% Use @afourwide to print on European A4 paper in wide format.
+\def\afourwide{\afourpaper
+\changepagesizes{9.5in}{6.5in}{\hoffset}{\normaloffset}{\bindingoffset}{7mm}}
+
+% Define macros to output various characters with catcode for normal text.
+\catcode`\"=\other
+\catcode`\~=\other
+\catcode`\^=\other
+\catcode`\_=\other
+\catcode`\|=\other
+\catcode`\<=\other
+\catcode`\>=\other
+\catcode`\+=\other
+\def\normaldoublequote{"}
+\def\normaltilde{~}
+\def\normalcaret{^}
+\def\normalunderscore{_}
+\def\normalverticalbar{|}
+\def\normalless{<}
+\def\normalgreater{>}
+\def\normalplus{+}
+
+% This macro is used to make a character print one way in ttfont
+% where it can probably just be output, and another way in other fonts,
+% where something hairier probably needs to be done.
+%
+% #1 is what to print if we are indeed using \tt; #2 is what to print
+% otherwise.  Since all the Computer Modern typewriter fonts have zero
+% interword stretch (and shrink), and it is reasonable to expect all
+% typewriter fonts to have this, we can check that font parameter.
+%
+\def\ifusingtt#1#2{\ifdim \fontdimen3\the\font=0pt #1\else #2\fi}
+
+% Turn off all special characters except @
+% (and those which the user can use as if they were ordinary).
+% Most of these we simply print from the \tt font, but for some, we can
+% use math or other variants that look better in normal text.
+
+\catcode`\"=\active
+\def\activedoublequote{{\tt \char '042}}
+\let"=\activedoublequote
+\catcode`\~=\active
+\def~{{\tt \char '176}}
+\chardef\hat=`\^
+\catcode`\^=\active
+\def\auxhat{\def^{'hat}}
+\def^{{\tt \hat}}
+
+\catcode`\_=\active
+\def_{\ifusingtt\normalunderscore\_}
+% Subroutine for the previous macro.
+\def\_{\leavevmode \kern.06em \vbox{\hrule width.3em height.1ex}}
+
+\catcode`\|=\active
+\def|{{\tt \char '174}}
+\chardef \less=`\<
+\catcode`\<=\active
+\def<{{\tt \less}}
+\chardef \gtr=`\>
+\catcode`\>=\active
+\def>{{\tt \gtr}}
+\catcode`\+=\active
+\def+{{\tt \char 43}}
+%\catcode 27=\active
+%\def^^[{$\diamondsuit$}
+
+% Set up an active definition for =, but don't enable it most of the time.
+{\catcode`\==\active
+\global\def={{\tt \char 61}}}
+
+\catcode`+=\active
+\catcode`\_=\active
+
+% If a .fmt file is being used, characters that might appear in a file
+% name cannot be active until we have parsed the command line.
+% So turn them off again, and have \everyjob (or @setfilename) turn them on.
+% \otherifyactive is called near the end of this file.
+\def\otherifyactive{\catcode`+=\other \catcode`\_=\other}
+
+\catcode`\@=0
+
+% \rawbackslashxx output one backslash character in current font
+\global\chardef\rawbackslashxx=`\\
+%{\catcode`\\=\other
+%@gdef@rawbackslashxx{\}}
+
+% \rawbackslash redefines \ as input to do \rawbackslashxx.
+{\catcode`\\=\active
+@gdef@rawbackslash{@let\=@rawbackslashxx }}
+
+% \normalbackslash outputs one backslash in fixed width font.
+\def\normalbackslash{{\tt\rawbackslashxx}}
+
+% Say @foo, not \foo, in error messages.
+\escapechar=`\@
+
+% \catcode 17=0   % Define control-q
+\catcode`\\=\active
+
+% Used sometimes to turn off (effectively) the active characters
+% even after parsing them.
+@def@turnoffactive{@let"=@normaldoublequote
+@let\=@realbackslash
+@let~=@normaltilde
+@let^=@normalcaret
+@let_=@normalunderscore
+@let|=@normalverticalbar
+@let<=@normalless
+@let>=@normalgreater
+@let+=@normalplus}
+
+@def@normalturnoffactive{@let"=@normaldoublequote
+@let\=@normalbackslash
+@let~=@normaltilde
+@let^=@normalcaret
+@let_=@normalunderscore
+@let|=@normalverticalbar
+@let<=@normalless
+@let>=@normalgreater
+@let+=@normalplus}
+
+% Make _ and + \other characters, temporarily.
+% This is canceled by @fixbackslash.
+@otherifyactive
+
+% If a .fmt file is being used, we don't want the `\input texinfo' to show up.
+% That is what \eatinput is for; after that, the `\' should revert to printing
+% a backslash.
+%
+@gdef@eatinput input texinfo{@fixbackslash}
+@global@let\ = @eatinput
+
+% On the other hand, perhaps the file did not have a `\input texinfo'. Then
+% the first `\{ in the file would cause an error. This macro tries to fix
+% that, assuming it is called before the first `\' could plausibly occur.
+% Also back turn on active characters that might appear in the input
+% file name, in case not using a pre-dumped format.
+%
+@gdef@fixbackslash{@ifx\@eatinput @let\ = @normalbackslash @fi
+  @catcode`+=@active @catcode`@_=@active}
+
+%% These look ok in all fonts, so just make them not special.  The @rm below
+%% makes sure that the current font starts out as the newly loaded cmr10
+@catcode`@$=@other @catcode`@%=@other @catcode`@&=@other @catcode`@#=@other
+
+@textfonts
+@rm
+
+@c Local variables:
+@c page-delimiter: "^\\\\message"
+@c End:
diff --git a/gdk/.cvsignore b/gdk/.cvsignore
new file mode 100644 (file)
index 0000000..79680c8
--- /dev/null
@@ -0,0 +1,6 @@
+*.lo
+Makefile
+.deps
+_libs
+libgdk.la
+
diff --git a/gdk/Makefile.am b/gdk/Makefile.am
new file mode 100644 (file)
index 0000000..f298e2c
--- /dev/null
@@ -0,0 +1,75 @@
+## Process this file with automake to produce Makefile.in
+
+gdkincludedir = $(includedir)/gdk
+
+lib_LTLIBRARIES = libgdk.la
+
+libgdk_la_SOURCES = \
+       gdk.c           \
+       gdkcolor.c      \
+       gdkcursor.c     \
+       gdkdraw.c       \
+       gdkfont.c       \
+       gdkgc.c         \
+       gdkglobals.c    \
+       gdkimage.c      \
+       gdkinput.c      \
+       gdkpixmap.c     \
+       gdkproperty.c   \
+       gdkrectangle.c  \
+       gdkselection.c  \
+       gdkvisual.c     \
+       gdkwindow.c     \
+       gdkxid.c        \
+        gxid_lib.c
+## this last one is ifdef'd out unless XINPUT_GXI is defined
+## It's easier than trying to get automake to handle compiling
+## it conditionally
+
+gdkinclude_HEADERS = \
+       gdk.h           \
+       gdkcursors.h    \
+       gdkkeysyms.h    \
+       gdkprivate.h    \
+       gdktypes.h      \
+       gdkinput.h      \
+       gdkinputnone.h  \
+       gdkinputcommon.h\
+       gdkinputgxi.h   \
+       gdkinputxfree.h \
+       gxid_lib.h      \
+       gxid_proto.h    \
+       gdkx.h
+
+libgdk_la_LDFLAGS = -version-info 1:0:0 \
+       @x_ldflags@ @x_libs@
+
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/glib @x_cflags@ 
+
+EXTRA_PROGRAMS = gxid
+
+bin_PROGRAMS = @xinput_progs@
+
+gxid_SOURCES = gxid.c
+
+gxid_LDADD = \
+       @x_ldflags@                             \
+       @x_libs@                                \
+       -lm
+
+BUILT_SOURCES = gdkcursors.h gdkkeysyms.h
+
+EXTRA_DIST = makecursors makecursors.sed makekeysyms makekeysyms.sed
+
+gdkcursors.h:
+       $(srcdir)/makecursors @x_includes@/X11/cursorfont.h > $@
+
+gdkkeysyms.h:
+       $(srcdir)/makekeysyms @x_includes@/X11/keysymdef.h > $@
+
+.PHONY: files
+
+files:
+       @files=`ls $(DISTFILES) 2> /dev/null `; for p in $$files; do \
+         echo $$p; \
+       done
diff --git a/gdk/gdk.c b/gdk/gdk.c
new file mode 100644 (file)
index 0000000..d5f85dd
--- /dev/null
+++ b/gdk/gdk.c
@@ -0,0 +1,2897 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "../config.h"
+
+#include <ctype.h>
+#include <locale.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif /* HAVE_SYS_SELECT_H_ */
+
+#define XLIB_ILLEGAL_ACCESS
+#include <X11/Xatom.h>
+#include <X11/Xlib.h>
+#include <X11/Xos.h>
+#include <X11/Xutil.h>
+#include <X11/Xmu/WinUtil.h>
+#include <X11/cursorfont.h>
+#include "gdk.h"
+#include "gdkprivate.h"
+#include "gdkinput.h"
+
+
+#ifndef X_GETTIMEOFDAY
+#define X_GETTIMEOFDAY(tv)  gettimeofday (tv, NULL)
+#endif /* X_GETTIMEOFDAY */
+
+
+#define DOUBLE_CLICK_TIME      250
+#define TRIPLE_CLICK_TIME      500
+#define DOUBLE_CLICK_DIST      5
+#define TRIPLE_CLICK_DIST      5
+
+
+#ifndef NO_FD_SET
+#  define SELECT_MASK fd_set
+#else
+#  ifndef _AIX
+     typedef long fd_mask;
+#  endif
+#  if defined(_IBMR2)
+#    define SELECT_MASK void
+#  else
+#    define SELECT_MASK int
+#  endif
+#endif
+
+
+typedef struct _GdkInput      GdkInput;
+typedef struct _GdkPredicate  GdkPredicate;
+
+struct _GdkInput
+{
+  gint tag;
+  gint source;
+  GdkInputCondition condition;
+  GdkInputFunction function;
+  gpointer data;
+};
+
+struct _GdkPredicate
+{
+  GdkEventFunc func;
+  gpointer data;
+};
+
+/* 
+ * Private function declarations
+ */
+static gint      gdk_event_wait         (void);
+static gint      gdk_event_translate    (GdkEvent     *event, 
+                                        XEvent       *xevent);
+static Bool      gdk_event_get_type     (Display      *display, 
+                                        XEvent       *xevent, 
+                                        XPointer      arg);
+static void      gdk_synthesize_click   (GdkEvent     *event, 
+                                        gint          nclicks);
+
+static void      gdk_dnd_drag_begin     (GdkWindow    *initial_window);
+static void      gdk_dnd_drag_enter     (Window        dest);
+static void      gdk_dnd_drag_leave     (Window        dest);
+static void      gdk_dnd_drag_end       (Window        dest, 
+                                        GdkPoint      coords);
+static GdkAtom   gdk_dnd_check_types    (GdkWindow    *window,
+                                        XEvent       *xevent);
+static void      gdk_print_atom         (GdkAtom       anatom);
+
+/* 
+ * old junk from offix, we might use it though so leave it 
+ */
+static Window       gdk_drop_get_client_window   (Display     *dpy, 
+                                                 Window       win);
+static GdkWindow *  gdk_drop_get_real_window     (GdkWindow   *w, 
+                                                 guint16     *x,
+                                                 guint16     *y);
+static void         gdk_exit_func                (void);
+static int          gdk_x_error                  (Display     *display, 
+                                                 XErrorEvent *error);
+static int          gdk_x_io_error               (Display     *display);
+static RETSIGTYPE   gdk_signal                   (int          signum);
+
+
+/* Private variable declarations
+ */
+static int initialized = 0;                         /* 1 if the library is initialized,
+                                                    * 0 otherwise.
+                                                    */
+static int connection_number = 0;                   /* The file descriptor number of our
+                                                    *  connection to the X server. This
+                                                    *  is used so that we may determine
+                                                    *  when events are pending by using
+                                                    *  the "select" system call.
+                                                    */
+
+static gint received_destroy_notify = FALSE;        /* Did we just receive a destroy notify
+                                                    *  event? If so, we need to actually
+                                                    *  destroy the window which received
+                                                    *  it now.
+                                                    */
+static GdkWindow *window_to_destroy = NULL;         /* If we previously received a destroy
+                                                    *  notify event then this is the window
+                                                    *  which received that event.
+                                                    */
+
+static struct timeval start;                        /* The time at which the library was
+                                                    *  last initialized.
+                                                    */
+static struct timeval timer;                        /* Timeout interval to use in the call
+                                                    *  to "select". This is used in
+                                                    *  conjunction with "timerp" to create
+                                                    *  a maximum time to wait for an event
+                                                    *  to arrive.
+                                                    */
+static struct timeval *timerp;                      /* The actual timer passed to "select"
+                                                    *  This may be NULL, in which case
+                                                    *  "select" will block until an event
+                                                    *  arrives.
+                                                    */
+static guint32 timer_val;                           /* The timeout length as specified by
+                                                    *  the user in milliseconds.
+                                                    */
+static GList *inputs;                               /* A list of the input file descriptors
+                                                    *  that we care about. Each list node
+                                                    *  contains a GdkInput struct that describes
+                                                    *  when we are interested in the specified
+                                                    *  file descriptor. That is, when it is
+                                                    *  available for read, write or has an
+                                                    *  exception pending.
+                                                    */
+static guint32 button_click_time[2];                /* The last 2 button click times. Used
+                                                    *  to determine if the latest button click
+                                                    *  is part of a double or triple click.
+                                                    */
+static GdkWindow *button_window[2];                 /* The last 2 windows to receive button presses.
+                                                    *  Also used to determine if the latest button
+                                                    *  click is part of a double or triple click.
+                                                    */
+static guint button_number[2];                      /* The last 2 buttons to be pressed.
+                                                    */
+
+#define OTHER_XEVENT_BUFSIZE 4
+static XEvent other_xevent[OTHER_XEVENT_BUFSIZE];   /* XEvents passed along to user  */
+static int other_xevent_i = 0;
+static GList *putback_events = NULL;
+
+static gulong base_id;
+static gint autorepeat;
+
+
+/*
+ *--------------------------------------------------------------
+ * gdk_init
+ *
+ *   Initialize the library for use.
+ *
+ * Arguments:
+ *   "argc" is the number of arguments.
+ *   "argv" is an array of strings.
+ *
+ * Results:
+ *   "argc" and "argv" are modified to reflect any arguments
+ *   which were not handled. (Such arguments should either
+ *   be handled by the application or dismissed).
+ *
+ * Side effects:
+ *   The library is initialized.
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+gdk_init (int    *argc,
+         char ***argv)
+{
+  XKeyboardState keyboard_state;
+  int synchronize;
+  int i, j, k;
+  XClassHint *class_hint;
+  int argc_orig = *argc;
+  char **argv_orig;
+
+  argv_orig = malloc ((argc_orig + 1) * sizeof (char*));
+  for (i = 0; i < argc_orig; i++)
+    argv_orig[i] = g_strdup ((*argv)[i]);
+  argv_orig[argc_orig] = NULL;
+
+  X_GETTIMEOFDAY (&start);
+
+  signal (SIGHUP, gdk_signal);
+  signal (SIGINT, gdk_signal);
+  signal (SIGQUIT, gdk_signal);
+  signal (SIGBUS, gdk_signal);
+  signal (SIGSEGV, gdk_signal);
+  signal (SIGPIPE, gdk_signal);
+  signal (SIGTERM, gdk_signal);
+
+  gdk_display_name = NULL;
+
+  XSetErrorHandler (gdk_x_error);
+  XSetIOErrorHandler (gdk_x_io_error);
+
+  synchronize = FALSE;
+
+  if (argc && argv)
+    {
+      if (*argc > 0)
+       gdk_progname = (*argv)[0];
+
+      for (i = 1; i < *argc;)
+       {
+         if (strcmp ("--display", (*argv)[i]) == 0)
+           {
+             (*argv)[i] = NULL;
+
+             if ((i + 1) < *argc)
+               {
+                 gdk_display_name = g_strdup ((*argv)[i + 1]);
+                 (*argv)[i + 1] = NULL;
+                 i += 1;
+               }
+           }
+         else if (strcmp ("--sync", (*argv)[i]) == 0)
+           {
+             (*argv)[i] = NULL;
+             synchronize = TRUE;
+           }
+         else if (strcmp ("--show-events", (*argv)[i]) == 0)
+           {
+             (*argv)[i] = NULL;
+             gdk_show_events = TRUE;
+           }
+         else if (strcmp ("--no-show-events", (*argv)[i]) == 0)
+           {
+             (*argv)[i] = NULL;
+             gdk_show_events = FALSE;
+           }
+         else if (strcmp ("--no-xshm", (*argv)[i]) == 0)
+           {
+             (*argv)[i] = NULL;
+             gdk_use_xshm = FALSE;
+           }
+         else if (strcmp ("--debug-level", (*argv)[i]) == 0)
+           {
+             if ((i + 1) < *argc)
+               {
+                 (*argv)[i++] = NULL;
+                 gdk_debug_level = atoi ((*argv)[i]);
+                 (*argv)[i] = NULL;
+               }
+           }
+         else if (strcmp ("-name", (*argv)[i]) == 0)
+           {
+             if ((i + 1) < *argc)
+               {
+                 (*argv)[i++] = NULL;
+                 gdk_progname = (*argv)[i];
+                 (*argv)[i] = NULL;
+               }
+           }
+         else if (strcmp ("-class", (*argv)[i]) == 0)
+           {
+             if ((i + 1) < *argc)
+               {
+                 (*argv)[i++] = NULL;
+                 gdk_progclass = (*argv)[i];
+                 (*argv)[i] = NULL;
+               }
+           }
+#ifdef XINPUT_GXI
+         else if (strcmp ("--gxid_host", (*argv)[i]) == 0)
+           {
+             if ((i + 1) < *argc)
+               {
+                 (*argv)[i++] = NULL;
+                 gdk_input_gxid_host = ((*argv)[i]);
+                 (*argv)[i] = NULL;
+               }
+           }
+         else if (strcmp ("--gxid_port", (*argv)[i]) == 0)
+           {
+             if ((i + 1) < *argc)
+               {
+                 (*argv)[i++] = NULL;
+                 gdk_input_gxid_port = atoi ((*argv)[i]);
+                 (*argv)[i] = NULL;
+               }
+           }
+#endif
+         i += 1;
+       }
+
+      for (i = 1; i < *argc; i++)
+       {
+         for (k = i; k < *argc; k++)
+           if ((*argv)[k] != NULL)
+             break;
+
+         if (k > i)
+           {
+             k -= i;
+             for (j = i + k; j < *argc; j++)
+               (*argv)[j-k] = (*argv)[j];
+             *argc -= k;
+           }
+       }
+    }
+  else
+    {
+      gdk_progname = "<unknown>";
+    }
+
+  gdk_display = XOpenDisplay (gdk_display_name);
+  if (!gdk_display)
+    g_error ("cannot open display: %s", XDisplayName (gdk_display_name));
+
+  /* This is really crappy. We have to look into the display structure
+   *  to find the base resource id. This is only needed for recording
+   *  and playback of events.
+   */
+  /* base_id = RESOURCE_BASE; */
+  base_id = 0;
+  if (gdk_show_events)
+    g_print ("base id: %lu\n", base_id);
+
+  connection_number = ConnectionNumber (gdk_display);
+  if (gdk_debug_level >= 1)
+    g_print ("connection number: %d\n", connection_number);
+
+  if (synchronize)
+    XSynchronize (gdk_display, True);
+
+  gdk_screen = DefaultScreen (gdk_display);
+  gdk_root_window = RootWindow (gdk_display, gdk_screen);
+
+  gdk_leader_window = XCreateSimpleWindow(gdk_display, gdk_root_window,
+                                         10, 10, 10, 10, 0, 0 , 0);
+  class_hint = XAllocClassHint();
+  class_hint->res_name = gdk_progname;
+  class_hint->res_class = gdk_progclass;
+  XSetClassHint(gdk_display, gdk_leader_window, class_hint);
+  XSetCommand(gdk_display, gdk_leader_window, argv_orig, argc_orig);
+  XFree (class_hint);
+
+  gdk_wm_delete_window = XInternAtom (gdk_display, "WM_DELETE_WINDOW", True);
+  gdk_wm_take_focus = XInternAtom (gdk_display, "WM_TAKE_FOCUS", True);
+  gdk_wm_protocols = XInternAtom (gdk_display, "WM_PROTOCOLS", True);
+  gdk_wm_window_protocols[0] = gdk_wm_delete_window;
+  gdk_wm_window_protocols[1] = gdk_wm_take_focus;
+  gdk_selection_property = XInternAtom (gdk_display, "GDK_SELECTION", False);
+
+  gdk_dnd.gdk_XdeEnter = gdk_atom_intern("_XDE_ENTER", FALSE);
+  gdk_dnd.gdk_XdeLeave = gdk_atom_intern("_XDE_LEAVE", FALSE);
+  gdk_dnd.gdk_XdeRequest = gdk_atom_intern("_XDE_REQUEST", FALSE);
+  gdk_dnd.gdk_XdeDataAvailable = gdk_atom_intern("_XDE_DATA_AVAILABLE", FALSE);
+  gdk_dnd.gdk_XdeTypelist = gdk_atom_intern("_XDE_TYPELIST", FALSE);
+  gdk_dnd.gdk_cursor_dragdefault = XCreateFontCursor(gdk_display, XC_bogosity);
+  gdk_dnd.gdk_cursor_dragok = XCreateFontCursor(gdk_display, XC_heart);
+
+  XGetKeyboardControl (gdk_display, &keyboard_state);
+  autorepeat = keyboard_state.global_auto_repeat;
+
+  timer.tv_sec = 0;
+  timer.tv_usec = 0;
+  timerp = NULL;
+
+  button_click_time[0] = 0;
+  button_click_time[1] = 0;
+  button_window[0] = NULL;
+  button_window[1] = NULL;
+  button_number[0] = -1;
+  button_number[1] = -1;
+
+  if (ATEXIT (gdk_exit_func))
+    g_warning ("unable to register exit function");
+
+  gdk_visual_init ();
+  gdk_window_init ();
+  gdk_image_init ();
+  gdk_input_init ();
+
+  initialized = 1;
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_exit
+ *
+ *   Restores the library to an un-itialized state and exits
+ *   the program using the "exit" system call.
+ *
+ * Arguments:
+ *   "errorcode" is the error value to pass to "exit".
+ *
+ * Results:
+ *   Allocated structures are freed and the program exits
+ *   cleanly.
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+gdk_exit (int errorcode)
+{
+ /* de-initialisation is done by the gdk_exit_funct(),
+    no need to do this here (Alex J.) */
+ exit (errorcode);
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_set_locale
+ *
+ * Arguments:
+ *
+ * Results:
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+gchar*
+gdk_set_locale ()
+{
+  if (!setlocale (LC_ALL,""))
+    g_print ("locale not supported by C library\n");
+
+  if (!XSupportsLocale ())
+    {
+      g_print ("locale not supported by Xlib, locale set to C\n");
+      setlocale (LC_ALL, "C");
+    }
+
+  if (!XSetLocaleModifiers (""))
+    {
+      g_print ("can not set locale modifiers\n");
+    }
+
+  return setlocale (LC_ALL,NULL);
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_events_pending
+ *
+ *   Returns the number of events pending on the queue.
+ *   These events have already been read from the server
+ *   connection.
+ *
+ * Arguments:
+ *
+ * Results:
+ *   Returns the number of events on XLib's event queue.
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+gint
+gdk_events_pending ()
+{
+  return XPending (gdk_display);
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_event_get
+ *
+ *   Gets the next event.
+ *
+ * Arguments:
+ *   "event" is used to hold the received event.
+ *   If "event" is NULL an event is received as normal
+ *   however it is not placed in "event" (and thus no
+ *   error occurs).
+ *
+ * Results:
+ *   Returns TRUE if an event was received that we care about
+ *   and FALSE otherwise. This function will also return
+ *   before an event is received if the timeout interval
+ *   runs out.
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+gint
+gdk_event_get (GdkEvent     *event,
+              GdkEventFunc  pred,
+              gpointer      data)
+{
+  GdkEvent *temp_event;
+  GdkPredicate event_pred;
+  GList *temp_list;
+  XEvent xevent;
+
+  /* If the last event we received was a destroy notify
+   *  event then we will actually destroy the "gdk" data
+   *  structures now. We don't want to destroy them at the
+   *  time of receiving the event since the main program
+   *  may try to access them and may need to destroy user
+   *  data that has been attached to the window
+   */
+  if (received_destroy_notify)
+    {
+      if (gdk_show_events)
+       g_print ("destroying window:\twindow: %ld\n",
+                ((GdkWindowPrivate*) window_to_destroy)->xwindow - base_id);
+
+      gdk_window_real_destroy (window_to_destroy);
+      received_destroy_notify = FALSE;
+      window_to_destroy = NULL;
+    }
+
+  /* Initially we haven't received an event and want to
+   *  return FALSE. If "event" is non-NULL, then initialize
+   *  it to the nothing event.
+   */
+  if (event)
+    {
+      event->any.type = GDK_NOTHING;
+      event->any.window = NULL;
+      event->any.send_event = FALSE;
+    }
+
+  if (pred)
+    {
+      temp_list = putback_events;
+      while (temp_list)
+       {
+         temp_event = temp_list->data;
+
+         if ((* pred) (temp_event, data))
+           {
+             if (event)
+               *event = *temp_event;
+             putback_events = g_list_remove_link (putback_events, temp_list);
+             g_list_free (temp_list);
+             return TRUE;
+           }
+
+         temp_list = temp_list->next;
+       }
+
+      event_pred.func = pred;
+      event_pred.data = data;
+
+      if (XCheckIfEvent (gdk_display, &xevent, gdk_event_get_type, (XPointer) &event_pred))
+       if (event)
+         return gdk_event_translate (event, &xevent);
+    }
+  else
+    {
+      if (putback_events)
+       {
+         temp_event = putback_events->data;
+         *event = *temp_event;
+
+         temp_list = putback_events;
+         putback_events = putback_events->next;
+         if (putback_events)
+           putback_events->prev = NULL;
+
+         temp_list->next = NULL;
+         temp_list->prev = NULL;
+         g_list_free (temp_list);
+         g_free (temp_event);
+
+         return TRUE;
+       }
+
+      /* Wait for an event to occur or the timeout to elapse.
+       * If an event occurs "gdk_event_wait" will return TRUE.
+       *  If the timeout elapses "gdk_event_wait" will return
+       *  FALSE.
+       */
+      if (gdk_event_wait ())
+       {
+         /* If we get here we can rest assurred that an event
+          *  has occurred. Read it.
+          */
+         XNextEvent (gdk_display, &xevent);
+
+         event->any.send_event = xevent.xany.send_event;
+
+         /* If "event" non-NULL.
+          */
+         if (event)
+           return gdk_event_translate (event, &xevent);
+       }
+    }
+
+  return FALSE;
+}
+
+void
+gdk_event_put (GdkEvent *event)
+{
+  GdkEvent *new_event;
+
+  g_return_if_fail (event != NULL);
+
+  new_event = g_new (GdkEvent, 1);
+  *new_event = *event;
+
+  putback_events = g_list_prepend (putback_events, new_event);
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_event_copy
+ *
+ *   Copy a event structure into new storage.
+ *
+ * Arguments:
+ *   "event" is the event struct to copy.
+ *
+ * Results:
+ *   A new event structure.  Free it with gdk_event_free.
+ *
+ * Side effects:
+ *   The reference count of the window in the event is increased.
+ *
+ *--------------------------------------------------------------
+ */
+
+static GMemChunk *event_chunk;
+
+GdkEvent*
+gdk_event_copy (GdkEvent *event)
+{
+  GdkEvent *new_event;
+  
+  g_return_val_if_fail (event != NULL, NULL);
+
+  if (event_chunk == NULL)
+    event_chunk = g_mem_chunk_new ("events",
+                                  sizeof (GdkEvent),
+                                  4096,
+                                  G_ALLOC_AND_FREE);
+
+  new_event = g_chunk_new (GdkEvent, event_chunk);
+  *new_event = *event;
+  gdk_window_ref (new_event->any.window);
+  return new_event;
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_event_free
+ *
+ *   Free a event structure obtained from gdk_event_copy.  Do not use
+ *   with other event structures.
+ *
+ * Arguments:
+ *   "event" is the event struct to free.
+ *
+ * Results:
+ *
+ * Side effects:
+ *   The reference count of the window in the event is decreased and
+ *   might be freed, too.
+ *
+ *-------------------------------------------------------------- */
+
+void
+gdk_event_free (GdkEvent *event)
+{
+  g_assert (event_chunk != NULL);
+  g_return_if_fail (event != NULL);
+
+  gdk_window_unref (event->any.window);
+  g_mem_chunk_free (event_chunk, event);
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_set_debug_level
+ *
+ *   Sets the debugging level.
+ *
+ * Arguments:
+ *   "level" is the new debugging level.
+ *
+ * Results:
+ *
+ * Side effects:
+ *   Other function calls to "gdk" use the debugging
+ *   level to determine what kind of debugging information
+ *   to print out.
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+gdk_set_debug_level (int level)
+{
+  gdk_debug_level = level;
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_set_show_events
+ *
+ *   Turns on/off the showing of events.
+ *
+ * Arguments:
+ *   "show_events" is a boolean describing whether or
+ *   not to show the events gdk receives.
+ *
+ * Results:
+ *
+ * Side effects:
+ *   When "show_events" is TRUE, calls to "gdk_event_get"
+ *   will output debugging informatin regarding the event
+ *   received to stdout.
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+gdk_set_show_events (int show_events)
+{
+  gdk_show_events = show_events;
+}
+
+void
+gdk_set_use_xshm (gint use_xshm)
+{
+  gdk_use_xshm = use_xshm;
+}
+
+gint
+gdk_get_debug_level ()
+{
+  return gdk_debug_level;
+}
+
+gint
+gdk_get_show_events ()
+{
+  return gdk_show_events;
+}
+
+gint
+gdk_get_use_xshm ()
+{
+  return gdk_use_xshm;
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_time_get
+ *
+ *   Get the number of milliseconds since the library was
+ *   initialized.
+ *
+ * Arguments:
+ *
+ * Results:
+ *   The time since the library was initialized is returned.
+ *   This time value is accurate to milliseconds even though
+ *   a more accurate time down to the microsecond could be
+ *   returned.
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+guint32
+gdk_time_get ()
+{
+  struct timeval end;
+  struct timeval elapsed;
+  guint32 milliseconds;
+
+  X_GETTIMEOFDAY (&end);
+
+  if (start.tv_usec > end.tv_usec)
+    {
+      end.tv_usec += 1000000;
+      end.tv_sec--;
+    }
+  elapsed.tv_sec = end.tv_sec - start.tv_sec;
+  elapsed.tv_usec = end.tv_usec - start.tv_usec;
+
+  milliseconds = (elapsed.tv_sec * 1000) + (elapsed.tv_usec / 1000);
+
+  return milliseconds;
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_timer_get
+ *
+ *   Returns the current timer.
+ *
+ * Arguments:
+ *
+ * Results:
+ *   Returns the current timer interval. This interval is
+ *   in units of milliseconds.
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+guint32
+gdk_timer_get ()
+{
+  return timer_val;
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_timer_set
+ *
+ *   Sets the timer interval.
+ *
+ * Arguments:
+ *   "milliseconds" is the new value for the timer.
+ *
+ * Results:
+ *
+ * Side effects:
+ *   Calls to "gdk_event_get" will last for a maximum
+ *   of time of "milliseconds". However, a value of 0
+ *   milliseconds will cause "gdk_event_get" to block
+ *   indefinately until an event is received.
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+gdk_timer_set (guint32 milliseconds)
+{
+  timer_val = milliseconds;
+  timer.tv_sec = milliseconds / 1000;
+  timer.tv_usec = (milliseconds % 1000) * 1000;
+
+}
+
+void
+gdk_timer_enable ()
+{
+  timerp = &timer;
+}
+
+void
+gdk_timer_disable ()
+{
+  timerp = NULL;
+}
+
+gint
+gdk_input_add (gint              source,
+              GdkInputCondition condition,
+              GdkInputFunction  function,
+              gpointer          data)
+{
+  static gint next_tag = 1;
+  GList *list;
+  GdkInput *input;
+  gint tag;
+
+  tag = 0;
+  list = inputs;
+
+  while (list)
+    {
+      input = list->data;
+      list = list->next;
+
+      if ((input->source == source) && (input->condition == condition))
+       {
+         input->function = function;
+         input->data = data;
+         tag = input->tag;
+       }
+    }
+
+  if (!tag)
+    {
+      input = g_new (GdkInput, 1);
+      input->tag = next_tag++;
+      input->source = source;
+      input->condition = condition;
+      input->function = function;
+      input->data = data;
+      tag = input->tag;
+
+      inputs = g_list_prepend (inputs, input);
+    }
+
+  return tag;
+}
+
+void
+gdk_input_remove (gint tag)
+{
+  GList *list;
+  GList *temp_list;
+  GdkInput *input;
+
+  list = inputs;
+  while (list)
+    {
+      input = list->data;
+
+      if (input->tag == tag)
+       {
+         temp_list = list;
+
+         if (list->next)
+           list->next->prev = list->prev;
+         if (list->prev)
+           list->prev->next = list->next;
+         if (inputs == list)
+           inputs = list->next;
+
+         temp_list->next = NULL;
+         temp_list->prev = NULL;
+
+         g_free (temp_list->data);
+         g_list_free (temp_list);
+         break;
+       }
+
+      list = list->next;
+    }
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_pointer_grab
+ *
+ *   Grabs the pointer to a specific window
+ *
+ * Arguments:
+ *   "window" is the window which will receive the grab
+ *   "owner_events" specifies whether events will be reported as is,
+ *     or relative to "window"
+ *   "event_mask" masks only interesting events
+ *   "confine_to" limits the cursor movement to the specified window
+ *   "cursor" changes the cursor for the duration of the grab
+ *   "time" specifies the time
+ *
+ * Results:
+ *
+ * Side effects:
+ *   requires a corresponding call to gdk_pointer_ungrab
+ *
+ *--------------------------------------------------------------
+ */
+
+gint
+gdk_pointer_grab (GdkWindow *     window,
+                 gint            owner_events,
+                 GdkEventMask    event_mask,
+                 GdkWindow *     confine_to,
+                 GdkCursor *     cursor,
+                 guint32         time)
+{
+  /*  From gdkwindow.c  */
+  extern int nevent_masks;
+  extern int event_mask_table[];
+
+  gint return_val;
+  GdkWindowPrivate *window_private;
+  GdkWindowPrivate *confine_to_private;
+  GdkCursorPrivate *cursor_private;
+  guint xevent_mask;
+  Window xwindow;
+  Window xconfine_to;
+  Cursor xcursor;
+  int i;
+
+  g_return_val_if_fail (window != NULL, 0);
+
+  window_private = (GdkWindowPrivate*) window;
+  confine_to_private = (GdkWindowPrivate*) confine_to;
+  cursor_private = (GdkCursorPrivate*) cursor;
+
+  xwindow = window_private->xwindow;
+
+  if (!confine_to)
+    xconfine_to = None;
+  else
+    xconfine_to = confine_to_private->xwindow;
+
+  if (!cursor)
+    xcursor = None;
+  else
+    xcursor = cursor_private->xcursor;
+
+
+  xevent_mask = 0;
+  for (i = 0; i < nevent_masks; i++)
+    {
+      if (event_mask & (1 << (i + 1)))
+       xevent_mask |= event_mask_table[i];
+    }
+
+  if (((GdkWindowPrivate *)window)->extension_events &&
+      gdk_input_vtable.grab_pointer)
+    return_val = gdk_input_vtable.grab_pointer (window,
+                                               owner_events,
+                                               event_mask,
+                                               confine_to,
+                                               time);
+  else
+    return_val = Success;;
+
+  if (return_val == Success)
+    return_val = XGrabPointer (window_private->xdisplay,
+                              xwindow,
+                              owner_events,
+                              xevent_mask,
+                              GrabModeAsync, GrabModeAsync,
+                              xconfine_to,
+                              xcursor,
+                              time);
+
+  return return_val;
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_pointer_ungrab
+ *
+ *   Releases any pointer grab
+ *
+ * Arguments:
+ *
+ * Results:
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+gdk_pointer_ungrab (guint32 time)
+{
+  if (gdk_input_vtable.ungrab_pointer)
+    gdk_input_vtable.ungrab_pointer (time);
+
+  XUngrabPointer (gdk_display, time);
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_keyboard_grab
+ *
+ *   Grabs the keyboard to a specific window
+ *
+ * Arguments:
+ *   "window" is the window which will receive the grab
+ *   "owner_events" specifies whether events will be reported as is,
+ *     or relative to "window"
+ *   "time" specifies the time
+ *
+ * Results:
+ *
+ * Side effects:
+ *   requires a corresponding call to gdk_keyboard_ungrab
+ *
+ *--------------------------------------------------------------
+ */
+
+gint
+gdk_keyboard_grab (GdkWindow *     window,
+                   gint            owner_events,
+                   guint32         time)
+{
+  GdkWindowPrivate *window_private;
+  Window xwindow;
+
+  g_return_val_if_fail (window != NULL, 0);
+
+  window_private = (GdkWindowPrivate*) window;
+  xwindow = window_private->xwindow;
+
+  return XGrabKeyboard (window_private->xdisplay,
+                       xwindow,
+                       owner_events,
+                       GrabModeAsync, GrabModeAsync,
+                       time);
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_keyboard_ungrab
+ *
+ *   Releases any keyboard grab
+ *
+ * Arguments:
+ *
+ * Results:
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+gdk_keyboard_ungrab (guint32 time)
+{
+  XUngrabKeyboard (gdk_display, time);
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_screen_width
+ *
+ *   Return the width of the screen.
+ *
+ * Arguments:
+ *
+ * Results:
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+gint
+gdk_screen_width ()
+{
+  gint return_val;
+
+  return_val = DisplayWidth (gdk_display, gdk_screen);
+
+  return return_val;
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_screen_height
+ *
+ *   Return the height of the screen.
+ *
+ * Arguments:
+ *
+ * Results:
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+gint
+gdk_screen_height ()
+{
+  gint return_val;
+
+  return_val = DisplayHeight (gdk_display, gdk_screen);
+
+  return return_val;
+}
+
+void
+gdk_key_repeat_disable ()
+{
+  XAutoRepeatOff (gdk_display);
+}
+
+void
+gdk_key_repeat_restore ()
+{
+  if (autorepeat)
+    XAutoRepeatOn (gdk_display);
+  else
+    XAutoRepeatOff (gdk_display);
+}
+
+
+/*
+ *--------------------------------------------------------------
+ * gdk_flush
+ *
+ *   Flushes the Xlib output buffer and then waits
+ *   until all requests have been received and processed
+ *   by the X server. The only real use for this function
+ *   is in dealing with XShm.
+ *
+ * Arguments:
+ *
+ * Results:
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+void gdk_flush ()
+{
+  XSync (gdk_display, False);
+}
+
+
+void
+gdk_beep ()
+{
+  XBell(gdk_display, 100);
+}
+
+
+/*
+ *--------------------------------------------------------------
+ * gdk_event_wait
+ *
+ *   Waits until an event occurs or the timer runs out.
+ *
+ * Arguments:
+ *
+ * Results:
+ *   Returns TRUE if an event is ready to be read and FALSE
+ *   if the timer ran out.
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+static gint
+gdk_event_wait ()
+{
+  GList *list;
+  GdkInput *input;
+  GdkInputCondition condition;
+  SELECT_MASK readfds;
+  SELECT_MASK writefds;
+  SELECT_MASK exceptfds;
+  int max_input;
+  int nfd;
+
+  /* If there are no events pending we will wait for an event.
+   * The time we wait is dependant on the "timer". If no timer
+   *  has been specified then we'll block until an event arrives.
+   *  If a timer has been specified we'll block until an event
+   *  arrives or the timer expires. (This is all done using the
+   *  "select" system call).
+   */
+
+  if (XPending (gdk_display) == 0)
+    {
+      FD_ZERO (&readfds);
+      FD_ZERO (&writefds);
+      FD_ZERO (&exceptfds);
+
+      FD_SET (connection_number, &readfds);
+      max_input = connection_number;
+
+      list = inputs;
+      while (list)
+       {
+         input = list->data;
+         list = list->next;
+
+         if (input->condition & GDK_INPUT_READ)
+           FD_SET (input->source, &readfds);
+         if (input->condition & GDK_INPUT_WRITE)
+           FD_SET (input->source, &writefds);
+         if (input->condition & GDK_INPUT_EXCEPTION)
+           FD_SET (input->source, &exceptfds);
+
+         max_input = MAX (max_input, input->source);
+       }
+
+      nfd = select (max_input+1, &readfds, &writefds, &exceptfds, timerp);
+
+      timerp = NULL;
+      timer_val = 0;
+
+      if (nfd > 0)
+       {
+         if (FD_ISSET (connection_number, &readfds))
+           {
+             if (XPending (gdk_display) == 0)
+               {
+                 if (nfd == 1)
+                   {
+                     XNoOp (gdk_display);
+                     XFlush (gdk_display);
+                   }
+                 return FALSE;
+               }
+             else
+               return TRUE;
+           }
+
+         list = inputs;
+         while (list)
+           {
+             input = list->data;
+             list = list->next;
+
+             condition = 0;
+             if (FD_ISSET (input->source, &readfds))
+               condition |= GDK_INPUT_READ;
+             if (FD_ISSET (input->source, &writefds))
+               condition |= GDK_INPUT_WRITE;
+             if (FD_ISSET (input->source, &exceptfds))
+               condition |= GDK_INPUT_EXCEPTION;
+
+             if (condition && input->function)
+               (* input->function) (input->data, input->source, condition);
+           }
+       }
+    }
+  else
+    return TRUE;
+
+  return FALSE;
+}
+
+static gint
+gdk_event_translate (GdkEvent *event,
+                    XEvent   *xevent)
+{
+
+  GdkWindow *window;
+  GdkWindowPrivate *window_private;
+  XComposeStatus compose;
+  int charcount;
+  char buf[16];
+  gint return_val;
+
+  /* Are static variables used for this purpose thread-safe? */
+  static GdkPoint dnd_drag_start = {0,0},
+                 dnd_drag_oldpos = {0,0};
+  static GdkRectangle dnd_drag_dropzone = {0,0,0,0};
+  static gint dnd_drag_perhaps = 0;
+  static GdkWindowPrivate *real_sw = NULL;
+  static Window dnd_drag_curwin = None, dnd_drag_target = None;
+
+  return_val = FALSE;
+
+  /* Find the GdkWindow that this event occurred in.
+   * All events occur in some GdkWindow (otherwise, why
+   *  would we be receiving them). It really is an error
+   *  to receive an event for which we cannot find the
+   *  corresponding GdkWindow. We handle events with window=None
+   *  specially - they are generated by XFree86's XInput under
+   *  some circumstances.
+   */
+
+  if ((xevent->xany.window == None) &&
+      gdk_input_vtable.window_none_event)
+    {
+      return_val = gdk_input_vtable.window_none_event (event,xevent);
+
+      if (return_val >= 0)     /* was handled */
+       return return_val;
+      else
+       return_val = FALSE;
+    }
+
+  window = gdk_window_lookup (xevent->xany.window);
+  window_private = (GdkWindowPrivate *) window;
+
+  /* We do a "manual" conversion of the XEvent to a
+   *  GdkEvent. The structures are mostly the same so
+   *  the conversion is fairly straightforward. We also
+   *  optionally print debugging info regarding events
+   *  received.
+   */
+  /* Addendum:
+   * During drag & drop you get events where the pointer is
+   * in other windows. Need to just do finer-grained checking
+   */
+  switch (xevent->type)
+    {
+    case KeyPress:
+      /* Lookup the string corresponding to the given keysym.
+       */
+      charcount = XLookupString (&xevent->xkey, buf, 16,
+                                (KeySym*) &event->key.keyval,
+                                &compose);
+
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("key press:\t\twindow: %ld  key: %12s  %d\n",
+                xevent->xkey.window - base_id,
+                XKeysymToString (event->key.keyval),
+                event->key.keyval);
+
+      event->key.type = GDK_KEY_PRESS;
+      event->key.window = window;
+      event->key.time = xevent->xkey.time;
+      event->key.state = (GdkModifierType) xevent->xkey.state;
+
+      return_val = !window_private->destroyed;
+      break;
+
+    case KeyRelease:
+      /* Lookup the string corresponding to the given keysym.
+       */
+      charcount = XLookupString (&xevent->xkey, buf, 16,
+                                (KeySym*) &event->key.keyval,
+                                &compose);
+
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("key release:\t\twindow: %ld  key: %12s  %d\n",
+                xevent->xkey.window - base_id,
+                XKeysymToString (event->key.keyval),
+                event->key.keyval);
+
+      event->key.type = GDK_KEY_RELEASE;
+      event->key.window = window;
+      event->key.time = xevent->xkey.time;
+      event->key.state = (GdkModifierType) xevent->xkey.state;
+
+      return_val = !window_private->destroyed;
+      break;
+
+    case ButtonPress:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("button press[%d]:\t\twindow: %ld  x,y: %d %d  button: %d\n",
+                window_private?window_private->dnd_drag_enabled:0,
+                xevent->xbutton.window - base_id,
+                xevent->xbutton.x, xevent->xbutton.y,
+                xevent->xbutton.button);
+
+      if (window_private &&
+         (window_private->extension_events != 0) &&
+         gdk_input_ignore_core)
+       break;
+
+      event->button.type = GDK_BUTTON_PRESS;
+      event->button.window = window;
+      event->button.time = xevent->xbutton.time;
+      event->button.x = xevent->xbutton.x;
+      event->button.y = xevent->xbutton.y;
+      event->button.pressure = 0.5;
+      event->button.xtilt = 0;
+      event->button.ytilt = 0;
+      event->button.state = (GdkModifierType) xevent->xbutton.state;
+      event->button.button = xevent->xbutton.button;
+      event->button.source = GDK_SOURCE_MOUSE;
+      event->button.deviceid = GDK_CORE_POINTER;
+
+      if ((event->button.time < (button_click_time[1] + TRIPLE_CLICK_TIME)) &&
+         (event->button.window == button_window[1]) &&
+         (event->button.button == button_number[1]))
+       {
+         gdk_synthesize_click (event, 3);
+
+         button_click_time[1] = 0;
+         button_click_time[0] = 0;
+         button_window[1] = NULL;
+         button_window[0] = 0;
+         button_number[1] = -1;
+         button_number[0] = -1;
+       }
+      else if ((event->button.time < (button_click_time[0] + DOUBLE_CLICK_TIME)) &&
+              (event->button.window == button_window[0]) &&
+              (event->button.button == button_number[0]))
+       {
+         gdk_synthesize_click (event, 2);
+
+         button_click_time[1] = button_click_time[0];
+         button_click_time[0] = event->button.time;
+         button_window[1] = button_window[0];
+         button_window[0] = event->button.window;
+         button_number[1] = button_number[0];
+         button_number[0] = event->button.button;
+       }
+      else
+       {
+         button_click_time[1] = 0;
+         button_click_time[0] = event->button.time;
+         button_window[1] = NULL;
+         button_window[0] = event->button.window;
+         button_number[1] = -1;
+         button_number[0] = event->button.button;
+       }
+      if(window_private
+        && window_private->dnd_drag_enabled
+        && !dnd_drag_perhaps
+        && !gdk_dnd.drag_really)
+       {
+         dnd_drag_perhaps = 1;
+         dnd_drag_start.x = xevent->xbutton.x_root;
+         dnd_drag_start.y = xevent->xbutton.y_root;
+         real_sw = window_private;
+         
+         if(gdk_dnd.drag_startwindows)
+           {
+             g_free(gdk_dnd.drag_startwindows);
+             gdk_dnd.drag_startwindows = NULL;
+           }
+         gdk_dnd.drag_numwindows = gdk_dnd.drag_really = 0;
+
+         {
+           /* Set motion mask for first DnD'd window, since it
+              will be the one that is actually dragged */
+           XWindowAttributes dnd_winattr;
+           XSetWindowAttributes dnd_setwinattr;
+           Status rv;
+
+           /* We need to get motion events while the button is down, so
+              we can know whether to really start dragging or not... */
+           XGetWindowAttributes(gdk_display, (Window)window_private->xwindow,
+                                &dnd_winattr);
+           
+           window_private->dnd_drag_savedeventmask = dnd_winattr.your_event_mask;
+           dnd_setwinattr.event_mask = 
+             window_private->dnd_drag_eventmask = ButtonMotionMask;
+           XChangeWindowAttributes(gdk_display, window_private->xwindow,
+                                   CWEventMask, &dnd_setwinattr);
+       }
+      }
+      return_val = window_private?(!window_private->destroyed):FALSE;
+      break;
+
+    case ButtonRelease:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("button release[%d]:\twindow: %ld  x,y: %d %d  button: %d\n",
+                window_private?window_private->dnd_drag_enabled:0,
+                xevent->xbutton.window - base_id,
+                xevent->xbutton.x, xevent->xbutton.y,
+                xevent->xbutton.button);
+
+      if (window_private &&
+         (window_private->extension_events != 0) &&
+         gdk_input_ignore_core)
+       break;
+
+      event->button.type = GDK_BUTTON_RELEASE;
+      event->button.window = window;
+      event->button.time = xevent->xbutton.time;
+      event->button.x = xevent->xbutton.x;
+      event->button.y = xevent->xbutton.y;
+      event->button.pressure = 0.5;
+      event->button.xtilt = 0;
+      event->button.ytilt = 0;
+      event->button.state = (GdkModifierType) xevent->xbutton.state;
+      event->button.button = xevent->xbutton.button;
+      event->button.source = GDK_SOURCE_MOUSE;
+      event->button.deviceid = GDK_CORE_POINTER;
+
+      if(dnd_drag_perhaps)
+       {
+       if(gdk_dnd.drag_really)
+         {
+         GdkPoint foo = {xevent->xbutton.x_root,
+                         xevent->xbutton.y_root};
+         XUngrabPointer(gdk_display, CurrentTime);
+
+         if(dnd_drag_target != None)
+           gdk_dnd_drag_end(dnd_drag_target, foo);
+         gdk_dnd.drag_really = 0;
+
+         if(gdk_dnd.drag_numwindows)
+           {
+             XSetWindowAttributes attrs;
+             /* Reset event mask to pre-drag value, assuming event_mask
+                doesn't change during drag */
+             attrs.event_mask = real_sw->dnd_drag_savedeventmask;
+             XChangeWindowAttributes(gdk_display, real_sw->xwindow,
+                                     CWEventMask, &attrs);
+           }
+
+         gdk_dnd.drag_numwindows = 0;
+         if(gdk_dnd.drag_startwindows)
+           {
+           g_free(gdk_dnd.drag_startwindows);
+           gdk_dnd.drag_startwindows = NULL;
+           }
+
+         real_sw = NULL;
+         }
+
+       dnd_drag_perhaps = 0;
+       dnd_drag_start.x = dnd_drag_start.y = 0;
+       dnd_drag_dropzone.x = dnd_drag_dropzone.y = 0;
+       dnd_drag_dropzone.width = dnd_drag_dropzone.height = 0;
+       dnd_drag_curwin = None;
+      }
+      return_val = window ? (!window_private->destroyed) : FALSE;
+      break;
+
+    case MotionNotify:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("motion notify:\t\twindow: %ld  x,y: %d %d  hint: %s d:%d r%d\n",
+                xevent->xmotion.window - base_id,
+                xevent->xmotion.x, xevent->xmotion.y,
+                (xevent->xmotion.is_hint) ? "true" : "false",
+                dnd_drag_perhaps, gdk_dnd.drag_really);
+
+      if (window_private &&
+         (window_private->extension_events != 0) &&
+         gdk_input_ignore_core)
+       break;
+
+      event->motion.type = GDK_MOTION_NOTIFY;
+      event->motion.window = window;
+      event->motion.time = xevent->xmotion.time;
+      event->motion.x = xevent->xmotion.x;
+      event->motion.y = xevent->xmotion.y;
+      event->motion.pressure = 0.5;
+      event->motion.xtilt = 0;
+      event->motion.ytilt = 0;
+      event->motion.state = (GdkModifierType) xevent->xmotion.state;
+      event->motion.is_hint = xevent->xmotion.is_hint;
+      event->motion.source = GDK_SOURCE_MOUSE;
+      event->motion.deviceid = GDK_CORE_POINTER;
+
+#define IS_IN_ZONE(cx, cy) (cx >= dnd_drag_dropzone.x \
+     && cy >= dnd_drag_dropzone.y \
+     && cx < (dnd_drag_dropzone.x + dnd_drag_dropzone.width) \
+     && cy < (dnd_drag_dropzone.y + dnd_drag_dropzone.height))
+
+      if(dnd_drag_perhaps && gdk_dnd.drag_really)
+       {
+         /* First, we have to find what window the motion was in... */
+         /* XXX there has to be a better way to do this, perhaps with
+            XTranslateCoordinates or XQueryTree - I don't know how,
+            and this sort of works */
+         Window curwin, childwin = gdk_root_window, rootwinret;
+         int x, y;
+         unsigned int mask;
+         while(childwin != None)
+           {
+             curwin = childwin;
+             XQueryPointer(gdk_display, curwin, &rootwinret, &childwin,
+                           &x, &y, &x, &y, &mask);
+           }
+         if(curwin != dnd_drag_curwin)
+           {
+             /* We have left one window and entered another
+                (do leave & enter bits) */
+             if(dnd_drag_curwin != real_sw->xwindow && dnd_drag_curwin != None)
+               gdk_dnd_drag_leave(dnd_drag_curwin);
+             dnd_drag_curwin = curwin;
+             gdk_dnd_drag_enter(dnd_drag_curwin);
+             dnd_drag_dropzone.x = dnd_drag_dropzone.y = 0;
+             dnd_drag_dropzone.width = dnd_drag_dropzone.height = 0;
+             dnd_drag_target = None;
+             XChangeActivePointerGrab(gdk_display,
+                                      ButtonMotionMask |
+                                      ButtonPressMask | ButtonReleaseMask |
+                                      EnterWindowMask | LeaveWindowMask,
+                                      gdk_dnd.gdk_cursor_dragdefault,
+                                      CurrentTime);
+           }
+         else if(dnd_drag_dropzone.width > 0
+                 && dnd_drag_dropzone.height > 0)
+           {
+             /* Handle all that dropzone stuff - thanks John ;-) */
+             if(dnd_drag_target != None
+                && IS_IN_ZONE(dnd_drag_oldpos.x, dnd_drag_oldpos.y)
+                && !IS_IN_ZONE(xevent->xmotion.x_root,
+                               xevent->xmotion.y_root))
+               {
+                 /* We were in the drop zone and moved out */
+                 dnd_drag_target = None;
+                 gdk_dnd_drag_leave(curwin);
+               }
+             else
+               {
+                 /* We were outside drop zone but in the window
+                    - have to send enter events */
+                 gdk_dnd_drag_enter(curwin);
+                 dnd_drag_curwin = curwin;
+                 dnd_drag_dropzone.x = dnd_drag_dropzone.y = 0;
+                 dnd_drag_target = None;
+               }
+           } else
+             dnd_drag_curwin = None;
+         return_val = FALSE;
+       }
+      else
+      return_val = window?(!window_private->destroyed):FALSE;
+      break;
+
+    case EnterNotify:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("enter notify:\t\twindow: %ld  detail: %d subwin: %ld\n",
+                xevent->xcrossing.window - base_id,
+                xevent->xcrossing.detail,
+                xevent->xcrossing.subwindow - base_id);
+
+      /* Tell XInput stuff about it if appropriate */
+      if (window_private &&
+         (window_private->extension_events != 0) &&
+         gdk_input_vtable.enter_event)
+       gdk_input_vtable.enter_event (&xevent->xcrossing, window);
+
+      event->crossing.type = GDK_ENTER_NOTIFY;
+      event->crossing.window = window;
+
+      /* If the subwindow field of the XEvent is non-NULL, then
+       *  lookup the corresponding GdkWindow.
+       */
+      if (xevent->xcrossing.subwindow != None)
+       event->crossing.subwindow = gdk_window_lookup (xevent->xcrossing.subwindow);
+      else
+       event->crossing.subwindow = NULL;
+
+      /* Translate the crossing detail into Gdk terms.
+       */
+      switch (xevent->xcrossing.detail)
+       {
+       case NotifyInferior:
+         event->crossing.detail = GDK_NOTIFY_INFERIOR;
+         break;
+       case NotifyAncestor:
+         event->crossing.detail = GDK_NOTIFY_ANCESTOR;
+         break;
+       case NotifyVirtual:
+         event->crossing.detail = GDK_NOTIFY_VIRTUAL;
+         break;
+       case NotifyNonlinear:
+         event->crossing.detail = GDK_NOTIFY_NONLINEAR;
+         break;
+       case NotifyNonlinearVirtual:
+         event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL;
+         break;
+       default:
+         event->crossing.detail = GDK_NOTIFY_UNKNOWN;
+         break;
+       }
+
+      if(dnd_drag_perhaps
+        && gdk_dnd.drag_really
+        && xevent->xcrossing.window == real_sw->xwindow)
+       {
+         gdk_dnd.drag_really = 0;
+         XUngrabPointer(gdk_display, CurrentTime);
+       }
+
+      return_val = (window ? !window_private->destroyed : FALSE);
+      break;
+
+    case LeaveNotify:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("leave notify:\t\twindow: %ld  detail: %d subwin: %ld\n",
+                xevent->xcrossing.window - base_id,
+                xevent->xcrossing.detail, xevent->xcrossing.subwindow - base_id);
+
+      event->crossing.type = GDK_LEAVE_NOTIFY;
+      event->crossing.window = window;
+
+      /* Translate the crossing detail into Gdk terms.
+       */
+      switch (xevent->xcrossing.detail)
+       {
+       case NotifyInferior:
+         event->crossing.detail = GDK_NOTIFY_INFERIOR;
+         break;
+       case NotifyAncestor:
+         event->crossing.detail = GDK_NOTIFY_ANCESTOR;
+         break;
+       case NotifyVirtual:
+         event->crossing.detail = GDK_NOTIFY_VIRTUAL;
+         break;
+       case NotifyNonlinear:
+         event->crossing.detail = GDK_NOTIFY_NONLINEAR;
+         break;
+       case NotifyNonlinearVirtual:
+         event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL;
+         break;
+       default:
+         event->crossing.detail = GDK_NOTIFY_UNKNOWN;
+         break;
+       }
+      if(dnd_drag_perhaps
+        && !gdk_dnd.drag_really)
+       {
+         gdk_dnd_drag_addwindow((GdkWindow *) real_sw);
+         gdk_dnd_drag_begin((GdkWindow *) real_sw);
+         XGrabPointer(gdk_display, real_sw->xwindow, False,
+                      ButtonMotionMask |
+                      ButtonPressMask | ButtonReleaseMask |
+                      EnterWindowMask | LeaveWindowMask,
+                      GrabModeAsync, GrabModeAsync, gdk_root_window,
+                      gdk_dnd.gdk_cursor_dragdefault, CurrentTime);
+         gdk_dnd.drag_really = 1;
+      }
+      return_val = window ? (!window_private->destroyed) : FALSE;
+      break;
+
+    case FocusIn:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("focus in:\t\twindow: %ld\n",
+                xevent->xfocus.window - base_id);
+
+      event->focus_change.type = GDK_FOCUS_CHANGE;
+      event->focus_change.window = window;
+      event->focus_change.in = TRUE;
+
+      return_val = !window_private->destroyed;
+      break;
+
+    case FocusOut:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("focus out:\t\twindow: %ld\n",
+                xevent->xfocus.window - base_id);
+
+      event->focus_change.type = GDK_FOCUS_CHANGE;
+      event->focus_change.window = window;
+      event->focus_change.in = FALSE;
+
+      return_val = !window_private->destroyed;
+      break;
+
+    case KeymapNotify:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("keymap notify\n");
+
+      /* Not currently handled */
+      break;
+
+    case Expose:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("expose:\t\twindow: %ld  %d  x,y: %d %d  w,h: %d %d\n",
+                xevent->xexpose.window - base_id, xevent->xexpose.count,
+                xevent->xexpose.x, xevent->xexpose.y,
+                xevent->xexpose.width, xevent->xexpose.height);
+
+      event->expose.type = GDK_EXPOSE;
+      event->expose.window = window;
+      event->expose.area.x = xevent->xexpose.x;
+      event->expose.area.y = xevent->xexpose.y;
+      event->expose.area.width = xevent->xexpose.width;
+      event->expose.area.height = xevent->xexpose.height;
+      event->expose.count = xevent->xexpose.count;
+
+      return_val = !window_private->destroyed;
+      break;
+
+    case GraphicsExpose:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("graphics expose:\tdrawable: %ld\n",
+                xevent->xgraphicsexpose.drawable - base_id);
+
+      event->expose.type = GDK_EXPOSE;
+      event->expose.window = window;
+      event->expose.area.x = xevent->xgraphicsexpose.x;
+      event->expose.area.y = xevent->xgraphicsexpose.y;
+      event->expose.area.width = xevent->xgraphicsexpose.width;
+      event->expose.area.height = xevent->xgraphicsexpose.height;
+      event->expose.count = xevent->xexpose.count;
+
+      return_val = !window_private->destroyed;
+      break;
+
+    case NoExpose:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("no expose:\t\tdrawable: %ld\n",
+                xevent->xnoexpose.drawable - base_id);
+
+      /* Not currently handled */
+      break;
+
+    case VisibilityNotify:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       switch (xevent->xvisibility.state)
+         {
+         case VisibilityFullyObscured:
+           g_print ("visibility notify:\twindow: %ld  none\n",
+                    xevent->xvisibility.window - base_id);
+           break;
+         case VisibilityPartiallyObscured:
+           g_print ("visibility notify:\twindow: %ld  partial\n",
+                    xevent->xvisibility.window - base_id);
+           break;
+         case VisibilityUnobscured:
+           g_print ("visibility notify:\twindow: %ld  full\n",
+                    xevent->xvisibility.window - base_id);
+           break;
+         }
+
+      /* Not currently handled */
+      break;
+
+    case CreateNotify:
+      /* Not currently handled */
+      break;
+
+    case DestroyNotify:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("destroy notify:\twindow: %ld\n",
+                xevent->xdestroywindow.window - base_id);
+
+      event->any.type = GDK_DESTROY;
+      event->any.window = window;
+
+      /* Remeber which window received the destroy notify
+       *  event so that we can destroy our associated
+       *  data structures the next time the user asks
+       *  us for an event.
+       */
+      received_destroy_notify = TRUE;
+      window_to_destroy = window;
+
+      return_val = !window_private->destroyed;
+      break;
+
+    case UnmapNotify:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("unmap notify:\t\twindow: %ld\n",
+                xevent->xmap.window - base_id);
+
+      event->any.type = GDK_UNMAP;
+      event->any.window = window;
+
+      return_val = !window_private->destroyed;
+      break;
+
+    case MapNotify:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("map notify:\t\twindow: %ld\n",
+                xevent->xmap.window - base_id);
+
+      event->any.type = GDK_MAP;
+      event->any.window = window;
+
+      return_val = !window_private->destroyed;
+      break;
+
+    case ReparentNotify:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("reparent notify:\twindow: %ld\n",
+                xevent->xreparent.window - base_id);
+
+      /* Not currently handled */
+      break;
+
+    case ConfigureNotify:
+      /* Print debugging info.
+       */
+      while ((XPending(gdk_display) > 0) &&
+               XCheckTypedWindowEvent(gdk_display, xevent->xany.window,
+                                      ConfigureNotify, xevent))
+         /*XSync(gdk_display, 0)*/;
+
+      if (gdk_show_events)
+       g_print ("configure notify:\twindow: %ld  x,y: %d %d  w,h: %d %d\n",
+                xevent->xconfigure.window - base_id,
+                xevent->xconfigure.x, xevent->xconfigure.y,
+                xevent->xconfigure.width, xevent->xconfigure.height);
+
+      if (window_private &&
+         (window_private->extension_events != 0) &&
+         gdk_input_vtable.configure_event)
+       gdk_input_vtable.configure_event (&xevent->xconfigure, window);
+
+      if ((window_private->window_type != GDK_WINDOW_CHILD) &&
+         ((window_private->width != xevent->xconfigure.width) ||
+          (window_private->height != xevent->xconfigure.height)))
+       {
+         event->configure.type = GDK_CONFIGURE;
+         event->configure.window = window;
+         event->configure.x = xevent->xconfigure.x;
+         event->configure.y = xevent->xconfigure.y;
+         event->configure.width = xevent->xconfigure.width;
+         event->configure.height = xevent->xconfigure.height;
+
+         window_private->x = xevent->xconfigure.x;
+         window_private->y = xevent->xconfigure.y;
+         window_private->width = xevent->xconfigure.width;
+         window_private->height = xevent->xconfigure.height;
+         if (window_private->resize_count > 1)
+           window_private->resize_count -= 1;
+
+         return_val = !window_private->destroyed;
+       }
+      break;
+
+    case PropertyNotify:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("property notify:\twindow: %ld\n",
+                xevent->xproperty.window - base_id);
+
+      event->property.type = GDK_PROPERTY_NOTIFY;
+      event->property.window = window;
+      event->property.atom = xevent->xproperty.atom;
+      event->property.time = xevent->xproperty.time;
+      event->property.state = xevent->xproperty.state;
+
+      return_val = !window_private->destroyed;
+      break;
+
+    case SelectionClear:
+      if (gdk_show_events)
+       g_print ("selection clear:\twindow: %ld\n",
+                xevent->xproperty.window - base_id);
+
+      event->selection.type = GDK_SELECTION_CLEAR;
+      event->selection.window = window;
+      event->selection.selection = xevent->xselectionclear.selection;
+      event->selection.time = xevent->xselectionclear.time;
+
+      return_val = !((GdkWindowPrivate*) window)->destroyed;
+      break;
+
+    case SelectionRequest:
+      if (gdk_show_events)
+       g_print ("selection request:\twindow: %ld\n",
+                xevent->xproperty.window - base_id);
+
+      event->selection.type = GDK_SELECTION_REQUEST;
+      event->selection.window = window;
+      event->selection.selection = xevent->xselectionrequest.selection;
+      event->selection.target = xevent->xselectionrequest.target;
+      event->selection.property = xevent->xselectionrequest.property;
+      event->selection.requestor = xevent->xselectionrequest.requestor;
+      event->selection.time = xevent->xselectionrequest.time;
+
+      return_val = !((GdkWindowPrivate*) window)->destroyed;
+      break;
+
+    case SelectionNotify:
+      if (gdk_show_events)
+       g_print ("selection notify:\twindow: %ld\n",
+                xevent->xproperty.window - base_id);
+
+
+      event->selection.type = GDK_SELECTION_NOTIFY;
+      event->selection.window = window;
+      event->selection.selection = xevent->xselection.selection;
+      event->selection.target = xevent->xselection.target;
+      event->selection.property = xevent->xselection.property;
+      event->selection.time = xevent->xselection.time;
+
+      return_val = !((GdkWindowPrivate*) window)->destroyed;
+      break;
+
+    case ColormapNotify:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("colormap notify:\twindow: %ld\n",
+                xevent->xcolormap.window - base_id);
+
+      /* Not currently handled */
+      break;
+
+    case ClientMessage:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("client message:\twindow: %ld\n",
+                xevent->xclient.window - base_id);
+
+      /* Client messages are the means of the window manager
+       *  communicating with a program. We'll first check to
+       *  see if this is really the window manager talking
+       *  to us.
+       */
+      if (xevent->xclient.message_type == gdk_wm_protocols)
+       {
+         if ((Atom) xevent->xclient.data.l[0] == gdk_wm_delete_window)
+           {
+             /* The delete window request specifies a window
+              *  to delete. We don't actually destroy the
+              *  window because "it is only a request". (The
+              *  window might contain vital data that the
+              *  program does not want destroyed). Instead
+              *  the event is passed along to the program,
+              *  which should then destroy the window.
+              */
+
+             /* Print debugging info.
+              */
+             if (gdk_show_events)
+               g_print ("delete window:\t\twindow: %ld\n",
+                        xevent->xclient.window - base_id);
+
+             event->any.type = GDK_DELETE;
+             event->any.window = window;
+
+             return_val = !window_private->destroyed;
+           }
+         else if ((Atom) xevent->xclient.data.l[0] == gdk_wm_take_focus)
+           {
+           }
+       }
+      else if (xevent->xclient.message_type == gdk_dnd.gdk_XdeEnter)
+       {
+         Atom reptype = 0;
+
+         event->dropenter.u.allflags = xevent->xclient.data.l[1];
+         if (gdk_show_events)
+           g_print ("GDK_DROP_ENTER\n");
+         return_val = FALSE;
+
+         /* Now figure out if we really want this drop...
+          * If someone is trying funky clipboard stuff, ignore 
+          */
+         if (window_private
+             && window_private->dnd_drop_enabled
+             && event->dropenter.u.flags.sendreply
+             && (reptype = gdk_dnd_check_types (window, xevent)))
+           {
+             XEvent replyev;
+
+             replyev.xclient.type = ClientMessage;
+             replyev.xclient.window = xevent->xclient.data.l[0];
+             replyev.xclient.format = 32;
+             replyev.xclient.message_type = gdk_dnd.gdk_XdeRequest;
+             replyev.xclient.data.l[0] = window_private->xwindow;
+
+             event->dragrequest.u.allflags = 0;
+             event->dragrequest.u.flags.protocol_version =
+               DND_PROTOCOL_VERSION;
+             event->dragrequest.u.flags.willaccept = 1;
+             event->dragrequest.u.flags.delete_data =
+               (window_private->dnd_drop_destructive_op) ? 1 : 0;
+
+             replyev.xclient.data.l[1] = event->dragrequest.u.allflags;
+             replyev.xclient.data.l[2] = replyev.xclient.data.l[3] = 0;
+             replyev.xclient.data.l[4] = reptype;
+
+             XSendEvent (gdk_display, replyev.xclient.window,
+                         False, NoEventMask, &replyev);
+
+             event->any.type = GDK_DROP_ENTER;
+             event->dropenter.requestor = replyev.xclient.window;
+             event->dropenter.u.allflags = xevent->xclient.data.l[1];
+           }
+       }
+      else if (xevent->xclient.message_type == gdk_dnd.gdk_XdeLeave)
+       {
+         if (gdk_show_events)
+           g_print ("GDK_DROP_LEAVE\n");
+         if (window_private && window_private->dnd_drop_enabled)
+           {
+             event->dropleave.type = GDK_DROP_LEAVE;
+             event->dropleave.window = window;
+             event->dropleave.requestor = xevent->xclient.data.l[0];
+             event->dropleave.u.allflags = xevent->xclient.data.l[1];
+             return_val = TRUE;
+           }
+         else
+           return_val = FALSE;
+       }
+      else if (xevent->xclient.message_type == gdk_dnd.gdk_XdeRequest)
+       {
+         /* 
+          * make sure to only handle requests from the window the cursor is
+          * over 
+          */
+         if (gdk_show_events)
+           g_print ("GDK_DRAG_REQUEST\n");
+         event->dragrequest.u.allflags = xevent->xclient.data.l[1];
+         return_val = FALSE;
+
+         if (window && gdk_dnd.drag_really &&
+             xevent->xclient.data.l[0] == dnd_drag_curwin &&
+             event->dragrequest.u.flags.sendreply == 0)
+           {
+             /* Got request - do we need to ask user? */
+             if (!event->dragrequest.u.flags.willaccept
+                 && event->dragrequest.u.flags.senddata)
+               {
+                 /* Yes we do :) */
+                 event->dragrequest.type = GDK_DRAG_REQUEST;
+                 event->dragrequest.window = window;
+                 event->dragrequest.requestor = xevent->xclient.data.l[0];
+                 event->dragrequest.isdrop = 0;
+                 event->dragrequest.drop_coords.x =
+                   event->dragrequest.drop_coords.y = 0;
+                 return_val = TRUE;
+               }
+             else if (event->dragrequest.u.flags.willaccept)
+               {
+                 window_private->dnd_drag_destructive_op =
+                   event->dragrequest.u.flags.delete_data;
+                 window_private->dnd_drag_accepted = 1;
+                 window_private->dnd_drag_data_type =
+                   xevent->xclient.data.l[4];
+
+                 dnd_drag_target = dnd_drag_curwin;
+                 XChangeActivePointerGrab (gdk_display,
+                                           ButtonMotionMask |
+                                           ButtonPressMask |
+                                           ButtonReleaseMask |
+                                           EnterWindowMask | LeaveWindowMask,
+                                           gdk_dnd.gdk_cursor_dragok,
+                                           CurrentTime);
+               }
+             dnd_drag_dropzone.x = xevent->xclient.data.l[2] & 65535;
+             dnd_drag_dropzone.y =
+               (xevent->xclient.data.l[2] >> 16) & 65535;
+             dnd_drag_dropzone.width = xevent->xclient.data.l[3] & 65535;
+             dnd_drag_dropzone.height =
+               (xevent->xclient.data.l[3] >> 16) & 65535;
+           }
+       }
+      else if(xevent->xclient.message_type == gdk_dnd.gdk_XdeDataAvailable)
+         {
+           gint tmp_int; Atom tmp_atom;
+           gulong tmp_long;
+           guchar *tmp_charptr;
+           gpointer tmp_ptr;
+           
+           if(gdk_show_events)
+             g_print("GDK_DROP_DATA_AVAIL\n");
+           event->dropdataavailable.u.allflags = xevent->xclient.data.l[1];
+           if(window
+              /* No preview of data ATM */
+              && event->dropdataavailable.u.flags.isdrop)
+             {
+               event->dropdataavailable.type = GDK_DROP_DATA_AVAIL;
+               event->dropdataavailable.window = window;
+               event->dropdataavailable.requestor = xevent->xclient.data.l[0];
+               event->dropdataavailable.data_type =
+                       gdk_atom_name(xevent->xclient.data.l[2]);
+               if(XGetWindowProperty (gdk_display,
+                                   event->dropdataavailable.requestor,
+                                   xevent->xclient.data.l[2],
+                                   0, LONG_MAX - 1,
+                                   False, XA_PRIMARY, &tmp_atom,
+                                   &tmp_int,
+                                   &event->dropdataavailable.data_numbytes,
+                                   &tmp_long,
+                                   &tmp_charptr)
+                  != Success)
+                 {
+                   g_warning("XGetWindowProperty on %#x may have failed\n",
+                           event->dropdataavailable.requestor);
+                           event->dropdataavailable.data = NULL;
+                 }
+               else
+                 {
+                   g_print("XGetWindowProperty got us %d bytes\n",
+                           event->dropdataavailable.data_numbytes);
+                   event->dropdataavailable.data =
+                       g_malloc(event->dropdataavailable.data_numbytes);
+                   memcpy(event->dropdataavailable.data,
+                       tmp_charptr, event->dropdataavailable.data_numbytes);
+                   XFree(tmp_charptr);
+                   return_val = TRUE;
+                 }
+             return_val = TRUE;
+           }
+       } else {
+         /* Send unknown ClientMessage's on to Gtk for it to use */
+         event->client.type = GDK_CLIENT_EVENT;
+         event->client.window = window;
+         event->client.message_type = xevent->xclient.message_type;
+         event->client.data_format = xevent->xclient.format;
+         memcpy(&event->client.data, &xevent->xclient.data,
+                sizeof(event->client.data));
+         return_val = TRUE;
+       }
+      return_val = return_val && !window_private->destroyed;
+      break;
+      
+    case MappingNotify:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("mapping notify\n");
+
+      /* Let XLib know that there is a new keyboard mapping.
+       */
+      XRefreshKeyboardMapping (&xevent->xmapping);
+      break;
+
+    default:
+      /* something else - (e.g., a Xinput event) */
+
+      if (window_private &&
+         (window_private->extension_events != 0) &&
+         gdk_input_vtable.other_event)
+       return_val = gdk_input_vtable.other_event(event, xevent, window);
+
+      if (return_val < 0)      /* not an XInput event, convert */
+       {
+         event->other.type = GDK_OTHER_EVENT;
+         event->other.window = window;
+         event->other.xevent = &other_xevent[other_xevent_i];
+         memcpy (&other_xevent[other_xevent_i], xevent, sizeof (XEvent));
+         other_xevent_i = (other_xevent_i+1) % OTHER_XEVENT_BUFSIZE;
+         return_val = TRUE;
+       }
+
+      return_val = return_val && !window_private->destroyed;
+      break;
+    }
+
+  return return_val;
+}
+
+static Bool
+gdk_event_get_type (Display  *display,
+                   XEvent   *xevent,
+                   XPointer  arg)
+{
+  GdkEvent event;
+  GdkPredicate *pred;
+
+  if (gdk_event_translate (&event, xevent))
+    {
+      pred = (GdkPredicate*) arg;
+      return (* pred->func) (&event, pred->data);
+    }
+
+  return FALSE;
+}
+
+static void
+gdk_synthesize_click (GdkEvent *event,
+                     gint      nclicks)
+{
+  GdkEvent temp_event;
+
+  g_return_if_fail (event != NULL);
+
+  temp_event = *event;
+  temp_event.type = (nclicks == 2) ? GDK_2BUTTON_PRESS : GDK_3BUTTON_PRESS;
+
+  gdk_event_put (&temp_event);
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_exit_func
+ *
+ *   This is the "atexit" function that makes sure the
+ *   library gets a chance to cleanup.
+ *
+ * Arguments:
+ *
+ * Results:
+ *
+ * Side effects:
+ *   The library is un-initialized and the program exits.
+ *
+ *--------------------------------------------------------------
+ */
+
+static void
+gdk_exit_func ()
+{
+  if (initialized)
+    {
+      gdk_image_exit ();
+      gdk_input_exit ();
+      gdk_key_repeat_restore ();
+
+      XCloseDisplay (gdk_display);
+      initialized = 0;
+    }
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_x_error
+ *
+ *   The X error handling routine.
+ *
+ * Arguments:
+ *   "display" is the X display the error orignated from.
+ *   "error" is the XErrorEvent that we are handling.
+ *
+ * Results:
+ *   Either we were expecting some sort of error to occur,
+ *   in which case we set the "gdk_error_code" flag, or this
+ *   error was unexpected, in which case we will print an
+ *   error message and exit. (Since trying to continue will
+ *   most likely simply lead to more errors).
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+static int
+gdk_x_error (Display     *display,
+            XErrorEvent *error)
+{
+  char buf[64];
+
+  if (gdk_error_warnings)
+    {
+      XGetErrorText (display, error->error_code, buf, 63);
+      g_error ("%s", buf);
+    }
+
+  gdk_error_code = -1;
+  return 0;
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_x_io_error
+ *
+ *   The X I/O error handling routine.
+ *
+ * Arguments:
+ *   "display" is the X display the error orignated from.
+ *
+ * Results:
+ *   An X I/O error basically means we lost our connection
+ *   to the X server. There is not much we can do to
+ *   continue, so simply print an error message and exit.
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+static int
+gdk_x_io_error (Display *display)
+{
+  g_error ("an x io error occurred");
+  return 0;
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_signal
+ *
+ *   The signal handler.
+ *
+ * Arguments:
+ *   "sig_num" is the number of the signal we received.
+ *
+ * Results:
+ *   The signals we catch are all fatal. So we simply build
+ *   up a nice little error message and print it and exit.
+ *   If in the process of doing so another signal is received
+ *   we notice that we are already exiting and simply kill
+ *   our process.
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+static RETSIGTYPE
+gdk_signal (int sig_num)
+{
+  static int caught_fatal_sig = 0;
+  char *sig;
+
+  if (caught_fatal_sig)
+    kill (getpid (), sig_num);
+  caught_fatal_sig = 1;
+
+  switch (sig_num)
+    {
+    case SIGHUP:
+      sig = "sighup";
+      break;
+    case SIGINT:
+      sig = "sigint";
+      break;
+    case SIGQUIT:
+      sig = "sigquit";
+      break;
+    case SIGBUS:
+      sig = "sigbus";
+      break;
+    case SIGSEGV:
+      sig = "sigsegv";
+      break;
+    case SIGPIPE:
+      sig = "sigpipe";
+      break;
+    case SIGTERM:
+      sig = "sigterm";
+      break;
+    default:
+      sig = "unknown signal";
+      break;
+    }
+
+  g_print ("\n** ERROR **: %s caught\n", sig);
+  gdk_exit (1);
+}
+
+static void
+gdk_dnd_drag_begin (GdkWindow *initial_window)
+{
+  GdkEventDragBegin tev;
+  tev.type = GDK_DRAG_BEGIN;
+  tev.window = initial_window;
+  tev.u.allflags = 0;
+  tev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
+
+  gdk_event_put ((GdkEvent *) &tev);
+}
+
+static void
+gdk_dnd_drag_enter (Window dest)
+{
+  XEvent sev;
+  GdkEventDropEnter tev;
+  int i;
+  GdkWindowPrivate *wp;
+  
+  sev.xclient.type = ClientMessage;
+  sev.xclient.format = 32;
+  sev.xclient.message_type = gdk_dnd.gdk_XdeEnter;
+  sev.xclient.window = dest;
+
+  tev.u.allflags = 0;
+  tev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
+  tev.u.flags.sendreply = 1;
+  for (i = 0; i < gdk_dnd.drag_numwindows; i++)
+    {
+      wp = (GdkWindowPrivate *) gdk_dnd.drag_startwindows[i];
+      if (wp->dnd_drag_data_numtypesavail)
+       {
+         sev.xclient.data.l[0] = wp->xwindow;
+         tev.u.flags.extended_typelist = (wp->dnd_drag_data_numtypesavail > 3)?1:0;
+         sev.xclient.data.l[1] = tev.u.allflags;
+         sev.xclient.data.l[2] = wp->dnd_drag_data_typesavail[0];
+         if (wp->dnd_drag_data_numtypesavail > 1)
+           {
+             sev.xclient.data.l[3] = wp->dnd_drag_data_typesavail[1];
+             if (wp->dnd_drag_data_numtypesavail > 2)
+               {
+                 sev.xclient.data.l[4] = wp->dnd_drag_data_typesavail[2];
+               }
+             else
+               sev.xclient.data.l[4] = None;
+           }
+         else
+           sev.xclient.data.l[3] = sev.xclient.data.l[4] = None;
+         XSendEvent (gdk_display, dest, False, NoEventMask, &sev);
+       }
+
+    }
+}
+
+static void
+gdk_dnd_drag_leave (Window dest)
+{
+  XEvent sev;
+  GdkEventDropLeave tev;
+  int i;
+  GdkWindowPrivate *wp;
+
+  tev.u.allflags = 0;
+
+  tev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
+  sev.xclient.type = ClientMessage;
+  sev.xclient.window = dest;
+  sev.xclient.format = 32;
+  sev.xclient.message_type = gdk_dnd.gdk_XdeLeave;
+  sev.xclient.data.l[1] = tev.u.allflags;
+  for (i = 0; i < gdk_dnd.drag_numwindows; i++)
+    {
+      wp = (GdkWindowPrivate *) gdk_dnd.drag_startwindows[i];
+      sev.xclient.data.l[0] = wp->xwindow;
+      XSendEvent(gdk_display, dest, False, NoEventMask, &sev);
+      wp->dnd_drag_accepted = 0;
+    }
+}
+
+/* 
+ * when a drop occurs, we go through the list of windows being dragged and
+ * tell them that it has occurred, so that they can set things up and reply
+ * to 'dest' window 
+ */
+static void
+gdk_dnd_drag_end (Window     dest, 
+                 GdkPoint   coords)
+{
+  GdkWindowPrivate *wp;
+  GdkEventDragRequest tev;
+  gchar *tmp_cptr;
+  int i;
+
+  tev.type = GDK_DRAG_REQUEST;
+  tev.drop_coords = coords;
+  tev.requestor = dest;
+  tev.u.allflags = 0;
+  tev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
+  tev.isdrop = 1;
+
+  for (i = 0; i < gdk_dnd.drag_numwindows; i++)
+    {
+      wp = (GdkWindowPrivate *) gdk_dnd.drag_startwindows[i];
+      if (wp->dnd_drag_accepted)
+       {
+         tev.window = (GdkWindow *) wp;
+         tev.u.flags.delete_data = wp->dnd_drag_destructive_op;
+         tev.data_type = 
+               gdk_atom_name(wp->dnd_drag_data_type);
+
+         gdk_event_put((GdkEvent *) &tev);
+       }
+    }
+}
+
+static GdkAtom
+gdk_dnd_check_types (GdkWindow   *window, 
+                    XEvent      *xevent)
+{
+  GdkWindowPrivate *wp = (GdkWindowPrivate *) window;
+  int i, j;
+  GdkEventDropEnter event;
+
+  g_return_val_if_fail(window != NULL, 0);
+  g_return_val_if_fail(xevent != NULL, 0);
+  g_return_val_if_fail(xevent->type == ClientMessage, 0);
+  g_return_val_if_fail(xevent->xclient.message_type == gdk_dnd.gdk_XdeEnter, 0);
+
+  if(wp->dnd_drop_data_numtypesavail <= 0 ||
+     !wp->dnd_drop_data_typesavail)
+    return 0;
+
+  for (i = 2; i <= 4; i++)
+    {
+      for (j = 0; j < wp->dnd_drop_data_numtypesavail; j++)
+       {
+         if (xevent->xclient.data.l[i] == wp->dnd_drop_data_typesavail[j])
+           return xevent->xclient.data.l[i];
+       }
+    }
+
+  /* Now we get the extended type list if it's available */
+  event.u.allflags = xevent->xclient.data.l[1];
+  if (event.u.flags.extended_typelist)
+    {
+      Atom *exttypes, realtype;
+      gulong nitems, nbar;
+      gint realfmt;
+
+      if (XGetWindowProperty(gdk_display, xevent->xclient.data.l[0],
+                            gdk_dnd.gdk_XdeTypelist, 0L, LONG_MAX - 1,
+                            False, AnyPropertyType, &realtype, &realfmt,
+                            &nitems, &nbar, (unsigned char **) &exttypes)
+        != Success)
+       return 0;
+
+      if (realfmt != (sizeof(Atom) * 8))
+       {
+         g_warning("XdeTypelist property had format of %d instead of the expected %d, on window %#lx\n",
+                   realfmt, sizeof(Atom) * 8, xevent->xclient.data.l[0]);
+         return 0;
+       }
+
+      for (i = 0; i <= nitems; i++)
+       {
+         for (j = 0; j < wp->dnd_drop_data_numtypesavail; j++)
+           {
+             if (exttypes[i] == wp->dnd_drop_data_typesavail[j])
+               {
+                 XFree (exttypes);
+                 return exttypes[i];
+               }
+           }
+       }
+      XFree (exttypes);
+    }
+  return 0;
+}
+
+/* 
+ * used for debugging only 
+ */
+static void
+gdk_print_atom (GdkAtom anatom)
+{
+  gchar *tmpstr = NULL;
+  tmpstr = (anatom!=None)?gdk_atom_name(anatom):"(none)";
+  g_print("Atom %lu has name %s\n", anatom, tmpstr);
+  if(tmpstr)
+    g_free(tmpstr);
+}
+
+/* 
+ * used only by below routine and itself 
+ */
+static Window 
+getchildren (Display     *dpy, 
+            Window       win, 
+            Atom         WM_STATE)
+{
+  Window root, parent, *children, inf = 0;
+  Atom type = None;
+  unsigned int nchildren, i;
+  int format;
+  unsigned long nitems, after;
+  unsigned char *data;
+
+  if (XQueryTree(dpy, win, &root, &parent, &children, &nchildren) == 0)
+    return 0;
+
+  for (i = 0; !inf && (i < nchildren); i++)
+    {
+      XGetWindowProperty (dpy, children[i], WM_STATE, 0, 0, False,
+                         AnyPropertyType, &type, &format, &nitems,
+                         &after, &data);
+      if (type != 0)
+       inf = children[i];
+    }
+
+  for (i = 0; !inf && (i < nchildren); i++)
+    inf = getchildren (dpy, children[i], WM_STATE);
+
+  if (children != 0) 
+    XFree ((char *) children);
+
+  return inf;
+}
+
+/* 
+ * find a window with WM_STATE, else return win itself, as per ICCCM
+ *
+ * modification of the XmuClientWindow() routine from X11R6.3
+ */
+Window
+gdk_get_client_window (Display  *dpy, 
+                      Window    win)
+{
+  Atom WM_STATE;
+  Atom type = None;
+  int format;
+  unsigned long nitems, after;
+  unsigned char *data;
+  Window inf;
+
+  if (win == 0)
+    return DefaultRootWindow(dpy);
+
+  if ((WM_STATE = XInternAtom (dpy, "WM_STATE", True)) == 0)
+    return win;
+
+  XGetWindowProperty (dpy, win, WM_STATE, 0, 0, False, AnyPropertyType,
+                     &type, &format, &nitems, &after, &data);
+  if (type)
+    return win;
+
+  inf = getchildren (dpy, win, WM_STATE);
+
+  if (inf == 0)
+    return win;
+  else
+    return inf;
+}
+
+static GdkWindow *
+gdk_drop_get_real_window (GdkWindow   *w, 
+                         guint16     *x, 
+                         guint16     *y)
+{
+  GdkWindow *retval = w;
+  GdkWindowPrivate *awin;
+  GList *children;
+  gint16 myx = *x, myy = *y;
+
+  g_return_val_if_fail(w != NULL && x != NULL && y != NULL, NULL);
+
+  myx = *x; 
+  myy = *y;
+
+descend:
+  for (children = gdk_window_get_children(retval); 
+       children && children->next;
+       children = children->next)
+    {
+      awin = (GdkWindowPrivate *) children->data;
+      if ((myx >= awin->x) && (myy >= awin->y)
+         && (myx < (awin->x + awin->width))
+         && (myy < (awin->y + awin->height)))
+       {
+         retval = (GdkWindow *) awin;
+         myx -= awin->x;
+         myy -= awin->y;
+         goto descend;
+       }
+    }
+
+  *x = myx; 
+  *y = myy;
+
+  return retval;
+}
+
+/* Sends a ClientMessage to all toplevel client windows */
+void
+gdk_event_send_clientmessage_toall(GdkEvent *event)
+{
+  XEvent sev;
+  Window *ret_children, ret_root, ret_parent, curwin;
+  unsigned int ret_nchildren;
+  int i;
+
+  g_return_if_fail(event != NULL);
+
+  /* Set up our event to send, with the exception of its target window */
+  sev.xclient.type = ClientMessage;
+  sev.xclient.display = gdk_display;
+  sev.xclient.format = event->client.data_format;
+  sev.xclient.serial = CurrentTime;
+  memcpy(&sev.xclient.data, &event->client.data, sizeof(sev.xclient.data));
+  sev.xclient.message_type = event->client.message_type;
+
+  /* OK, we're all set, now let's find some windows to send this to */
+  if(XQueryTree(gdk_display, gdk_root_window, &ret_root, &ret_parent,
+               &ret_children, &ret_nchildren) != True)
+    return;
+
+  /* foreach true child window of the root window, send an event to it */
+  for(i = 0; i < ret_nchildren; i++) {
+    curwin = gdk_get_client_window(gdk_display, ret_children[i]);
+    sev.xclient.window = curwin;
+    XSendEvent(gdk_display, curwin, False, NoEventMask, &sev);
+  }
+
+  XFree(ret_children);
+}
diff --git a/gdk/gdk.h b/gdk/gdk.h
new file mode 100644 (file)
index 0000000..ac341b2
--- /dev/null
+++ b/gdk/gdk.h
@@ -0,0 +1,614 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GDK_H__
+#define __GDK_H__
+
+
+#include <gdk/gdktypes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* Initialization, exit and events
+ */
+void   gdk_init            (int    *argc,
+                           char ***argv);
+void   gdk_exit            (int     error_code);
+gchar* gdk_set_locale      (void);
+
+gint gdk_events_pending  (void);
+gint gdk_event_get       (GdkEvent     *event,
+                         GdkEventFunc  pred,
+                         gpointer      data);
+void gdk_event_put       (GdkEvent     *event);
+
+GdkEvent *gdk_event_copy (GdkEvent *event);
+void      gdk_event_free (GdkEvent *event);
+
+void gdk_set_debug_level (gint  level);
+void gdk_set_show_events (gint  show_events);
+void gdk_set_use_xshm    (gint  use_xshm);
+
+gint gdk_get_debug_level (void);
+gint gdk_get_show_events (void);
+gint gdk_get_use_xshm    (void);
+
+guint32 gdk_time_get      (void);
+guint32 gdk_timer_get     (void);
+void    gdk_timer_set     (guint32 milliseconds);
+void    gdk_timer_enable  (void);
+void    gdk_timer_disable (void);
+
+gint gdk_input_add    (gint              source,
+                      GdkInputCondition condition,
+                      GdkInputFunction  function,
+                      gpointer          data);
+void gdk_input_remove (gint              tag);
+
+gint gdk_pointer_grab   (GdkWindow *     window,
+                        gint            owner_events,
+                        GdkEventMask    event_mask,
+                        GdkWindow *     confine_to,
+                        GdkCursor *     cursor,
+                        guint32         time);
+void gdk_pointer_ungrab (guint32         time);
+
+gint gdk_keyboard_grab   (GdkWindow *     window,
+                          gint            owner_events,
+                          guint32         time);
+void gdk_keyboard_ungrab (guint32         time);
+
+gint gdk_screen_width  (void);
+gint gdk_screen_height (void);
+
+void gdk_flush (void);
+void gdk_beep (void);
+
+void gdk_key_repeat_disable (void);
+void gdk_key_repeat_restore (void);
+
+
+/* Visuals
+ */
+gint          gdk_visual_get_best_depth      (void);
+GdkVisualType gdk_visual_get_best_type       (void);
+GdkVisual*    gdk_visual_get_system          (void);
+GdkVisual*    gdk_visual_get_best            (void);
+GdkVisual*    gdk_visual_get_best_with_depth (gint           depth);
+GdkVisual*    gdk_visual_get_best_with_type  (GdkVisualType  visual_type);
+GdkVisual*    gdk_visual_get_best_with_both  (gint           depth,
+                                             GdkVisualType  visual_type);
+
+/* Actually, these are no-ops... */
+GdkVisual* gdk_visual_ref (GdkVisual *visual);
+void       gdk_visual_unref (GdkVisual *visual);
+
+void gdk_query_depths       (gint           **depths,
+                            gint            *count);
+void gdk_query_visual_types (GdkVisualType  **visual_types,
+                            gint            *count);
+void gdk_query_visuals      (GdkVisual      **visuals,
+                            gint            *count);
+
+
+/* Windows
+ */
+GdkWindow*    gdk_window_new         (GdkWindow     *parent,
+                                     GdkWindowAttr *attributes,
+                                     gint           attributes_mask);
+
+GdkWindow *   gdk_window_foreign_new (guint32        anid);
+void          gdk_window_destroy     (GdkWindow     *window);
+GdkWindow*    gdk_window_ref         (GdkWindow     *window);
+void          gdk_window_unref       (GdkWindow     *window);
+
+void          gdk_window_show        (GdkWindow    *window);
+void          gdk_window_hide        (GdkWindow    *window);
+void          gdk_window_move        (GdkWindow    *window,
+                                     gint          x,
+                                     gint          y);
+void          gdk_window_resize      (GdkWindow    *window,
+                                     gint          width,
+                                     gint          height);
+void          gdk_window_move_resize (GdkWindow    *window,
+                                     gint          x,
+                                     gint          y,
+                                     gint          width,
+                                     gint          height);
+void          gdk_window_reparent    (GdkWindow    *window,
+                                     GdkWindow    *new_parent,
+                                     gint          x,
+                                     gint          y);
+void          gdk_window_clear       (GdkWindow    *window);
+void          gdk_window_clear_area  (GdkWindow    *window,
+                                     gint          x,
+                                     gint          y,
+                                     gint          width,
+                                     gint          height);
+void          gdk_window_clear_area_e(GdkWindow    *window,
+                                     gint          x,
+                                     gint          y,
+                                     gint          width,
+                                     gint          height);
+void          gdk_window_copy_area   (GdkWindow    *window,
+                                     GdkGC        *gc,
+                                     gint          x,
+                                     gint          y,
+                                     GdkWindow    *source_window,
+                                     gint          source_x,
+                                     gint          source_y,
+                                     gint          width,
+                                     gint          height);
+void          gdk_window_raise       (GdkWindow    *window);
+void          gdk_window_lower       (GdkWindow    *window);
+
+void          gdk_window_set_user_data   (GdkWindow       *window,
+                                         gpointer         user_data);
+
+
+/* 
+ * This allows for making shaped (partially transparent) windows
+ * - cool feature, needed for Drag and Drag for example.
+ *  The shape_mask can be the mask
+ *  from gdk_pixmap_create_from_xpm.   Stefan Wille
+ */
+void gdk_window_shape_combine_mask (GdkWindow       *window,
+                                   GdkBitmap       *shape_mask,
+                                   gint             offset_x,
+                                   gint             offset_y);
+
+/* 
+ * Drag & Drop
+ * Algorithm (drop source):
+ * A window being dragged will be sent a GDK_DRAG_BEGIN message.
+ * It will then do gdk_dnd_drag_addwindow() for any other windows that are to be
+ * dragged.
+ * When we get a DROP_ENTER incoming, we send it on to the window in question.
+ * That window needs to use gdk_dnd_drop_enter_reply() to indicate the state of
+ * things (it must call that even if it's not going to accept the drop)
+ *
+ * These two turn on/off drag or drop, and if enabling it also
+ * sets the list of types supported. The list of types passed in
+ * should be in order of decreasing preference.
+ */
+void gdk_window_dnd_drag_set (GdkWindow  *window,
+                             guint8      drag_enable,
+                             gchar     **typelist,
+                             guint       numtypes);
+
+/* 
+ *XXX todo: add a GDK_DROP_ENTER which can look at actual data
+ */
+void gdk_window_dnd_drop_set (GdkWindow  *window,
+                             guint8      drop_enable,
+                             gchar     **typelist,
+                             guint       numtypes,
+                             guint8      destructive_op);
+
+/* 
+ * This is used by the GDK_DRAG_BEGIN handler. An example of usage would be a
+ * file manager where multiple icons were selected and the drag began.
+ * The icon that the drag actually began on would gdk_dnd_drag_addwindow
+ * for all the other icons that were being dragged... 
+ */
+void gdk_dnd_drag_addwindow  (GdkWindow  *window);
+void gdk_window_dnd_data_set (GdkWindow  *window,
+                             GdkEvent   *event,
+                             gpointer    data,
+                             gulong      data_numbytes);
+
+
+void          gdk_window_set_hints       (GdkWindow       *window,
+                                         gint             x,
+                                         gint             y,
+                                         gint             min_width,
+                                         gint             min_height,
+                                         gint             max_width,
+                                         gint             max_height,
+                                         gint             flags);
+void          gdk_window_set_title       (GdkWindow       *window,
+                                         const gchar     *title);
+void          gdk_window_set_background  (GdkWindow       *window,
+                                         GdkColor        *color);
+void          gdk_window_set_back_pixmap (GdkWindow       *window,
+                                         GdkPixmap       *pixmap,
+                                         gint             parent_relative);
+void          gdk_window_set_cursor      (GdkWindow       *window,
+                                         GdkCursor       *cursor);
+void          gdk_window_set_colormap    (GdkWindow       *window,
+                                         GdkColormap     *colormap);
+void          gdk_window_get_user_data   (GdkWindow       *window,
+                                         gpointer        *data);
+void          gdk_window_get_geometry    (GdkWindow       *window,
+                                         gint            *x,
+                                         gint            *y,
+                                         gint            *width,
+                                         gint            *height,
+                                         gint            *depth);
+void          gdk_window_get_position    (GdkWindow       *window,
+                                         gint            *x,
+                                         gint            *y);
+void          gdk_window_get_size        (GdkWindow       *window,
+                                         gint            *width,
+                                         gint            *height);
+GdkVisual*    gdk_window_get_visual      (GdkWindow       *window);
+GdkColormap*  gdk_window_get_colormap    (GdkWindow       *window);
+GdkWindowType gdk_window_get_type        (GdkWindow       *window);
+gint          gdk_window_get_origin      (GdkWindow       *window,
+                                         gint            *x,
+                                         gint            *y);
+GdkWindow*    gdk_window_get_pointer     (GdkWindow       *window,
+                                         gint            *x,
+                                         gint            *y,
+                                         GdkModifierType *mask);
+GdkWindow*    gdk_window_get_parent      (GdkWindow       *window);
+GdkWindow*    gdk_window_get_toplevel    (GdkWindow       *window);
+GList*        gdk_window_get_children    (GdkWindow       *window);
+GdkEventMask  gdk_window_get_events      (GdkWindow       *window);
+void          gdk_window_set_events      (GdkWindow       *window,
+                                         GdkEventMask     event_mask);
+
+/* Cursors
+ */
+GdkCursor* gdk_cursor_new     (GdkCursorType   cursor_type);
+void       gdk_cursor_destroy (GdkCursor      *cursor);
+
+
+/* GCs
+ */
+GdkGC* gdk_gc_new                 (GdkWindow        *window);
+GdkGC* gdk_gc_new_with_values     (GdkWindow        *window,
+                                  GdkGCValues      *values,
+                                  GdkGCValuesMask   values_mask);
+void   gdk_gc_destroy             (GdkGC            *gc);
+void   gdk_gc_get_values          (GdkGC            *gc,
+                                  GdkGCValues      *values);
+void   gdk_gc_set_foreground      (GdkGC            *gc,
+                                  GdkColor         *color);
+void   gdk_gc_set_background      (GdkGC            *gc,
+                                  GdkColor         *color);
+void   gdk_gc_set_font            (GdkGC            *gc,
+                                  GdkFont          *font);
+void   gdk_gc_set_function        (GdkGC            *gc,
+                                  GdkFunction       function);
+void   gdk_gc_set_fill            (GdkGC            *gc,
+                                  GdkFill           fill);
+void   gdk_gc_set_tile            (GdkGC            *gc,
+                                  GdkPixmap        *tile);
+void   gdk_gc_set_stipple         (GdkGC            *gc,
+                                  GdkPixmap        *stipple);
+void   gdk_gc_set_ts_origin       (GdkGC            *gc,
+                                  gint              x,
+                                  gint              y);
+void   gdk_gc_set_clip_origin     (GdkGC            *gc,
+                                  gint              x,
+                                  gint              y);
+void   gdk_gc_set_clip_mask       (GdkGC            *gc,
+                                  GdkBitmap        *mask);
+void   gdk_gc_set_clip_rectangle  (GdkGC            *gc,
+                                   GdkRectangle     *rectangle);
+void   gdk_gc_set_subwindow       (GdkGC            *gc,
+                                  GdkSubwindowMode  mode);
+void   gdk_gc_set_exposures       (GdkGC            *gc,
+                                  gint              exposures);
+void   gdk_gc_set_line_attributes (GdkGC            *gc,
+                                  gint              line_width,
+                                  GdkLineStyle      line_style,
+                                  GdkCapStyle       cap_style,
+                                  GdkJoinStyle      join_style);
+
+
+/* Pixmaps
+ */
+GdkPixmap* gdk_pixmap_new               (GdkWindow  *window,
+                                        gint        width,
+                                        gint        height,
+                                        gint        depth);
+GdkBitmap* gdk_bitmap_create_from_data  (GdkWindow  *window,
+                                        gchar      *data,
+                                        gint        width,
+                                        gint        height);
+GdkPixmap* gdk_pixmap_create_from_data  (GdkWindow  *window,
+                                        gchar      *data,
+                                        gint        width,
+                                        gint        height,
+                                        gint        depth,
+                                        GdkColor   *fg,
+                                        GdkColor   *bg);
+GdkPixmap* gdk_pixmap_create_from_xpm   (GdkWindow  *window,
+                                        GdkBitmap **mask,
+                                        GdkColor   *transparent_color,
+                                        const gchar *filename);
+GdkPixmap* gdk_pixmap_create_from_xpm_d (GdkWindow  *window,
+                                        GdkBitmap **mask,
+                                        GdkColor   *transparent_color,
+                                        gchar     **data);
+void       gdk_pixmap_destroy           (GdkPixmap  *pixmap);
+
+
+
+/* Images
+ */
+GdkImage* gdk_image_new_bitmap(GdkVisual *,
+                               gpointer,
+                               gint,
+                               gint);
+GdkImage*  gdk_image_new       (GdkImageType  type,
+                               GdkVisual    *visual,
+                               gint          width,
+                               gint          height);
+GdkImage*  gdk_image_get       (GdkWindow    *window,
+                               gint          x,
+                               gint          y,
+                               gint          width,
+                               gint          height);
+void       gdk_image_put_pixel (GdkImage     *image,
+                               gint          x,
+                               gint          y,
+                               guint32       pixel);
+guint32    gdk_image_get_pixel (GdkImage     *image,
+                               gint          x,
+                               gint          y);
+void       gdk_image_destroy   (GdkImage     *image);
+
+
+/* Color
+ */
+GdkColormap* gdk_colormap_new     (GdkVisual   *visual,
+                                  gint         allocate);
+void         gdk_colormap_destroy (GdkColormap *colormap);
+
+GdkColormap* gdk_colormap_ref (GdkColormap *cmap);
+void         gdk_colormap_unref (GdkColormap *cmap);
+
+GdkColormap* gdk_colormap_get_system       (void);
+gint         gdk_colormap_get_system_size  (void);
+
+void gdk_colormap_change (GdkColormap   *colormap,
+                         gint           ncolors);
+void gdk_colors_store    (GdkColormap   *colormap,
+                         GdkColor      *colors,
+                         gint           ncolors);
+gint gdk_colors_alloc    (GdkColormap   *colormap,
+                         gint           contiguous,
+                         gulong        *planes,
+                         gint           nplanes,
+                         gulong        *pixels,
+                         gint           npixels);
+void gdk_colors_free     (GdkColormap   *colormap,
+                         gulong        *pixels,
+                         gint           npixels,
+                         gulong         planes);
+gint gdk_color_white     (GdkColormap   *colormap,
+                         GdkColor      *color);
+gint gdk_color_black     (GdkColormap   *colormap,
+                         GdkColor      *color);
+gint gdk_color_parse     (const gchar   *spec,
+                         GdkColor      *color);
+gint gdk_color_alloc     (GdkColormap   *colormap,
+                         GdkColor      *color);
+gint gdk_color_change    (GdkColormap   *colormap,
+                         GdkColor      *color);
+gint gdk_color_equal     (GdkColor      *colora,
+                         GdkColor      *colorb);
+
+
+/* Fonts
+ */
+GdkFont* gdk_font_load      (const gchar    *font_name);
+GdkFont* gdk_fontset_load   (gchar    *fontset_name);
+void     gdk_font_free      (GdkFont  *font);
+void     gdk_fontset_free   (GdkFont  *font);
+GdkFont* gdk_font_ref       (GdkFont  *font);
+gint     gdk_font_id        (GdkFont  *font);
+gint     gdk_font_equal     (GdkFont  *fonta,
+                            GdkFont  *fontb);
+gint     gdk_string_width   (GdkFont  *font,
+                            const gchar    *string);
+gint     gdk_text_width     (GdkFont  *font,
+                            const gchar    *text,
+                            gint      text_length);
+gint     gdk_char_width     (GdkFont  *font,
+                            gchar     character);
+gint     gdk_string_measure (GdkFont  *font,
+                             const gchar    *string);
+gint     gdk_text_measure   (GdkFont  *font,
+                             const gchar    *text,
+                             gint      text_length);
+gint     gdk_char_measure   (GdkFont  *font,
+                             gchar     character);
+
+
+/* Drawing
+ */
+void gdk_draw_point      (GdkDrawable  *drawable,
+                          GdkGC        *gc,
+                          gint          x,
+                          gint          y);
+void gdk_draw_line       (GdkDrawable  *drawable,
+                         GdkGC        *gc,
+                         gint          x1,
+                         gint          y1,
+                         gint          x2,
+                         gint          y2);
+void gdk_draw_rectangle  (GdkDrawable  *drawable,
+                         GdkGC        *gc,
+                         gint          filled,
+                         gint          x,
+                         gint          y,
+                         gint          width,
+                         gint          height);
+void gdk_draw_arc        (GdkDrawable  *drawable,
+                         GdkGC        *gc,
+                         gint          filled,
+                         gint          x,
+                         gint          y,
+                         gint          width,
+                         gint          height,
+                         gint          angle1,
+                         gint          angle2);
+void gdk_draw_polygon    (GdkDrawable  *drawable,
+                         GdkGC        *gc,
+                         gint          filled,
+                         GdkPoint     *points,
+                         gint          npoints);
+void gdk_draw_string     (GdkDrawable  *drawable,
+                         GdkFont      *font,
+                         GdkGC        *gc,
+                         gint          x,
+                         gint          y,
+                         const gchar        *string);
+void gdk_draw_text       (GdkDrawable  *drawable,
+                         GdkFont      *font,
+                         GdkGC        *gc,
+                         gint          x,
+                         gint          y,
+                         const gchar        *text,
+                         gint          text_length);
+void gdk_draw_pixmap     (GdkDrawable  *drawable,
+                         GdkGC        *gc,
+                         GdkDrawable  *src,
+                         gint          xsrc,
+                         gint          ysrc,
+                         gint          xdest,
+                         gint          ydest,
+                         gint          width,
+                         gint          height);
+void gdk_draw_bitmap     (GdkDrawable  *drawable,
+                         GdkGC        *gc,
+                         GdkDrawable  *src,
+                         gint          xsrc,
+                         gint          ysrc,
+                         gint          xdest,
+                         gint          ydest,
+                         gint          width,
+                         gint          height);
+void gdk_draw_image      (GdkDrawable  *drawable,
+                         GdkGC        *gc,
+                         GdkImage     *image,
+                         gint          xsrc,
+                         gint          ysrc,
+                         gint          xdest,
+                         gint          ydest,
+                         gint          width,
+                         gint          height);
+void gdk_draw_points     (GdkDrawable  *drawable,
+                         GdkGC        *gc,
+                         GdkPoint     *points,
+                         gint          npoints);
+void gdk_draw_segments   (GdkDrawable  *drawable,
+                         GdkGC        *gc,
+                         GdkSegment   *segs,
+                         gint          nsegs);
+
+
+/* Selections
+ */
+gint       gdk_selection_owner_set (GdkWindow    *owner,
+                                   GdkAtom       selection,
+                                   guint32       time,
+                                   gint          send_event);
+GdkWindow* gdk_selection_owner_get (GdkAtom       selection);
+void       gdk_selection_convert   (GdkWindow    *requestor,
+                                   GdkAtom       selection,
+                                   GdkAtom       target,
+                                   guint32       time);
+gint       gdk_selection_property_get (GdkWindow  *requestor,
+                                      guchar    **data,
+                                      GdkAtom    *prop_type,
+                                      gint       *prop_format);
+void       gdk_selection_send_notify (guint32       requestor,
+                                     GdkAtom       selection,
+                                     GdkAtom       target,
+                                     GdkAtom       property,
+                                     guint32       time);
+
+/* Properties
+ */
+GdkAtom gdk_atom_intern     (const gchar *atom_name,
+                            gint         only_if_exists);
+gchar*  gdk_atom_name       (GdkAtom atom);
+gint    gdk_property_get    (GdkWindow   *window,
+                            GdkAtom      property,
+                            GdkAtom      type,
+                            gulong       offset,
+                            gulong       length,
+                            gint         pdelete,
+                            GdkAtom     *actual_property_type,
+                            gint        *actual_format,
+                            gint        *actual_length,
+                            guchar     **data);
+
+void    gdk_property_change (GdkWindow   *window,
+                            GdkAtom      property,
+                            GdkAtom      type,
+                            gint         format,
+                            GdkPropMode  mode,
+                            guchar      *data,
+                            gint         nelements);
+void    gdk_property_delete (GdkWindow   *window,
+                            GdkAtom      property);
+
+
+/* Rectangle utilities
+ */
+gint gdk_rectangle_intersect (GdkRectangle *src1,
+                             GdkRectangle *src2,
+                             GdkRectangle *dest);
+
+/* XInput support
+ */
+
+void gdk_input_init                        (void);
+void gdk_input_exit                        (void);
+GList *gdk_input_list_devices               (void);
+void gdk_input_set_extension_events         (GdkWindow *window,
+                                            gint mask,
+                                            GdkExtensionMode mode);
+void gdk_input_set_source                  (guint32 deviceid,
+                                            GdkInputSource source);
+gint gdk_input_set_mode                    (guint32 deviceid,
+                                            GdkInputMode mode);
+void gdk_input_set_axes                            (guint32 deviceid,
+                                            GdkAxisUse *axes);
+void gdk_input_window_get_pointer     (GdkWindow       *window,
+                                      guint32         deviceid,
+                                      gdouble         *x,
+                                      gdouble         *y,
+                                      gdouble         *pressure,
+                                      gdouble         *xtilt,
+                                      gdouble         *ytilt,
+                                      GdkModifierType *mask);
+
+GdkTimeCoord *gdk_input_motion_events (GdkWindow *window,
+                                      guint32 deviceid,
+                                      guint32 start,
+                                      guint32 stop,
+                                      gint *nevents_return);
+
+/* Miscellaneous */
+void gdk_event_send_clientmessage_toall(GdkEvent *event);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GDK_H__ */
diff --git a/gdk/gdkcolor.c b/gdk/gdkcolor.c
new file mode 100644 (file)
index 0000000..5e66f08
--- /dev/null
@@ -0,0 +1,718 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <X11/Xlib.h>
+#include "gdk.h"
+#include "gdkprivate.h"
+
+
+static gint  gdk_colormap_match_color (GdkColormap *cmap,
+                                      GdkColor    *color,
+                                      const gchar *available);
+static void  gdk_colormap_add         (GdkColormap *cmap);
+static void  gdk_colormap_remove      (GdkColormap *cmap);
+static guint gdk_colormap_hash        (Colormap    *cmap);
+static gint  gdk_colormap_cmp         (Colormap    *a,
+                                      Colormap    *b);
+
+static GHashTable *colormap_hash = NULL;
+
+
+GdkColormap*
+gdk_colormap_new (GdkVisual *visual,
+                 gint       private_cmap)
+{
+  GdkColormap *colormap;
+  GdkColormapPrivate *private;
+  Visual *xvisual;
+  XColor default_colors[256];
+  int size;
+  int i;
+
+  g_return_val_if_fail (visual != NULL, NULL);
+
+  private = g_new (GdkColormapPrivate, 1);
+  colormap = (GdkColormap*) private;
+
+  private->xdisplay = gdk_display;
+  private->visual = visual;
+  private->next_color = 0;
+  private->ref_count = 1;
+  xvisual = ((GdkVisualPrivate*) visual)->xvisual;
+
+  switch (visual->type)
+    {
+    case GDK_VISUAL_GRAYSCALE:
+    case GDK_VISUAL_PSEUDO_COLOR:
+      private->private_val = private_cmap;
+      private->xcolormap = XCreateColormap (private->xdisplay, gdk_root_window,
+                                           xvisual, (private_cmap) ? (AllocAll) : (AllocNone));
+
+      if (private_cmap)
+       {
+         for (i = 0; i < 256; i++)
+           default_colors[i].pixel = i;
+
+         XQueryColors (private->xdisplay,
+                       DefaultColormap (private->xdisplay, gdk_screen),
+                       default_colors, visual->colormap_size);
+
+         for (i = 0; i < visual->colormap_size; i++)
+           {
+             colormap->colors[i].pixel = default_colors[i].pixel;
+             colormap->colors[i].red = default_colors[i].red;
+             colormap->colors[i].green = default_colors[i].green;
+             colormap->colors[i].blue = default_colors[i].blue;
+           }
+
+         gdk_colormap_change (colormap, visual->colormap_size);
+       }
+      break;
+
+    case GDK_VISUAL_DIRECT_COLOR:
+      private->private_val = TRUE;
+      private->xcolormap = XCreateColormap (private->xdisplay, gdk_root_window,
+                                           xvisual, AllocAll);
+
+      size = 1 << visual->red_prec;
+      for (i = 0; i < size; i++)
+       colormap->colors[i].red = i * 65535 / (size - 1);
+
+      size = 1 << visual->green_prec;
+      for (i = 0; i < size; i++)
+       colormap->colors[i].green = i * 65535 / (size - 1);
+
+      size = 1 << visual->blue_prec;
+      for (i = 0; i < size; i++)
+       colormap->colors[i].blue = i * 65535 / (size - 1);
+
+      gdk_colormap_change (colormap, visual->colormap_size);
+      break;
+
+    case GDK_VISUAL_STATIC_GRAY:
+    case GDK_VISUAL_STATIC_COLOR:
+    case GDK_VISUAL_TRUE_COLOR:
+      private->private_val = FALSE;
+      private->xcolormap = XCreateColormap (private->xdisplay, gdk_root_window,
+                                           xvisual, AllocNone);
+      break;
+    }
+
+  gdk_colormap_add (colormap);
+
+  return colormap;
+}
+
+void
+gdk_colormap_real_destroy (GdkColormap *colormap)
+{
+  GdkColormapPrivate *private = (GdkColormapPrivate*) colormap;
+
+  g_return_if_fail (colormap != NULL);
+
+  if (private->ref_count > 0)
+    return;
+
+  gdk_colormap_remove (colormap);
+  XFreeColormap (private->xdisplay, private->xcolormap);
+  g_free (colormap);
+}
+
+void
+gdk_colormap_destroy (GdkColormap *colormap)
+{
+  gdk_colormap_unref (colormap);
+}
+
+GdkColormap*
+gdk_colormap_ref (GdkColormap *cmap)
+{
+  GdkColormapPrivate *private = (GdkColormapPrivate *)cmap;
+  g_return_val_if_fail (cmap != NULL, NULL);
+
+  private->ref_count += 1;
+  return cmap;
+}
+
+void
+gdk_colormap_unref (GdkColormap *cmap)
+{
+  GdkColormapPrivate *private = (GdkColormapPrivate *)cmap;
+  g_return_if_fail (cmap != NULL);
+
+  private->ref_count -= 1;
+  if (private->ref_count == 0)
+    gdk_colormap_real_destroy (cmap);
+}
+
+GdkColormap*
+gdk_colormap_get_system (void)
+{
+  static GdkColormap *colormap = NULL;
+  GdkColormapPrivate *private;
+  XColor xpalette[256];
+  gint i;
+
+  if (!colormap)
+    {
+      private = g_new (GdkColormapPrivate, 1);
+      colormap = (GdkColormap*) private;
+
+      private->xdisplay = gdk_display;
+      private->xcolormap = DefaultColormap (gdk_display, gdk_screen);
+      private->visual = gdk_visual_get_system ();
+      private->private_val = FALSE;
+      private->next_color = 0;
+      private->ref_count = 1;
+
+      for (i = 0; i < 256; i++)
+       {
+         xpalette[i].pixel = i;
+         xpalette[i].red = 0;
+         xpalette[i].green = 0;
+         xpalette[i].blue = 0;
+       }
+
+      XQueryColors (gdk_display, private->xcolormap, xpalette, 256);
+
+      for (i = 0; i < 256; i++)
+       {
+         colormap->colors[i].pixel = xpalette[i].pixel;
+         colormap->colors[i].red = xpalette[i].red;
+         colormap->colors[i].green = xpalette[i].green;
+         colormap->colors[i].blue = xpalette[i].blue;
+       }
+
+      gdk_colormap_add (colormap);
+    }
+
+  return colormap;
+}
+
+gint
+gdk_colormap_get_system_size (void)
+{
+  return DisplayCells (gdk_display, gdk_screen);
+}
+
+void
+gdk_colormap_change (GdkColormap *colormap,
+                    gint         ncolors)
+{
+  GdkColormapPrivate *private;
+  GdkVisual *visual;
+  XColor palette[256];
+  gint shift;
+  int max_colors;
+  int size;
+  int i;
+
+  g_return_if_fail (colormap != NULL);
+
+  private = (GdkColormapPrivate*) colormap;
+  switch (private->visual->type)
+    {
+    case GDK_VISUAL_GRAYSCALE:
+    case GDK_VISUAL_PSEUDO_COLOR:
+      for (i = 0; i < ncolors; i++)
+       {
+         palette[i].pixel = colormap->colors[i].pixel;
+         palette[i].red = colormap->colors[i].red;
+         palette[i].green = colormap->colors[i].green;
+         palette[i].blue = colormap->colors[i].blue;
+         palette[i].flags = DoRed | DoGreen | DoBlue;
+       }
+
+      XStoreColors (private->xdisplay, private->xcolormap, palette, ncolors);
+      private->next_color = MAX (private->next_color, ncolors);
+      break;
+
+    case GDK_VISUAL_DIRECT_COLOR:
+      visual = private->visual;
+
+      shift = visual->red_shift;
+      max_colors = 1 << visual->red_prec;
+      size = (ncolors < max_colors) ? (ncolors) : (max_colors);
+
+      for (i = 0; i < size; i++)
+       {
+         palette[i].pixel = i << shift;
+         palette[i].red = colormap->colors[i].red;
+         palette[i].flags = DoRed;
+       }
+
+      XStoreColors (private->xdisplay, private->xcolormap, palette, size);
+
+      shift = visual->green_shift;
+      max_colors = 1 << visual->green_prec;
+      size = (ncolors < max_colors) ? (ncolors) : (max_colors);
+
+      for (i = 0; i < size; i++)
+       {
+         palette[i].pixel = i << shift;
+         palette[i].green = colormap->colors[i].green;
+         palette[i].flags = DoGreen;
+       }
+
+      XStoreColors (private->xdisplay, private->xcolormap, palette, size);
+
+      shift = visual->blue_shift;
+      max_colors = 1 << visual->blue_prec;
+      size = (ncolors < max_colors) ? (ncolors) : (max_colors);
+
+      for (i = 0; i < size; i++)
+       {
+         palette[i].pixel = i << shift;
+         palette[i].blue = colormap->colors[i].blue;
+         palette[i].flags = DoBlue;
+       }
+
+      XStoreColors (private->xdisplay, private->xcolormap, palette, size);
+      break;
+
+    default:
+      break;
+    }
+}
+
+void
+gdk_colors_store (GdkColormap   *colormap,
+                 GdkColor      *colors,
+                 gint           ncolors)
+{
+  gint i;
+
+  for (i = 0; i < ncolors; i++)
+    {
+      colormap->colors[i].pixel = colors[i].pixel;
+      colormap->colors[i].red = colors[i].red;
+      colormap->colors[i].green = colors[i].green;
+      colormap->colors[i].blue = colors[i].blue;
+    }
+
+  gdk_colormap_change (colormap, ncolors);
+}
+
+gint
+gdk_colors_alloc (GdkColormap   *colormap,
+                 gint           contiguous,
+                 gulong        *planes,
+                 gint           nplanes,
+                 gulong        *pixels,
+                 gint           npixels)
+{
+  GdkColormapPrivate *private;
+  gint return_val;
+
+  g_return_val_if_fail (colormap != NULL, 0);
+
+  private = (GdkColormapPrivate*) colormap;
+
+  return_val = XAllocColorCells (private->xdisplay, private->xcolormap,
+                                contiguous, planes, nplanes, pixels, npixels);
+
+  return return_val;
+}
+
+void
+gdk_colors_free (GdkColormap *colormap,
+                gulong      *pixels,
+                gint         npixels,
+                gulong       planes)
+{
+  GdkColormapPrivate *private;
+
+  g_return_if_fail (colormap != NULL);
+
+  private = (GdkColormapPrivate*) colormap;
+
+  XFreeColors (private->xdisplay, private->xcolormap,
+              pixels, npixels, planes);
+}
+
+gint
+gdk_color_white (GdkColormap *colormap,
+                GdkColor    *color)
+{
+  gint return_val;
+
+  g_return_val_if_fail (colormap != NULL, FALSE);
+
+  if (color)
+    {
+      color->pixel = WhitePixel (gdk_display, gdk_screen);
+      color->red = 65535;
+      color->green = 65535;
+      color->blue = 65535;
+
+      return_val = gdk_color_alloc (colormap, color);
+    }
+  else
+    return_val = FALSE;
+
+  return return_val;
+}
+
+gint
+gdk_color_black (GdkColormap *colormap,
+                GdkColor    *color)
+{
+  gint return_val;
+
+  g_return_val_if_fail (colormap != NULL, FALSE);
+
+  if (color)
+    {
+      color->pixel = BlackPixel (gdk_display, gdk_screen);
+      color->red = 0;
+      color->green = 0;
+      color->blue = 0;
+
+      return_val = gdk_color_alloc (colormap, color);
+    }
+  else
+    return_val = FALSE;
+
+  return return_val;
+}
+
+gint
+gdk_color_parse (const gchar *spec,
+                GdkColor *color)
+{
+  Colormap xcolormap;
+  XColor xcolor;
+  gint return_val;
+
+  g_return_val_if_fail (spec != NULL, FALSE);
+  g_return_val_if_fail (color != NULL, FALSE);
+
+  xcolormap = DefaultColormap (gdk_display, gdk_screen);
+
+  if (XParseColor (gdk_display, xcolormap, spec, &xcolor))
+    {
+      return_val = TRUE;
+      color->red = xcolor.red;
+      color->green = xcolor.green;
+      color->blue = xcolor.blue;
+    }
+  else
+    return_val = FALSE;
+
+  return return_val;
+}
+
+gint
+gdk_color_alloc (GdkColormap *colormap,
+                GdkColor    *color)
+{
+  GdkColormapPrivate *private;
+  GdkVisual *visual;
+  XColor xcolor;
+  gchar available[256];
+  gint available_init;
+  gint return_val;
+  gint i, index;
+
+  g_return_val_if_fail (colormap != NULL, FALSE);
+  g_return_val_if_fail (color != NULL, FALSE);
+
+  xcolor.red = color->red;
+  xcolor.green = color->green;
+  xcolor.blue = color->blue;
+  xcolor.pixel = color->pixel;
+  xcolor.flags = DoRed | DoGreen | DoBlue;
+
+  return_val = FALSE;
+  private = (GdkColormapPrivate*) colormap;
+
+  switch (private->visual->type)
+    {
+    case GDK_VISUAL_GRAYSCALE:
+    case GDK_VISUAL_PSEUDO_COLOR:
+      if (private->private_val)
+       {
+         if (private->next_color > 255)
+           {
+             for (i = 0; i < 256; i++)
+               available[i] = TRUE;
+
+             index = gdk_colormap_match_color (colormap, color, available);
+             if (index != -1)
+               {
+                 available[index] = FALSE;
+                 *color = colormap->colors[index];
+                 return_val = TRUE;
+               }
+             else
+               {
+                 return_val = FALSE;
+               }
+           }
+         else
+           {
+             xcolor.pixel = 255 - private->next_color;
+             color->pixel = xcolor.pixel;
+             private->next_color += 1;
+
+             XStoreColor (private->xdisplay, private->xcolormap, &xcolor);
+             return_val = TRUE;
+           }
+       }
+      else
+       {
+         available_init = 1;
+
+         while (1)
+           {
+             if (XAllocColor (private->xdisplay, private->xcolormap, &xcolor))
+               {
+                 color->pixel = xcolor.pixel;
+                 color->red = xcolor.red;
+                 color->green = xcolor.green;
+                 color->blue = xcolor.blue;
+
+                 colormap->colors[color->pixel] = *color;
+
+                 return_val = TRUE;
+                 break;
+               }
+             else
+               {
+                 if (available_init)
+                   {
+                     available_init = 0;
+                     for (i = 0; i < 256; i++)
+                       available[i] = TRUE;
+                   }
+
+                 index = gdk_colormap_match_color (colormap, color, available);
+                 if (index != -1)
+                   {
+                     available[index] = FALSE;
+                     xcolor.red = colormap->colors[index].red;
+                     xcolor.green = colormap->colors[index].green;
+                     xcolor.blue = colormap->colors[index].blue;
+                   }
+                 else
+                   {
+                     return_val = FALSE;
+                     break;
+                   }
+               }
+           }
+       }
+      break;
+
+    case GDK_VISUAL_DIRECT_COLOR:
+      visual = private->visual;
+      xcolor.pixel = (((xcolor.red >> (16 - visual->red_prec)) << visual->red_shift) +
+                     ((xcolor.green >> (16 - visual->green_prec)) << visual->green_shift) +
+                     ((xcolor.blue >> (16 - visual->blue_prec)) << visual->blue_shift));
+      color->pixel = xcolor.pixel;
+      return_val = TRUE;
+      break;
+
+    case GDK_VISUAL_STATIC_GRAY:
+    case GDK_VISUAL_STATIC_COLOR:
+    case GDK_VISUAL_TRUE_COLOR:
+      if (XAllocColor (private->xdisplay, private->xcolormap, &xcolor))
+       {
+         color->pixel = xcolor.pixel;
+         return_val = TRUE;
+       }
+      else
+       return_val = FALSE;
+      break;
+    }
+
+  return return_val;
+}
+
+gint
+gdk_color_change (GdkColormap *colormap,
+                 GdkColor    *color)
+{
+  GdkColormapPrivate *private;
+  XColor xcolor;
+
+  g_return_val_if_fail (colormap != NULL, FALSE);
+  g_return_val_if_fail (color != NULL, FALSE);
+
+  xcolor.pixel = color->pixel;
+  xcolor.red = color->red;
+  xcolor.green = color->green;
+  xcolor.blue = color->blue;
+  xcolor.flags = DoRed | DoGreen | DoBlue;
+
+  private = (GdkColormapPrivate*) colormap;
+  XStoreColor (private->xdisplay, private->xcolormap, &xcolor);
+
+  return TRUE;
+}
+
+gint
+gdk_color_equal (GdkColor *colora,
+                GdkColor *colorb)
+{
+  g_return_val_if_fail (colora != NULL, FALSE);
+  g_return_val_if_fail (colorb != NULL, FALSE);
+
+  return ((colora->red == colorb->red) &&
+         (colora->green == colorb->green) &&
+         (colora->blue == colorb->blue));
+}
+
+GdkColormap*
+gdkx_colormap_get (Colormap xcolormap)
+{
+  GdkColormap *colormap;
+  GdkColormapPrivate *private;
+  XColor xpalette[256];
+  gint i;
+
+  colormap = gdk_colormap_lookup (xcolormap);
+  if (colormap)
+    return colormap;
+
+  if (xcolormap == DefaultColormap (gdk_display, gdk_screen))
+    return gdk_colormap_get_system ();
+
+  private = g_new (GdkColormapPrivate, 1);
+  colormap = (GdkColormap*) private;
+
+  private->xdisplay = gdk_display;
+  private->xcolormap = xcolormap;
+  private->visual = NULL;
+  private->private_val = TRUE;
+  private->next_color = 0;
+
+  for (i = 0; i < 256; i++)
+    {
+      xpalette[i].pixel = i;
+      xpalette[i].red = 0;
+      xpalette[i].green = 0;
+      xpalette[i].blue = 0;
+    }
+
+  XQueryColors (gdk_display, private->xcolormap, xpalette, 256);
+
+  for (i = 0; i < 256; i++)
+    {
+      colormap->colors[i].pixel = xpalette[i].pixel;
+      colormap->colors[i].red = xpalette[i].red;
+      colormap->colors[i].green = xpalette[i].green;
+      colormap->colors[i].blue = xpalette[i].blue;
+    }
+
+  gdk_colormap_add (colormap);
+
+  return colormap;
+}
+
+
+static gint
+gdk_colormap_match_color (GdkColormap *cmap,
+                         GdkColor    *color,
+                         const gchar *available)
+{
+  GdkColor *colors;
+  guint sum, max;
+  gint rdiff, gdiff, bdiff;
+  gint i, index;
+
+  g_return_val_if_fail (cmap != NULL, 0);
+  g_return_val_if_fail (color != NULL, 0);
+
+  colors = cmap->colors;
+  max = 3 * (65536);
+  index = -1;
+
+  for (i = 0; i < 256; i++)
+    {
+      if ((!available) || (available && available[i]))
+       {
+         rdiff = (color->red - colors[i].red);
+         gdiff = (color->green - colors[i].green);
+         bdiff = (color->blue - colors[i].blue);
+
+         sum = ABS (rdiff) + ABS (gdiff) + ABS (bdiff);
+
+         if (sum < max)
+           {
+             index = i;
+             max = sum;
+           }
+       }
+    }
+
+  return index;
+}
+
+
+GdkColormap*
+gdk_colormap_lookup (Colormap xcolormap)
+{
+  GdkColormap *cmap;
+
+  if (!colormap_hash)
+    return NULL;
+
+  cmap = g_hash_table_lookup (colormap_hash, &xcolormap);
+  return cmap;
+}
+
+static void
+gdk_colormap_add (GdkColormap *cmap)
+{
+  GdkColormapPrivate *private;
+
+  if (!colormap_hash)
+    colormap_hash = g_hash_table_new ((GHashFunc) gdk_colormap_hash,
+                                     (GCompareFunc) gdk_colormap_cmp);
+
+  private = (GdkColormapPrivate*) cmap;
+
+  g_hash_table_insert (colormap_hash, &private->xcolormap, cmap);
+}
+
+static void
+gdk_colormap_remove (GdkColormap *cmap)
+{
+  GdkColormapPrivate *private;
+
+  if (!colormap_hash)
+    colormap_hash = g_hash_table_new ((GHashFunc) gdk_colormap_hash,
+                                     (GCompareFunc) gdk_colormap_cmp);
+
+  private = (GdkColormapPrivate*) cmap;
+
+  g_hash_table_remove (colormap_hash, &private->xcolormap);
+}
+
+static guint
+gdk_colormap_hash (Colormap *cmap)
+{
+  return *cmap;
+}
+
+static gint
+gdk_colormap_cmp (Colormap *a,
+                 Colormap *b)
+{
+  return (*a == *b);
+}
diff --git a/gdk/gdkcursor.c b/gdk/gdkcursor.c
new file mode 100644 (file)
index 0000000..22bfd25
--- /dev/null
@@ -0,0 +1,52 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <X11/Xlib.h>
+#include <X11/cursorfont.h>
+#include "gdk.h"
+#include "gdkprivate.h"
+
+
+GdkCursor*
+gdk_cursor_new (GdkCursorType cursor_type)
+{
+  GdkCursorPrivate *private;
+  GdkCursor *cursor;
+  Cursor xcursor;
+
+  xcursor = XCreateFontCursor (gdk_display, cursor_type);
+  private = g_new (GdkCursorPrivate, 1);
+  private->xdisplay = gdk_display;
+  private->xcursor = xcursor;
+  cursor = (GdkCursor*) private;
+  cursor->type = cursor_type;
+
+  return cursor;
+}
+
+void
+gdk_cursor_destroy (GdkCursor *cursor)
+{
+  GdkCursorPrivate *private;
+
+  g_return_if_fail (cursor != NULL);
+
+  private = (GdkCursorPrivate *) cursor;
+  XFreeCursor (private->xdisplay, private->xcursor);
+
+  g_free (private);
+}
diff --git a/gdk/gdkdraw.c b/gdk/gdkdraw.c
new file mode 100644 (file)
index 0000000..47482f7
--- /dev/null
@@ -0,0 +1,383 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <X11/Xlib.h>
+#include <X11/Xos.h>
+#include "gdk.h"
+#include "gdkprivate.h"
+
+
+void
+gdk_draw_point (GdkDrawable *drawable,
+                GdkGC       *gc,
+                gint         x,
+                gint         y)
+{
+  GdkWindowPrivate *drawable_private;
+  GdkGCPrivate *gc_private;
+
+  g_return_if_fail (drawable != NULL);
+  g_return_if_fail (gc != NULL);
+
+  drawable_private = (GdkWindowPrivate*) drawable;
+  gc_private = (GdkGCPrivate*) gc;
+
+  XDrawPoint (drawable_private->xdisplay, drawable_private->xwindow,
+              gc_private->xgc, x, y);
+}
+
+void
+gdk_draw_line (GdkDrawable *drawable,
+              GdkGC       *gc,
+              gint         x1,
+              gint         y1,
+              gint         x2,
+              gint         y2)
+{
+  GdkWindowPrivate *drawable_private;
+  GdkGCPrivate *gc_private;
+
+  g_return_if_fail (drawable != NULL);
+  g_return_if_fail (gc != NULL);
+
+  drawable_private = (GdkWindowPrivate*) drawable;
+  gc_private = (GdkGCPrivate*) gc;
+
+  XDrawLine (drawable_private->xdisplay, drawable_private->xwindow,
+            gc_private->xgc, x1, y1, x2, y2);
+}
+
+void
+gdk_draw_rectangle (GdkDrawable *drawable,
+                   GdkGC       *gc,
+                   gint         filled,
+                   gint         x,
+                   gint         y,
+                   gint         width,
+                   gint         height)
+{
+  GdkWindowPrivate *drawable_private;
+  GdkGCPrivate *gc_private;
+
+  g_return_if_fail (drawable != NULL);
+  g_return_if_fail (gc != NULL);
+
+  drawable_private = (GdkWindowPrivate*) drawable;
+  gc_private = (GdkGCPrivate*) gc;
+
+  if (width == -1)
+    width = drawable_private->width;
+  if (height == -1)
+    height = drawable_private->height;
+
+  if (filled)
+    XFillRectangle (drawable_private->xdisplay, drawable_private->xwindow,
+                   gc_private->xgc, x, y, width, height);
+  else
+    XDrawRectangle (drawable_private->xdisplay, drawable_private->xwindow,
+                   gc_private->xgc, x, y, width, height);
+}
+
+void
+gdk_draw_arc (GdkDrawable *drawable,
+             GdkGC       *gc,
+             gint         filled,
+             gint         x,
+             gint         y,
+             gint         width,
+             gint         height,
+             gint         angle1,
+             gint         angle2)
+{
+  GdkWindowPrivate *drawable_private;
+  GdkGCPrivate *gc_private;
+
+  g_return_if_fail (drawable != NULL);
+  g_return_if_fail (gc != NULL);
+
+  drawable_private = (GdkWindowPrivate*) drawable;
+  gc_private = (GdkGCPrivate*) gc;
+
+  if (width == -1)
+    width = drawable_private->width;
+  if (height == -1)
+    height = drawable_private->height;
+
+  if (filled)
+    XFillArc (drawable_private->xdisplay, drawable_private->xwindow,
+             gc_private->xgc, x, y, width, height, angle1, angle2);
+  else
+    XDrawArc (drawable_private->xdisplay, drawable_private->xwindow,
+             gc_private->xgc, x, y, width, height, angle1, angle2);
+}
+
+void
+gdk_draw_polygon (GdkDrawable *drawable,
+                 GdkGC       *gc,
+                 gint         filled,
+                 GdkPoint    *points,
+                 gint         npoints)
+{
+  GdkWindowPrivate *drawable_private;
+  GdkGCPrivate *gc_private;
+
+  g_return_if_fail (drawable != NULL);
+  g_return_if_fail (gc != NULL);
+
+  drawable_private = (GdkWindowPrivate*) drawable;
+  gc_private = (GdkGCPrivate*) gc;
+
+  if (filled)
+    {
+      XFillPolygon (drawable_private->xdisplay, drawable_private->xwindow,
+                   gc_private->xgc, (XPoint*) points, npoints, Complex, CoordModeOrigin);
+    }
+  else
+    {
+      XDrawLines (drawable_private->xdisplay, drawable_private->xwindow,
+                 gc_private->xgc, (XPoint*) points, npoints, CoordModeOrigin);
+
+      if ((points[0].x != points[npoints-1].x) ||
+         (points[0].y != points[npoints-1].y))
+       XDrawLine (drawable_private->xdisplay, drawable_private->xwindow,
+                  gc_private->xgc, points[npoints-1].x, points[npoints-1].y,
+                  points[0].x, points[0].y);
+    }
+}
+
+/* gdk_draw_string
+ *
+ * Modified by Li-Da Lho to draw 16 bits and Multibyte strings
+ *
+ * Interface changed: add "GdkFont *font" to specify font or fontset explicitely
+ */
+void
+gdk_draw_string (GdkDrawable *drawable,
+                GdkFont     *font,
+                GdkGC       *gc,
+                gint         x,
+                gint         y,
+                const gchar *string)
+{
+  GdkWindowPrivate *drawable_private;
+  GdkFontPrivate *font_private;
+  GdkGCPrivate *gc_private;
+
+  g_return_if_fail (drawable != NULL);
+  g_return_if_fail (font != NULL);
+  g_return_if_fail (gc != NULL);
+  g_return_if_fail (string != NULL);
+
+  drawable_private = (GdkWindowPrivate*) drawable;
+  gc_private = (GdkGCPrivate*) gc;
+  font_private = (GdkFontPrivate*) font;
+
+  if (font->type == GDK_FONT_FONT)
+    {
+      XFontStruct *xfont = (XFontStruct *) font_private->xfont;
+      XSetFont(drawable_private->xdisplay, gc_private->xgc, xfont->fid);
+      if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
+       {
+         XDrawString (drawable_private->xdisplay, drawable_private->xwindow,
+                      gc_private->xgc, x, y, string, strlen (string));
+       }
+      else
+       {
+         XDrawString16 (drawable_private->xdisplay, drawable_private->xwindow,
+                        gc_private->xgc, x, y, (XChar2b *) string,
+                        strlen (string) / 2);
+       }
+    }
+  else if (font->type == GDK_FONT_FONTSET)
+    {
+      XFontSet fontset = (XFontSet) font_private->xfont;
+      XmbDrawString (drawable_private->xdisplay, drawable_private->xwindow,
+                    fontset, gc_private->xgc, x, y, string, strlen (string));
+    }
+  else
+    g_error("undefined font type\n");
+}
+
+/* gdk_draw_text
+ *
+ * Modified by Li-Da Lho to draw 16 bits and Multibyte strings
+ *
+ * Interface changed: add "GdkFont *font" to specify font or fontset explicitely
+ */
+void
+gdk_draw_text (GdkDrawable *drawable,
+              GdkFont     *font,
+              GdkGC       *gc,
+              gint         x,
+              gint         y,
+              const gchar *text,
+              gint         text_length)
+{
+  GdkWindowPrivate *drawable_private;
+  GdkFontPrivate *font_private;
+  GdkGCPrivate *gc_private;
+
+  g_return_if_fail (drawable != NULL);
+  g_return_if_fail (font != NULL);
+  g_return_if_fail (gc != NULL);
+  g_return_if_fail (text != NULL);
+
+  drawable_private = (GdkWindowPrivate*) drawable;
+  gc_private = (GdkGCPrivate*) gc;
+  font_private = (GdkFontPrivate*) font;
+
+  if (font->type == GDK_FONT_FONT)
+    {
+      XFontStruct *xfont = (XFontStruct *) font_private->xfont;
+      XSetFont(drawable_private->xdisplay, gc_private->xgc, xfont->fid);
+      if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
+       {
+         XDrawString (drawable_private->xdisplay, drawable_private->xwindow,
+                      gc_private->xgc, x, y, text, text_length);
+       }
+      else
+       {
+         XDrawString16 (drawable_private->xdisplay, drawable_private->xwindow,
+                        gc_private->xgc, x, y, (XChar2b *) text, text_length / 2);
+       }
+    }
+  else if (font->type == GDK_FONT_FONTSET)
+    {
+      XFontSet fontset = (XFontSet) font_private->xfont;
+      XmbDrawString (drawable_private->xdisplay, drawable_private->xwindow,
+                    fontset, gc_private->xgc, x, y, text, text_length);
+    }
+  else
+    g_error("undefined font type\n");
+}
+
+void
+gdk_draw_pixmap (GdkDrawable *drawable,
+                GdkGC       *gc,
+                GdkPixmap   *src,
+                gint         xsrc,
+                gint         ysrc,
+                gint         xdest,
+                gint         ydest,
+                gint         width,
+                gint         height)
+{
+  GdkWindowPrivate *drawable_private;
+  GdkWindowPrivate *src_private;
+  GdkGCPrivate *gc_private;
+
+  g_return_if_fail (drawable != NULL);
+  g_return_if_fail (src != NULL);
+  g_return_if_fail (gc != NULL);
+
+  drawable_private = (GdkWindowPrivate*) drawable;
+  src_private = (GdkWindowPrivate*) src;
+  gc_private = (GdkGCPrivate*) gc;
+
+  if (width == -1)
+    width = src_private->width;
+  if (height == -1)
+    height = src_private->height;
+
+  XCopyArea (drawable_private->xdisplay,
+            src_private->xwindow,
+            drawable_private->xwindow,
+            gc_private->xgc,
+            xsrc, ysrc,
+            width, height,
+            xdest, ydest);
+}
+
+void
+gdk_draw_image (GdkDrawable *drawable,
+               GdkGC       *gc,
+               GdkImage    *image,
+               gint         xsrc,
+               gint         ysrc,
+               gint         xdest,
+               gint         ydest,
+               gint         width,
+               gint         height)
+{
+  GdkImagePrivate *image_private;
+
+  g_return_if_fail (drawable != NULL);
+  g_return_if_fail (image != NULL);
+  g_return_if_fail (gc != NULL);
+
+  image_private = (GdkImagePrivate*) image;
+
+  g_return_if_fail (image_private->image_put != NULL);
+
+  if (width == -1)
+    width = image->width;
+  if (height == -1)
+    height = image->height;
+
+  (* image_private->image_put) (drawable, gc, image, xsrc, ysrc,
+                               xdest, ydest, width, height);
+}
+
+void
+gdk_draw_points (GdkDrawable *drawable,
+                GdkGC       *gc,
+                GdkPoint    *points,
+                gint         npoints)
+{
+  GdkWindowPrivate *drawable_private;
+  GdkGCPrivate *gc_private;
+
+  g_return_if_fail (drawable != NULL);
+  g_return_if_fail ((points != NULL) && (npoints > 0));
+  g_return_if_fail (gc != NULL);
+
+  drawable_private = (GdkWindowPrivate*) drawable;
+  gc_private = (GdkGCPrivate*) gc;
+
+  XDrawPoints (drawable_private->xdisplay,
+              drawable_private->xwindow,
+              gc_private->xgc,
+              (XPoint *) points,
+              npoints,
+              CoordModeOrigin);
+}
+
+void
+gdk_draw_segments (GdkDrawable *drawable,
+                  GdkGC       *gc,
+                  GdkSegment  *segs,
+                  gint         nsegs)
+{
+  GdkWindowPrivate *drawable_private;
+  GdkGCPrivate *gc_private;
+
+  if (nsegs <= 0)
+    return;
+
+  g_return_if_fail (drawable != NULL);
+  g_return_if_fail (segs != NULL);
+  g_return_if_fail (gc != NULL);
+
+  drawable_private = (GdkWindowPrivate*) drawable;
+  gc_private = (GdkGCPrivate*) gc;
+
+  XDrawSegments (drawable_private->xdisplay,
+                drawable_private->xwindow,
+                gc_private->xgc,
+                (XSegment *) segs,
+                nsegs);
+}
diff --git a/gdk/gdkfont.c b/gdk/gdkfont.c
new file mode 100644 (file)
index 0000000..e1b1e72
--- /dev/null
@@ -0,0 +1,379 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <X11/Xlib.h>
+#include <X11/Xos.h>
+#include "gdk.h"
+#include "gdkprivate.h"
+
+GdkFont*
+gdk_font_load (const gchar *font_name)
+{
+  GdkFont *font;
+  GdkFontPrivate *private;
+
+  private = g_new (GdkFontPrivate, 1);
+  font = (GdkFont*) private;
+
+  private->xdisplay = gdk_display;
+  private->xfont = XLoadQueryFont (private->xdisplay, font_name);
+  private->ref_count = 1;
+
+  if (!private->xfont)
+    {
+      g_free (font);
+      return NULL;
+    }
+  else
+    {
+      font->type = GDK_FONT_FONT;
+      font->ascent =  ((XFontStruct *) private->xfont)->ascent;
+      font->descent = ((XFontStruct *) private->xfont)->descent;
+    }
+
+  gdk_xid_table_insert (&((XFontStruct *) private->xfont)->fid, font);
+
+  return font;
+}
+
+GdkFont*
+gdk_fontset_load(gchar *fontset_name)
+{
+  GdkFont *font;
+  GdkFontPrivate *private;
+  XFontSet fontset;
+  gint  missing_charset_count;
+  gchar **missing_charset_list;
+  gchar *def_string;
+
+  private = g_new (GdkFontPrivate, 1);
+  font = (GdkFont*) private;
+
+  private->xdisplay = gdk_display;
+  fontset = XCreateFontSet (gdk_display, fontset_name,
+                           &missing_charset_list, &missing_charset_count,
+                           &def_string);
+
+  if (missing_charset_count)
+    {
+      g_print ("Missing charsets in FontSet creation");
+      XFreeStringList (missing_charset_list);
+    }
+
+  private->ref_count = 1;
+
+  if (!fontset)
+    {
+      g_free (font);
+      return NULL;
+    }
+  else
+    {
+      XFontSetExtents *extent = XExtentsOfFontSet(fontset);
+
+      private->xfont = fontset;
+      font->type = GDK_FONT_FONTSET;
+      /* how to define ascent and descent for fontset ??? */
+      font->ascent =  extent->max_logical_extent.height;
+      font->descent = font->ascent / 4 ;
+    }
+  return font;
+}
+void
+gdk_font_free (GdkFont *font)
+{
+  GdkFontPrivate *private;
+
+  g_return_if_fail (font != NULL);
+
+  private = (GdkFontPrivate*) font;
+
+  private->ref_count -= 1;
+  if (private->ref_count == 0)
+    {
+      gdk_xid_table_remove (((XFontStruct *) private->xfont)->fid);
+      XFreeFont (private->xdisplay, (XFontStruct *) private->xfont);
+      g_free (font);
+    }
+}
+
+void
+gdk_fontset_free (GdkFont *font)
+{
+  GdkFontPrivate *private;
+
+  g_return_if_fail (font != NULL);
+
+  private = (GdkFontPrivate*) font;
+
+  private->ref_count -= 1;
+  if (private->ref_count == 0)
+    {
+      XFreeFontSet (private->xdisplay, (XFontSet) private->xfont);
+      g_free (font);
+    }
+}
+
+GdkFont*
+gdk_font_ref (GdkFont *font)
+{
+  GdkFontPrivate *private;
+
+  g_return_val_if_fail (font != NULL, NULL);
+
+  private = (GdkFontPrivate*) font;
+  private->ref_count += 1;
+  return font;
+}
+
+gint
+gdk_font_id (GdkFont *font)
+{
+  GdkFontPrivate *font_private;
+
+  g_return_val_if_fail (font != NULL, 0);
+
+  font_private = (GdkFontPrivate*) font;
+
+  if (font->type == GDK_FONT_FONT)
+    {
+      return ((XFontStruct *) font_private->xfont)->fid;
+    }
+  else
+    {
+      return 0;
+    }
+}
+
+gint
+gdk_font_equal (GdkFont *fonta,
+                GdkFont *fontb)
+{
+  GdkFontPrivate *privatea;
+  GdkFontPrivate *privateb;
+
+  g_return_val_if_fail (fonta != NULL, FALSE);
+  g_return_val_if_fail (fontb != NULL, FALSE);
+
+  privatea = (GdkFontPrivate*) fonta;
+  privateb = (GdkFontPrivate*) fontb;
+
+  if (fonta->type == GDK_FONT_FONT && fontb->type == GDK_FONT_FONT)
+    {
+      return (((XFontStruct *) privatea->xfont)->fid ==
+             ((XFontStruct *) privateb->xfont)->fid);
+    }
+  else if (fonta->type == GDK_FONT_FONTSET && fontb->type == GDK_FONT_FONTSET)
+    {
+      /* how to compare two fontsets ?? by basename or XFontSet ?? */
+      return (((XFontSet) privatea->xfont) == ((XFontSet) privateb->xfont));
+    }
+  else
+    /* fontset != font */
+    return 0;
+}
+
+gint
+gdk_string_width (GdkFont     *font,
+                 const gchar *string)
+{
+  GdkFontPrivate *font_private;
+  gint width;
+  XFontStruct *xfont;
+  XFontSet fontset;
+
+  g_return_val_if_fail (font != NULL, -1);
+  g_return_val_if_fail (string != NULL, -1);
+
+  font_private = (GdkFontPrivate*) font;
+
+  switch (font->type)
+    {
+    case GDK_FONT_FONT:
+      xfont = (XFontStruct *) font_private->xfont;
+      if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
+       {
+         width = XTextWidth (xfont, string, strlen (string));
+       }
+      else
+       {
+         width = XTextWidth16 (xfont, (XChar2b *) string, strlen (string) / 2);
+       }
+      break;
+    case GDK_FONT_FONTSET:
+      fontset = (XFontSet) font_private->xfont;
+      width = XmbTextEscapement (fontset, string, strlen(string));
+      break;
+    default:
+      width = 0;
+    }
+
+  return width;
+}
+
+gint
+gdk_text_width (GdkFont      *font,
+               const gchar  *text,
+               gint          text_length)
+{
+  GdkFontPrivate *private;
+  gint width;
+  XFontStruct *xfont;
+  XFontSet fontset;
+
+  g_return_val_if_fail (font != NULL, -1);
+  g_return_val_if_fail (text != NULL, -1);
+
+  private = (GdkFontPrivate*) font;
+
+  switch (font->type)
+    {
+    case GDK_FONT_FONT:
+      xfont = (XFontStruct *) private->xfont;
+      if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
+       {
+         width = XTextWidth (xfont, text, text_length);
+       }
+      else
+       {
+         width = XTextWidth16 (xfont, (XChar2b *) text, text_length / 2);
+       }
+      break;
+    case GDK_FONT_FONTSET:
+      fontset = (XFontSet) private->xfont;
+      width = XmbTextEscapement (fontset, text, text_length);
+      break;
+    default:
+      width = 0;
+    }
+  return width;
+}
+
+/* Problem: What if a character is a 16 bits character ?? */
+gint
+gdk_char_width (GdkFont *font,
+               gchar    character)
+{
+  GdkFontPrivate *private;
+  XCharStruct *chars;
+  gint width;
+  guint ch = character & 0xff;  /* get rid of sign-extension */
+  XFontStruct *xfont;
+  XFontSet fontset;
+
+  g_return_val_if_fail (font != NULL, -1);
+
+  private = (GdkFontPrivate*) font;
+
+  switch (font->type)
+    {
+    case GDK_FONT_FONT:
+      /* only 8 bits characters are considered here */
+      xfont = (XFontStruct *) private->xfont;
+      if ((xfont->min_byte1 == 0) &&
+         (xfont->max_byte1 == 0) &&
+         (ch >= xfont->min_char_or_byte2) &&
+         (ch <= xfont->max_char_or_byte2))
+       {
+         chars = xfont->per_char;
+         if (chars)
+           width = chars[ch - xfont->min_char_or_byte2].width;
+         else
+           width = xfont->min_bounds.width;
+       }
+      else
+       {
+         width = XTextWidth (xfont, &character, 1);
+       }
+      break;
+    case GDK_FONT_FONTSET:
+      fontset = (XFontSet) private->xfont;
+      width = XmbTextEscapement (fontset, &character, 1) ;
+      break;
+    default:
+      width = 0;
+    }
+  return width;
+}
+
+gint
+gdk_string_measure (GdkFont     *font,
+                    const gchar *string)
+{
+  g_return_val_if_fail (font != NULL, -1);
+  g_return_val_if_fail (string != NULL, -1);
+
+  return gdk_text_measure (font, string, strlen (string));
+}
+
+gint
+gdk_text_measure (GdkFont     *font,
+                  const gchar *text,
+                  gint         text_length)
+{
+  GdkFontPrivate *private;
+  XCharStruct overall;
+  XFontStruct *xfont;
+  XFontSet    fontset;
+  XRectangle  ink, log;
+  int direction;
+  int font_ascent;
+  int font_descent;
+  gint width;
+
+  g_return_val_if_fail (font != NULL, -1);
+  g_return_val_if_fail (text != NULL, -1);
+
+  private = (GdkFontPrivate*) font;
+
+  switch (font->type)
+    {
+    case GDK_FONT_FONT:
+      xfont = (XFontStruct *) private->xfont;
+      if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
+       {
+         XTextExtents (xfont, text, text_length,
+                       &direction, &font_ascent, &font_descent,
+                       &overall);
+       }
+      else
+       {
+         XTextExtents16 (xfont, (XChar2b *) text, text_length / 2,
+                         &direction, &font_ascent, &font_descent,
+                         &overall);
+       }
+      width = overall.rbearing;
+      break;
+    case GDK_FONT_FONTSET:
+      fontset = (XFontSet) private->xfont;
+      XmbTextExtents (fontset, text, text_length, &ink, &log);
+      width = log.width;
+      break;
+    default:
+      width = 0;
+    }
+  return width;
+}
+
+gint
+gdk_char_measure (GdkFont *font,
+                  gchar    character)
+{
+  g_return_val_if_fail (font != NULL, -1);
+
+  return gdk_text_measure (font, &character, 1);
+}
diff --git a/gdk/gdkgc.c b/gdk/gdkgc.c
new file mode 100644 (file)
index 0000000..3dc11ce
--- /dev/null
@@ -0,0 +1,636 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <string.h>
+#include <X11/Xlib.h>
+#include "gdk.h"
+#include "gdkprivate.h"
+
+
+GdkGC*
+gdk_gc_new (GdkWindow *window)
+{
+  return gdk_gc_new_with_values (window, NULL, 0);
+}
+
+GdkGC*
+gdk_gc_new_with_values (GdkWindow       *window,
+                       GdkGCValues     *values,
+                       GdkGCValuesMask  values_mask)
+{
+  GdkGC *gc;
+  GdkGCPrivate *private;
+  Window xwindow;
+  XGCValues xvalues;
+  unsigned long xvalues_mask;
+
+  private = g_new (GdkGCPrivate, 1);
+  gc = (GdkGC*) private;
+
+  xwindow = ((GdkWindowPrivate*) window)->xwindow;
+  private->xdisplay = ((GdkWindowPrivate*) window)->xdisplay;
+
+  xvalues.function = GXcopy;
+  xvalues.fill_style = FillSolid;
+  xvalues.arc_mode = ArcPieSlice;
+  xvalues.subwindow_mode = ClipByChildren;
+  xvalues.graphics_exposures = True;
+  xvalues_mask = GCFunction | GCFillStyle | GCArcMode | GCSubwindowMode | GCGraphicsExposures;
+
+  if (values_mask & GDK_GC_FOREGROUND)
+    {
+      xvalues.foreground = values->foreground.pixel;
+      xvalues_mask |= GCForeground;
+    }
+  if (values_mask & GDK_GC_BACKGROUND)
+    {
+      xvalues.background = values->background.pixel;
+      xvalues_mask |= GCBackground;
+    }
+  if ((values_mask & GDK_GC_FONT) && (values->font->type == GDK_FONT_FONT))
+    {
+      xvalues.font = ((XFontStruct *) ((GdkFontPrivate*) values->font)->xfont)->fid;
+      xvalues_mask |= GCFont;
+    }
+  if (values_mask & GDK_GC_FUNCTION)
+    {
+      switch (values->function)
+       {
+       case GDK_COPY:
+         xvalues.function = GXcopy;
+         break;
+       case GDK_INVERT:
+         xvalues.function = GXinvert;
+         break;
+       case GDK_XOR:
+         xvalues.function = GXxor;
+         break;
+       }
+      xvalues_mask |= GCFunction;
+    }
+  if (values_mask & GDK_GC_FILL)
+    {
+      switch (values->fill)
+       {
+       case GDK_SOLID:
+         xvalues.fill_style = FillSolid;
+         break;
+       case GDK_TILED:
+         xvalues.fill_style = FillTiled;
+         break;
+       case GDK_STIPPLED:
+         xvalues.fill_style = FillStippled;
+         break;
+       case GDK_OPAQUE_STIPPLED:
+         xvalues.fill_style = FillOpaqueStippled;
+         break;
+       }
+      xvalues_mask |= GCFillStyle;
+    }
+  if (values_mask & GDK_GC_TILE)
+    {
+      xvalues.tile = ((GdkPixmapPrivate*) values->tile)->xwindow;
+      xvalues_mask |= GCTile;
+    }
+  if (values_mask & GDK_GC_STIPPLE)
+    {
+      xvalues.stipple = ((GdkPixmapPrivate*) values->stipple)->xwindow;
+      xvalues_mask |= GCStipple;
+    }
+  if (values_mask & GDK_GC_CLIP_MASK)
+    {
+      xvalues.clip_mask = ((GdkPixmapPrivate*) values->clip_mask)->xwindow;
+      xvalues_mask |= GCClipMask;
+    }
+  if (values_mask & GDK_GC_SUBWINDOW)
+    {
+      xvalues.subwindow_mode = values->subwindow_mode;
+      xvalues_mask |= GCSubwindowMode;
+    }
+  if (values_mask & GDK_GC_TS_X_ORIGIN)
+    {
+      xvalues.ts_x_origin = values->ts_x_origin;
+      xvalues_mask |= GCTileStipXOrigin;
+    }
+  if (values_mask & GDK_GC_TS_Y_ORIGIN)
+    {
+      xvalues.ts_y_origin = values->ts_y_origin;
+      xvalues_mask |= GCTileStipYOrigin;
+    }
+  if (values_mask & GDK_GC_CLIP_X_ORIGIN)
+    {
+      xvalues.clip_x_origin = values->clip_x_origin;
+      xvalues_mask |= GCClipXOrigin;
+    }
+  if (values_mask & GDK_GC_CLIP_Y_ORIGIN)
+    {
+      xvalues.clip_y_origin = values->clip_y_origin;
+      xvalues_mask |= GCClipYOrigin;
+    }
+  if (values_mask & GDK_GC_EXPOSURES)
+    {
+      xvalues.graphics_exposures = values->graphics_exposures;
+      xvalues_mask |= GCGraphicsExposures;
+    }
+  if (values_mask & GDK_GC_LINE_WIDTH)
+    {
+      xvalues.line_width = values->line_width;
+      xvalues_mask |= GCLineWidth;
+    }
+  if (values_mask & GDK_GC_LINE_STYLE)
+    {
+      switch (values->line_style)
+       {
+       case GDK_LINE_SOLID:
+         xvalues.line_style = LineSolid;
+         break;
+       case GDK_LINE_ON_OFF_DASH:
+         xvalues.line_style = LineOnOffDash;
+         break;
+       case GDK_LINE_DOUBLE_DASH:
+         xvalues.line_style = LineDoubleDash;
+         break;
+       }
+      xvalues_mask |= GCLineStyle;
+    }
+  if (values_mask & GDK_GC_CAP_STYLE)
+    {
+      switch (values->cap_style)
+       {
+       case GDK_CAP_NOT_LAST:
+         xvalues.cap_style = CapNotLast;
+         break;
+       case GDK_CAP_BUTT:
+         xvalues.cap_style = CapButt;
+         break;
+       case GDK_CAP_ROUND:
+         xvalues.cap_style = CapRound;
+         break;
+       case GDK_CAP_PROJECTING:
+         xvalues.cap_style = CapProjecting;
+         break;
+       }
+      xvalues_mask |= GCCapStyle;
+    }
+  if (values_mask & GDK_GC_JOIN_STYLE)
+    {
+      switch (values->join_style)
+       {
+       case GDK_JOIN_MITER:
+         xvalues.join_style = JoinMiter;
+         break;
+       case GDK_JOIN_ROUND:
+         xvalues.join_style = JoinRound;
+         break;
+       case GDK_JOIN_BEVEL:
+         xvalues.join_style = JoinBevel;
+         break;
+       }
+      xvalues_mask |= GCJoinStyle;
+    }
+
+  private->xgc = XCreateGC (private->xdisplay, xwindow, xvalues_mask, &xvalues);
+
+  return gc;
+}
+
+void
+gdk_gc_destroy (GdkGC *gc)
+{
+  GdkGCPrivate *private;
+
+  g_return_if_fail (gc != NULL);
+
+  private = (GdkGCPrivate*) gc;
+  XFreeGC (private->xdisplay, private->xgc);
+
+  memset (gc, 0, sizeof (GdkGCPrivate));
+  g_free (gc);
+}
+
+void
+gdk_gc_get_values (GdkGC       *gc,
+                  GdkGCValues *values)
+{
+  GdkGCPrivate *private;
+  XGCValues xvalues;
+
+  g_return_if_fail (gc != NULL);
+  g_return_if_fail (values != NULL);
+
+  private = (GdkGCPrivate*) gc;
+
+  if (XGetGCValues (private->xdisplay, private->xgc,
+                   GCForeground | GCBackground | GCFont |
+                   GCFunction | GCTile | GCStipple | /* GCClipMask | */
+                   GCSubwindowMode | GCGraphicsExposures |
+                   GCTileStipXOrigin | GCTileStipYOrigin |
+                   GCClipXOrigin | GCClipYOrigin |
+                   GCLineWidth | GCLineStyle | GCCapStyle |
+                   GCFillStyle | GCJoinStyle, &xvalues))
+    {
+      values->foreground.pixel = xvalues.foreground;
+      values->background.pixel = xvalues.background;
+      values->font = gdk_font_lookup (xvalues.font);
+
+      switch (xvalues.function)
+       {
+       case GXcopy:
+         values->function = GDK_COPY;
+         break;
+       case GXinvert:
+         values->function = GDK_INVERT;
+         break;
+       case GXxor:
+         values->function = GDK_XOR;
+         break;
+       }
+
+      switch (xvalues.fill_style)
+       {
+       case FillSolid:
+         values->fill = GDK_SOLID;
+         break;
+       case FillTiled:
+         values->fill = GDK_TILED;
+         break;
+       case FillStippled:
+         values->fill = GDK_STIPPLED;
+         break;
+       case FillOpaqueStippled:
+         values->fill = GDK_OPAQUE_STIPPLED;
+         break;
+       }
+
+      values->tile = gdk_pixmap_lookup (xvalues.tile);
+      values->stipple = gdk_pixmap_lookup (xvalues.stipple);
+      values->clip_mask = NULL;
+      values->subwindow_mode = xvalues.subwindow_mode;
+      values->ts_x_origin = xvalues.ts_x_origin;
+      values->ts_y_origin = xvalues.ts_y_origin;
+      values->clip_x_origin = xvalues.clip_x_origin;
+      values->clip_y_origin = xvalues.clip_y_origin;
+      values->graphics_exposures = xvalues.graphics_exposures;
+      values->line_width = xvalues.line_width;
+
+      switch (xvalues.line_style)
+       {
+       case LineSolid:
+         values->line_style = GDK_LINE_SOLID;
+         break;
+       case LineOnOffDash:
+         values->line_style = GDK_LINE_ON_OFF_DASH;
+         break;
+       case LineDoubleDash:
+         values->line_style = GDK_LINE_DOUBLE_DASH;
+         break;
+       }
+
+      switch (xvalues.cap_style)
+       {
+       case CapNotLast:
+         values->cap_style = GDK_CAP_NOT_LAST;
+         break;
+       case CapButt:
+         values->cap_style = GDK_CAP_BUTT;
+         break;
+       case CapRound:
+         values->cap_style = GDK_CAP_ROUND;
+         break;
+       case CapProjecting:
+         values->cap_style = GDK_CAP_PROJECTING;
+         break;
+       }
+
+      switch (xvalues.join_style)
+       {
+       case JoinMiter:
+         values->join_style = GDK_JOIN_MITER;
+         break;
+       case JoinRound:
+         values->join_style = GDK_JOIN_ROUND;
+         break;
+       case JoinBevel:
+         values->join_style = GDK_JOIN_BEVEL;
+         break;
+       }
+    }
+  else
+    {
+      memset (values, 0, sizeof (GdkGCValues));
+    }
+}
+
+void
+gdk_gc_set_foreground (GdkGC    *gc,
+                      GdkColor *color)
+{
+  GdkGCPrivate *private;
+
+  g_return_if_fail (gc != NULL);
+  g_return_if_fail (color != NULL);
+
+  private = (GdkGCPrivate*) gc;
+  XSetForeground (private->xdisplay, private->xgc, color->pixel);
+}
+
+void
+gdk_gc_set_background (GdkGC    *gc,
+                      GdkColor *color)
+{
+  GdkGCPrivate *private;
+
+  g_return_if_fail (gc != NULL);
+  g_return_if_fail (color != NULL);
+
+  private = (GdkGCPrivate*) gc;
+  XSetBackground (private->xdisplay, private->xgc, color->pixel);
+}
+
+void
+gdk_gc_set_font (GdkGC   *gc,
+                GdkFont *font)
+{
+  GdkGCPrivate *gc_private;
+  GdkFontPrivate *font_private;
+
+  g_return_if_fail (gc != NULL);
+  g_return_if_fail (font != NULL);
+
+  gc_private = (GdkGCPrivate*) gc;
+  font_private = (GdkFontPrivate*) font;
+
+  XSetFont (gc_private->xdisplay, gc_private->xgc,
+           ((XFontStruct *) font_private->xfont)->fid);
+}
+
+void
+gdk_gc_set_function (GdkGC       *gc,
+                    GdkFunction  function)
+{
+  GdkGCPrivate *private;
+
+  g_return_if_fail (gc != NULL);
+
+  private = (GdkGCPrivate*) gc;
+
+  switch (function)
+    {
+    case GDK_COPY:
+      XSetFunction (private->xdisplay, private->xgc, GXcopy);
+      break;
+    case GDK_INVERT:
+      XSetFunction (private->xdisplay, private->xgc, GXinvert);
+      break;
+    case GDK_XOR:
+      XSetFunction (private->xdisplay, private->xgc, GXor);
+      break;
+    }
+}
+
+void
+gdk_gc_set_fill (GdkGC   *gc,
+                GdkFill  fill)
+{
+  GdkGCPrivate *private;
+
+  g_return_if_fail (gc != NULL);
+
+  private = (GdkGCPrivate*) gc;
+
+  switch (fill)
+    {
+    case GDK_SOLID:
+      XSetFillStyle (private->xdisplay, private->xgc, FillSolid);
+      break;
+    case GDK_TILED:
+      XSetFillStyle (private->xdisplay, private->xgc, FillTiled);
+      break;
+    case GDK_STIPPLED:
+      XSetFillStyle (private->xdisplay, private->xgc, FillStippled);
+      break;
+    case GDK_OPAQUE_STIPPLED:
+      XSetFillStyle (private->xdisplay, private->xgc, FillOpaqueStippled);
+      break;
+    }
+}
+
+void
+gdk_gc_set_tile (GdkGC     *gc,
+                GdkPixmap *tile)
+{
+  GdkGCPrivate *private;
+  GdkPixmapPrivate *pixmap_private;
+  Pixmap pixmap;
+
+  g_return_if_fail (gc != NULL);
+
+  private = (GdkGCPrivate*) gc;
+
+  pixmap = None;
+  if (tile)
+    {
+      pixmap_private = (GdkPixmapPrivate*) tile;
+      pixmap = pixmap_private->xwindow;
+    }
+
+  XSetTile (private->xdisplay, private->xgc, pixmap);
+}
+
+void
+gdk_gc_set_stipple (GdkGC     *gc,
+                   GdkPixmap *stipple)
+{
+  GdkGCPrivate *private;
+  GdkPixmapPrivate *pixmap_private;
+  Pixmap pixmap;
+
+  g_return_if_fail (gc != NULL);
+
+  private = (GdkGCPrivate*) gc;
+
+  pixmap = None;
+  if (stipple)
+    {
+      pixmap_private = (GdkPixmapPrivate*) stipple;
+      pixmap = pixmap_private->xwindow;
+    }
+
+  XSetStipple (private->xdisplay, private->xgc, pixmap);
+}
+
+void
+gdk_gc_set_ts_origin (GdkGC *gc,
+                     gint   x,
+                     gint   y)
+{
+  GdkGCPrivate *private;
+
+  g_return_if_fail (gc != NULL);
+
+  private = (GdkGCPrivate*) gc;
+
+  XSetTSOrigin (private->xdisplay, private->xgc, x, y);
+}
+
+void
+gdk_gc_set_clip_origin (GdkGC *gc,
+                       gint   x,
+                       gint   y)
+{
+  GdkGCPrivate *private;
+
+  g_return_if_fail (gc != NULL);
+
+  private = (GdkGCPrivate*) gc;
+
+  XSetClipOrigin (private->xdisplay, private->xgc, x, y);
+}
+
+void
+gdk_gc_set_clip_mask (GdkGC     *gc,
+                     GdkBitmap *mask)
+{
+  GdkGCPrivate *private;
+  Pixmap xmask;
+
+  g_return_if_fail (gc != NULL);
+
+  private = (GdkGCPrivate*) gc;
+
+  if (mask)
+    xmask = ((GdkWindowPrivate*) mask)->xwindow;
+  else
+    xmask = None;
+
+  XSetClipMask (private->xdisplay, private->xgc, xmask);
+}
+
+
+void
+gdk_gc_set_clip_rectangle (GdkGC        *gc,
+                           GdkRectangle *rectangle)
+{
+  GdkGCPrivate *private;
+  XRectangle xrectangle;
+
+  g_return_if_fail (gc != NULL);
+
+  private = (GdkGCPrivate*) gc;
+
+  xrectangle.x = rectangle->x; 
+  xrectangle.y = rectangle->y;
+  xrectangle.width = rectangle->width;
+  xrectangle.height = rectangle->height;
+
+  XSetClipRectangles (private->xdisplay, private->xgc, 0, 0,
+                      &xrectangle, 1, Unsorted);
+} 
+
+void
+gdk_gc_set_subwindow (GdkGC            *gc,
+                     GdkSubwindowMode  mode)
+{
+  GdkGCPrivate *private;
+
+  g_return_if_fail (gc != NULL);
+
+  private = (GdkGCPrivate*) gc;
+
+  XSetSubwindowMode (private->xdisplay, private->xgc, mode);
+}
+
+void
+gdk_gc_set_exposures (GdkGC *gc,
+                     gint   exposures)
+{
+  GdkGCPrivate *private;
+
+  g_return_if_fail (gc != NULL);
+
+  private = (GdkGCPrivate*) gc;
+
+  XSetGraphicsExposures (private->xdisplay, private->xgc, exposures);
+}
+
+void
+gdk_gc_set_line_attributes (GdkGC       *gc,
+                           gint         line_width,
+                           GdkLineStyle line_style,
+                           GdkCapStyle  cap_style,
+                           GdkJoinStyle join_style)
+{
+  GdkGCPrivate *private;
+  int xline_style;
+  int xcap_style;
+  int xjoin_style;
+
+  g_return_if_fail (gc != NULL);
+
+  private = (GdkGCPrivate*) gc;
+
+  switch (line_style)
+    {
+    case GDK_LINE_SOLID:
+      xline_style = LineSolid;
+      break;
+    case GDK_LINE_ON_OFF_DASH:
+      xline_style = LineOnOffDash;
+      break;
+    case GDK_LINE_DOUBLE_DASH:
+      xline_style = LineDoubleDash;
+      break;
+    default:
+      xline_style = None;
+    }
+
+  switch (cap_style)
+    {
+    case GDK_CAP_NOT_LAST:
+      xcap_style = CapNotLast;
+      break;
+    case GDK_CAP_BUTT:
+      xcap_style = CapButt;
+      break;
+    case GDK_CAP_ROUND:
+      xcap_style = CapRound;
+      break;
+    case GDK_CAP_PROJECTING:
+      xcap_style = CapProjecting;
+      break;
+    default:
+      xcap_style = None;
+    }
+
+  switch (join_style)
+    {
+    case GDK_JOIN_MITER:
+      xjoin_style = JoinMiter;
+      break;
+    case GDK_JOIN_ROUND:
+      xjoin_style = JoinRound;
+      break;
+    case GDK_JOIN_BEVEL:
+      xjoin_style = JoinBevel;
+      break;
+    default:
+      xjoin_style = None;
+    }
+
+  XSetLineAttributes (private->xdisplay, private->xgc, line_width,
+                     xline_style, xcap_style, xjoin_style);
+}
diff --git a/gdk/gdkglobals.c b/gdk/gdkglobals.c
new file mode 100644 (file)
index 0000000..58f7bf8
--- /dev/null
@@ -0,0 +1,47 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdio.h>
+#include <X11/Xlib.h>
+#include "gdktypes.h"
+#include "gdkprivate.h"
+
+gint              gdk_debug_level = 0;
+gint              gdk_show_events = FALSE;
+gint              gdk_use_xshm = TRUE;
+gchar            *gdk_display_name = NULL;
+Display          *gdk_display = NULL;
+gint              gdk_screen;
+Window            gdk_root_window;
+Window            gdk_leader_window;
+GdkWindowPrivate  gdk_root_parent;
+Atom              gdk_wm_delete_window;
+Atom              gdk_wm_take_focus;
+Atom              gdk_wm_protocols;
+Atom              gdk_wm_window_protocols[2];
+Atom              gdk_selection_property;
+GdkDndGlobals     gdk_dnd = {None,None,None,
+                            None,None,None,
+                            None,
+                            None,None,
+                            NULL,
+                            0, 0,
+                            {0,0}};
+gchar            *gdk_progname = NULL;
+gchar            *gdk_progclass = NULL;
+gint              gdk_error_code;
+gint              gdk_error_warnings = TRUE;
diff --git a/gdk/gdkimage.c b/gdk/gdkimage.c
new file mode 100644 (file)
index 0000000..bcda311
--- /dev/null
@@ -0,0 +1,492 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "../config.h"
+
+#include <sys/types.h>
+
+#if defined (HAVE_IPC_H) && defined (HAVE_SHM_H) && defined (HAVE_XSHM_H)
+#define USE_SHM
+#endif
+
+#ifdef USE_SHM
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#endif /* USE_SHM */
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#ifdef USE_SHM
+#include <X11/extensions/XShm.h>
+#endif /* USE_SHM */
+
+#include "gdk.h"
+#include "gdkprivate.h"
+
+
+static void gdk_image_put_normal (GdkDrawable *drawable,
+                                 GdkGC       *gc,
+                                 GdkImage    *image,
+                                 gint         xsrc,
+                                 gint         ysrc,
+                                 gint         xdest,
+                                 gint         ydest,
+                                 gint         width,
+                                 gint         height);
+static void gdk_image_put_shared (GdkDrawable *drawable,
+                                 GdkGC       *gc,
+                                 GdkImage    *image,
+                                 gint         xsrc,
+                                 gint         ysrc,
+                                 gint         xdest,
+                                 gint         ydest,
+                                 gint         width,
+                                 gint         height);
+
+
+static GList *image_list = NULL;
+
+
+void
+gdk_image_exit ()
+{
+  GdkImage *image;
+
+  while (image_list)
+    {
+      image = image_list->data;
+      gdk_image_destroy (image);
+    }
+}
+
+GdkImage *
+gdk_image_new_bitmap(GdkVisual *visual, gpointer data, gint w, gint h)
+/*
+ * Desc: create a new bitmap image
+ */
+{
+        Visual *xvisual;
+        GdkImage *image;
+        GdkImagePrivate *private;
+        private = g_new(GdkImagePrivate, 1);
+        image = (GdkImage *) private;
+        private->xdisplay = gdk_display;
+        private->image_put = gdk_image_put_normal;
+        image->type = GDK_IMAGE_NORMAL;
+        image->visual = visual;
+        image->width = w;
+        image->height = h;
+        image->depth = 1;
+        xvisual = ((GdkVisualPrivate*) visual)->xvisual;
+        private->ximage = XCreateImage(private->xdisplay, xvisual, 1, XYBitmap,
+                                      0, 0, w ,h, 8, 0);
+        private->ximage->data = data;
+        private->ximage->bitmap_bit_order = MSBFirst;
+        private->ximage->byte_order = MSBFirst;
+        image->byte_order = MSBFirst;
+        image->mem =  private->ximage->data;
+        image->bpl = private->ximage->bytes_per_line;
+        image->bpp = 1;
+       return(image);
+} /* gdk_image_new_bitmap() */
+
+static int
+gdk_image_check_xshm(Display *display)
+/* 
+ * Desc: query the server for support for the MIT_SHM extension
+ * Return:  0 = not available
+ *          1 = shared XImage support available
+ *          2 = shared Pixmap support available also
+ */
+{
+#ifdef USE_SHM
+  int major, minor, ignore;
+  Bool pixmaps;
+  
+  if (XQueryExtension(display, "MIT-SHM", &ignore, &ignore, &ignore)) 
+    {
+      if (XShmQueryVersion(display, &major, &minor, &pixmaps )==True) 
+       {
+         return (pixmaps==True) ? 2 : 1;
+       }
+    }
+#endif /* USE_SHM */
+  return 0;
+}
+
+void
+gdk_image_init ()
+{
+  if (gdk_use_xshm)
+    {
+      if (!gdk_image_check_xshm (gdk_display))
+       {
+         g_warning ("MIT-SHM Extension not availible on server");
+         gdk_use_xshm = False;
+       }
+    }
+}
+
+GdkImage*
+gdk_image_new (GdkImageType  type,
+              GdkVisual    *visual,
+              gint          width,
+              gint          height)
+{
+  GdkImage *image;
+  GdkImagePrivate *private;
+#ifdef USE_SHM
+  XShmSegmentInfo *x_shm_info;
+#endif /* USE_SHM */
+  Visual *xvisual;
+
+  switch (type)
+    {
+    case GDK_IMAGE_FASTEST:
+      image = gdk_image_new (GDK_IMAGE_SHARED, visual, width, height);
+
+      if (!image)
+       image = gdk_image_new (GDK_IMAGE_NORMAL, visual, width, height);
+      break;
+
+    default:
+      private = g_new (GdkImagePrivate, 1);
+      image = (GdkImage*) private;
+
+      private->xdisplay = gdk_display;
+      private->image_put = NULL;
+
+      image->type = type;
+      image->visual = visual;
+      image->width = width;
+      image->height = height;
+      image->depth = visual->depth;
+
+      xvisual = ((GdkVisualPrivate*) visual)->xvisual;
+
+      switch (type)
+       {
+       case GDK_IMAGE_SHARED:
+#ifdef USE_SHM
+         if (gdk_use_xshm)
+           {
+             private->image_put = gdk_image_put_shared;
+
+             private->x_shm_info = g_new (XShmSegmentInfo, 1);
+             x_shm_info = private->x_shm_info;
+
+             private->ximage = XShmCreateImage (private->xdisplay, xvisual, visual->depth,
+                                                ZPixmap, NULL, x_shm_info, width, height);
+             if (private->ximage == NULL)
+               {
+                 g_warning ("XShmCreateImage failed");
+                 
+                 g_free (image);
+                 gdk_use_xshm = False;
+                 return NULL;
+               }
+
+             x_shm_info->shmid = shmget (IPC_PRIVATE,
+                                         private->ximage->bytes_per_line * private->ximage->height,
+                                         IPC_CREAT | 0777);
+
+             if (x_shm_info->shmid == -1)
+               {
+                 g_warning ("shmget failed!");
+
+                 XDestroyImage (private->ximage);
+                 g_free (private->x_shm_info);
+                 g_free (image);
+
+                 gdk_use_xshm = False;
+                 gdk_use_xshm = False;
+                 return NULL;
+               }
+
+             x_shm_info->readOnly = False;
+             x_shm_info->shmaddr = shmat (x_shm_info->shmid, 0, 0);
+             private->ximage->data = x_shm_info->shmaddr;
+
+             if (x_shm_info->shmaddr == (char*) -1)
+               {
+                 g_warning ("shmat failed!");
+
+                 XDestroyImage (private->ximage);
+                 shmctl (x_shm_info->shmid, IPC_RMID, 0);
+                 
+                 g_free (private->x_shm_info);
+                 g_free (image);
+
+                 return NULL;
+               }
+
+#ifdef IPC_RMID_DEFERRED_RELEASE
+             if (x_shm_info->shmaddr != (char*) -1)
+               shmctl (x_shm_info->shmid, IPC_RMID, 0);                      
+#endif
+
+             gdk_error_code = 0;
+             gdk_error_warnings = 0;
+
+             XShmAttach (private->xdisplay, x_shm_info);
+             XSync (private->xdisplay, False);
+
+             gdk_error_warnings = 1;
+             if (gdk_error_code == -1)
+               {
+                 g_warning ("XShmAttach failed!");
+
+                 XDestroyImage (private->ximage);
+                 shmdt (x_shm_info->shmaddr);
+                 shmctl (x_shm_info->shmid, IPC_RMID, 0);
+                  
+                 g_free (private->x_shm_info);
+                 g_free (image);
+
+                 gdk_use_xshm = False;
+                 return NULL;
+               }
+
+             if (image)
+               image_list = g_list_prepend (image_list, image);
+           }
+         else
+           {
+             g_free (image);
+             return NULL;
+           }
+         break;
+#else /* USE_SHM */
+         g_free (image);
+         return NULL;
+#endif /* USE_SHM */
+       case GDK_IMAGE_NORMAL:
+         private->image_put = gdk_image_put_normal;
+
+         private->ximage = XCreateImage (private->xdisplay, xvisual, visual->depth,
+                                         ZPixmap, 0, 0, width, height, 32, 0);
+
+         private->ximage->data = g_new (char, private->ximage->bytes_per_line *
+                                         private->ximage->height);
+         break;
+
+       case GDK_IMAGE_FASTEST:
+         g_assert_not_reached ();
+       }
+
+      if (image)
+       {
+         image->byte_order = private->ximage->byte_order;
+         image->mem = private->ximage->data;
+         image->bpl = private->ximage->bytes_per_line;
+
+         switch (private->ximage->bits_per_pixel)
+           {
+           case 8:
+             image->bpp = 1;
+             break;
+           case 16:
+             image->bpp = 2;
+             break;
+           case 24:
+             image->bpp = 3;
+             break;
+           case 32:
+             image->bpp = 4;
+             break;
+           }
+       }
+    }
+
+  return image;
+}
+
+GdkImage*
+gdk_image_get (GdkWindow *window,
+              gint       x,
+              gint       y,
+              gint       width,
+              gint       height)
+{
+  GdkImage *image;
+  GdkImagePrivate *private;
+  GdkWindowPrivate *win_private;
+
+  g_return_val_if_fail (window != NULL, NULL);
+
+  win_private = (GdkWindowPrivate *) window;
+
+  private = g_new (GdkImagePrivate, 1);
+  image = (GdkImage*) private;
+
+  private->xdisplay = gdk_display;
+  private->image_put = gdk_image_put_normal;
+  private->ximage = XGetImage (private->xdisplay,
+                              win_private->xwindow,
+                              x, y, width, height,
+                              AllPlanes, ZPixmap);
+
+  image->type = GDK_IMAGE_NORMAL;
+  image->visual = gdk_window_get_visual (window);
+  image->width = width;
+  image->height = height;
+  image->depth = private->ximage->depth;
+
+  image->mem = private->ximage->data;
+  image->bpl = private->ximage->bytes_per_line;
+  image->bpp = 1;
+
+  return image;
+}
+
+guint32
+gdk_image_get_pixel (GdkImage *image,
+                    gint x,
+                    gint y)
+{
+  guint32 pixel;
+  GdkImagePrivate *private;
+
+  g_return_val_if_fail (image != NULL, 0);
+
+  private = (GdkImagePrivate *) image;
+
+  pixel = XGetPixel (private->ximage, x, y);
+
+  return pixel;
+}
+
+void
+gdk_image_put_pixel (GdkImage *image,
+                    gint x,
+                    gint y,
+                    guint32 pixel)
+{
+  GdkImagePrivate *private;
+
+  g_return_if_fail (image != NULL);
+
+  private = (GdkImagePrivate *) image;
+
+  pixel = XPutPixel (private->ximage, x, y, pixel);
+}
+
+void
+gdk_image_destroy (GdkImage *image)
+{
+  GdkImagePrivate *private;
+#ifdef USE_SHM
+  XShmSegmentInfo *x_shm_info;
+#endif /* USE_SHM */
+
+  g_return_if_fail (image != NULL);
+
+  private = (GdkImagePrivate*) image;
+  switch (image->type)
+    {
+    case GDK_IMAGE_NORMAL:
+      XDestroyImage (private->ximage);
+      break;
+
+    case GDK_IMAGE_SHARED:
+#ifdef USE_SHM
+      XShmDetach (private->xdisplay, private->x_shm_info);
+      XDestroyImage (private->ximage);
+
+      x_shm_info = private->x_shm_info;
+      shmdt (x_shm_info->shmaddr);
+      shmctl (x_shm_info->shmid, IPC_RMID, 0);
+      
+      g_free (private->x_shm_info);
+
+      image_list = g_list_remove (image_list, image);
+#else /* USE_SHM */
+      g_error ("trying to destroy shared memory image when gdk was compiled without shared memory support");
+#endif /* USE_SHM */
+      break;
+
+    case GDK_IMAGE_FASTEST:
+      g_assert_not_reached ();
+    }
+
+  g_free (image);
+}
+
+static void
+gdk_image_put_normal (GdkDrawable *drawable,
+                     GdkGC       *gc,
+                     GdkImage    *image,
+                     gint         xsrc,
+                     gint         ysrc,
+                     gint         xdest,
+                     gint         ydest,
+                     gint         width,
+                     gint         height)
+{
+  GdkWindowPrivate *drawable_private;
+  GdkImagePrivate *image_private;
+  GdkGCPrivate *gc_private;
+
+  g_return_if_fail (drawable != NULL);
+  g_return_if_fail (image != NULL);
+  g_return_if_fail (gc != NULL);
+
+  drawable_private = (GdkWindowPrivate*) drawable;
+  image_private = (GdkImagePrivate*) image;
+  gc_private = (GdkGCPrivate*) gc;
+
+  g_return_if_fail (image->type == GDK_IMAGE_NORMAL);
+
+  XPutImage (drawable_private->xdisplay, drawable_private->xwindow,
+            gc_private->xgc, image_private->ximage,
+            xsrc, ysrc, xdest, ydest, width, height);
+}
+
+static void
+gdk_image_put_shared (GdkDrawable *drawable,
+                     GdkGC       *gc,
+                     GdkImage    *image,
+                     gint         xsrc,
+                     gint         ysrc,
+                     gint         xdest,
+                     gint         ydest,
+                     gint         width,
+                     gint         height)
+{
+#ifdef USE_SHM
+  GdkWindowPrivate *drawable_private;
+  GdkImagePrivate *image_private;
+  GdkGCPrivate *gc_private;
+
+  g_return_if_fail (drawable != NULL);
+  g_return_if_fail (image != NULL);
+  g_return_if_fail (gc != NULL);
+
+  drawable_private = (GdkWindowPrivate*) drawable;
+  image_private = (GdkImagePrivate*) image;
+  gc_private = (GdkGCPrivate*) gc;
+
+  g_return_if_fail (image->type == GDK_IMAGE_SHARED);
+
+  XShmPutImage (drawable_private->xdisplay, drawable_private->xwindow,
+               gc_private->xgc, image_private->ximage,
+               xsrc, ysrc, xdest, ydest, width, height, False);
+#else /* USE_SHM */
+  g_error ("trying to draw shared memory image when gdk was compiled without shared memory support");
+#endif /* USE_SHM */
+}
diff --git a/gdk/gdkinput.c b/gdk/gdkinput.c
new file mode 100644 (file)
index 0000000..ad4b1fc
--- /dev/null
@@ -0,0 +1,324 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdlib.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include "../config.h"
+#include "gdk.h"
+#include "gdkx.h"
+#include "gdkprivate.h"
+#include "gdkinput.h"
+
+
+/* Forward declarations */
+
+static gint gdk_input_enable_window (GdkWindow *window,
+                                    GdkDevicePrivate *gdkdev);
+static gint gdk_input_disable_window (GdkWindow *window,
+                                     GdkDevicePrivate *gdkdev);
+static GdkInputWindow *gdk_input_window_find (GdkWindow *window);
+static GdkDevicePrivate *gdk_input_find_device (guint32 id);
+
+
+/* Incorporate the specific routines depending on compilation options */
+
+static GdkAxisUse gdk_input_core_axes[] = { GDK_AXIS_X, GDK_AXIS_Y };
+
+static GdkDeviceInfo gdk_input_core_info =
+{
+  GDK_CORE_POINTER,
+  "Core Pointer",
+  GDK_SOURCE_MOUSE,
+  GDK_MODE_SCREEN,
+  TRUE,
+  2,
+  gdk_input_core_axes
+};
+
+/* Global variables  */
+
+GdkInputVTable    gdk_input_vtable;
+/* information about network port and host for gxid daemon */
+gchar            *gdk_input_gxid_host;
+gint              gdk_input_gxid_port;
+gint              gdk_input_ignore_core;
+
+/* Local variables */
+
+static GList            *gdk_input_devices;
+static GList            *gdk_input_windows;
+
+#include "gdkinputnone.h"
+#include "gdkinputcommon.h"
+#include "gdkinputxfree.h"
+#include "gdkinputgxi.h"
+
+GList *
+gdk_input_list_devices ()
+{
+  return gdk_input_devices;
+}
+
+void
+gdk_input_set_source (guint32 deviceid, GdkInputSource source)
+{
+  GdkDevicePrivate *gdkdev = gdk_input_find_device(deviceid);
+  g_return_if_fail (gdkdev != NULL);
+
+  gdkdev->info.source = source;
+}
+
+gint
+gdk_input_set_mode (guint32 deviceid, GdkInputMode mode)
+{
+  if (deviceid == GDK_CORE_POINTER)
+    return FALSE;
+
+  if (gdk_input_vtable.set_mode)
+    return gdk_input_vtable.set_mode(deviceid,mode);
+  else
+    return FALSE;
+}
+
+void
+gdk_input_set_axes (guint32 deviceid, GdkAxisUse *axes)
+{
+  if (deviceid != GDK_CORE_POINTER && gdk_input_vtable.set_axes)
+    gdk_input_vtable.set_axes (deviceid, axes);
+}
+
+GdkTimeCoord *
+gdk_input_motion_events (GdkWindow *window,
+                        guint32 deviceid,
+                        guint32 start,
+                        guint32 stop,
+                        gint *nevents_return)
+{
+  XTimeCoord *xcoords;
+  GdkTimeCoord *coords;
+  int i;
+
+  if (deviceid == GDK_CORE_POINTER)
+    {
+      xcoords = XGetMotionEvents (gdk_display,
+                                 ((GdkWindowPrivate *)window)->xwindow,
+                                 start, stop, nevents_return);
+      if (xcoords)
+       {
+         coords = g_new (GdkTimeCoord, *nevents_return);
+         for (i=0; i<*nevents_return; i++)
+           {
+             coords[i].time = xcoords[i].time;
+             coords[i].x = xcoords[i].x;
+             coords[i].y = xcoords[i].y;
+             coords[i].pressure = 0.5;
+             coords[i].xtilt = 0.0;
+             coords[i].ytilt = 0.0;
+           }
+
+         XFree(xcoords);
+
+         return coords;
+       }
+      else
+       return NULL;
+    }
+  else
+    {
+      if (gdk_input_vtable.motion_events)
+       {
+         return gdk_input_vtable.motion_events(window,
+                                               deviceid, start, stop,
+                                               nevents_return);
+       }
+      else
+       {
+         *nevents_return = 0;
+         return NULL;
+       }
+    }
+}
+
+static gint
+gdk_input_enable_window (GdkWindow *window, GdkDevicePrivate *gdkdev)
+{
+  if (gdk_input_vtable.enable_window)
+    return gdk_input_vtable.enable_window (window, gdkdev);
+  else
+    return TRUE;
+}
+
+static gint
+gdk_input_disable_window (GdkWindow *window, GdkDevicePrivate *gdkdev)
+{
+  if (gdk_input_vtable.disable_window)
+    return gdk_input_vtable.disable_window(window,gdkdev);
+  else
+    return TRUE;
+}
+
+
+static GdkInputWindow *
+gdk_input_window_find(GdkWindow *window)
+{
+  GList *tmp_list;
+
+  for (tmp_list=gdk_input_windows; tmp_list; tmp_list=tmp_list->next)
+    if (((GdkInputWindow *)(tmp_list->data))->window == window)
+      return (GdkInputWindow *)(tmp_list->data);
+
+  return NULL;      /* Not found */
+}
+
+/* FIXME: this routine currently needs to be called between creation
+   and the corresponding configure event (because it doesn't get the
+   root_relative_geometry).  This should work with
+   gtk_window_set_extension_events, but will likely fail in other
+   cases */
+
+void
+gdk_input_set_extension_events (GdkWindow *window, gint mask,
+                               GdkExtensionMode mode)
+{
+  GList *tmp_list;
+  GdkInputWindow *iw;
+
+  g_return_if_fail (window != NULL);
+
+  if (mode == GDK_EXTENSION_EVENTS_NONE)
+    mask = 0;
+
+  if (mask != 0)
+    {
+      iw = g_new(GdkInputWindow,1);
+
+      iw->window = window;
+      iw->mode = mode;
+
+      iw->obscuring = NULL;
+      iw->num_obscuring = 0;
+      iw->grabbed = FALSE;
+
+      gdk_input_windows = g_list_append(gdk_input_windows,iw);
+      ((GdkWindowPrivate *)window)->extension_events = mask;
+
+      /* Add enter window events to the event mask */
+      /* FIXME, this is not needed for XINPUT_NONE */
+      gdk_window_set_events (window,
+                            gdk_window_get_events (window) | 
+                            GDK_ENTER_NOTIFY_MASK);
+    }
+  else
+    {
+      iw = gdk_input_window_find (window);
+      if (iw)
+       {
+         gdk_input_windows = g_list_remove(gdk_input_windows,iw);
+         g_free(iw);
+       }
+
+      ((GdkWindowPrivate *)window)->extension_events = 0;
+    }
+
+  for (tmp_list = gdk_input_devices; tmp_list; tmp_list = tmp_list->next)
+    {
+      GdkDevicePrivate *gdkdev = (GdkDevicePrivate *)(tmp_list->data);
+
+      if (gdkdev->info.deviceid != GDK_CORE_POINTER)
+       {
+         if (mask != 0 && gdkdev->info.mode != GDK_MODE_DISABLED
+             && (gdkdev->info.has_cursor || mode == GDK_EXTENSION_EVENTS_ALL))
+           gdk_input_enable_window(window,gdkdev);
+         else
+           gdk_input_disable_window(window,gdkdev);
+       }
+    }
+}
+
+void
+gdk_input_window_destroy (GdkWindow *window)
+{
+  GdkInputWindow *input_window;
+
+  input_window = gdk_input_window_find (window);
+  g_return_if_fail (input_window != NULL);
+
+  gdk_input_windows = g_list_remove(gdk_input_windows,input_window);
+  g_free(input_window);
+}
+
+void
+gdk_input_exit (void)
+{
+  GList *tmp_list;
+  GdkDevicePrivate *gdkdev;
+
+  for (tmp_list = gdk_input_devices; tmp_list; tmp_list = tmp_list->next)
+    {
+      gdkdev = (GdkDevicePrivate *)(tmp_list->data);
+      if (gdkdev->info.deviceid != GDK_CORE_POINTER)
+       {
+         gdk_input_set_mode(gdkdev->info.deviceid,GDK_MODE_DISABLED);
+
+         g_free(gdkdev->info.name);
+#ifndef XINPUT_NONE      
+         g_free(gdkdev->axes);
+#endif   
+         g_free(gdkdev->info.axes);
+         g_free(gdkdev);
+       }
+    }
+
+  g_list_free(gdk_input_devices);
+
+  for (tmp_list = gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
+    {
+      g_free(tmp_list->data);
+    }
+  g_list_free(gdk_input_windows);
+}
+
+static GdkDevicePrivate *
+gdk_input_find_device(guint32 id)
+{
+  GList *tmp_list = gdk_input_devices;
+  GdkDevicePrivate *gdkdev;
+  while (tmp_list)
+    {
+      gdkdev = (GdkDevicePrivate *)(tmp_list->data);
+      if (gdkdev->info.deviceid == id)
+       return gdkdev;
+      tmp_list = tmp_list->next;
+    }
+  return NULL;
+}
+
+void
+gdk_input_window_get_pointer (GdkWindow       *window,
+                             guint32     deviceid,
+                             gdouble         *x,
+                             gdouble         *y,
+                             gdouble         *pressure,
+                             gdouble         *xtilt,
+                             gdouble         *ytilt,
+                             GdkModifierType *mask)
+{
+  if (gdk_input_vtable.get_pointer)
+    gdk_input_vtable.get_pointer (window, deviceid, x, y, pressure,
+                                 xtilt, ytilt, mask);
+}
diff --git a/gdk/gdkinput.h b/gdk/gdkinput.h
new file mode 100644 (file)
index 0000000..21aee60
--- /dev/null
@@ -0,0 +1,143 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __GDK_INPUT_H__
+#define __GDK_INPUT_H__
+
+#ifndef XINPUT_NONE
+#include <X11/extensions/XInput.h>
+#endif
+
+typedef struct _GdkAxisInfo    GdkAxisInfo;
+typedef struct _GdkInputVTable GdkInputVTable;
+typedef struct _GdkDevicePrivate GdkDevicePrivate;
+typedef struct _GdkInputWindow GdkInputWindow;
+
+struct _GdkInputVTable {
+  gint (*set_mode) (guint32 deviceid, GdkInputMode mode);
+  void (*set_axes) (guint32 deviceid, GdkAxisUse *axes);
+  GdkTimeCoord* (*motion_events) (GdkWindow *window,
+                                 guint32 deviceid,
+                                 guint32 start,
+                                 guint32 stop,
+                                 gint *nevents_return);
+  void (*get_pointer)   (GdkWindow       *window,
+                        guint32          deviceid,
+                        gdouble         *x,
+                        gdouble         *y,
+                        gdouble         *pressure,
+                        gdouble         *xtilt,
+                        gdouble         *ytilt,
+                        GdkModifierType *mask);
+  gint (*grab_pointer) (GdkWindow *     window,
+                       gint            owner_events,
+                       GdkEventMask    event_mask,
+                       GdkWindow *     confine_to,
+                       guint32         time);
+  void (*ungrab_pointer) (guint32 time);
+
+  void (*configure_event) (XConfigureEvent *xevent, GdkWindow *window);
+  void (*enter_event) (XCrossingEvent *xevent, GdkWindow *window);
+  gint (*other_event) (GdkEvent *event, XEvent *xevent, GdkWindow *window);
+  /* Handle an unidentified event. Returns TRUE if handled, FALSE
+     otherwise */
+  gint (*window_none_event) (GdkEvent *event, XEvent *xevent);
+  gint (*enable_window) (GdkWindow *window, GdkDevicePrivate *gdkdev);
+  gint (*disable_window) (GdkWindow *window, GdkDevicePrivate *gdkdev);
+};
+
+/* information about a device axis */
+struct _GdkAxisInfo
+{
+  /* reported x resolution */
+  gint xresolution;
+
+  /* reported x minimum/maximum values */
+  gint xmin_value, xmax_value;
+
+  /* calibrated resolution (for aspect ration) - only relative values
+     between axes used */
+  gint resolution;
+  
+  /* calibrated minimum/maximum values */
+  gint min_value, max_value;
+};
+
+#define GDK_INPUT_NUM_EVENTC 6
+
+struct _GdkDevicePrivate {
+  GdkDeviceInfo  info;
+
+#ifndef XINPUT_NONE
+  /* information about the axes */
+  GdkAxisInfo *axes;
+
+  /* reverse lookup on axis use type */
+  gint axis_for_use[GDK_AXIS_LAST];
+  
+  /* Information about XInput device */
+  XDevice       *xdevice;
+
+  int buttonpress_type, buttonrelease_type, motionnotify_type,
+      proximityin_type, proximityout_type, changenotify_type;
+
+  /* true if we need to select a different set of events, but
+     can't because this is the core pointer */
+  gint needs_update;
+
+  /* Mask of buttons (used for button grabs) */
+  gint button_state;
+
+  /* true if we've claimed the device as active. (used only for XINPUT_GXI) */
+  gint claimed;
+#endif /* !XINPUT_NONE */
+};
+
+struct _GdkInputWindow
+{
+  /* gdk window */
+  GdkWindow *window;
+
+  /* Extension mode (GDK_EXTENSION_EVENTS_ALL/CURSOR) */
+  GdkExtensionMode mode;
+
+  /* position relative to root window */
+  gint16 root_x;
+  gint16 root_y;
+
+  /* rectangles relative to window of windows obscuring this one */
+  GdkRectangle *obscuring;
+  gint num_obscuring;
+
+  /* Is there a pointer grab for this window ? */
+  gint grabbed;
+};
+
+/* Global data */
+
+extern GdkInputVTable gdk_input_vtable;
+/* information about network port and host for gxid daemon */
+extern gchar           *gdk_input_gxid_host;
+extern gint             gdk_input_gxid_port;
+extern gint             gdk_input_ignore_core;
+
+/* Function declarations */
+
+void gdk_input_window_destroy (GdkWindow *window);
+
+#endif __GDK_INPUT_H__
diff --git a/gdk/gdkinputcommon.h b/gdk/gdkinputcommon.h
new file mode 100644 (file)
index 0000000..5e457e0
--- /dev/null
@@ -0,0 +1,687 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#if defined(XINPUT_GXI) || defined(XINPUT_XFREE)
+
+/* Forward declarations */
+static void gdk_input_get_root_relative_geometry (Display *dpy, Window w, 
+                                                 int *x_ret, int *y_ret,
+                                                 int *width_ret, 
+                                                 int *height_ret);
+static GdkDevicePrivate *gdk_input_device_new(XDeviceInfo *device, 
+                                             gint include_core);
+static void gdk_input_common_find_events(GdkWindow *window,
+                                        GdkDevicePrivate *gdkdev,
+                                        gint mask,
+                                        XEventClass *classes,
+                                        int *num_classes);
+static void gdk_input_common_select_events(GdkWindow *window,
+                                          GdkDevicePrivate *gdkdev);
+static void gdk_input_translate_coordinates(GdkDevicePrivate *gdkdev,
+                                           GdkInputWindow *input_window,
+                                           gint *axis_data,
+                                           gdouble *x, gdouble *y,
+                                           gdouble *pressure,
+                                           gdouble *xtilt, gdouble *ytilt);
+static guint gdk_input_translate_state(guint state, guint device_state);
+static gint gdk_input_common_init(gint include_core);
+static gint  gdk_input_common_other_event (GdkEvent *event, 
+                                          XEvent *xevent, 
+                                          GdkInputWindow *input_window,
+                                          GdkDevicePrivate *gdkdev);
+static void gdk_input_common_set_axes (guint32 deviceid, GdkAxisUse *axes);
+static GdkTimeCoord * gdk_input_common_motion_events (GdkWindow *window,
+                                                     guint32 deviceid,
+                                                     guint32 start,
+                                                     guint32 stop,
+                                                     gint *nevents_return);
+static void  gdk_input_common_get_pointer     (GdkWindow       *window,
+                                              guint32     deviceid,
+                                              gdouble         *x,
+                                              gdouble         *y,
+                                              gdouble         *pressure,
+                                              gdouble         *xtilt,
+                                              gdouble         *ytilt,
+                                              GdkModifierType *mask);
+
+/* Global variables */
+
+static gint gdk_input_root_width;
+static gint gdk_input_root_height;
+
+static void
+gdk_input_get_root_relative_geometry(Display *dpy, Window w, int *x_ret, int *y_ret,
+                              int *width_ret, int *height_ret)
+{
+  Window root,parent;
+  Window *children;
+  int nchildren;
+  int x,y,width,height;
+  int xc,yc,widthc,heightc,border_widthc,depthc;
+  
+  XQueryTree(dpy,w,&root,&parent,&children,&nchildren);
+  if (children) XFree(children);
+  XGetGeometry(dpy,w,&root,&x,&y,&width,&height,&border_widthc,
+              &depthc);
+  x += border_widthc;
+  y += border_widthc;
+
+  while (root != parent)
+    {
+      w = parent;
+      XQueryTree(dpy,w,&root,&parent,&children,&nchildren);
+      if (children) XFree(children);
+      XGetGeometry(dpy,w,&root,&xc,&yc,&widthc,&heightc,
+                  &border_widthc,&depthc);
+      x += xc + border_widthc;
+      y += yc + border_widthc;
+    }
+
+  if (x_ret)
+    *x_ret = x;
+  if (y_ret)
+    *y_ret = y;
+  if (width_ret)
+    *width_ret = width;
+  if (height_ret)
+    *height_ret = height;
+}
+
+static GdkDevicePrivate *
+gdk_input_device_new(XDeviceInfo *device, gint include_core)
+{
+  GdkDevicePrivate *gdkdev;
+  gchar *tmp_name, *p;
+  XAnyClassPtr class;
+  gint i,j;
+
+  gdkdev = g_new(GdkDevicePrivate,1);
+
+  gdkdev->info.deviceid = device->id;
+  if (device->name[0]) {
+    gdkdev->info.name = g_new(char, strlen(device->name)+1);
+    strcpy(gdkdev->info.name,device->name);
+  } else {
+    /* XFree86 3.2 gives an empty name to the default core devices,
+       (fixed in 3.2A) */
+    gdkdev->info.name = g_strdup("pointer");
+    strcpy(gdkdev->info.name,"pointer");
+    gdkdev->info.source = GDK_SOURCE_MOUSE;
+  }
+
+  gdkdev->info.mode = GDK_MODE_DISABLED;
+
+  /* Try to figure out what kind of device this is by its name -
+     could invite a very, very, long list... Lowercase name
+     for comparison purposes */
+
+  tmp_name = g_strdup(gdkdev->info.name);
+  for (p = tmp_name; *p; p++)
+    {
+      if (*p >= 'A' && *p <= 'Z')
+       *p += 'a' - 'A';
+    }
+  
+  if (!strcmp (tmp_name, "pointer"))
+    gdkdev->info.source = GDK_SOURCE_MOUSE;
+  else if (!strcmp (tmp_name, "wacom") ||
+          !strcmp (tmp_name, "pen"))
+    gdkdev->info.source = GDK_SOURCE_PEN;
+  else if (!strcmp (tmp_name, "eraser"))
+    gdkdev->info.source = GDK_SOURCE_ERASER;
+  else if (!strcmp (tmp_name, "cursor"))
+    gdkdev->info.source = GDK_SOURCE_CURSOR;
+  else
+    gdkdev->info.source = GDK_SOURCE_PEN;
+
+  g_free(tmp_name);
+
+  gdkdev->xdevice = NULL;
+
+  /* step through the classes */
+
+  gdkdev->info.num_axes = 0;
+  gdkdev->axes = 0;
+  gdkdev->info.has_cursor = 0;
+  gdkdev->needs_update = FALSE;
+  gdkdev->claimed = FALSE;
+  gdkdev->button_state = 0;
+
+  class = device->inputclassinfo;
+  for (i=0;i<device->num_classes;i++) 
+    {
+      switch (class->class) {
+      case ButtonClass:
+       {
+         break;
+       }
+      case ValuatorClass:
+       {
+         XValuatorInfo *xvi = (XValuatorInfo *)class;
+         gdkdev->info.num_axes = xvi->num_axes;
+         gdkdev->axes = g_new(GdkAxisInfo, xvi->num_axes);
+         gdkdev->info.axes = g_new(GdkAxisUse, xvi->num_axes);
+         for (j=0;j<xvi->num_axes;j++)
+           {
+             gdkdev->axes[j].resolution = 
+               gdkdev->axes[j].xresolution = xvi->axes[j].resolution;
+             gdkdev->axes[j].min_value =
+               gdkdev->axes[j].xmin_value = xvi->axes[j].min_value;
+             gdkdev->axes[j].max_value =
+               gdkdev->axes[j].xmax_value = xvi->axes[j].max_value;
+             gdkdev->info.axes[j] = GDK_AXIS_IGNORE;
+           }
+         j=0;
+         if (j<xvi->num_axes)
+           gdkdev->info.axes[j++] = GDK_AXIS_X;
+         if (j<xvi->num_axes)
+           gdkdev->info.axes[j++] = GDK_AXIS_Y;
+         if (j<xvi->num_axes)
+           gdkdev->info.axes[j++] = GDK_AXIS_PRESSURE;
+         if (j<xvi->num_axes)
+           gdkdev->info.axes[j++] = GDK_AXIS_XTILT;
+         if (j<xvi->num_axes)
+           gdkdev->info.axes[j++] = GDK_AXIS_YTILT;
+         
+         /* set up reverse lookup on axis use */
+         for (j=GDK_AXIS_IGNORE;j<GDK_AXIS_LAST;j++)
+           gdkdev->axis_for_use[j] = -1;
+         
+         for (j=0;j<xvi->num_axes;j++)
+           if (gdkdev->info.axes[j] != GDK_AXIS_IGNORE)
+             gdkdev->axis_for_use[gdkdev->info.axes[j]] = j;
+                      
+         break;
+       }
+      }
+      class = (XAnyClassPtr)(((char *)class) + class->length);
+    }
+  /* return NULL if no axes */
+  if (!gdkdev->info.num_axes || !gdkdev->axes ||
+      (!include_core && device->use == IsXPointer))
+    {
+      g_free(gdkdev->info.name);
+      if (gdkdev->axes)
+       g_free(gdkdev->axes);
+      g_free(gdkdev);
+      return NULL;
+    }
+
+  if (device->use != IsXPointer)
+      gdkdev->xdevice = XOpenDevice(gdk_display, gdkdev->info.deviceid);
+
+  return gdkdev;
+}
+
+static void
+gdk_input_common_find_events(GdkWindow *window,
+                            GdkDevicePrivate *gdkdev,
+                            gint mask,
+                            XEventClass *classes,
+                            int *num_classes)
+{
+  gint i;
+  XEventClass class;
+  
+  i = 0;
+  /* We have to track press and release events in pairs to keep
+     track of button state correctly and implement grabbing */
+  if (mask & GDK_BUTTON_PRESS_MASK || mask & GDK_BUTTON_RELEASE_MASK)
+    {
+      DeviceButtonPress   (gdkdev->xdevice, gdkdev->buttonpress_type,
+                          class);
+      if (class != 0)
+         classes[i++] = class;
+      DeviceButtonRelease (gdkdev->xdevice, gdkdev->buttonrelease_type,
+                          class);
+      if (class != 0)
+         classes[i++] = class;
+    }
+  if (mask & GDK_POINTER_MOTION_MASK)
+    {
+      DeviceMotionNotify  (gdkdev->xdevice, gdkdev->motionnotify_type, class);
+      if (class != 0)
+         classes[i++] = class;
+    }
+  if (mask & GDK_POINTER_MOTION_HINT_MASK)
+    {
+      /* We'll get into trouble if the macros change, but at least we'll
+        know about it, and we avoid warnings now */
+      DevicePointerMotionHint (gdkdev->xdevice, 0, class);
+      if (class != 0)
+         classes[i++] = class;
+    }
+  if (mask & GDK_PROXIMITY_IN_MASK)
+    {
+      ProximityIn   (gdkdev->xdevice, gdkdev->proximityin_type, class);
+      if (class != 0)
+         classes[i++] = class;
+    }
+  if (mask & GDK_PROXIMITY_OUT_MASK)
+    {
+      ProximityOut  (gdkdev->xdevice, gdkdev->proximityout_type, class);
+      if (class != 0)
+         classes[i++] = class;
+    }
+
+  *num_classes = i;
+}
+
+static void
+gdk_input_common_select_events(GdkWindow *window,
+                              GdkDevicePrivate *gdkdev)
+{
+  XEventClass classes[6];
+  gint num_classes;
+
+  if (gdkdev->info.mode == GDK_MODE_DISABLED)
+    gdk_input_common_find_events(window, gdkdev, 0, classes, &num_classes);
+  else
+    gdk_input_common_find_events(window, gdkdev, 
+                                ((GdkWindowPrivate *)window)->extension_events,
+                                classes, &num_classes);
+  
+  XSelectExtensionEvent (gdk_display,
+                        GDK_WINDOW_XWINDOW(window),
+                        classes, num_classes);
+}
+
+gint 
+gdk_input_common_init(gint include_core)
+{
+  char **extensions;
+  XDeviceInfo   *devices;
+  int num_devices;
+  int num_extensions, loop;
+  Display *display = gdk_display;
+
+  /* Init global vars */
+  gdk_window_get_geometry(NULL,        /* use root window */
+                         NULL,NULL,
+                         &gdk_input_root_width,&gdk_input_root_height, 
+                         NULL);
+
+  /* Init XInput extension */
+  
+  extensions = XListExtensions(display, &num_extensions);
+  for (loop = 0; loop < num_extensions &&
+        (strcmp(extensions[loop], "XInputExtension") != 0); loop++);
+  XFreeExtensionList(extensions);
+  if (loop == num_extensions)  /* XInput extension not found */
+    return FALSE;
+
+  gdk_input_devices = 0;
+  devices = XListInputDevices(display, &num_devices);
+  
+  for(loop=0; loop<num_devices; loop++)
+    {
+      GdkDevicePrivate *gdkdev = gdk_input_device_new(&devices[loop],
+                                                     include_core);
+      if (gdkdev)
+       gdk_input_devices = g_list_append(gdk_input_devices, gdkdev);
+    }
+  XFreeDeviceList(devices);
+
+  gdk_input_devices = g_list_append (gdk_input_devices, &gdk_input_core_info);
+
+  return TRUE;
+}
+
+static void
+gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
+                                GdkInputWindow *input_window,
+                                gint *axis_data,
+                                gdouble *x, gdouble *y, gdouble *pressure,
+                                gdouble *xtilt, gdouble *ytilt)
+{
+  GdkWindowPrivate *win_priv;
+
+  int x_axis, y_axis, pressure_axis, xtilt_axis, ytilt_axis;
+
+  double device_width, device_height;
+  double x_offset, y_offset, x_scale, y_scale;
+
+  win_priv = (GdkWindowPrivate *) input_window->window;
+
+  x_axis = gdkdev->axis_for_use[GDK_AXIS_X];
+  y_axis = gdkdev->axis_for_use[GDK_AXIS_Y];
+  pressure_axis = gdkdev->axis_for_use[GDK_AXIS_PRESSURE];
+  xtilt_axis = gdkdev->axis_for_use[GDK_AXIS_XTILT];
+  ytilt_axis = gdkdev->axis_for_use[GDK_AXIS_YTILT];
+
+  device_width = gdkdev->axes[x_axis].max_value - 
+                  gdkdev->axes[x_axis].min_value;
+  device_height = gdkdev->axes[y_axis].max_value - 
+                    gdkdev->axes[y_axis].min_value;
+
+  if (gdkdev->info.mode == GDK_MODE_SCREEN) 
+    {
+      x_scale = gdk_input_root_width / device_width;
+      y_scale = gdk_input_root_height / device_height;
+
+      x_offset = - input_window->root_x;
+      y_offset = - input_window->root_y;
+    }
+  else                         /* GDK_MODE_WINDOW */
+    {
+      double device_aspect = (device_height*gdkdev->axes[y_axis].resolution) /
+       (device_width*gdkdev->axes[x_axis].resolution);
+
+      if (device_aspect * win_priv->width >= win_priv->height)
+       {
+         /* device taller than window */
+         x_scale = win_priv->width / device_width;
+         y_scale = (x_scale * gdkdev->axes[x_axis].resolution)
+           / gdkdev->axes[y_axis].resolution;
+
+         x_offset = 0;
+         y_offset = -(device_height * y_scale - 
+                              win_priv->height)/2;
+       }
+      else
+       {
+         /* window taller than device */
+         y_scale = win_priv->height / device_height;
+         x_scale = (y_scale * gdkdev->axes[y_axis].resolution)
+           / gdkdev->axes[x_axis].resolution;
+
+         y_offset = 0;
+         x_offset = - (device_width * x_scale - win_priv->width)/2;
+       }
+    }
+  
+  if (x) *x = x_offset + x_scale*axis_data[x_axis];
+  if (y) *y = y_offset + y_scale*axis_data[y_axis];
+
+  if (pressure)
+    {
+      if (pressure_axis != -1)
+       *pressure = ((double)axis_data[pressure_axis] 
+                    - gdkdev->axes[pressure_axis].min_value) 
+         / (gdkdev->axes[pressure_axis].max_value 
+            - gdkdev->axes[pressure_axis].min_value);
+      else
+       *pressure = 0.5;
+    }
+
+  if (xtilt)
+    {
+      if (xtilt_axis != -1)
+       {
+         *xtilt = 2. * (double)(axis_data[xtilt_axis] - 
+                                (gdkdev->axes[xtilt_axis].min_value +
+                                 gdkdev->axes[xtilt_axis].max_value)/2) /
+           (gdkdev->axes[xtilt_axis].max_value -
+            gdkdev->axes[xtilt_axis].min_value);
+       }
+      else *xtilt = 0;
+    }
+  
+  if (ytilt)
+    {
+      if (ytilt_axis != -1)
+       {
+         *ytilt = 2. * (double)(axis_data[ytilt_axis] - 
+                                (gdkdev->axes[ytilt_axis].min_value +
+                                 gdkdev->axes[ytilt_axis].max_value)/2) /
+           (gdkdev->axes[ytilt_axis].max_value -
+            gdkdev->axes[ytilt_axis].min_value);
+       }
+      else
+       *ytilt = 0;
+    }
+}
+
+/* combine the state of the core device and the device state
+   into one - for now we do this in a simple-minded manner -
+   we just take the keyboard portion of the core device and
+   the button portion (all of?) the device state.
+   Any button remapping should go on here. */
+static guint
+gdk_input_translate_state(guint state, guint device_state)
+{
+  return device_state | (state & 0xFF);
+}
+
+static gint 
+gdk_input_common_other_event (GdkEvent *event, 
+                             XEvent *xevent, 
+                             GdkInputWindow *input_window,
+                             GdkDevicePrivate *gdkdev)
+{
+  if ((xevent->type == gdkdev->buttonpress_type) ||
+      (xevent->type == gdkdev->buttonrelease_type)) 
+    {
+      XDeviceButtonEvent *xdbe = (XDeviceButtonEvent *)(xevent);
+
+      if (xdbe->type == gdkdev->buttonpress_type)
+       {
+         event->button.type = GDK_BUTTON_PRESS;
+         gdkdev->button_state |= 1 << xdbe->button;
+       }
+      else
+       {
+         event->button.type = GDK_BUTTON_RELEASE;
+         gdkdev->button_state &= ~(1 << xdbe->button);
+       }
+      event->button.window = input_window->window;
+      event->button.time = xdbe->time;
+      event->button.source = gdkdev->info.source;
+      event->button.deviceid = xdbe->deviceid;
+
+      gdk_input_translate_coordinates (gdkdev,input_window, xdbe->axis_data,
+                                      &event->button.x,&event->button.y,
+                                      &event->button.pressure,
+                                      &event->button.xtilt, 
+                                      &event->button.ytilt);
+      event->button.state = gdk_input_translate_state(xdbe->state,xdbe->device_state);
+      event->button.button = xdbe->button;
+
+      return TRUE;
+  }
+
+  if (xevent->type == gdkdev->motionnotify_type) 
+    {
+      XDeviceMotionEvent *xdme = (XDeviceMotionEvent *)(xevent);
+
+      gdk_input_translate_coordinates(gdkdev,input_window,xdme->axis_data,
+                                     &event->motion.x,&event->motion.y,
+                                     &event->motion.pressure,
+                                     &event->motion.xtilt, 
+                                     &event->motion.ytilt);
+
+      event->motion.type = GDK_MOTION_NOTIFY;
+      event->motion.window = input_window->window;
+      event->motion.time = xdme->time;
+      event->motion.deviceid = xdme->deviceid;
+      event->motion.state = gdk_input_translate_state(xdme->state,
+                                                     xdme->device_state);
+      event->motion.source = gdkdev->info.source;
+      event->motion.deviceid = xdme->deviceid;
+
+      if (gdk_show_events)
+       g_print ("motion notify:\t\twindow: %ld  device: %ld  x,y: %f %f  hint: %s\n",
+                xdme->window,
+                xdme->deviceid,
+                event->motion.x, event->motion.y,
+                (xevent->xmotion.is_hint) ? "true" : "false");
+      
+      
+      return TRUE;
+    }
+
+  if (xevent->type == gdkdev->proximityin_type ||
+      xevent->type == gdkdev->proximityout_type)
+    {
+      XProximityNotifyEvent *xpne = (XProximityNotifyEvent *)(xevent);
+
+      event->proximity.type = (xevent->type == gdkdev->proximityin_type)?
+       GDK_PROXIMITY_IN:GDK_PROXIMITY_OUT;
+      event->proximity.window = input_window->window;
+      event->proximity.time = xpne->time;
+      event->proximity.source = gdkdev->info.source;
+      event->proximity.deviceid = xpne->deviceid;
+      
+      return TRUE;
+  }
+
+  return -1;                   /* wasn't one of our event types */
+}
+
+static void
+gdk_input_common_set_axes (guint32 deviceid, GdkAxisUse *axes)
+{
+  int i;
+  GdkDevicePrivate *gdkdev = gdk_input_find_device(deviceid);
+  g_return_if_fail (gdkdev != NULL);
+
+  for (i=GDK_AXIS_IGNORE;i<GDK_AXIS_LAST;i++)
+    {
+      gdkdev->axis_for_use[i] = -1;
+    }
+
+  for (i=0;i<gdkdev->info.num_axes;i++)
+    {
+      gdkdev->info.axes[i] = axes[i];
+      gdkdev->axis_for_use[axes[i]] = i;
+    }
+}
+
+static GdkTimeCoord *
+gdk_input_common_motion_events (GdkWindow *window,
+                               guint32 deviceid,
+                               guint32 start,
+                               guint32 stop,
+                               gint *nevents_return)
+{
+  GdkTimeCoord *coords;
+  XDeviceTimeCoord *device_coords;
+  GdkInputWindow *input_window;
+  GdkDevicePrivate *gdkdev;
+
+  int mode_return;
+  int axis_count_return;
+  int i;
+
+  gdkdev = gdk_input_find_device (deviceid);
+  input_window = gdk_input_window_find (window);
+
+  g_return_val_if_fail (gdkdev != NULL, NULL);
+  g_return_val_if_fail (gdkdev->xdevice != NULL, NULL);
+  g_return_val_if_fail (input_window != NULL, NULL);
+
+  device_coords = XGetDeviceMotionEvents (gdk_display,
+                                         gdkdev->xdevice,
+                                         start, stop,
+                                         nevents_return, &mode_return,
+                                         &axis_count_return);
+
+  if (device_coords)
+    {
+      coords = g_new (GdkTimeCoord, *nevents_return);
+      
+      for (i=0; i<*nevents_return; i++)
+       {
+         gdk_input_translate_coordinates (gdkdev, input_window,
+                                          device_coords[i].data,
+                                          &coords[i].x, &coords[i].y,
+                                          &coords[i].pressure,
+                                          &coords[i].xtilt, &coords[i].ytilt);
+       }
+      XFreeDeviceMotionEvents (device_coords);
+
+      return coords;
+    }
+  else
+    return NULL;
+}
+
+static void 
+gdk_input_common_get_pointer     (GdkWindow       *window,
+                                 guint32          deviceid,
+                                 gdouble         *x,
+                                 gdouble         *y,
+                                 gdouble         *pressure,
+                                 gdouble         *xtilt,
+                                 gdouble         *ytilt,
+                                 GdkModifierType *mask)
+{
+  GdkDevicePrivate *gdkdev;
+  GdkInputWindow *input_window;
+  XDeviceState *state;
+  XInputClass *input_class;
+  gint x_int, y_int;
+  gint i;
+
+  /* we probably need to get the mask in any case */
+
+  if (deviceid == GDK_CORE_POINTER)
+    {
+      gdk_window_get_pointer (window, &x_int, &y_int, mask);
+      if (x) *x = x_int;
+      if (y) *y = y_int;
+      if (pressure) *pressure = 0.5;
+      if (xtilt) *xtilt = 0;
+      if (ytilt) *ytilt = 0;
+    }
+  else
+    {
+      if (mask)
+       gdk_window_get_pointer (window, NULL, NULL, mask);
+      
+      gdkdev = gdk_input_find_device (deviceid);
+      input_window = gdk_input_window_find (window);
+
+      g_return_if_fail (gdkdev != NULL);
+      g_return_if_fail (gdkdev->xdevice != NULL);
+      g_return_if_fail (input_window != NULL);
+
+      state = XQueryDeviceState (gdk_display, gdkdev->xdevice);
+      input_class = state->data;
+      for (i=0; i<state->num_classes; i++)
+       {
+         switch (input_class->class)
+           {
+           case ValuatorClass:
+             gdk_input_translate_coordinates(gdkdev, input_window,
+                                             ((XValuatorState *)input_class)->valuators,
+                                             x, y, pressure,
+                                             xtilt, ytilt);
+                                                      
+                                                      
+               break;
+           case ButtonClass:
+             if (mask)
+               {
+                 *mask &= ~(GDK_BUTTON1_MASK | GDK_BUTTON2_MASK |
+                            GDK_BUTTON3_MASK | GDK_BUTTON4_MASK |
+                            GDK_BUTTON5_MASK);
+                 for (i=0; i < ((XButtonState *)input_class)->num_buttons; i++)
+                   {
+                     if (((XButtonState *)input_class)->buttons[i])
+                       *mask |= GDK_BUTTON1_MASK << i;
+                   }
+               }
+             break;
+           }
+         input_class = (XInputClass *)(((char *)input_class)+input_class->length);
+       }
+    }
+}
+
+#endif
diff --git a/gdk/gdkinputgxi.h b/gdk/gdkinputgxi.h
new file mode 100644 (file)
index 0000000..a30e05f
--- /dev/null
@@ -0,0 +1,628 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef XINPUT_GXI
+
+/* #define DEBUG_SWITCHING */
+
+#include <gxid_lib.h>
+
+/* Forward declarations */
+static void gdk_input_gxi_select_notify (GdkDevicePrivate *gdkdev);
+static gint gdk_input_gxi_set_mode (guint32 deviceid, GdkInputMode mode);
+static gint gdk_input_is_extension_device (guint32 deviceid);
+static void gdk_input_gxi_configure_event (XConfigureEvent *xevent, 
+                                          GdkWindow *window);
+static void gdk_input_gxi_enter_event (XCrossingEvent *xevent, 
+                                      GdkWindow *window);
+static gint gdk_input_gxi_other_event (GdkEvent *event, 
+                                      XEvent *xevent, 
+                                      GdkWindow *window);
+static void gdk_input_gxi_update_device (GdkDevicePrivate *gdkdev);
+
+static gint gdk_input_gxi_window_none_event (GdkEvent *event, XEvent *xevent);
+static gint gdk_input_gxi_enable_window (GdkWindow *window, 
+                                        GdkDevicePrivate *gdkdev);
+static gint gdk_input_gxi_disable_window (GdkWindow *window, 
+                                         GdkDevicePrivate *gdkdev);
+static Window gdk_input_find_root_child(Display *dpy, Window w);
+static void gdk_input_compute_obscuring(GdkInputWindow *input_window);
+static gint gdk_input_is_obscured(GdkInputWindow *input_window, gdouble x, 
+                                 gdouble y);
+static GdkTimeCoord *gdk_input_gxi_motion_events (GdkWindow *window,
+                                                 guint32 deviceid,
+                                                 guint32 start,
+                                                 guint32 stop,
+                                                 gint *nevents_return);
+static void gdk_input_gxi_get_pointer (GdkWindow       *window,
+                                      guint32     deviceid,
+                                      gdouble         *x,
+                                      gdouble         *y,
+                                      gdouble         *pressure,
+                                      gdouble         *xtilt,
+                                      gdouble         *ytilt,
+                                      GdkModifierType *mask);
+static gint gdk_input_gxi_grab_pointer (GdkWindow *     window,
+                                       gint            owner_events,
+                                       GdkEventMask    event_mask,
+                                       GdkWindow *     confine_to,
+                                       guint32         time);
+static void gdk_input_gxi_ungrab_pointer (guint32 time);
+
+/* Local variables */
+
+static GdkDevicePrivate *gdk_input_current_device;
+static GdkDevicePrivate *gdk_input_core_pointer;
+
+void
+gdk_input_init(void)
+{
+  GList *tmp_list;
+  
+  gdk_input_vtable.set_mode           = gdk_input_gxi_set_mode;
+  gdk_input_vtable.set_axes        = gdk_input_common_set_axes;
+  gdk_input_vtable.motion_events      = gdk_input_gxi_motion_events;
+  gdk_input_vtable.get_pointer       = gdk_input_gxi_get_pointer;
+  gdk_input_vtable.grab_pointer              = gdk_input_gxi_grab_pointer;
+  gdk_input_vtable.ungrab_pointer     = gdk_input_gxi_ungrab_pointer;
+  gdk_input_vtable.configure_event    = gdk_input_gxi_configure_event;
+  gdk_input_vtable.enter_event        = gdk_input_gxi_enter_event;
+  gdk_input_vtable.other_event        = gdk_input_gxi_other_event;
+  gdk_input_vtable.window_none_event  = gdk_input_gxi_window_none_event;
+  gdk_input_vtable.enable_window      = gdk_input_gxi_enable_window;
+  gdk_input_vtable.disable_window     = gdk_input_gxi_disable_window;
+
+  gdk_input_ignore_core = FALSE;
+  gdk_input_core_pointer = NULL;
+
+  if (!gdk_input_gxid_host) 
+    {
+      gdk_input_gxid_host = getenv("GXID_HOST");
+    }
+  if (!gdk_input_gxid_port) 
+    {
+      char *t = getenv("GXID_PORT");
+      if (t)
+       gdk_input_gxid_port = atoi(t);
+    }
+  
+  gdk_input_common_init(TRUE);
+
+  /* find initial core pointer */
+  
+  for (tmp_list = gdk_input_devices; tmp_list; tmp_list = tmp_list->next) 
+    {
+      GdkDevicePrivate *gdkdev = (GdkDevicePrivate *)tmp_list->data;
+      if (gdk_input_is_extension_device(gdkdev->info.deviceid))
+       {
+         gdk_input_gxi_select_notify (gdkdev);
+       }
+      else
+       {
+         if (gdkdev->info.deviceid != GDK_CORE_POINTER)
+           gdk_input_core_pointer = gdkdev;
+       }
+    }
+}
+
+static void
+gdk_input_gxi_select_notify (GdkDevicePrivate *gdkdev)
+{
+  XEventClass class;
+
+  ChangeDeviceNotify  (gdkdev->xdevice, gdkdev->changenotify_type, class);
+
+  XSelectExtensionEvent (gdk_display, gdk_root_window, &class, 1);
+}
+
+/* Set the core pointer. Device should already be enabled. */
+static gint
+gdk_input_gxi_set_core_pointer(GdkDevicePrivate *gdkdev)
+{
+  int x_axis,y_axis;
+
+  g_return_val_if_fail(gdkdev->xdevice,FALSE);
+
+  x_axis = gdkdev->axis_for_use[GDK_AXIS_X];
+  y_axis = gdkdev->axis_for_use[GDK_AXIS_Y];
+
+  g_return_val_if_fail(x_axis != -1 && y_axis != -1,FALSE);
+
+  /* core_pointer might not be up to date so we check with the server
+     before change the pointer */
+
+  if ( !gdk_input_is_extension_device(gdkdev->info.deviceid) )
+    {
+#if 0
+      if (gdkdev != gdk_input_core_pointer)
+       g_warning("core pointer inconsistency");
+#endif      
+      return TRUE;
+    }
+
+  if ( XChangePointerDevice(gdk_display,gdkdev->xdevice, x_axis, y_axis) 
+       != Success )
+    {
+      return FALSE;
+    }
+  else
+    {
+      gdk_input_gxi_update_device (gdk_input_core_pointer);
+      gdk_input_core_pointer = gdkdev;
+      return TRUE;
+    }
+}
+
+
+/* FIXME, merge with gdk_input_xfree_set_mode */
+
+static gint
+gdk_input_gxi_set_mode (guint32 deviceid, GdkInputMode mode)
+{
+  GList *tmp_list;
+  GdkDevicePrivate *gdkdev;
+  GdkInputMode old_mode;
+  GdkInputWindow *input_window;
+
+  gdkdev = gdk_input_find_device(deviceid);
+  g_return_val_if_fail (gdkdev != NULL,FALSE);
+  old_mode = gdkdev->info.mode;
+
+  if (gdkdev->info.mode == mode)
+    return TRUE;
+  
+  gdkdev->info.mode = mode;
+
+  if (old_mode != GDK_MODE_DISABLED)
+    {
+      for (tmp_list = gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
+       {
+         input_window = (GdkInputWindow *)tmp_list->data;
+         if (input_window->mode != GDK_EXTENSION_EVENTS_CURSOR)
+           gdk_input_disable_window (input_window->window, gdkdev);
+       }
+    }
+  
+  if (mode != GDK_MODE_DISABLED)
+    {
+      for (tmp_list = gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
+       {
+         input_window = (GdkInputWindow *)tmp_list->data;
+         if (input_window->mode != GDK_EXTENSION_EVENTS_CURSOR)
+           if (!gdk_input_enable_window(input_window->window, gdkdev))
+             {
+               gdk_input_set_mode(deviceid, old_mode);
+               return FALSE;
+             }
+       }
+    }
+
+  return TRUE;
+
+}
+
+gint
+gdk_input_is_extension_device (guint32 deviceid)
+{
+  XDeviceInfo   *devices;
+  int num_devices, loop;
+
+  if (deviceid == GDK_CORE_POINTER)
+    return FALSE;
+  
+  devices = XListInputDevices(gdk_display, &num_devices);
+  for(loop=0; loop<num_devices; loop++)
+    {
+      if ((devices[loop].id == deviceid) && (devices[loop].use == IsXExtensionDevice)) 
+       {
+         XFreeDeviceList(devices);
+         return TRUE;
+       }
+    }
+
+  XFreeDeviceList(devices);
+  return FALSE;
+}
+
+static void
+gdk_input_gxi_configure_event (XConfigureEvent *xevent, GdkWindow *window)
+{
+  GdkInputWindow *input_window;
+  gint root_x, root_y;
+
+  input_window = gdk_input_window_find(window);
+  g_return_if_fail (input_window != NULL);
+
+  gdk_input_get_root_relative_geometry(gdk_display,GDK_WINDOW_XWINDOW(window),
+                                &root_x, &root_y, NULL, NULL);
+  input_window->root_x = root_x;
+  input_window->root_y = root_y;
+  gdk_input_compute_obscuring(input_window);
+}
+
+static void
+gdk_input_gxi_enter_event (XCrossingEvent *xevent, GdkWindow *window)
+{
+  GdkInputWindow *input_window;
+
+  input_window = gdk_input_window_find(window);
+  g_return_if_fail (input_window != NULL);
+
+  gdk_input_compute_obscuring(input_window);
+}
+
+static gint 
+gdk_input_gxi_other_event (GdkEvent *event, 
+                          XEvent *xevent, 
+                          GdkWindow *window)
+{
+  GdkInputWindow *input_window;
+
+  GdkDevicePrivate *gdkdev;
+  gint return_val;
+
+  input_window = gdk_input_window_find(window);
+  g_return_val_if_fail (window != NULL, -1);
+
+  /* This is a sort of a hack, as there isn't any XDeviceAnyEvent -
+     but it's potentially faster than scanning through the types of
+     every device. If we were deceived, then it won't match any of
+     the types for the device anyways */
+  gdkdev = gdk_input_find_device(((XDeviceButtonEvent *)xevent)->deviceid);
+
+  if (!gdkdev) {
+    return -1;                 /* we don't handle it - not an XInput event */
+  }
+
+  if (gdkdev->info.mode == GDK_MODE_DISABLED ||
+      input_window->mode == GDK_EXTENSION_EVENTS_CURSOR)
+    return FALSE;
+  
+  if (gdkdev != gdk_input_current_device &&
+      xevent->type != gdkdev->changenotify_type)
+    {
+      gdk_input_current_device = gdkdev;
+    }
+
+  return_val = gdk_input_common_other_event (event, xevent, 
+                                            input_window, gdkdev);
+
+  if (return_val > 0 && event->type == GDK_MOTION_NOTIFY &&
+      (!gdkdev->button_state) && (!input_window->grabbed) &&
+      ((event->motion.x < 0) || (event->motion.y < 0) ||
+       (event->motion.x > ((GdkWindowPrivate *)window)->width) || 
+       (event->motion.y > ((GdkWindowPrivate *)window)->height) ||
+       gdk_input_is_obscured(input_window,event->motion.x,event->motion.y)))
+    {
+#ifdef DEBUG_SWITCHING
+      g_print("gdkinput: Setting core pointer to %d on motion at (%f,%f)\n",
+             gdkdev->info.deviceid,event->motion.x,event->motion.y);
+      g_print("   window geometry is: %dx%d\n",
+             ((GdkWindowPrivate *)window)->width,
+             ((GdkWindowPrivate *)window)->height);
+#endif      
+      gdk_input_gxi_set_core_pointer(gdkdev);
+      return FALSE;
+    }
+  else
+    return return_val;
+
+}
+
+static void
+gdk_input_gxi_update_device (GdkDevicePrivate *gdkdev)
+{
+  GList *t;
+
+  if (gdk_input_is_extension_device (gdkdev->info.deviceid))
+    {
+      if (!gdkdev->xdevice)
+       {
+         gdkdev->xdevice = XOpenDevice(gdk_display, gdkdev->info.deviceid);
+         gdk_input_gxi_select_notify (gdkdev);
+         gdkdev->needs_update = 1;
+       }
+      if (gdkdev->needs_update && gdkdev->xdevice)
+       {
+         for (t = gdk_input_windows; t; t = t->next)
+           gdk_input_common_select_events (((GdkInputWindow *)t->data)->window,
+                                        gdkdev);
+         gdkdev->needs_update = 0;
+       }
+    }
+}
+
+static gint 
+gdk_input_gxi_window_none_event (GdkEvent *event, XEvent *xevent)
+{
+  GdkDevicePrivate *gdkdev = 
+    gdk_input_find_device(((XDeviceButtonEvent *)xevent)->deviceid);
+
+  if (!gdkdev) {
+    return -1;                 /* we don't handle it - not an XInput event */
+  }
+
+  if (xevent->type == gdkdev->changenotify_type)
+    {
+      if (gdk_input_core_pointer != gdkdev)
+       {
+#ifdef DEBUG_SWITCHING
+         g_print("ChangeNotify from %d to %d:\n",
+                 gdk_input_core_pointer->info.deviceid,
+                 gdkdev->info.deviceid);
+#endif
+         gdk_input_gxi_update_device (gdk_input_core_pointer);
+         gdk_input_core_pointer = gdkdev;
+       }
+    }
+               
+  return FALSE;
+}
+
+static gint
+gdk_input_gxi_enable_window (GdkWindow *window, GdkDevicePrivate *gdkdev)
+{
+  GdkInputWindow *input_window;
+
+  input_window = gdk_input_window_find (window);
+  g_return_val_if_fail (input_window != NULL, FALSE);
+
+  if (!gdkdev->claimed)
+    {
+      if (gxid_claim_device(gdk_input_gxid_host, gdk_input_gxid_port,
+                           gdkdev->info.deviceid,
+                           GDK_WINDOW_XWINDOW(window), FALSE) !=
+         GXID_RETURN_OK)
+       {
+         g_warning("Could not get device (is gxid running?)\n");
+         return FALSE;
+       }
+      gdkdev->claimed = TRUE;
+    }
+
+  if (gdkdev->xdevice && gdkdev != gdk_input_core_pointer)
+    gdk_input_common_select_events(window, gdkdev);
+  else
+    gdkdev->needs_update = TRUE;
+  
+  return TRUE;
+}
+
+static gint
+gdk_input_gxi_disable_window(GdkWindow *window, GdkDevicePrivate *gdkdev)
+{
+  GdkInputWindow *input_window;
+
+  input_window = gdk_input_window_find (window);
+  g_return_val_if_fail (input_window != NULL, FALSE);
+
+  if (gdkdev->claimed)
+    {
+      gxid_release_device(gdk_input_gxid_host, gdk_input_gxid_port,
+                         gdkdev->info.deviceid,
+                         GDK_WINDOW_XWINDOW(window));
+
+      gdkdev->claimed = FALSE;
+    }
+
+  if (gdkdev->xdevice && gdkdev != gdk_input_core_pointer)
+    gdk_input_common_select_events(window, gdkdev);
+  else
+    gdkdev->needs_update = TRUE;
+  
+  return TRUE;
+}
+
+static gint
+gdk_input_is_obscured(GdkInputWindow *input_window, gdouble x, gdouble y)
+{
+  int i;
+  for (i=0;i<input_window->num_obscuring;i++)
+    {
+      GdkRectangle *rect = &input_window->obscuring[i];
+      if ((x >= rect->x) &&
+         (y >= rect->y) &&
+         (x < rect->x + rect->width) &&
+         (y < rect->y + rect->height))
+       return TRUE;
+    }
+  return FALSE;
+}
+
+/* If this routine needs fixing, the corresponding routine
+   in gxid.c will need it too. */
+
+static Window 
+gdk_input_find_root_child(Display *dpy, Window w)
+{
+  Window root,parent;
+  Window *children;
+  int nchildren;
+
+  parent = w;
+  do 
+    {
+      w = parent;
+      XQueryTree(dpy,w,&root,&parent,&children,&nchildren);
+      if (children) XFree(children);
+    } 
+  while (parent != root);
+  
+  return w;
+}
+
+void
+gdk_input_compute_obscuring(GdkInputWindow *input_window)
+{
+  int i;
+  int x,y,width,height;
+  int xc,yc,widthc,heightc,border_widthc,depthc;
+
+  Window root,parent;
+  Window *children;
+  int nchildren;
+
+  Window w = GDK_WINDOW_XWINDOW(input_window->window);
+  Window root_child = gdk_input_find_root_child(gdk_display,w);
+  gdk_input_get_root_relative_geometry(gdk_display,w,&x,&y,&width,&height);
+
+  input_window->root_x = x;
+  input_window->root_y = y;
+
+  XQueryTree(gdk_display,GDK_ROOT_WINDOW(),
+            &root,&parent,&children,&nchildren);
+
+
+  if (input_window->obscuring)
+    g_free(input_window->obscuring);
+  input_window->obscuring = 0;
+  input_window->num_obscuring = 0;
+
+  for (i=0;i<nchildren;i++)
+    if (children[i] == root_child)
+      break;
+
+  if (i>=nchildren-1)
+    {
+      if (nchildren)
+       XFree(children);
+      return;
+    }
+
+  input_window->obscuring = g_new(GdkRectangle,(nchildren-i-1));
+
+  for (i=i+1;i<nchildren;i++)
+    {
+      int xmin, xmax, ymin, ymax;
+      XGetGeometry(gdk_display,children[i],&root,&xc,&yc,&widthc,&heightc,
+                  &border_widthc, &depthc);
+      xmin = xc>x ? xc : x;
+      xmax = (xc+widthc)<(x+width) ? xc+widthc : x+width;
+      ymin = yc>y ? yc : y;
+      ymax = (yc+heightc)<(y+height) ? yc+heightc : y+height;
+      if ((xmin < xmax) && (ymin < ymax))
+       {
+         XWindowAttributes attributes;
+         XGetWindowAttributes(gdk_display,children[i],&attributes);
+         if (attributes.map_state == IsViewable)
+           {
+             GdkRectangle *rect = &input_window->obscuring[input_window->num_obscuring];
+             
+             /* we store the whole window, not just the obscuring part */
+             rect->x = xc - x;
+             rect->y = yc - y;
+             rect->width = widthc;
+             rect->height = heightc;
+             input_window->num_obscuring++;
+           }
+       }
+    }
+
+  if (nchildren)
+    XFree(children);
+}
+
+static void 
+gdk_input_gxi_get_pointer     (GdkWindow       *window,
+                              guint32     deviceid,
+                              gdouble         *x,
+                              gdouble         *y,
+                              gdouble         *pressure,
+                              gdouble         *xtilt,
+                              gdouble         *ytilt,
+                              GdkModifierType *mask)
+{
+  GdkDevicePrivate *gdkdev;
+
+  gdkdev = gdk_input_find_device (deviceid);
+  g_return_if_fail (gdkdev != NULL);
+
+  if (gdkdev == gdk_input_core_pointer)
+    gdk_input_common_get_pointer (window, GDK_CORE_POINTER, x, y,
+                                 pressure, xtilt, ytilt, mask);
+  else
+    gdk_input_common_get_pointer (window, deviceid, x, y,
+                                 pressure, xtilt, ytilt, mask);
+}
+
+static GdkTimeCoord *
+gdk_input_gxi_motion_events (GdkWindow *window,
+                            guint32 deviceid,
+                            guint32 start,
+                            guint32 stop,
+                            gint *nevents_return)
+{
+  GdkDevicePrivate *gdkdev;
+
+  gdkdev = gdk_input_find_device (deviceid);
+  g_return_val_if_fail (gdkdev != NULL, NULL);
+  
+
+  if (gdkdev == gdk_input_core_pointer)
+    return gdk_input_motion_events (window, GDK_CORE_POINTER, start, stop,
+                                   nevents_return);
+  else
+    return gdk_input_common_motion_events (window, deviceid, start, stop,
+                                          nevents_return);
+  
+}
+
+static gint 
+gdk_input_gxi_grab_pointer (GdkWindow *     window,
+                           gint            owner_events,
+                           GdkEventMask    event_mask,
+                           GdkWindow *     confine_to,
+                           guint32         time)
+{
+  GdkInputWindow *input_window, *new_window;
+  GList *tmp_list;
+
+  tmp_list = gdk_input_windows;
+  while (tmp_list)
+    {
+      input_window = (GdkInputWindow *)tmp_list->data;
+      if (input_window->grabbed)
+       return AlreadyGrabbed;
+
+      if (input_window->window == window)
+       new_window = input_window;
+      
+      tmp_list = tmp_list->next;
+    }
+
+  new_window->grabbed = TRUE;
+  return Success;
+}
+
+static void 
+gdk_input_gxi_ungrab_pointer (guint32 time)
+{
+  GdkInputWindow *input_window;
+  GList *tmp_list;
+
+  tmp_list = gdk_input_windows;
+  while (tmp_list)
+    {
+      input_window = (GdkInputWindow *)tmp_list->data;
+      if (input_window->grabbed)
+       input_window->grabbed = FALSE;
+      tmp_list = tmp_list->next;
+    }
+}
+
+#endif /* XINPUT_GXI */
diff --git a/gdk/gdkinputnone.h b/gdk/gdkinputnone.h
new file mode 100644 (file)
index 0000000..8ae8c41
--- /dev/null
@@ -0,0 +1,72 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef XINPUT_NONE
+
+static void gdk_input_none_get_pointer (GdkWindow       *window,
+                                       guint32   deviceid,
+                                       gdouble         *x,
+                                       gdouble         *y,
+                                       gdouble         *pressure,
+                                       gdouble         *xtilt,
+                                       gdouble         *ytilt,
+                                       GdkModifierType *mask);
+
+void
+gdk_input_init ()
+{
+  gdk_input_vtable.set_mode           = NULL;
+  gdk_input_vtable.set_axes           = NULL;
+  gdk_input_vtable.motion_events      = NULL;
+  gdk_input_vtable.get_pointer        = gdk_input_none_get_pointer;
+  gdk_input_vtable.grab_pointer       = NULL;
+  gdk_input_vtable.ungrab_pointer     = NULL;
+  gdk_input_vtable.configure_event    = NULL;
+  gdk_input_vtable.enter_event        = NULL;
+  gdk_input_vtable.other_event        = NULL;
+  gdk_input_vtable.window_none_event  = NULL;
+  gdk_input_vtable.enable_window      = NULL;
+  gdk_input_vtable.disable_window     = NULL;
+
+  gdk_input_devices = g_list_append (NULL, &gdk_input_core_info);
+
+  gdk_input_ignore_core = FALSE;
+}
+
+static void
+gdk_input_none_get_pointer (GdkWindow       *window,
+                           guint32          deviceid,
+                           gdouble         *x,
+                           gdouble         *y,
+                           gdouble         *pressure,
+                           gdouble         *xtilt,
+                           gdouble         *ytilt,
+                           GdkModifierType *mask)
+{
+  gint x_int, y_int;
+
+  gdk_window_get_pointer (window, &x_int, &y_int, mask);
+
+  if (x) *x = x_int;
+  if (y) *y = y_int;
+  if (pressure) *pressure = 0.5;
+  if (xtilt) *xtilt = 0;
+  if (ytilt) *ytilt = 0;
+}
+
+#endif /* XINPUT_NONE */
diff --git a/gdk/gdkinputxfree.h b/gdk/gdkinputxfree.h
new file mode 100644 (file)
index 0000000..f742490
--- /dev/null
@@ -0,0 +1,368 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef XINPUT_XFREE
+
+/* forward declarations */
+
+static gint gdk_input_xfree_set_mode (guint32 deviceid, GdkInputMode mode);
+static void gdk_input_check_proximity();
+static void gdk_input_xfree_configure_event (XConfigureEvent *xevent, 
+                                            GdkWindow *window);
+static void gdk_input_xfree_enter_event (XCrossingEvent *xevent, 
+                                      GdkWindow *window);
+static gint gdk_input_xfree_other_event (GdkEvent *event, 
+                                        XEvent *xevent, 
+                                        GdkWindow *window);
+static gint gdk_input_xfree_enable_window(GdkWindow *window, 
+                                         GdkDevicePrivate *gdkdev);
+static gint gdk_input_xfree_disable_window(GdkWindow *window,
+                                          GdkDevicePrivate *gdkdev);
+static gint gdk_input_xfree_grab_pointer (GdkWindow *     window,
+                                       gint            owner_events,
+                                       GdkEventMask    event_mask,
+                                       GdkWindow *     confine_to,
+                                       guint32         time);
+static void gdk_input_xfree_ungrab_pointer (guint32 time);
+
+void 
+gdk_input_init(void)
+{
+  gdk_input_vtable.set_mode           = gdk_input_xfree_set_mode;
+  gdk_input_vtable.set_axes        = gdk_input_common_set_axes;
+  gdk_input_vtable.motion_events      = gdk_input_common_motion_events;
+  gdk_input_vtable.get_pointer       = gdk_input_common_get_pointer;
+  gdk_input_vtable.grab_pointer              = gdk_input_xfree_grab_pointer;
+  gdk_input_vtable.ungrab_pointer     = gdk_input_xfree_ungrab_pointer;
+  gdk_input_vtable.configure_event    = gdk_input_xfree_configure_event;
+  gdk_input_vtable.enter_event        = gdk_input_xfree_enter_event;
+  gdk_input_vtable.other_event        = gdk_input_xfree_other_event;
+  gdk_input_vtable.window_none_event  = NULL;
+  gdk_input_vtable.enable_window      = gdk_input_xfree_enable_window;
+  gdk_input_vtable.disable_window     = gdk_input_xfree_disable_window;
+
+  gdk_input_ignore_core = FALSE;
+  gdk_input_common_init(FALSE);
+}
+
+static gint
+gdk_input_xfree_set_mode (guint32 deviceid, GdkInputMode mode)
+{
+  GList *tmp_list;
+  GdkDevicePrivate *gdkdev;
+  GdkInputMode old_mode;
+  GdkInputWindow *input_window;
+
+  gdkdev = gdk_input_find_device(deviceid);
+  g_return_val_if_fail (gdkdev != NULL,FALSE);
+  old_mode = gdkdev->info.mode;
+
+  if (gdkdev->info.mode == mode)
+    return TRUE;
+
+  gdkdev->info.mode = mode;
+
+  if (mode == GDK_MODE_WINDOW)
+    {
+      gdkdev->info.has_cursor = FALSE;
+      for (tmp_list = gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
+       {
+         input_window = (GdkInputWindow *)tmp_list->data;
+         if (input_window->mode != GDK_EXTENSION_EVENTS_CURSOR)
+           gdk_input_enable_window (input_window->window, gdkdev);
+         else
+           if (old_mode != GDK_MODE_DISABLED)
+             gdk_input_disable_window (input_window->window, gdkdev);
+       }
+    }
+  else if (mode == GDK_MODE_SCREEN)
+    {
+      gdkdev->info.has_cursor = TRUE;
+      for (tmp_list = gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
+       gdk_input_enable_window (((GdkInputWindow *)tmp_list->data)->window,
+                                gdkdev);
+    }
+  else  /* mode == GDK_MODE_DISABLED */
+    {
+      for (tmp_list = gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
+       {
+         input_window = (GdkInputWindow *)tmp_list->data;
+         if (old_mode != GDK_MODE_WINDOW ||
+             input_window->mode != GDK_EXTENSION_EVENTS_CURSOR)
+           gdk_input_disable_window (input_window->window, gdkdev);
+       }
+    }
+
+  return TRUE;
+  
+}
+
+static void
+gdk_input_check_proximity()
+{
+  gint new_proximity = 0;
+  GList *tmp_list = gdk_input_devices;
+
+  while (tmp_list && !new_proximity) 
+    {
+      GdkDevicePrivate *gdkdev = (GdkDevicePrivate *)(tmp_list->data);
+
+      if (gdkdev->info.mode != GDK_MODE_DISABLED 
+         && gdkdev->info.deviceid != GDK_CORE_POINTER
+         && gdkdev->xdevice)
+       {
+         XDeviceState *state = XQueryDeviceState(GDK_DISPLAY(),
+                                                 gdkdev->xdevice);
+         XInputClass *xic;
+         int i;
+         
+         xic = state->data;
+         for (i=0; i<state->num_classes; i++)
+           {
+             if (xic->class == ValuatorClass)
+               {
+                 XValuatorState *xvs = (XValuatorState *)xic;
+                 if ((xvs->mode & ProximityState) == InProximity)
+                   {
+                     new_proximity = TRUE;
+                   }
+                 break;
+               }
+             xic = (XInputClass *)((char *)xic + xic->length);
+           }
+       }
+      tmp_list = tmp_list->next;
+    }
+
+  gdk_input_ignore_core = new_proximity;
+}
+
+static void
+gdk_input_xfree_configure_event (XConfigureEvent *xevent, GdkWindow *window)
+{
+  GdkInputWindow *input_window;
+  gint root_x, root_y;
+
+  input_window = gdk_input_window_find(window);
+  g_return_if_fail (window != NULL);
+
+  gdk_input_get_root_relative_geometry(GDK_DISPLAY(),GDK_WINDOW_XWINDOW(window),
+                                &root_x, 
+                                &root_y, NULL, NULL);
+
+  input_window->root_x = root_x;
+  input_window->root_y = root_y;
+}
+
+static void 
+gdk_input_xfree_enter_event (XCrossingEvent *xevent, 
+                                      GdkWindow *window)
+{
+  GdkInputWindow *input_window;
+  gint root_x, root_y;
+
+  input_window = gdk_input_window_find(window);
+  g_return_if_fail (window != NULL);
+
+  gdk_input_check_proximity();
+
+  gdk_input_get_root_relative_geometry(GDK_DISPLAY(),GDK_WINDOW_XWINDOW(window),
+                                &root_x, 
+                                &root_y, NULL, NULL);
+
+  input_window->root_x = root_x;
+  input_window->root_y = root_y;
+}
+
+static gint 
+gdk_input_xfree_other_event (GdkEvent *event, 
+                            XEvent *xevent, 
+                            GdkWindow *window)
+{
+  GdkInputWindow *input_window;
+
+  GdkDevicePrivate *gdkdev;
+  gint return_val;
+
+  input_window = gdk_input_window_find(window);
+  g_return_val_if_fail (window != NULL, -1);
+
+  /* This is a sort of a hack, as there isn't any XDeviceAnyEvent -
+     but it's potentially faster than scanning through the types of
+     every device. If we were deceived, then it won't match any of
+     the types for the device anyways */
+  gdkdev = gdk_input_find_device(((XDeviceButtonEvent *)xevent)->deviceid);
+
+  if (!gdkdev) {
+    return -1;                 /* we don't handle it - not an XInput event */
+  }
+
+  /* FIXME: It would be nice if we could just get rid of the events 
+     entirely, instead of having to ignore them */
+  if (gdkdev->info.mode == GDK_MODE_DISABLED ||
+      (gdkdev->info.mode == GDK_MODE_WINDOW 
+       && input_window->mode == GDK_EXTENSION_EVENTS_CURSOR))
+    return FALSE;
+  
+  if (!gdk_input_ignore_core)
+    gdk_input_check_proximity();
+
+  return_val = gdk_input_common_other_event (event, xevent, 
+                                            input_window, gdkdev);
+
+  if (return_val > 0 && event->type == GDK_PROXIMITY_OUT &&
+      gdk_input_ignore_core)
+    gdk_input_check_proximity();
+
+  /* Do a passive button grab. We have to be careful not to release
+     an explicit grab, if any. Doubling the grab should be harmless,
+     but we check anyways. */
+
+  /* FIXME, finding the proper events here is going to be SLOW - but
+     we might have different sets for each window/device combination */
+  
+  if (return_val> 0 && !input_window->grabbed)
+    {
+      if (event->type == GDK_BUTTON_PRESS)
+       {
+         XEventClass event_classes[6];
+         gint num_classes;
+         
+         gdk_input_common_find_events (window, gdkdev, 
+                                       ((GdkWindowPrivate *)window)->extension_events, 
+                                       event_classes, &num_classes);
+         
+       XGrabDevice( GDK_DISPLAY(), gdkdev->xdevice,
+                    GDK_WINDOW_XWINDOW (window),
+                    TRUE, num_classes, event_classes,
+                    GrabModeAsync, GrabModeAsync, event->button.time);
+       }
+      else if (event->type == GDK_BUTTON_RELEASE)
+       XUngrabDevice( GDK_DISPLAY(), gdkdev->xdevice, event->button.time);
+    }
+
+  return return_val;
+}
+
+static gint
+gdk_input_xfree_enable_window(GdkWindow *window, GdkDevicePrivate *gdkdev)
+{
+  /* FIXME: watchout, gdkdev might be core pointer, never opened */
+  gdk_input_common_select_events (window, gdkdev);
+  return TRUE;
+}
+
+static gint
+gdk_input_xfree_disable_window(GdkWindow *window, GdkDevicePrivate *gdkdev)
+{
+  gdk_input_common_select_events (window, gdkdev);
+  return TRUE;
+}
+
+static gint 
+gdk_input_xfree_grab_pointer (GdkWindow *     window,
+                             gint            owner_events,
+                             GdkEventMask    event_mask,
+                             GdkWindow *     confine_to,
+                             guint32         time)
+{
+  GdkInputWindow *input_window, *new_window;
+  GdkDevicePrivate *gdkdev;
+  GList *tmp_list;
+  XEventClass event_classes[6];
+  gint num_classes;
+
+  tmp_list = gdk_input_windows;
+  new_window = NULL;
+  while (tmp_list)
+    {
+      input_window = (GdkInputWindow *)tmp_list->data;
+      if (input_window->grabbed)
+       return AlreadyGrabbed;
+
+      if (input_window->window == window)
+       {
+         new_window = input_window;
+         break;
+       }
+      
+      tmp_list = tmp_list->next;
+    }
+  
+  g_return_if_fail (new_window == NULL);
+  
+  new_window->grabbed = TRUE;
+
+  tmp_list = gdk_input_devices;
+  while (tmp_list)
+    {
+      gdkdev = (GdkDevicePrivate *)tmp_list->data;
+      if (gdkdev->info.deviceid != GDK_CORE_POINTER &&
+         gdkdev->xdevice && !gdkdev->button_state)
+       {
+         gdk_input_common_find_events (window, gdkdev, 
+                                       ((GdkWindowPrivate *)window)->extension_events, 
+                                       event_classes, &num_classes);
+
+         /* FIXME: we should do something on failure */
+         XGrabDevice( GDK_DISPLAY(), gdkdev->xdevice,
+                      GDK_WINDOW_XWINDOW (window),
+                      TRUE, num_classes, event_classes,
+                      GrabModeAsync, GrabModeAsync, time);
+       }
+      tmp_list = tmp_list->next;
+    }
+  
+  return Success;
+}
+
+static void 
+gdk_input_xfree_ungrab_pointer (guint32 time)
+{
+  GdkInputWindow *input_window;
+  GdkDevicePrivate *gdkdev;
+  GList *tmp_list;
+
+  tmp_list = gdk_input_windows;
+  while (tmp_list)
+    {
+      input_window = (GdkInputWindow *)tmp_list->data;
+      if (input_window->grabbed)
+       break;
+      tmp_list = tmp_list->next;
+    }
+
+  if (tmp_list)                        /* we found a grabbed window */
+    {
+      input_window->grabbed = FALSE;
+
+      tmp_list = gdk_input_devices;
+      while (tmp_list)
+       {
+         gdkdev = (GdkDevicePrivate *)tmp_list->data;
+         if (gdkdev->info.deviceid != GDK_CORE_POINTER &&
+             gdkdev->xdevice && !gdkdev->button_state)
+           {
+             XUngrabDevice( gdk_display, gdkdev->xdevice, time);
+           }
+         tmp_list = tmp_list->next;
+       }
+    }
+}
+
+#endif /* XINPUT_XFREE */
diff --git a/gdk/gdkpixmap.c b/gdk/gdkpixmap.c
new file mode 100644 (file)
index 0000000..d2d96b6
--- /dev/null
@@ -0,0 +1,657 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "../config.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <X11/Xlib.h>
+
+#include "gdk.h"
+#include "gdkprivate.h"
+
+typedef struct
+{
+  gchar *color_string;
+  GdkColor color;
+  gint transparent;
+} _GdkPixmapColor;
+
+GdkPixmap*
+gdk_pixmap_new (GdkWindow *window,
+               gint       width,
+               gint       height,
+               gint       depth)
+{
+  GdkPixmap *pixmap;
+  GdkWindowPrivate *private;
+  GdkWindowPrivate *window_private;
+
+  if (!window)
+    window = (GdkWindow*) &gdk_root_parent;
+
+  if (depth == -1)
+    gdk_window_get_geometry (window, NULL, NULL, NULL, NULL, &depth);
+
+  private = g_new (GdkWindowPrivate, 1);
+  pixmap = (GdkPixmap*) private;
+
+  window_private = (GdkWindowPrivate*) window;
+
+  private->xdisplay = window_private->xdisplay;
+  private->window_type = GDK_WINDOW_PIXMAP;
+  private->xwindow = XCreatePixmap (private->xdisplay, window_private->xwindow,
+                                   width, height, depth);
+  private->parent = NULL;
+  private->x = 0;
+  private->y = 0;
+  private->width = width;
+  private->height = height;
+  private->resize_count = 0;
+  private->ref_count = 1;
+  private->destroyed = 0;
+
+  gdk_xid_table_insert (&private->xwindow, pixmap);
+
+  return pixmap;
+}
+
+GdkPixmap *
+gdk_bitmap_create_from_data (GdkWindow *window,
+                            gchar     *data,
+                            gint       width,
+                            gint       height)
+{
+  GdkPixmap *pixmap;
+  GdkWindowPrivate *private;
+  GdkWindowPrivate *window_private;
+
+  g_return_val_if_fail (data != NULL, NULL);
+
+  if (!window)
+    window = (GdkWindow*) &gdk_root_parent;
+
+  private = g_new (GdkWindowPrivate, 1);
+  pixmap = (GdkPixmap*) private;
+
+  window_private = (GdkWindowPrivate*) window;
+
+  private->parent = NULL;
+  private->xdisplay = window_private->xdisplay;
+  private->window_type = GDK_WINDOW_PIXMAP;
+  private->x = 0;
+  private->y = 0;
+  private->width = width;
+  private->height = height;
+  private->resize_count = 0;
+  private->ref_count = 1;
+  private->destroyed = FALSE;
+
+  private->xwindow = XCreateBitmapFromData (private->xdisplay,
+                                           window_private->xwindow,
+                                           data, width, height);
+
+  gdk_xid_table_insert (&private->xwindow, pixmap);
+
+  return pixmap;
+}
+
+GdkPixmap*
+gdk_pixmap_create_from_data (GdkWindow *window,
+                            gchar     *data,
+                            gint       width,
+                            gint       height,
+                            gint       depth,
+                            GdkColor  *fg,
+                            GdkColor  *bg)
+{
+  GdkPixmap *pixmap;
+  GdkWindowPrivate *private;
+  GdkWindowPrivate *window_private;
+
+  g_return_val_if_fail (data != NULL, NULL);
+  g_return_val_if_fail (fg != NULL, NULL);
+  g_return_val_if_fail (bg != NULL, NULL);
+
+  if (!window)
+    window = (GdkWindow*) &gdk_root_parent;
+
+  if (depth == -1)
+    gdk_window_get_geometry (window, NULL, NULL, NULL, NULL, &depth);
+
+  private = g_new (GdkWindowPrivate, 1);
+  pixmap = (GdkPixmap*) private;
+
+  window_private = (GdkWindowPrivate*) window;
+
+  private->parent = NULL;
+  private->xdisplay = window_private->xdisplay;
+  private->window_type = GDK_WINDOW_PIXMAP;
+  private->x = 0;
+  private->y = 0;
+  private->width = width;
+  private->height = height;
+  private->resize_count = 0;
+  private->ref_count = 1;
+  private->destroyed = FALSE;
+
+  private->xwindow = XCreatePixmapFromBitmapData (private->xdisplay,
+                                                 window_private->xwindow,
+                                                 data, width, height,
+                                                 fg->pixel, bg->pixel, depth);
+
+  gdk_xid_table_insert (&private->xwindow, pixmap);
+
+  return pixmap;
+}
+
+gint
+gdk_pixmap_seek_string (FILE  *infile,
+                        const gchar *str,
+                        gint   skip_comments)
+{
+  char instr[1024];
+
+  while (!feof (infile))
+    {
+      fscanf (infile, "%s", instr);
+      if (skip_comments == TRUE && strcmp (instr, "/*") == 0)
+        {
+          fscanf (infile, "%s", instr);
+          while (!feof (infile) && strcmp (instr, "*/") != 0)
+            fscanf (infile, "%s", instr);
+          fscanf(infile, "%s", instr);
+        }
+      if (strcmp (instr, str)==0)
+        return TRUE;
+    }
+
+  return FALSE;
+}
+
+gint
+gdk_pixmap_seek_char (FILE  *infile,
+                      gchar  c)
+{
+  gchar b, oldb;
+
+  while (!feof (infile))
+    {
+      fscanf(infile, "%c", &b);
+      if (c != b && b == '/')
+        {
+          fscanf (infile, "%c", &b);
+          if (b == '*')
+            {
+              oldb = b;
+              while (!feof (infile) && !(oldb == '*' && b == '/'))
+                {
+                  oldb = b;
+                  fscanf (infile, "%c", &b);
+                }
+              fscanf (infile, "%c", &b);
+            }
+        }
+      if (c == b)
+        return TRUE;
+    }
+
+  return FALSE;
+}
+
+gint
+gdk_pixmap_read_string (FILE  *infile,
+                        gchar **buffer,
+                       int *buffer_size)
+{
+  gchar c;
+  gint cnt = 0;
+
+  if ((*buffer) == NULL)
+    {
+      (*buffer_size) = 10 * sizeof (gchar);
+      (*buffer) = (gchar *) malloc (*buffer_size);
+    }
+
+  do
+    fscanf (infile, "%c", &c);
+  while (!feof (infile) && c != '"');
+
+  if (c != '"')
+    return FALSE;
+
+  while (!feof (infile))
+    {
+      fscanf (infile, "%c", &c);
+
+      if (cnt == (*buffer_size))
+       {
+         (*buffer_size) *= 2;
+         (*buffer) = (gchar *) realloc ((*buffer), *buffer_size);        
+       }
+
+      if (c != '"')
+        (*buffer)[cnt++] = c;
+      else
+        {
+          (*buffer)[cnt++] = 0;
+          return TRUE;
+        }
+    }
+
+  return FALSE;
+}
+
+gchar*
+gdk_pixmap_skip_whitespaces (gchar *buffer)
+{
+  gint32 index = 0;
+
+  while (buffer[index] != 0 && (buffer[index] == 0x20 || buffer[index] == 0x09))
+    index++;
+
+  return &buffer[index];
+}
+
+gchar*
+gdk_pixmap_skip_string (gchar *buffer)
+{
+  gint32 index = 0;
+
+  while (buffer[index] != 0 && buffer[index] != 0x20 && buffer[index] != 0x09)
+    index++;
+
+  return &buffer[index];
+}
+
+gchar*
+gdk_pixmap_extract_color (gchar *buffer)
+{
+  gint counter, finished = FALSE, numnames;
+  gchar *ptr = NULL, ch, temp[128];
+  gchar color[128], *retcol;
+
+  counter = 0;
+  while (ptr == NULL)
+    {
+      if (buffer[counter] == 'c')
+        {
+          ch = buffer[counter + 1];
+          if (ch == 0x20 || ch == 0x09)
+            ptr = &buffer[counter + 1];
+        }
+      else if (buffer[counter] == 0)
+        return NULL;
+
+      counter++;
+    }
+
+  if (ptr == NULL)
+    return NULL;
+
+  ptr = gdk_pixmap_skip_whitespaces (ptr);
+
+  if (ptr[0] == 0)
+    return NULL;
+  else if (ptr[0] == '#')
+    {
+      retcol = g_new(gchar, strlen (ptr) + 1);
+      strcpy (retcol, ptr);
+      return retcol;
+    }
+
+  color[0] = 0;
+  numnames = 0;
+
+  while (finished == FALSE)
+    {
+      sscanf (ptr, "%s", temp);
+
+      if ((gint)ptr[0] == 0 || strcmp ("s", temp) == 0 || strcmp ("m", temp) == 0 ||
+          strcmp ("g", temp) == 0 || strcmp ("g4", temp) == 0)
+       finished = TRUE;
+      else
+        {
+          if (numnames > 0)
+            strcat (color, " ");
+          strcat (color, temp);
+          ptr = gdk_pixmap_skip_string (ptr);
+          ptr = gdk_pixmap_skip_whitespaces (ptr);
+          numnames++;
+        }
+    }
+
+  retcol = g_new(gchar, strlen (color) + 1);
+  strcpy (retcol, color);
+  return retcol;
+}
+
+
+GdkPixmap*
+gdk_pixmap_create_from_xpm (GdkWindow  *window,
+                           GdkBitmap **mask,
+                           GdkColor   *transparent_color,
+                           const gchar *filename)
+{
+  FILE *infile = NULL;
+  GdkPixmap *pixmap = NULL;
+  GdkImage *image = NULL;
+  GdkColormap *colormap;
+  GdkVisual *visual;
+  GdkGC *gc;
+  GdkColor tmp_color;
+  gint width, height, num_cols, cpp, cnt, n, ns, xcnt, ycnt;
+  gchar *buffer = NULL, *color_name = NULL, pixel_str[32];
+  guint buffer_size = 0;
+  _GdkPixmapColor *colors = NULL, *color = NULL;
+  gulong index;
+
+  if (!window)
+    window = (GdkWindow*) &gdk_root_parent;
+
+  infile = fopen (filename, "rb");
+  if (infile != NULL)
+    {
+      if (gdk_pixmap_seek_string (infile, "XPM", FALSE) == TRUE)
+        {
+          if (gdk_pixmap_seek_char (infile,'{') == TRUE)
+            {
+              gdk_pixmap_seek_char (infile, '"');
+              fseek (infile, -1, SEEK_CUR);
+              gdk_pixmap_read_string (infile, &buffer, &buffer_size);
+
+              sscanf (buffer,"%d %d %d %d", &width, &height, &num_cols, &cpp);
+
+              colors = g_new(_GdkPixmapColor, num_cols);
+
+              colormap = gdk_window_get_colormap (window);
+              visual = gdk_window_get_visual (window);
+
+             if (transparent_color == NULL) 
+               {
+                 gdk_color_white (colormap, &tmp_color);
+                 transparent_color = &tmp_color;
+               }
+
+              for (cnt = 0; cnt < num_cols; cnt++)
+                {
+                  gdk_pixmap_seek_char (infile, '"');
+                  fseek (infile, -1, SEEK_CUR);
+                  gdk_pixmap_read_string (infile, &buffer, &buffer_size);
+
+                  colors[cnt].color_string = g_new(gchar, cpp + 1);
+                  for (n = 0; n < cpp; n++)
+                    colors[cnt].color_string[n] = buffer[n];
+                  colors[cnt].color_string[n] = 0;
+                 colors[cnt].transparent = FALSE;
+
+                  if (color_name != NULL)
+                    g_free (color_name);
+
+                  color_name = gdk_pixmap_extract_color (&buffer[cpp]);
+
+                  if (color_name != NULL)
+                    {
+                      if (gdk_color_parse (color_name, &colors[cnt].color) == FALSE)
+                       {
+                         colors[cnt].color = *transparent_color;
+                         colors[cnt].transparent = TRUE;
+                       }
+                    }
+                  else
+                   {
+                     colors[cnt].color = *transparent_color;
+                     colors[cnt].transparent = TRUE;
+                   }
+
+                  gdk_color_alloc (colormap, &colors[cnt].color);
+                }
+
+              index = 0;
+              image = gdk_image_new (GDK_IMAGE_FASTEST, visual, width, height);
+
+             gc = NULL;
+             if (mask)
+               {
+                 *mask = gdk_pixmap_new (window, width, height, 1);
+                 gc = gdk_gc_new (*mask);
+
+                 gdk_color_black (colormap, &tmp_color);
+                 gdk_gc_set_foreground (gc, &tmp_color);
+                 gdk_draw_rectangle (*mask, gc, TRUE, 0, 0, -1, -1);
+
+                 gdk_color_white (colormap, &tmp_color);
+                 gdk_gc_set_foreground (gc, &tmp_color);
+               }
+
+              for (ycnt = 0; ycnt < height; ycnt++)
+                {
+                  gdk_pixmap_read_string (infile, &buffer, &buffer_size);
+
+                  for (n = 0, cnt = 0, xcnt = 0; n < (width * cpp); n += cpp, xcnt++)
+                    {
+                      strncpy (pixel_str, &buffer[n], cpp);
+                      pixel_str[cpp] = 0;
+                      color = NULL;
+                      ns = 0;
+
+                      while (color == NULL)
+                        {
+                          if (strcmp (pixel_str, colors[ns].color_string) == 0)
+                            color = &colors[ns];
+                          else
+                            ns++;
+                        }
+
+                      gdk_image_put_pixel (image, xcnt, ycnt, color->color.pixel);
+
+                     if (mask && color->transparent)
+                       {
+                         if (cnt < xcnt)
+                           gdk_draw_line (*mask, gc, cnt, ycnt, xcnt - 1, ycnt);
+                         cnt = xcnt + 1;
+                       }
+                    }
+
+                 if (mask && (cnt < xcnt))
+                   gdk_draw_line (*mask, gc, cnt, ycnt, xcnt - 1, ycnt);
+                }
+
+             if (mask)
+               gdk_gc_destroy (gc);
+
+              pixmap = gdk_pixmap_new (window, width, height, visual->depth);
+
+              gc = gdk_gc_new (pixmap);
+              gdk_gc_set_foreground (gc, transparent_color);
+              gdk_draw_image (pixmap, gc, image, 0, 0, 0, 0, image->width, image->height);
+              gdk_gc_destroy (gc);
+              gdk_image_destroy (image);
+            }
+        }
+
+      fclose (infile);
+      free (buffer);
+
+      if (colors != NULL)
+        {
+          for (cnt = 0; cnt < num_cols; cnt++)
+            g_free (colors[cnt].color_string);
+          g_free (colors);
+        }
+    }
+
+  return pixmap;
+}
+
+GdkPixmap*
+gdk_pixmap_create_from_xpm_d (GdkWindow  *window,
+                             GdkBitmap **mask,
+                             GdkColor   *transparent_color,
+                             gchar     **data)
+{
+  GdkPixmap *pixmap = NULL;
+  GdkImage *image = NULL;
+  GdkColormap *colormap;
+  GdkVisual *visual;
+  GdkGC *gc;
+  GdkColor tmp_color;
+  gint width, height, num_cols, cpp, cnt, n, ns, xcnt, ycnt, i;
+  gchar *buffer, *color_name = NULL, pixel_str[32];
+  _GdkPixmapColor *colors = NULL, *color = NULL;
+  gulong index;
+
+  if (!window)
+    window = (GdkWindow*) &gdk_root_parent;
+
+  i = 0;
+  buffer = data[i++];
+  sscanf (buffer,"%d %d %d %d", &width, &height, &num_cols, &cpp);
+
+  colors = g_new(_GdkPixmapColor, num_cols);
+
+  colormap = gdk_window_get_colormap (window);
+  visual = gdk_window_get_visual (window);
+
+  if (transparent_color == NULL) 
+    {
+      gdk_color_white (colormap, &tmp_color);
+      transparent_color = &tmp_color;
+    }
+
+  for (cnt = 0; cnt < num_cols; cnt++)
+    {
+      buffer = data[i++];
+
+      colors[cnt].color_string = g_new(gchar, cpp + 1);
+      for (n = 0; n < cpp; n++)
+       colors[cnt].color_string[n] = buffer[n];
+      colors[cnt].color_string[n] = 0;
+      colors[cnt].transparent = FALSE;
+
+      if (color_name != NULL)
+       g_free (color_name);
+
+      color_name = gdk_pixmap_extract_color (&buffer[cpp]);
+
+      if (color_name != NULL)
+       {
+         if (gdk_color_parse (color_name, &colors[cnt].color) == FALSE)
+           {
+             colors[cnt].color = *transparent_color;
+             colors[cnt].transparent = TRUE;
+           }
+       }
+      else
+       {
+         colors[cnt].color = *transparent_color;
+         colors[cnt].transparent = TRUE;
+       }
+
+      gdk_color_alloc (colormap, &colors[cnt].color);
+    }
+
+  index = 0;
+  image = gdk_image_new (GDK_IMAGE_FASTEST, visual, width, height);
+
+  gc = NULL;
+  if (mask)
+    {
+      *mask = gdk_pixmap_new (window, width, height, 1);
+      gc = gdk_gc_new (*mask);
+
+      gdk_color_black (colormap, &tmp_color);
+      gdk_gc_set_foreground (gc, &tmp_color);
+      gdk_draw_rectangle (*mask, gc, TRUE, 0, 0, -1, -1);
+
+      gdk_color_white (colormap, &tmp_color);
+      gdk_gc_set_foreground (gc, &tmp_color);
+    }
+
+  for (ycnt = 0; ycnt < height; ycnt++)
+    {
+      buffer = data[i++];
+
+      for (n = 0, cnt = 0, xcnt = 0; n < (width * cpp); n += cpp, xcnt++)
+       {
+         strncpy (pixel_str, &buffer[n], cpp);
+         pixel_str[cpp] = 0;
+         color = NULL;
+         ns = 0;
+
+         while (color == NULL)
+           {
+             if (strcmp (pixel_str, colors[ns].color_string) == 0)
+               color = &colors[ns];
+             else
+               ns++;
+           }
+
+         gdk_image_put_pixel (image, xcnt, ycnt, color->color.pixel);
+
+         if (mask && color->transparent)
+           {
+             if (cnt < xcnt)
+               gdk_draw_line (*mask, gc, cnt, ycnt, xcnt - 1, ycnt);
+             cnt = xcnt + 1;
+           }
+       }
+
+      if (mask && (cnt < xcnt))
+       gdk_draw_line (*mask, gc, cnt, ycnt, xcnt - 1, ycnt);
+    }
+
+  if (mask)
+    gdk_gc_destroy (gc);
+
+  pixmap = gdk_pixmap_new (window, width, height, visual->depth);
+
+  gc = gdk_gc_new (pixmap);
+  gdk_gc_set_foreground (gc, transparent_color);
+  gdk_draw_image (pixmap, gc, image, 0, 0, 0, 0, image->width, image->height);
+  gdk_gc_destroy (gc);
+  gdk_image_destroy (image);
+
+  if (colors != NULL)
+    {
+      for (cnt = 0; cnt < num_cols; cnt++)
+       g_free (colors[cnt].color_string);
+      g_free (colors);
+    }
+
+  return pixmap;
+}
+
+void
+gdk_pixmap_destroy (GdkPixmap *pixmap)
+{
+  GdkWindowPrivate *private;
+
+  g_return_if_fail (pixmap != NULL);
+
+  private = (GdkPixmapPrivate*) pixmap;
+  if (private->ref_count <= 0)
+    {
+      XFreePixmap (private->xdisplay, private->xwindow);
+      gdk_xid_table_remove (private->xwindow);
+      g_free (pixmap);
+    }
+  else
+    {
+      private->ref_count -= 1;
+    }
+}
diff --git a/gdk/gdkprivate.h b/gdk/gdkprivate.h
new file mode 100644 (file)
index 0000000..3c1677e
--- /dev/null
@@ -0,0 +1,197 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GDK_PRIVATE_H__
+#define __GDK_PRIVATE_H__
+
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <gdk/gdktypes.h>
+
+#define DND_PROTOCOL_VERSION 0
+
+#define gdk_window_lookup(xid)     ((GdkWindow*) gdk_xid_table_lookup (xid))
+#define gdk_pixmap_lookup(xid)     ((GdkPixmap*) gdk_xid_table_lookup (xid))
+#define gdk_font_lookup(xid)       ((GdkFont*) gdk_xid_table_lookup (xid))
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+typedef struct _GdkWindowPrivate    GdkWindowPrivate;
+typedef struct _GdkWindowPrivate    GdkPixmapPrivate;
+typedef struct _GdkImagePrivate     GdkImagePrivate;
+typedef struct _GdkGCPrivate        GdkGCPrivate;
+typedef struct _GdkColormapPrivate  GdkColormapPrivate;
+typedef struct _GdkVisualPrivate    GdkVisualPrivate;
+typedef struct _GdkFontPrivate      GdkFontPrivate;
+typedef struct _GdkCursorPrivate    GdkCursorPrivate;
+
+
+struct _GdkWindowPrivate
+{
+  GdkWindow window;
+  GdkWindow *parent;
+  Window xwindow;
+  Display *xdisplay;
+  gint16 x;
+  gint16 y;
+  guint16 width;
+  guint16 height;
+  guint8 resize_count;
+  guint8 ref_count;
+  guint8 window_type;
+  guint8 destroyed : 2;
+  guint8 dnd_drag_enabled : 1,
+    dnd_drag_datashow : 1,
+    dnd_drag_destructive_op : 1,
+    dnd_drag_accepted : 1,
+    dnd_drop_enabled : 1,
+    dnd_drop_destructive_op : 1;
+  GdkAtom dnd_drag_data_type, *dnd_drag_data_typesavail;
+  guint dnd_drag_data_numtypesavail;
+  /* We have to turn on MotionMask/EnterWindowMask/LeaveWindowMask
+     during drags, then set it back to what it was after */
+  glong dnd_drag_savedeventmask, dnd_drag_eventmask;
+  GdkAtom *dnd_drop_data_typesavail;
+  guint dnd_drop_data_numtypesavail;
+  /* need to allow custom drag/drop cursors */
+
+  gint extension_events;
+};
+
+struct _GdkImagePrivate
+{
+  GdkImage image;
+  XImage *ximage;
+  Display *xdisplay;
+  gpointer x_shm_info;
+
+  void (*image_put) (GdkDrawable *window,
+                    GdkGC       *gc,
+                    GdkImage    *image,
+                    gint         xsrc,
+                    gint         ysrc,
+                    gint         xdest,
+                    gint         ydest,
+                    gint         width,
+                    gint         height);
+};
+
+struct _GdkGCPrivate
+{
+  GdkGC gc;
+  GC xgc;
+  Display *xdisplay;
+};
+
+struct _GdkColormapPrivate
+{
+  GdkColormap colormap;
+  Colormap xcolormap;
+  Display *xdisplay;
+  GdkVisual *visual;
+  gint private_val;
+  gint next_color;
+  gint ref_count;
+};
+
+struct _GdkVisualPrivate
+{
+  GdkVisual visual;
+  Visual *xvisual;
+};
+
+struct _GdkFontPrivate
+{
+  GdkFont font;
+  /* XFontStruct *xfont; */
+  /* generic pointer point to XFontStruct or XFontSet */
+  gpointer xfont;
+  Display *xdisplay;
+  gint ref_count;
+};
+
+struct _GdkCursorPrivate
+{
+  GdkCursor cursor;
+  Cursor xcursor;
+  Display *xdisplay;
+};
+
+struct _GdkDndGlobals {
+  GdkAtom            gdk_XdeEnter, gdk_XdeLeave, gdk_XdeRequest;
+  GdkAtom            gdk_XdeDataAvailable, gdk_XdeDataShow, gdk_XdeCancel;
+  GdkAtom            gdk_XdeTypelist;
+  Cursor          gdk_cursor_dragdefault, gdk_cursor_dragok;
+  GdkWindow     **drag_startwindows;
+  guint           drag_numwindows;
+  guint8          drag_really;
+  GdkPoint        drag_dropcoords;
+};
+typedef struct _GdkDndGlobals GdkDndGlobals;
+
+void gdk_window_init (void);
+void gdk_visual_init (void);
+
+void gdk_image_init  (void);
+void gdk_image_exit (void);
+
+GdkColormap* gdk_colormap_lookup (Colormap  xcolormap);
+GdkVisual*   gdk_visual_lookup   (Visual   *xvisual);
+
+void gdk_window_real_destroy         (GdkWindow *window);
+void gdk_window_add_colormap_windows (GdkWindow *window);
+
+void     gdk_xid_table_insert (XID      *xid,
+                              gpointer  data);
+void     gdk_xid_table_remove (XID       xid);
+gpointer gdk_xid_table_lookup (XID       xid);
+
+
+extern gint              gdk_debug_level;
+extern gint              gdk_show_events;
+extern gint              gdk_use_xshm;
+extern gint              gdk_stack_trace;
+extern gchar            *gdk_display_name;
+extern Display          *gdk_display;
+extern gint              gdk_screen;
+extern Window            gdk_root_window;
+extern Window            gdk_leader_window;
+extern GdkWindowPrivate  gdk_root_parent;
+extern Atom              gdk_wm_delete_window;
+extern Atom              gdk_wm_take_focus;
+extern Atom              gdk_wm_protocols;
+extern Atom              gdk_wm_window_protocols[];
+extern Atom              gdk_selection_property;
+extern GdkDndGlobals     gdk_dnd;
+extern GdkWindow        *selection_owner[];
+extern gchar            *gdk_progname;
+extern gchar            *gdk_progclass;
+extern gint              gdk_error_code;
+extern gint              gdk_error_warnings;
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GDK_PRIVATE_H__ */
diff --git a/gdk/gdkproperty.c b/gdk/gdkproperty.c
new file mode 100644 (file)
index 0000000..35d8a50
--- /dev/null
@@ -0,0 +1,194 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <string.h>
+#include "gdk.h"
+#include "gdkprivate.h"
+
+
+GdkAtom
+gdk_atom_intern (const gchar *atom_name,
+                gint         only_if_exists)
+{
+  return XInternAtom (gdk_display, atom_name, only_if_exists);
+}
+
+gchar *
+gdk_atom_name (GdkAtom atom)
+{
+  gchar *t;
+  gchar *name;
+
+  /* If this atom doesn't exist, we'll die with an X error unless
+     we take precautions */
+
+  gdk_error_warnings = 0;
+  t = XGetAtomName (gdk_display, atom);
+  gdk_error_warnings = 1;
+
+  if (gdk_error_code == -1)
+    {
+      return NULL;
+    }
+  else
+    {
+      name = g_strdup (t);
+      XFree (t);
+      
+      return name;
+    }
+}
+
+gint
+gdk_property_get (GdkWindow   *window,
+                 GdkAtom      property,
+                 GdkAtom      type,
+                 gulong       offset,
+                 gulong       length,
+                 gint         pdelete,
+                 GdkAtom     *actual_property_type,
+                 gint        *actual_format_type,
+                 gint        *actual_length,
+                 guchar     **data)
+{
+  GdkWindowPrivate *private;
+  Display *xdisplay;
+  Window xwindow;
+  Atom ret_prop_type;
+  gint ret_format;
+  gulong ret_nitems;
+  gulong ret_bytes_after;
+  gulong ret_length;
+  guchar *ret_data;
+
+  if (window)
+    {
+      private = (GdkWindowPrivate*) window;
+      xdisplay = private->xdisplay;
+      xwindow = private->xwindow;
+    }
+  else
+    {
+      xdisplay = gdk_display;
+      xwindow = gdk_root_window;
+    }
+
+  XGetWindowProperty (xdisplay, xwindow, property,
+                     offset, (length + 3) / 4, pdelete,
+                     type, &ret_prop_type, &ret_format,
+                     &ret_nitems, &ret_bytes_after,
+                     &ret_data);
+
+  if ((ret_prop_type == None) && (ret_format == 0))
+    return FALSE;
+
+  if (actual_property_type)
+    *actual_property_type = ret_prop_type;
+  if (actual_format_type)
+    *actual_format_type = ret_format;
+
+  if (ret_prop_type != property)
+    {
+      XFree (ret_data);
+      return FALSE;
+    }
+
+  /* FIXME: ignoring bytes_after could have very bad effects */
+
+  if (data)
+    {
+      switch (ret_format)
+       {
+       case 8:
+         ret_length = ret_nitems;
+         break;
+       case 16:
+         ret_length = 2 * ret_nitems;
+         break;
+       case 32:
+         ret_length = 4 * ret_nitems;
+         break;
+       default:
+         g_warning ("unknown property return format: %d", ret_format);
+         XFree (ret_data);
+         return FALSE;
+       }
+
+      *data = g_new (guchar, ret_length);
+      memcpy (*data, ret_data, ret_length);
+      if (actual_length)
+       *actual_length = ret_length;
+    }
+
+  XFree (ret_data);
+
+  return TRUE;
+}
+
+void
+gdk_property_change (GdkWindow   *window,
+                    GdkAtom      property,
+                    GdkAtom      type,
+                    gint         format,
+                    GdkPropMode  mode,
+                    guchar      *data,
+                    gint         nelements)
+{
+  GdkWindowPrivate *private;
+  Display *xdisplay;
+  Window xwindow;
+
+  if (window)
+    {
+      private = (GdkWindowPrivate*) window;
+      xdisplay = private->xdisplay;
+      xwindow = private->xwindow;
+    }
+  else
+    {
+      xdisplay = gdk_display;
+      xwindow = gdk_root_window;
+    }
+
+  XChangeProperty (xdisplay, xwindow, property, type,
+                  format, mode, data, nelements);
+}
+
+void
+gdk_property_delete (GdkWindow *window,
+                    GdkAtom    property)
+{
+  GdkWindowPrivate *private;
+  Display *xdisplay;
+  Window xwindow;
+
+  if (window)
+    {
+      private = (GdkWindowPrivate*) window;
+      xdisplay = private->xdisplay;
+      xwindow = private->xwindow;
+    }
+  else
+    {
+      xdisplay = gdk_display;
+      xwindow = gdk_root_window;
+    }
+
+  XDeleteProperty (xdisplay, xwindow, property);
+}
diff --git a/gdk/gdkrectangle.c b/gdk/gdkrectangle.c
new file mode 100644 (file)
index 0000000..dbb35b6
--- /dev/null
@@ -0,0 +1,83 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gdk.h"
+
+
+gint
+gdk_rectangle_intersect (GdkRectangle *src1,
+                        GdkRectangle *src2,
+                        GdkRectangle *dest)
+{
+  GdkRectangle *temp;
+  gint src1_x2, src1_y2;
+  gint src2_x2, src2_y2;
+  gint return_val;
+
+  g_return_val_if_fail (src1 != NULL, FALSE);
+  g_return_val_if_fail (src2 != NULL, FALSE);
+  g_return_val_if_fail (dest != NULL, FALSE);
+
+  return_val = FALSE;
+
+  if (src2->x < src1->x)
+    {
+      temp = src1;
+      src1 = src2;
+      src2 = temp;
+    }
+  dest->x = src2->x;
+
+  src1_x2 = src1->x + src1->width;
+  src2_x2 = src2->x + src2->width;
+
+  if (src2->x < src1_x2)
+    {
+      if (src1_x2 < src2_x2)
+       dest->width = src1_x2 - dest->x;
+      else
+       dest->width = src2_x2 - dest->x;
+
+      if (src2->y < src1->y)
+       {
+         temp = src1;
+         src1 = src2;
+         src2 = temp;
+       }
+      dest->y = src2->y;
+
+      src1_y2 = src1->y + src1->height;
+      src2_y2 = src2->y + src2->height;
+
+      if (src2->y < src1_y2)
+       {
+         return_val = TRUE;
+
+         if (src1_y2 < src2_y2)
+           dest->height = src1_y2 - dest->y;
+         else
+           dest->height = src2_y2 - dest->y;
+
+         if (dest->height == 0)
+           return_val = FALSE;
+         if (dest->width == 0)
+           return_val = FALSE;
+       }
+    }
+
+  return return_val;
+}
diff --git a/gdk/gdkselection.c b/gdk/gdkselection.c
new file mode 100644 (file)
index 0000000..6bd4251
--- /dev/null
@@ -0,0 +1,168 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <string.h>
+#include "gdk.h"
+#include "gdkprivate.h"
+
+
+gint
+gdk_selection_owner_set (GdkWindow *owner,
+                        GdkAtom    selection,
+                        guint32    time,
+                        gint       send_event)
+{
+  GdkWindowPrivate *private;
+  Display *xdisplay;
+  Window xwindow;
+
+  if (owner)
+    {
+      private = (GdkWindowPrivate*) owner;
+      xdisplay = private->xdisplay;
+      xwindow = private->xwindow;
+    }
+  else
+    {
+      xdisplay = gdk_display;
+      xwindow = None;
+    }
+
+  XSetSelectionOwner (xdisplay, selection, xwindow, time);
+
+  return (XGetSelectionOwner (xdisplay, selection) == xwindow);
+}
+
+GdkWindow*
+gdk_selection_owner_get (GdkAtom selection)
+{
+  Window xwindow;
+
+  xwindow = XGetSelectionOwner (gdk_display, selection);
+  if (xwindow == None)
+    return NULL;
+
+  return gdk_window_lookup (xwindow);
+}
+
+void
+gdk_selection_convert (GdkWindow *requestor,
+                      GdkAtom    selection,
+                      GdkAtom    target,
+                      guint32    time)
+{
+  GdkWindowPrivate *private;
+
+  g_return_if_fail (requestor != NULL);
+
+  private = (GdkWindowPrivate*) requestor;
+
+  XConvertSelection (private->xdisplay, selection, target,
+                    gdk_selection_property, private->xwindow, time);
+}
+
+gint
+gdk_selection_property_get (GdkWindow  *requestor,
+                           guchar    **data,
+                           GdkAtom    *ret_type,
+                           gint       *ret_format)
+{
+  GdkWindowPrivate *private;
+  gulong nitems;
+  gulong nbytes;
+  gulong length;
+  GdkAtom prop_type;
+  gint prop_format;
+  guchar *t;
+
+  g_return_val_if_fail (requestor != NULL, 0);
+
+  /* If retrieved chunks are typically small, (and the ICCM says the
+     should be) it would be a win to try first with a buffer of
+     moderate length, to avoid two round trips to the server */
+
+  private = (GdkWindowPrivate*) requestor;
+
+  XGetWindowProperty (private->xdisplay, private->xwindow,
+                     gdk_selection_property, 0, 0, False,
+                     AnyPropertyType, &prop_type, &prop_format,
+                     &nitems, &nbytes, &t);
+
+  if (ret_type)
+    *ret_type = prop_type;
+  if (ret_format)
+    *ret_format = prop_format;
+
+  if (prop_type == None)
+    {
+      *data = NULL;
+      return 0;
+    }
+    
+  XFree (t);
+
+  /* Add on an extra byte to handle null termination.  X guarantees
+     that t will be 1 longer than nbytes and null terminated */
+  length = nbytes + 1;
+
+  /* We can't delete the selection here, because it might be the INCR
+     protocol, in which case the client has to make sure they'll be
+     notified of PropertyChange events _before_ the property is deleted.
+     Otherwise there's no guarantee we'll win the race ... */
+  XGetWindowProperty (private->xdisplay, private->xwindow,
+                     gdk_selection_property, 0, (nbytes + 3) / 4, False,
+                     AnyPropertyType, &prop_type, &prop_format,
+                     &nitems, &nbytes, &t);
+
+  if (prop_type != None)
+    {
+      *data = g_new (guchar, length);
+      memcpy (*data, t, length);
+      XFree (t);
+      return length-1;
+    }
+  else
+    {
+      *data = NULL;
+      return 0;
+    }
+}
+
+
+void
+gdk_selection_send_notify (guint32  requestor,
+                          GdkAtom  selection,
+                          GdkAtom  target,
+                          GdkAtom  property,
+                          guint32  time)
+{
+  XSelectionEvent xevent;
+
+  xevent.type = SelectionNotify;
+  xevent.serial = 0;
+  xevent.send_event = True;
+  xevent.display = gdk_display;
+  xevent.requestor = requestor;
+  xevent.selection = selection;
+  xevent.target = target;
+  xevent.property = property;
+  xevent.time = time;
+
+  XSendEvent (gdk_display, requestor, False, NoEventMask, (XEvent*) &xevent);
+}
diff --git a/gdk/gdktypes.h b/gdk/gdktypes.h
new file mode 100644 (file)
index 0000000..7fc7434
--- /dev/null
@@ -0,0 +1,967 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GDK_TYPES_H__
+#define __GDK_TYPES_H__
+
+
+/* GDK uses "glib". (And so does GTK).
+ */
+#include <glib.h>
+
+
+#define GDK_NONE             0L
+#define GDK_CURRENT_TIME     0L
+#define GDK_PARENT_RELATIVE  1L
+
+/* special deviceid for core pointer events */
+#define GDK_CORE_POINTER 0xfedc
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* Type definitions for the basic structures.
+ */
+
+typedef gulong                    GdkAtom;
+typedef struct _GdkColor          GdkColor;
+typedef struct _GdkColormap       GdkColormap;
+typedef struct _GdkVisual         GdkVisual;
+typedef struct _GdkWindowAttr     GdkWindowAttr;
+typedef struct _GdkWindow         GdkWindow;
+typedef struct _GdkWindow         GdkPixmap;
+typedef struct _GdkWindow         GdkBitmap;
+typedef struct _GdkWindow         GdkDrawable;
+typedef struct _GdkImage          GdkImage;
+typedef struct _GdkGCValues       GdkGCValues;
+typedef struct _GdkGC             GdkGC;
+typedef struct _GdkPoint          GdkPoint;
+typedef struct _GdkRectangle      GdkRectangle;
+typedef struct _GdkSegment        GdkSegment;
+typedef struct _GdkFont           GdkFont;
+typedef struct _GdkCursor         GdkCursor;
+
+typedef struct _GdkEventAny       GdkEventAny;
+typedef struct _GdkEventExpose    GdkEventExpose;
+typedef struct _GdkEventMotion    GdkEventMotion;
+typedef struct _GdkEventButton    GdkEventButton;
+typedef struct _GdkEventKey       GdkEventKey;
+typedef struct _GdkEventFocus     GdkEventFocus;
+typedef struct _GdkEventCrossing  GdkEventCrossing;
+typedef struct _GdkEventConfigure GdkEventConfigure;
+typedef struct _GdkEventProperty  GdkEventProperty;
+typedef struct _GdkEventSelection GdkEventSelection;
+typedef struct _GdkEventProximity GdkEventProximity;
+typedef struct _GdkEventOther     GdkEventOther;
+typedef struct _GdkEventDragBegin GdkEventDragBegin;
+typedef struct _GdkEventDragRequest GdkEventDragRequest;
+typedef struct _GdkEventDropEnter GdkEventDropEnter;
+typedef struct _GdkEventDropDataAvailable GdkEventDropDataAvailable;
+typedef struct _GdkEventDropLeave GdkEventDropLeave;
+typedef struct _GdkEventClient    GdkEventClient;
+typedef union  _GdkEvent          GdkEvent;
+typedef struct _GdkDeviceInfo     GdkDeviceInfo;
+typedef struct _GdkTimeCoord      GdkTimeCoord;
+typedef gint (*GdkEventFunc) (GdkEvent *event,
+                             gpointer  data);
+
+
+/* Types of windows.
+ *   Root: There is only 1 root window and it is initialized
+ *         at startup. Creating a window of type GDK_WINDOW_ROOT
+ *         is an error.
+ *   Toplevel: Windows which interact with the window manager.
+ *   Child: Windows which are children of some other type of window.
+ *          (Any other type of window). Most windows are child windows.
+ *   Dialog: A special kind of toplevel window which interacts with
+ *           the window manager slightly differently than a regular
+ *           toplevel window. Dialog windows should be used for any
+ *           transient window.
+ *   Pixmap: Pixmaps are really just another kind of window which
+ *           doesn't actually appear on the screen. It can't have
+ *           children, either and is really just a convenience so
+ *           that the drawing functions can work on both windows
+ *           and pixmaps transparently. (ie. You shouldn't pass a
+ *           pixmap to any procedure which accepts a window with the
+ *           exception of the drawing functions).
+ */
+typedef enum
+{
+  GDK_WINDOW_ROOT,
+  GDK_WINDOW_TOPLEVEL,
+  GDK_WINDOW_CHILD,
+  GDK_WINDOW_DIALOG,
+  GDK_WINDOW_TEMP,
+  GDK_WINDOW_PIXMAP
+} GdkWindowType;
+
+/* Classes of windows.
+ *   InputOutput: Almost every window should be of this type. Such windows
+ *                receive events and are also displayed on screen.
+ *   InputOnly: Used only in special circumstances when events need to be
+ *              stolen from another window or windows. Input only windows
+ *              have no visible output, so they are handy for placing over
+ *              top of a group of windows in order to grab the events (or
+ *              filter the events) from those windows.
+ */
+typedef enum
+{
+  GDK_INPUT_OUTPUT,
+  GDK_INPUT_ONLY
+} GdkWindowClass;
+
+/* Types of images.
+ *   Normal: Normal X image type. These are slow as they involve passing
+ *           the entire image through the X connection each time a draw
+ *           request is required.
+ *   Shared: Shared memory X image type. These are fast as the X server
+ *           and the program actually use the same piece of memory. They
+ *           should be used with care though as there is the possibility
+ *           for both the X server and the program to be reading/writing
+ *           the image simultaneously and producing undesired results.
+ */
+typedef enum
+{
+  GDK_IMAGE_NORMAL,
+  GDK_IMAGE_SHARED,
+  GDK_IMAGE_FASTEST
+} GdkImageType;
+
+/* Types of visuals.
+ *   StaticGray:
+ *   Grayscale:
+ *   StaticColor:
+ *   PseudoColor:
+ *   TrueColor:
+ *   DirectColor:
+ */
+typedef enum
+{
+  GDK_VISUAL_STATIC_GRAY,
+  GDK_VISUAL_GRAYSCALE,
+  GDK_VISUAL_STATIC_COLOR,
+  GDK_VISUAL_PSEUDO_COLOR,
+  GDK_VISUAL_TRUE_COLOR,
+  GDK_VISUAL_DIRECT_COLOR
+} GdkVisualType;
+
+/* Types of font.
+ *   GDK_FONT_FONT: the font is an XFontStruct.
+ *   GDK_FONT_FONTSET: the font is an XFontSet used for I18N.
+ */
+typedef enum
+{
+  GDK_FONT_FONT,
+  GDK_FONT_FONTSET
+} GdkFontType;
+
+/* Window attribute mask values.
+ *   GDK_WA_TITLE: The "title" field is valid.
+ *   GDK_WA_X: The "x" field is valid.
+ *   GDK_WA_Y: The "y" field is valid.
+ *   GDK_WA_CURSOR: The "cursor" field is valid.
+ *   GDK_WA_COLORMAP: The "colormap" field is valid.
+ *   GDK_WA_VISUAL: The "visual" field is valid.
+ */
+typedef enum
+{
+  GDK_WA_TITLE    = 1 << 1,
+  GDK_WA_X        = 1 << 2,
+  GDK_WA_Y        = 1 << 3,
+  GDK_WA_CURSOR   = 1 << 4,
+  GDK_WA_COLORMAP = 1 << 5,
+  GDK_WA_VISUAL   = 1 << 6,
+  GDK_WA_WMCLASS  = 1 << 7
+} GdkWindowAttributesType;
+
+/* Size restriction enumeration.
+ */
+typedef enum
+{
+  GDK_HINT_POS       = 1 << 0,
+  GDK_HINT_MIN_SIZE  = 1 << 1,
+  GDK_HINT_MAX_SIZE  = 1 << 2
+} GdkWindowHints;
+
+/* GC function types.
+ *   Copy: Overwrites destination pixels with the source pixels.
+ *   Invert: Inverts the destination pixels.
+ *   Xor: Xor's the destination pixels with the source pixels.
+ */
+typedef enum
+{
+  GDK_COPY,
+  GDK_INVERT,
+  GDK_XOR
+} GdkFunction;
+
+/* GC fill types.
+ *  Solid:
+ *  Tiled:
+ *  Stippled:
+ *  OpaqueStippled:
+ */
+typedef enum
+{
+  GDK_SOLID,
+  GDK_TILED,
+  GDK_STIPPLED,
+  GDK_OPAQUE_STIPPLED
+} GdkFill;
+
+/* GC line styles
+ *  Solid:
+ *  OnOffDash:
+ *  DoubleDash:
+ */
+typedef enum
+{
+  GDK_LINE_SOLID,
+  GDK_LINE_ON_OFF_DASH,
+  GDK_LINE_DOUBLE_DASH
+} GdkLineStyle;
+
+/* GC cap styles
+ *  CapNotLast:
+ *  CapButt:
+ *  CapRound:
+ *  CapProjecting:
+ */
+typedef enum
+{
+  GDK_CAP_NOT_LAST,
+  GDK_CAP_BUTT,
+  GDK_CAP_ROUND,
+  GDK_CAP_PROJECTING
+} GdkCapStyle;
+
+/* GC join styles
+ *  JoinMiter:
+ *  JoinRound:
+ *  JoinBevel:
+ */
+typedef enum
+{
+  GDK_JOIN_MITER,
+  GDK_JOIN_ROUND,
+  GDK_JOIN_BEVEL
+} GdkJoinStyle;
+
+/* Cursor types.
+ */
+typedef enum
+{
+#include <gdk/gdkcursors.h>
+  GDK_LAST_CURSOR
+} GdkCursorType;
+
+/* Event types.
+ *   Nothing: No event occurred.
+ *   Delete: A window delete event was sent by the window manager.
+ *           The specified window should be deleted.
+ *   Destroy: A window has been destroyed.
+ *   Expose: Part of a window has been uncovered.
+ *   MotionNotify: The mouse has moved.
+ *   ButtonPress: A mouse button was pressed.
+ *   ButtonRelease: A mouse button was release.
+ *   KeyPress: A key was pressed.
+ *   KeyRelease: A key was released.
+ *   EnterNotify: A window was entered.
+ *   LeaveNotify: A window was exited.
+ *   FocusChange: The focus window has changed. (The focus window gets
+ *                keyboard events).
+ *   Resize: A window has been resized.
+ *   Map: A window has been mapped. (It is now visible on the screen).
+ *   Unmap: A window has been unmapped. (It is no longer visible on
+ *          the screen).
+ */
+typedef enum
+{
+  GDK_NOTHING           = -1,
+  GDK_DELETE            = 0,
+  GDK_DESTROY           = 1,
+  GDK_EXPOSE            = 2,
+  GDK_MOTION_NOTIFY     = 3,
+  GDK_BUTTON_PRESS      = 4,
+  GDK_2BUTTON_PRESS     = 5,
+  GDK_3BUTTON_PRESS     = 6,
+  GDK_BUTTON_RELEASE    = 7,
+  GDK_KEY_PRESS         = 8,
+  GDK_KEY_RELEASE       = 9,
+  GDK_ENTER_NOTIFY      = 10,
+  GDK_LEAVE_NOTIFY      = 11,
+  GDK_FOCUS_CHANGE      = 12,
+  GDK_CONFIGURE         = 13,
+  GDK_MAP               = 14,
+  GDK_UNMAP             = 15,
+  GDK_PROPERTY_NOTIFY   = 16,
+  GDK_SELECTION_CLEAR   = 17,
+  GDK_SELECTION_REQUEST = 18,
+  GDK_SELECTION_NOTIFY  = 19,
+  GDK_PROXIMITY_IN      = 20,
+  GDK_PROXIMITY_OUT     = 21,
+  GDK_DRAG_BEGIN       = 22,
+  GDK_DRAG_REQUEST      = 23,
+  GDK_DROP_ENTER        = 24,
+  GDK_DROP_LEAVE        = 25,
+  GDK_DROP_DATA_AVAIL   = 26,
+  GDK_CLIENT_EVENT      = 27,
+  GDK_OTHER_EVENT       = 9999
+} GdkEventType;
+
+/* Event masks. (Used to select what types of events a window
+ *  will receive).
+ */
+typedef enum
+{
+  GDK_EXPOSURE_MASK             = 1 << 1,
+  GDK_POINTER_MOTION_MASK       = 1 << 2,
+  GDK_POINTER_MOTION_HINT_MASK  = 1 << 3,
+  GDK_BUTTON_MOTION_MASK        = 1 << 4,
+  GDK_BUTTON1_MOTION_MASK       = 1 << 5,
+  GDK_BUTTON2_MOTION_MASK       = 1 << 6,
+  GDK_BUTTON3_MOTION_MASK       = 1 << 7,
+  GDK_BUTTON_PRESS_MASK         = 1 << 8,
+  GDK_BUTTON_RELEASE_MASK       = 1 << 9,
+  GDK_KEY_PRESS_MASK            = 1 << 10,
+  GDK_KEY_RELEASE_MASK          = 1 << 11,
+  GDK_ENTER_NOTIFY_MASK         = 1 << 12,
+  GDK_LEAVE_NOTIFY_MASK         = 1 << 13,
+  GDK_FOCUS_CHANGE_MASK         = 1 << 14,
+  GDK_STRUCTURE_MASK            = 1 << 15,
+  GDK_PROPERTY_CHANGE_MASK      = 1 << 16,
+  GDK_PROXIMITY_IN_MASK         = 1 << 17,
+  GDK_PROXIMITY_OUT_MASK        = 1 << 18,
+  GDK_ALL_EVENTS_MASK           = 0x07FFFF
+} GdkEventMask;
+
+/* Types of enter/leave notifications.
+ *   Ancestor:
+ *   Virtual:
+ *   Inferior:
+ *   Nonlinear:
+ *   NonlinearVirtual:
+ *   Unknown: An unknown type of enter/leave event occurred.
+ */
+typedef enum
+{
+  GDK_NOTIFY_ANCESTOR           = 0,
+  GDK_NOTIFY_VIRTUAL            = 1,
+  GDK_NOTIFY_INFERIOR           = 2,
+  GDK_NOTIFY_NONLINEAR          = 3,
+  GDK_NOTIFY_NONLINEAR_VIRTUAL  = 4,
+  GDK_NOTIFY_UNKNOWN            = 5
+} GdkNotifyType;
+
+/* Types of modifiers.
+ */
+typedef enum
+{
+  GDK_SHIFT_MASK    = 1 << 0,
+  GDK_LOCK_MASK     = 1 << 1,
+  GDK_CONTROL_MASK  = 1 << 2,
+  GDK_MOD1_MASK     = 1 << 3,
+  GDK_MOD2_MASK     = 1 << 4,
+  GDK_MOD3_MASK     = 1 << 5,
+  GDK_MOD4_MASK     = 1 << 6,
+  GDK_MOD5_MASK     = 1 << 7,
+  GDK_BUTTON1_MASK  = 1 << 8,
+  GDK_BUTTON2_MASK  = 1 << 9,
+  GDK_BUTTON3_MASK  = 1 << 10,
+  GDK_BUTTON4_MASK  = 1 << 11,
+  GDK_BUTTON5_MASK  = 1 << 12
+} GdkModifierType;
+
+typedef enum
+{
+  GDK_CLIP_BY_CHILDREN  = 0,
+  GDK_INCLUDE_INFERIORS = 1
+} GdkSubwindowMode;
+
+typedef enum
+{
+  GDK_INPUT_READ       = 1 << 0,
+  GDK_INPUT_WRITE      = 1 << 1,
+  GDK_INPUT_EXCEPTION  = 1 << 2
+} GdkInputCondition;
+
+typedef enum
+{
+  GDK_OK          = 0,
+  GDK_ERROR       = -1,
+  GDK_ERROR_PARAM = -2,
+  GDK_ERROR_FILE  = -3,
+  GDK_ERROR_MEM   = -4
+} GdkStatus;
+
+typedef enum
+{
+  GDK_LSB_FIRST,
+  GDK_MSB_FIRST
+} GdkByteOrder;
+
+typedef enum
+{
+  GDK_GC_FOREGROUND    = 1 << 0,
+  GDK_GC_BACKGROUND    = 1 << 1,
+  GDK_GC_FONT          = 1 << 2,
+  GDK_GC_FUNCTION      = 1 << 3,
+  GDK_GC_FILL          = 1 << 4,
+  GDK_GC_TILE          = 1 << 5,
+  GDK_GC_STIPPLE       = 1 << 6,
+  GDK_GC_CLIP_MASK     = 1 << 7,
+  GDK_GC_SUBWINDOW     = 1 << 8,
+  GDK_GC_TS_X_ORIGIN   = 1 << 9,
+  GDK_GC_TS_Y_ORIGIN   = 1 << 10,
+  GDK_GC_CLIP_X_ORIGIN = 1 << 11,
+  GDK_GC_CLIP_Y_ORIGIN = 1 << 12,
+  GDK_GC_EXPOSURES     = 1 << 13,
+  GDK_GC_LINE_WIDTH    = 1 << 14,
+  GDK_GC_LINE_STYLE    = 1 << 15,
+  GDK_GC_CAP_STYLE     = 1 << 16,
+  GDK_GC_JOIN_STYLE    = 1 << 17
+} GdkGCValuesMask;
+
+typedef enum
+{
+  GDK_SELECTION_PRIMARY = 1,
+  GDK_SELECTION_SECONDARY = 2
+} GdkSelection;
+
+typedef enum
+{
+  GDK_PROPERTY_NEW_VALUE,
+  GDK_PROPERTY_DELETE
+} GdkPropertyState;
+
+typedef enum
+{
+  GDK_PROP_MODE_REPLACE,
+  GDK_PROP_MODE_PREPEND,
+  GDK_PROP_MODE_APPEND
+} GdkPropMode;
+
+/* These definitions are for version 1 of the OffiX D&D protocol,
+   taken from <OffiX/DragAndDropTypes.h> */
+typedef enum
+{
+  GDK_DNDTYPE_NOTDND = -1,
+  GDK_DNDTYPE_UNKNOWN = 0,
+  GDK_DNDTYPE_RAWDATA = 1,
+  GDK_DNDTYPE_FILE = 2,
+  GDK_DNDTYPE_FILES = 3,
+  GDK_DNDTYPE_TEXT = 4,
+  GDK_DNDTYPE_DIR = 5,
+  GDK_DNDTYPE_LINK = 6,
+  GDK_DNDTYPE_EXE = 7,
+  GDK_DNDTYPE_URL = 8,
+  GDK_DNDTYPE_MIME = 9,
+  GDK_DNDTYPE_END = 10
+} GdkDndType;
+
+/* Enums for XInput support */
+
+typedef enum
+{
+  GDK_SOURCE_MOUSE,
+  GDK_SOURCE_PEN,
+  GDK_SOURCE_ERASER,
+  GDK_SOURCE_CURSOR
+} GdkInputSource;
+
+typedef enum
+{
+  GDK_MODE_DISABLED,
+  GDK_MODE_SCREEN,
+  GDK_MODE_WINDOW
+} GdkInputMode;
+
+typedef enum
+{
+  GDK_AXIS_IGNORE,
+  GDK_AXIS_X,
+  GDK_AXIS_Y,
+  GDK_AXIS_PRESSURE,
+  GDK_AXIS_XTILT,
+  GDK_AXIS_YTILT,
+  GDK_AXIS_LAST
+} GdkAxisUse;
+
+/* The next two types define enums for predefined atoms relating
+   to selections. In general, one will need to use gdk_intern_atom */
+
+typedef enum
+{
+  GDK_TARGET_BITMAP = 5,
+  GDK_TARGET_COLORMAP = 7,
+  GDK_TARGET_DRAWABLE = 17,
+  GDK_TARGET_PIXMAP = 20,
+  GDK_TARGET_STRING = 31
+} GdkTarget;
+
+typedef enum
+{
+  GDK_SELECTION_TYPE_ATOM = 4,
+  GDK_SELECTION_TYPE_BITMAP = 5,
+  GDK_SELECTION_TYPE_COLORMAP = 7,
+  GDK_SELECTION_TYPE_DRAWABLE = 17,
+  GDK_SELECTION_TYPE_INTEGER = 19,
+  GDK_SELECTION_TYPE_PIXMAP = 20,
+  GDK_SELECTION_TYPE_WINDOW = 33,
+  GDK_SELECTION_TYPE_STRING = 31
+} GdkSelectionType;
+
+typedef enum
+{
+  GDK_EXTENSION_EVENTS_NONE,
+  GDK_EXTENSION_EVENTS_ALL,
+  GDK_EXTENSION_EVENTS_CURSOR
+} GdkExtensionMode;
+
+typedef void (*GdkInputFunction) (gpointer          data,
+                                 gint              source,
+                                 GdkInputCondition condition);
+
+/* The color type.
+ *   A color consists of red, green and blue values in the
+ *    range 0-65535 and a pixel value. The pixel value is highly
+ *    dependent on the depth and colormap which this color will
+ *    be used to draw into. Therefore, sharing colors between
+ *    colormaps is a bad idea.
+ */
+struct _GdkColor
+{
+  gulong  pixel;
+  gushort red;
+  gushort green;
+  gushort blue;
+};
+
+/* The colormap type.
+ *   Colormaps consist of 256 colors.
+ */
+struct _GdkColormap
+{
+  GdkColor colors[256];
+};
+
+/* The visual type.
+ *   "type" is the type of visual this is (PseudoColor, TrueColor, etc).
+ *   "depth" is the bit depth of this visual.
+ *   "colormap_size" is the size of a colormap for this visual.
+ *   "bits_per_rgb" is the number of significant bits per red, green and blue.
+ *  The red, green and blue masks, shifts and precisions refer
+ *   to value needed to calculate pixel values in TrueColor and DirectColor
+ *   visuals. The "mask" is the significant bits within the pixel. The
+ *   "shift" is the number of bits left we must shift a primary for it
+ *   to be in position (according to the "mask"). "prec" refers to how
+ *   much precision the pixel value contains for a particular primary.
+ */
+struct _GdkVisual
+{
+  GdkVisualType type;
+  gint depth;
+  GdkByteOrder byte_order;
+  gint colormap_size;
+  gint bits_per_rgb;
+
+  guint32 red_mask;
+  gint red_shift;
+  gint red_prec;
+
+  guint32 green_mask;
+  gint green_shift;
+  gint green_prec;
+
+  guint32 blue_mask;
+  gint blue_shift;
+  gint blue_prec;
+};
+
+struct _GdkWindowAttr
+{
+  gchar *title;
+  gint event_mask;
+  gint16 x, y;
+  gint16 width;
+  gint16 height;
+  GdkWindowClass wclass;
+  GdkVisual *visual;
+  GdkColormap *colormap;
+  GdkWindowType window_type;
+  GdkCursor *cursor;
+  gchar *wmclass_name;
+  gchar *wmclass_class;
+};
+
+struct _GdkWindow
+{
+  gpointer user_data;
+};
+
+struct _GdkImage
+{
+  GdkImageType  type;
+  GdkVisual    *visual;     /* visual used to create the image */
+  GdkByteOrder  byte_order;
+  guint16       width;
+  guint16       height;
+  guint16       depth;
+  guint16       bpp;        /* bytes per pixel */
+  guint16       bpl;        /* bytes per line */
+  gpointer      mem;
+};
+
+struct _GdkGCValues
+{
+  GdkColor          foreground;
+  GdkColor          background;
+  GdkFont          *font;
+  GdkFunction       function;
+  GdkFill           fill;
+  GdkPixmap        *tile;
+  GdkPixmap        *stipple;
+  GdkPixmap        *clip_mask;
+  GdkSubwindowMode  subwindow_mode;
+  gint              ts_x_origin;
+  gint              ts_y_origin;
+  gint              clip_x_origin;
+  gint              clip_y_origin;
+  gint              graphics_exposures;
+  gint              line_width;
+  GdkLineStyle      line_style;
+  GdkCapStyle       cap_style;
+  GdkJoinStyle      join_style;
+};
+
+struct _GdkGC
+{
+  gint dummy_var;
+};
+
+struct _GdkPoint
+{
+  gint16 x;
+  gint16 y;
+};
+
+struct _GdkRectangle
+{
+  gint16 x;
+  gint16 y;
+  guint16 width;
+  guint16 height;
+};
+
+struct _GdkSegment
+{
+  gint16 x1;
+  gint16 y1;
+  gint16 x2;
+  gint16 y2;
+};
+
+struct _GdkFont
+{
+  GdkFontType type;
+  gint ascent;
+  gint descent;
+};
+
+struct _GdkCursor
+{
+  GdkCursorType type;
+};
+
+/* Types for XInput support */
+
+struct _GdkDeviceInfo
+{
+  guint32 deviceid;
+  gchar *name;
+  GdkInputSource source;
+  GdkInputMode mode;
+  gint has_cursor;     /* TRUE if the X pointer follows device motion */
+  gint num_axes;
+  GdkAxisUse *axes;    /* Specifies use for each axis */
+};
+
+struct _GdkTimeCoord
+{
+  guint32 time;
+  gdouble x;
+  gdouble y;
+  gdouble pressure;
+  gdouble xtilt;
+  gdouble ytilt;
+};
+
+struct _GdkEventAny
+{
+  GdkEventType type;
+  GdkWindow *window;
+  gint8 send_event;
+};
+
+struct _GdkEventExpose
+{
+  GdkEventType type;
+  GdkWindow *window;
+  GdkRectangle area;
+  gint count; /* If non-zero, how many more events follow. */
+};
+
+struct _GdkEventMotion
+{
+  GdkEventType type;
+  GdkWindow *window;
+  guint32 time;
+  gdouble x;
+  gdouble y;
+  gdouble pressure;
+  gdouble xtilt;
+  gdouble ytilt;
+  guint state;
+  gint16 is_hint;
+  GdkInputSource source;
+  guint32 deviceid;
+};
+
+struct _GdkEventButton
+{
+  GdkEventType type;
+  GdkWindow *window;
+  guint32 time;
+  gdouble x;
+  gdouble y;
+  gdouble pressure;
+  gdouble xtilt;
+  gdouble ytilt;
+  guint state;
+  guint button;
+  GdkInputSource source;
+  guint32 deviceid;
+};
+
+struct _GdkEventKey
+{
+  GdkEventType type;
+  GdkWindow *window;
+  guint32 time;
+  guint state;
+  guint keyval;
+};
+
+struct _GdkEventCrossing
+{
+  GdkEventType type;
+  GdkWindow *window;
+  GdkWindow *subwindow;
+  GdkNotifyType detail;
+};
+
+struct _GdkEventFocus
+{
+  GdkEventType type;
+  GdkWindow *window;
+  gint16 in;
+};
+
+struct _GdkEventConfigure
+{
+  GdkEventType type;
+  GdkWindow *window;
+  gint16 x, y;
+  gint16 width;
+  gint16 height;
+};
+
+struct _GdkEventProperty
+{
+  GdkEventType type;
+  GdkWindow *window;
+  GdkAtom atom;
+  guint32 time;
+  guint state;
+};
+
+struct _GdkEventSelection
+{
+  GdkEventType type;
+  GdkWindow *window;
+  GdkAtom selection;
+  GdkAtom target;
+  GdkAtom property;
+  guint32 requestor;
+  guint32 time;
+};
+
+/* This event type will be used pretty rarely. It only is important
+   for XInput aware programs that are drawing their own cursor */
+
+struct _GdkEventProximity
+{
+  GdkEventType type;
+  GdkWindow *window;
+  guint32 time;
+  GdkInputSource source;
+  guint32 deviceid;
+};
+
+struct _GdkEventDragRequest
+{
+  GdkEventType type;
+  GdkWindow *window;
+  guint32 requestor;
+  union {
+    struct {
+      guint protocol_version:4;
+      guint sendreply:1;
+      guint willaccept:1;
+      guint delete_data:1; /* Do *not* delete if link is sent, only
+                             if data is sent */
+      guint senddata:1;
+      guint reserved:22;
+    } flags;
+    glong allflags;
+  } u;
+  guint8 isdrop; /* This gdk event can be generated by a couple of
+                   X events - this lets the app know whether the
+                   drop really occurred or we just set the data */
+
+  GdkPoint drop_coords;
+  gchar *data_type;
+};
+
+struct _GdkEventDragBegin
+{
+  GdkEventType type;
+  GdkWindow *window;
+  union {
+    struct {
+      guint protocol_version:4;
+      guint reserved:28;
+    } flags;
+    glong allflags;
+  } u;
+};
+
+struct _GdkEventDropEnter
+{
+  GdkEventType type;
+  GdkWindow *window;
+  guint32 requestor;
+  union {
+    struct {
+      guint protocol_version:4;
+      guint sendreply:1;
+      guint extended_typelist:1;
+      guint reserved:26;
+    } flags;
+    glong allflags;
+  } u;
+};
+
+struct _GdkEventDropLeave
+{
+  GdkEventType type;
+  GdkWindow *window;
+  guint32 requestor;
+  union {
+    struct {
+      guint protocol_version:4;
+      guint reserved:28;
+    } flags;
+    glong allflags;
+  } u;
+};
+
+struct _GdkEventDropDataAvailable
+{
+  GdkEventType type;
+  GdkWindow *window;
+  guint32 requestor;
+  union {
+    struct {
+      guint protocol_version:4;
+      guint isdrop:1;
+      guint reserved:25;
+    } flags;
+    glong allflags;
+  } u;
+  gchar *data_type; /* MIME type */
+  gulong data_numbytes;
+  gpointer data;
+};
+
+struct _GdkEventClient
+{
+  GdkEventType type;
+  GdkWindow *window;
+  GdkAtom message_type;
+  gushort data_format;
+  union {
+    char b[20];
+    short s[10];
+    long l[5];
+  } data;
+};
+
+#ifndef _XLIB_H_
+#define XEvent void
+#endif
+
+struct _GdkEventOther
+{
+  GdkEventType type;
+  GdkWindow *window;
+  XEvent *xevent;
+};
+
+union _GdkEvent
+{
+  GdkEventType      type;
+  GdkEventAny       any;
+  GdkEventExpose    expose;
+  GdkEventMotion    motion;
+  GdkEventButton    button;
+  GdkEventKey       key;
+  GdkEventCrossing  crossing;
+  GdkEventFocus     focus_change;
+  GdkEventConfigure configure;
+  GdkEventProperty  property;
+  GdkEventSelection selection;
+  GdkEventProximity proximity;
+  GdkEventDragBegin dragbegin;
+  GdkEventDragRequest dragrequest;
+  GdkEventDropEnter dropenter;
+  GdkEventDropLeave dropleave;
+  GdkEventDropDataAvailable dropdataavailable;
+  GdkEventClient    client;
+  GdkEventOther     other;
+};
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GDK_TYPES_H__ */
diff --git a/gdk/gdkvisual.c b/gdk/gdkvisual.c
new file mode 100644 (file)
index 0000000..22acee6
--- /dev/null
@@ -0,0 +1,431 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include "gdk.h"
+#include "gdkprivate.h"
+
+
+static void  gdk_visual_add            (GdkVisual *visual);
+static void  gdk_visual_decompose_mask (gulong     mask,
+                                       gint      *shift,
+                                       gint      *prec);
+static guint gdk_visual_hash           (Visual    *key);
+static gint  gdk_visual_compare        (Visual    *a,
+                                       Visual    *b);
+
+
+static GdkVisualPrivate *system_visual;
+static GdkVisualPrivate *visuals;
+static gint nvisuals;
+
+static gint available_depths[4];
+static gint navailable_depths;
+
+static GdkVisualType available_types[6];
+static gint navailable_types;
+
+static char* visual_names[] =
+{
+  "static gray",
+  "grayscale",
+  "static color",
+  "pseudo color",
+  "true color",
+  "direct color",
+};
+
+static GHashTable *visual_hash = NULL;
+
+void
+gdk_visual_init ()
+{
+  static gint possible_depths[5] = { 32, 24, 16, 15, 8 };
+  static GdkVisualType possible_types[6] =
+    {
+      GDK_VISUAL_DIRECT_COLOR,
+      GDK_VISUAL_TRUE_COLOR,
+      GDK_VISUAL_PSEUDO_COLOR,
+      GDK_VISUAL_STATIC_COLOR,
+      GDK_VISUAL_GRAYSCALE,
+      GDK_VISUAL_STATIC_GRAY
+    };
+
+  static gint npossible_depths = 5;
+  static gint npossible_types = 6;
+
+  XVisualInfo *visual_list;
+  XVisualInfo visual_template;
+  GdkVisualPrivate temp_visual;
+  Visual *default_xvisual;
+  int nxvisuals;
+  int i, j;
+
+  visual_template.screen = gdk_screen;
+  visual_list = XGetVisualInfo (gdk_display, VisualScreenMask, &visual_template, &nxvisuals);
+  visuals = g_new (GdkVisualPrivate, nxvisuals);
+
+  default_xvisual = DefaultVisual (gdk_display, gdk_screen);
+
+  nvisuals = 0;
+  for (i = 0; i < nxvisuals; i++)
+    {
+      if (visual_list[i].depth >= 8)
+       {
+#ifdef __cplusplus
+         switch (visual_list[i].c_class)
+#else /* __cplusplus */
+         switch (visual_list[i].class)
+#endif /* __cplusplus */
+           {
+           case StaticGray:
+             visuals[nvisuals].visual.type = GDK_VISUAL_STATIC_GRAY;
+             break;
+           case GrayScale:
+             visuals[nvisuals].visual.type = GDK_VISUAL_GRAYSCALE;
+             break;
+           case StaticColor:
+             visuals[nvisuals].visual.type = GDK_VISUAL_STATIC_COLOR;
+             break;
+           case PseudoColor:
+             visuals[nvisuals].visual.type = GDK_VISUAL_PSEUDO_COLOR;
+             break;
+           case TrueColor:
+             visuals[nvisuals].visual.type = GDK_VISUAL_TRUE_COLOR;
+             break;
+           case DirectColor:
+             visuals[nvisuals].visual.type = GDK_VISUAL_DIRECT_COLOR;
+             break;
+           }
+
+         visuals[nvisuals].visual.depth = visual_list[i].depth;
+         visuals[nvisuals].visual.byte_order =
+           (ImageByteOrder(gdk_display) == LSBFirst) ?
+           GDK_LSB_FIRST : GDK_MSB_FIRST;
+         visuals[nvisuals].visual.red_mask = visual_list[i].red_mask;
+         visuals[nvisuals].visual.green_mask = visual_list[i].green_mask;
+         visuals[nvisuals].visual.blue_mask = visual_list[i].blue_mask;
+         visuals[nvisuals].visual.colormap_size = visual_list[i].colormap_size;
+         visuals[nvisuals].visual.bits_per_rgb = visual_list[i].bits_per_rgb;
+         visuals[nvisuals].xvisual = visual_list[i].visual;
+
+         if ((visuals[nvisuals].visual.type == GDK_VISUAL_TRUE_COLOR) ||
+             (visuals[nvisuals].visual.type == GDK_VISUAL_DIRECT_COLOR))
+           {
+             gdk_visual_decompose_mask (visuals[nvisuals].visual.red_mask,
+                                        &visuals[nvisuals].visual.red_shift,
+                                        &visuals[nvisuals].visual.red_prec);
+
+             gdk_visual_decompose_mask (visuals[nvisuals].visual.green_mask,
+                                        &visuals[nvisuals].visual.green_shift,
+                                        &visuals[nvisuals].visual.green_prec);
+
+             gdk_visual_decompose_mask (visuals[nvisuals].visual.blue_mask,
+                                        &visuals[nvisuals].visual.blue_shift,
+                                        &visuals[nvisuals].visual.blue_prec);
+           }
+         else
+           {
+             visuals[nvisuals].visual.red_mask = 0;
+             visuals[nvisuals].visual.red_shift = 0;
+             visuals[nvisuals].visual.red_prec = 0;
+
+             visuals[nvisuals].visual.green_mask = 0;
+             visuals[nvisuals].visual.green_shift = 0;
+             visuals[nvisuals].visual.green_prec = 0;
+
+             visuals[nvisuals].visual.blue_mask = 0;
+             visuals[nvisuals].visual.blue_shift = 0;
+             visuals[nvisuals].visual.blue_prec = 0;
+           }
+
+         nvisuals += 1;
+       }
+    }
+
+  XFree (visual_list);
+
+  for (i = 0; i < nvisuals; i++)
+    {
+      for (j = i+1; j < nvisuals; j++)
+       {
+         if (visuals[j].visual.depth >= visuals[i].visual.depth)
+           {
+             if ((visuals[j].visual.depth == 8) && (visuals[i].visual.depth == 8))
+               {
+                 if (visuals[j].visual.type == GDK_VISUAL_PSEUDO_COLOR)
+                   {
+                     temp_visual = visuals[j];
+                     visuals[j] = visuals[i];
+                     visuals[i] = temp_visual;
+                   }
+                 else if ((visuals[i].visual.type != GDK_VISUAL_PSEUDO_COLOR) &&
+                          visuals[j].visual.type > visuals[i].visual.type)
+                   {
+                     temp_visual = visuals[j];
+                     visuals[j] = visuals[i];
+                     visuals[i] = temp_visual;
+                   }
+               }
+             else if ((visuals[j].visual.depth > visuals[i].visual.depth) ||
+                      ((visuals[j].visual.depth == visuals[i].visual.depth) &&
+                       (visuals[j].visual.type > visuals[i].visual.type)))
+               {
+                 temp_visual = visuals[j];
+                 visuals[j] = visuals[i];
+                 visuals[i] = temp_visual;
+               }
+           }
+       }
+    }
+
+  for (i = 0; i < nvisuals; i++)
+    if (default_xvisual->visualid == visuals[i].xvisual->visualid)
+      {
+       system_visual = &visuals[i];
+       break;
+      }
+
+  if (gdk_debug_level >= 1)
+    for (i = 0; i < nvisuals; i++)
+      g_print ("visual: %s: %d\n",
+              visual_names[visuals[i].visual.type],
+              visuals[i].visual.depth);
+
+  navailable_depths = 0;
+  for (i = 0; i < npossible_depths; i++)
+    {
+      for (j = 0; j < nvisuals; j++)
+       {
+         if (visuals[j].visual.depth == possible_depths[i])
+           {
+             available_depths[navailable_depths++] = visuals[j].visual.depth;
+             break;
+           }
+       }
+    }
+
+  if (navailable_depths == 0)
+    g_error ("unable to find a usable depth");
+
+  navailable_types = 0;
+  for (i = 0; i < npossible_types; i++)
+    {
+      for (j = 0; j < nvisuals; j++)
+       {
+         if (visuals[j].visual.type == possible_types[i])
+           {
+             available_types[navailable_types++] = visuals[j].visual.type;
+             break;
+           }
+       }
+    }
+
+  for (i = 0; i < nvisuals; i++)
+    gdk_visual_add ((GdkVisual*) &visuals[i]);
+
+  if (npossible_types == 0)
+    g_error ("unable to find a usable visual type");
+}
+
+GdkVisual*
+gdk_visual_ref (GdkVisual *visual)
+{
+  return visual;
+}
+
+void
+gdk_visual_unref (GdkVisual *visual)
+{
+  return;
+}
+
+gint
+gdk_visual_get_best_depth ()
+{
+  return available_depths[0];
+}
+
+GdkVisualType
+gdk_visual_get_best_type ()
+{
+  return available_types[0];
+}
+
+GdkVisual*
+gdk_visual_get_system ()
+{
+  return ((GdkVisual*) system_visual);
+}
+
+GdkVisual*
+gdk_visual_get_best ()
+{
+  return ((GdkVisual*) &(visuals[0]));
+}
+
+GdkVisual*
+gdk_visual_get_best_with_depth (gint depth)
+{
+  GdkVisual *return_val;
+  int i;
+
+  return_val = NULL;
+  for (i = 0; i < nvisuals; i++)
+    if (depth == visuals[i].visual.depth)
+      {
+       return_val = (GdkVisual*) &(visuals[i]);
+       break;
+      }
+
+  return return_val;
+}
+
+GdkVisual*
+gdk_visual_get_best_with_type (GdkVisualType visual_type)
+{
+  GdkVisual *return_val;
+  int i;
+
+  return_val = NULL;
+  for (i = 0; i < nvisuals; i++)
+    if (visual_type == visuals[i].visual.type)
+      {
+       return_val = (GdkVisual*) &(visuals[i]);
+       break;
+      }
+
+  return return_val;
+}
+
+GdkVisual*
+gdk_visual_get_best_with_both (gint          depth,
+                              GdkVisualType visual_type)
+{
+  GdkVisual *return_val;
+  int i;
+
+  return_val = NULL;
+  for (i = 0; i < nvisuals; i++)
+    if ((depth == visuals[i].visual.depth) &&
+       (visual_type == visuals[i].visual.type))
+      {
+       return_val = (GdkVisual*) &(visuals[i]);
+       break;
+      }
+
+  return return_val;
+}
+
+void
+gdk_query_depths  (gint **depths,
+                  gint  *count)
+{
+  *count = navailable_depths;
+  *depths = available_depths;
+}
+
+void
+gdk_query_visual_types (GdkVisualType **visual_types,
+                       gint           *count)
+{
+  *count = navailable_types;
+  *visual_types = available_types;
+}
+
+void
+gdk_query_visuals (GdkVisual **visual_return,
+                  gint       *count)
+{
+  *count = nvisuals;
+  *visual_return = (GdkVisual*) visuals;
+}
+
+
+GdkVisual*
+gdk_visual_lookup (Visual *xvisual)
+{
+  GdkVisual *visual;
+
+  if (!visual_hash)
+    return NULL;
+
+  visual = g_hash_table_lookup (visual_hash, xvisual);
+  return visual;
+}
+
+GdkVisual*
+gdkx_visual_get (VisualID xvisualid)
+{
+  int i;
+
+  for (i = 0; i < nvisuals; i++)
+    if (xvisualid == visuals[i].xvisual->visualid)
+      return (GdkVisual*) &visuals[i];
+
+  return NULL;
+}
+
+
+static void
+gdk_visual_add (GdkVisual *visual)
+{
+  GdkVisualPrivate *private;
+
+  if (!visual_hash)
+    visual_hash = g_hash_table_new ((GHashFunc) gdk_visual_hash,
+                                   (GCompareFunc) gdk_visual_compare);
+
+  private = (GdkVisualPrivate*) visual;
+
+  g_hash_table_insert (visual_hash, private->xvisual, visual);
+}
+
+static void
+gdk_visual_decompose_mask (gulong  mask,
+                          gint   *shift,
+                          gint   *prec)
+{
+  *shift = 0;
+  *prec = 0;
+
+  while (!(mask & 0x1))
+    {
+      (*shift)++;
+      mask >>= 1;
+    }
+
+  while (mask & 0x1)
+    {
+      (*prec)++;
+      mask >>= 1;
+    }
+}
+
+static guint
+gdk_visual_hash (Visual *key)
+{
+  return key->visualid;
+}
+
+static gint
+gdk_visual_compare (Visual *a,
+                   Visual *b)
+{
+  return (a->visualid == b->visualid);
+}
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
new file mode 100644 (file)
index 0000000..aef1367
--- /dev/null
@@ -0,0 +1,1358 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <X11/extensions/shape.h>
+#include <netinet/in.h>
+#include "gdk.h"
+#include "gdkinput.h"
+#include "gdkprivate.h"
+#include <stdlib.h>
+
+int nevent_masks = 16;
+int event_mask_table[18] =
+{
+  ExposureMask,
+  PointerMotionMask,
+  PointerMotionHintMask,
+  ButtonMotionMask,
+  Button1MotionMask,
+  Button2MotionMask,
+  Button3MotionMask,
+  ButtonPressMask | OwnerGrabButtonMask,
+  ButtonReleaseMask | OwnerGrabButtonMask,
+  KeyPressMask,
+  KeyReleaseMask,
+  EnterWindowMask,
+  LeaveWindowMask,
+  FocusChangeMask,
+  StructureNotifyMask,
+  PropertyChangeMask,
+  0,                           /* PROXIMITY_IN */
+  0                            /* PROXIMTY_OUT */
+};
+
+
+void
+gdk_window_init ()
+{
+  XWindowAttributes xattributes;
+  unsigned int width;
+  unsigned int height;
+  unsigned int border_width;
+  unsigned int depth;
+  int x, y;
+
+  XGetGeometry (gdk_display, gdk_root_window, &gdk_root_window,
+               &x, &y, &width, &height, &border_width, &depth);
+  XGetWindowAttributes (gdk_display, gdk_root_window, &xattributes);
+
+  gdk_root_parent.xdisplay = gdk_display;
+  gdk_root_parent.xwindow = gdk_root_window;
+  gdk_root_parent.window_type = GDK_WINDOW_ROOT;
+  gdk_root_parent.window.user_data = NULL;
+}
+
+GdkWindow*
+gdk_window_new (GdkWindow     *parent,
+               GdkWindowAttr *attributes,
+               gint           attributes_mask)
+{
+  GdkWindow *window;
+  GdkWindowPrivate *private;
+  GdkWindowPrivate *parent_private;
+  GdkVisual *visual;
+  GdkColormap *colormap;
+  Display *parent_display;
+  Window xparent;
+  Visual *xvisual;
+  XSetWindowAttributes xattributes;
+  long xattributes_mask;
+  XSizeHints size_hints;
+  XWMHints wm_hints;
+  XTextProperty text_property;
+  XClassHint *class_hint;
+  int x, y, depth;
+  unsigned int class;
+  char *title;
+  int i;
+
+  g_return_val_if_fail (attributes != NULL, NULL);
+
+  if (!parent)
+    parent = (GdkWindow*) &gdk_root_parent;
+
+  parent_private = (GdkWindowPrivate*) parent;
+  xparent = parent_private->xwindow;
+  parent_display = parent_private->xdisplay;
+
+  private = g_new (GdkWindowPrivate, 1);
+  window = (GdkWindow*) private;
+
+  private->parent = parent;
+  private->xdisplay = parent_display;
+  private->destroyed = FALSE;
+  private->resize_count = 0;
+  private->ref_count = 1;
+  xattributes_mask = 0;
+
+  if (attributes_mask & GDK_WA_X)
+    x = attributes->x;
+  else
+    x = 0;
+
+  if (attributes_mask & GDK_WA_Y)
+    y = attributes->y;
+  else
+    y = 0;
+
+  private->x = x;
+  private->y = y;
+  private->width = (attributes->width > 1) ? (attributes->width) : (1);
+  private->height = (attributes->height > 1) ? (attributes->height) : (1);
+  private->window_type = attributes->window_type;
+  private->extension_events = FALSE;
+  private->dnd_drag_data_type = None;
+  private->dnd_drag_data_typesavail =
+    private->dnd_drop_data_typesavail = NULL;
+  private->dnd_drop_enabled = private->dnd_drag_enabled =
+    private->dnd_drag_accepted = private->dnd_drag_datashow =
+    private->dnd_drop_data_numtypesavail =
+    private->dnd_drag_data_numtypesavail = 0;
+  private->dnd_drag_eventmask = private->dnd_drag_savedeventmask = 0;
+
+  window->user_data = NULL;
+
+  if (attributes_mask & GDK_WA_VISUAL)
+    visual = attributes->visual;
+  else
+    visual = gdk_visual_get_system ();
+  xvisual = ((GdkVisualPrivate*) visual)->xvisual;
+
+  xattributes.event_mask = StructureNotifyMask;
+  for (i = 0; i < nevent_masks; i++)
+    {
+      if (attributes->event_mask & (1 << (i + 1)))
+       xattributes.event_mask |= event_mask_table[i];
+    }
+
+  if (xattributes.event_mask)
+    xattributes_mask |= CWEventMask;
+
+  if (attributes->wclass == GDK_INPUT_OUTPUT)
+    {
+      class = InputOutput;
+      depth = visual->depth;
+
+      if (attributes_mask & GDK_WA_COLORMAP)
+       colormap = attributes->colormap;
+      else
+       colormap = gdk_colormap_get_system ();
+
+      xattributes.background_pixel = BlackPixel (gdk_display, gdk_screen);
+      xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);
+      xattributes_mask |= CWBorderPixel | CWBackPixel;
+
+      switch (private->window_type)
+       {
+       case GDK_WINDOW_TOPLEVEL:
+         xattributes.colormap = ((GdkColormapPrivate*) colormap)->xcolormap;
+         xattributes_mask |= CWColormap;
+
+         xparent = gdk_root_window;
+         break;
+
+       case GDK_WINDOW_CHILD:
+         xattributes.colormap = ((GdkColormapPrivate*) colormap)->xcolormap;
+         xattributes_mask |= CWColormap;
+         break;
+
+       case GDK_WINDOW_DIALOG:
+         xattributes.colormap = ((GdkColormapPrivate*) colormap)->xcolormap;
+         xattributes_mask |= CWColormap;
+
+         xparent = gdk_root_window;
+         break;
+
+       case GDK_WINDOW_TEMP:
+         xattributes.colormap = ((GdkColormapPrivate*) colormap)->xcolormap;
+         xattributes_mask |= CWColormap;
+
+         xparent = gdk_root_window;
+
+         xattributes.save_under = True;
+         xattributes.override_redirect = True;
+         xattributes.cursor = None;
+         xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
+         break;
+       case GDK_WINDOW_ROOT:
+         g_error ("cannot make windows of type GDK_WINDOW_ROOT");
+         break;
+       case GDK_WINDOW_PIXMAP:
+         g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
+         break;
+       }
+    }
+  else
+    {
+      depth = 1;
+      class = InputOnly;
+      colormap = NULL;
+    }
+
+  private->xwindow = XCreateWindow (private->xdisplay, xparent,
+                                   x, y, private->width, private->height,
+                                   0, depth, class, xvisual,
+                                   xattributes_mask, &xattributes);
+  gdk_xid_table_insert (&private->xwindow, window);
+
+  switch (private->window_type)
+    {
+    case GDK_WINDOW_DIALOG:
+      XSetTransientForHint (private->xdisplay, private->xwindow, xparent);
+    case GDK_WINDOW_TOPLEVEL:
+    case GDK_WINDOW_TEMP:
+      XSetWMProtocols (private->xdisplay, private->xwindow, gdk_wm_window_protocols, 2);
+      break;
+    case GDK_WINDOW_CHILD:
+      if ((attributes->wclass == GDK_INPUT_OUTPUT) &&
+         (colormap != gdk_colormap_get_system ()) &&
+         (colormap != gdk_window_get_colormap (gdk_window_get_toplevel (window))))
+       {
+         g_print ("adding colormap window\n");
+         gdk_window_add_colormap_windows (window);
+       }
+      break;
+    default:
+      break;
+    }
+
+  size_hints.flags = PSize | PBaseSize;
+  size_hints.width = private->width;
+  size_hints.height = private->height;
+  size_hints.base_width = private->width;
+  size_hints.base_height = private->height;
+
+  wm_hints.flags = InputHint | StateHint | WindowGroupHint;
+  wm_hints.window_group = gdk_leader_window;
+  wm_hints.input = True;
+  wm_hints.initial_state = NormalState;
+
+  XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
+  XSetWMHints (private->xdisplay, private->xwindow, &wm_hints);
+
+  if (attributes_mask & GDK_WA_TITLE)
+    title = attributes->title;
+  else
+    title = gdk_progname;
+
+  if (XStringListToTextProperty (&title, 1, &text_property))
+    {
+      XSetWMName (private->xdisplay, private->xwindow, &text_property);
+      XSetWMIconName (private->xdisplay, private->xwindow, &text_property);
+      XFree (text_property.value);
+    }
+
+  if (attributes_mask & GDK_WA_WMCLASS)
+    {
+      class_hint = XAllocClassHint ();
+      class_hint->res_name = attributes->wmclass_name;
+      class_hint->res_class = attributes->wmclass_class;
+      XSetClassHint (private->xdisplay, private->xwindow, class_hint);
+      XFree (class_hint);
+    }
+
+  gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
+                                 (attributes->cursor) :
+                                 NULL));
+
+  return window;
+}
+
+GdkWindow *
+gdk_window_foreign_new (guint32 anid)
+{
+  GdkWindow *window;
+  GdkWindowPrivate *private;
+  XWindowAttributes attrs;
+
+  private = g_new (GdkWindowPrivate, 1);
+  window = (GdkWindow*) private;
+
+  XGetWindowAttributes (gdk_display, anid, &attrs);
+
+  private->parent = NULL;
+  private->xwindow = anid;
+  private->xdisplay = gdk_display;
+  private->x = attrs.x;
+  private->y = attrs.y;
+  private->width = attrs.width;
+  private->height = attrs.height;
+  private->resize_count = 0;
+  private->ref_count = 1;
+  if (anid == attrs.root)
+    private->window_type = GDK_WINDOW_ROOT;
+  else
+    private->window_type = GDK_WINDOW_TOPLEVEL;
+  /* the above is probably wrong, but it may not be worth the extra
+     X call to get it right */
+    
+  private->destroyed = FALSE;
+  private->extension_events = 0;
+
+  window->user_data = NULL;
+
+  gdk_xid_table_insert (&private->xwindow, window);
+
+  return window;
+}
+
+void
+gdk_window_destroy (GdkWindow *window)
+{
+  GdkWindowPrivate *private;
+  GdkWindowPrivate *temp_private;
+  GdkWindow *temp_window;
+  GList *children;
+  GList *tmp;
+
+  g_return_if_fail (window != NULL);
+
+  private = (GdkWindowPrivate*) window;
+  if(private->dnd_drag_data_numtypesavail > 0) 
+    {
+      free(private->dnd_drag_data_typesavail);
+      private->dnd_drag_data_typesavail = NULL;
+    }
+  if(private->dnd_drop_data_numtypesavail > 0) 
+    {
+      free(private->dnd_drop_data_typesavail);
+      private->dnd_drop_data_typesavail = NULL;
+    }
+  
+  switch (private->window_type)
+    {
+    case GDK_WINDOW_TOPLEVEL:
+    case GDK_WINDOW_CHILD:
+    case GDK_WINDOW_DIALOG:
+    case GDK_WINDOW_TEMP:
+      if (private->ref_count >= 1)
+       private->ref_count -= 1;
+
+      if (!private->destroyed || (private->destroyed == 2))
+       {
+         children = gdk_window_get_children (window);
+         tmp = children;
+
+         while (tmp)
+           {
+             temp_window = tmp->data;
+             tmp = tmp->next;
+
+             temp_private = (GdkWindowPrivate*) temp_window;
+             if (temp_private && !temp_private->destroyed)
+               /* Removes some nice coredumps... /David */
+               {
+                 temp_private->destroyed = 2;
+                 temp_private->ref_count += 1;
+                 gdk_window_destroy (temp_window);
+               }
+           }
+
+         g_list_free (children);
+
+         if (!private->destroyed)
+           XDestroyWindow (private->xdisplay, private->xwindow);
+         private->destroyed = TRUE;
+       }
+      break;
+
+    case GDK_WINDOW_ROOT:
+      g_error ("attempted to destroy root window");
+      break;
+
+    case GDK_WINDOW_PIXMAP:
+      g_warning ("called gdk_window_destroy on a pixmap (use gdk_pixmap_destroy)");
+      gdk_pixmap_destroy (window);
+      break;
+    }
+}
+
+void
+gdk_window_real_destroy (GdkWindow *window)
+{
+  GdkWindowPrivate *private;
+
+  g_return_if_fail (window != NULL);
+
+  private = (GdkWindowPrivate*) window;
+
+  if (private->extension_events != 0)
+    gdk_input_window_destroy (window);
+
+  if (private->ref_count == 0)
+    {
+      gdk_xid_table_remove (private->xwindow);
+      g_free (window);
+    }
+}
+
+GdkWindow*
+gdk_window_ref (GdkWindow *window)
+{
+  GdkWindowPrivate *private = (GdkWindowPrivate *)window;
+  g_return_if_fail (window != NULL);
+
+  private->ref_count += 1;
+  return window;
+}
+
+void
+gdk_window_unref (GdkWindow *window)
+{
+  GdkWindowPrivate *private = (GdkWindowPrivate *)window;
+  g_return_if_fail (window != NULL);
+
+  private->ref_count -= 1;
+  if (private->ref_count == 0)
+    gdk_window_real_destroy (window);
+}
+
+void
+gdk_window_show (GdkWindow *window)
+{
+  GdkWindowPrivate *private;
+
+  g_return_if_fail (window != NULL);
+
+  private = (GdkWindowPrivate*) window;
+  if (!private->destroyed)
+    {
+      XRaiseWindow (private->xdisplay, private->xwindow);
+      XMapWindow (private->xdisplay, private->xwindow);
+    }
+}
+
+void
+gdk_window_hide (GdkWindow *window)
+{
+  GdkWindowPrivate *private;
+
+  g_return_if_fail (window != NULL);
+
+  private = (GdkWindowPrivate*) window;
+  if (!private->destroyed)
+    XUnmapWindow (private->xdisplay, private->xwindow);
+}
+
+void
+gdk_window_move (GdkWindow *window,
+                gint       x,
+                gint       y)
+{
+  GdkWindowPrivate *private;
+
+  g_return_if_fail (window != NULL);
+
+  private = (GdkWindowPrivate*) window;
+  XMoveWindow (private->xdisplay, private->xwindow, x, y);
+
+  if (private->window_type == GDK_WINDOW_CHILD)
+    {
+      private->x = x;
+      private->y = y;
+    }
+}
+
+void
+gdk_window_resize (GdkWindow *window,
+                  gint       width,
+                  gint       height)
+{
+  GdkWindowPrivate *private;
+
+  g_return_if_fail (window != NULL);
+
+  if (width < 1)
+    width = 1;
+  if (height < 1)
+    height = 1;
+
+  private = (GdkWindowPrivate*) window;
+
+  if (!private->destroyed &&
+      ((private->resize_count > 0) ||
+       (private->width != (guint16) width) ||
+       (private->height != (guint16) height)))
+    {
+      XResizeWindow (private->xdisplay, private->xwindow, width, height);
+      private->resize_count += 1;
+
+      if (private->window_type == GDK_WINDOW_CHILD)
+       {
+         private->width = width;
+         private->height = height;
+       }
+    }
+}
+
+void
+gdk_window_move_resize (GdkWindow *window,
+                       gint       x,
+                       gint       y,
+                       gint       width,
+                       gint       height)
+{
+  GdkWindowPrivate *private;
+
+  g_return_if_fail (window != NULL);
+
+  if (width < 1)
+    width = 1;
+  if (height < 1)
+    height = 1;
+
+  private = (GdkWindowPrivate*) window;
+  XMoveResizeWindow (private->xdisplay, private->xwindow, x, y, width, height);
+
+  if (!private->destroyed &&
+      (private->window_type == GDK_WINDOW_CHILD))
+    {
+      private->x = x;
+      private->y = y;
+      private->width = width;
+      private->height = height;
+    }
+}
+
+void
+gdk_window_reparent (GdkWindow *window,
+                    GdkWindow *new_parent,
+                    gint       x,
+                    gint       y)
+{
+  GdkWindowPrivate *window_private;
+  GdkWindowPrivate *parent_private;
+
+  g_return_if_fail (window != NULL);
+
+  if (!new_parent)
+    new_parent = (GdkWindow*) &gdk_root_parent;
+
+  window_private = (GdkWindowPrivate*) window;
+  parent_private = (GdkWindowPrivate*) new_parent;
+
+  XReparentWindow (window_private->xdisplay,
+                  window_private->xwindow,
+                  parent_private->xwindow,
+                  x, y);
+}
+
+void
+gdk_window_clear (GdkWindow *window)
+{
+  GdkWindowPrivate *private;
+
+  g_return_if_fail (window != NULL);
+
+  private = (GdkWindowPrivate*) window;
+
+  XClearWindow (private->xdisplay, private->xwindow);
+}
+
+void
+gdk_window_clear_area (GdkWindow *window,
+                      gint       x,
+                      gint       y,
+                      gint       width,
+                      gint       height)
+{
+  GdkWindowPrivate *private;
+
+  g_return_if_fail (window != NULL);
+
+  private = (GdkWindowPrivate*) window;
+
+  if (!private->destroyed)
+    XClearArea (private->xdisplay, private->xwindow,
+               x, y, width, height, False);
+}
+
+void
+gdk_window_clear_area_e (GdkWindow *window,
+                        gint       x,
+                        gint       y,
+                        gint       width,
+                        gint       height)
+{
+  GdkWindowPrivate *private;
+
+  g_return_if_fail (window != NULL);
+
+  private = (GdkWindowPrivate*) window;
+
+  if (!private->destroyed)
+    XClearArea (private->xdisplay, private->xwindow,
+               x, y, width, height, True);
+}
+
+void
+gdk_window_copy_area (GdkWindow    *window,
+                     GdkGC        *gc,
+                     gint          x,
+                     gint          y,
+                     GdkWindow    *source_window,
+                     gint          source_x,
+                     gint          source_y,
+                     gint          width,
+                     gint          height)
+{
+  GdkWindowPrivate *src_private;
+  GdkWindowPrivate *dest_private;
+  GdkGCPrivate *gc_private;
+
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (gc != NULL);
+  
+  if (source_window == NULL)
+    source_window = window;
+
+  src_private = (GdkWindowPrivate*) source_window;
+  dest_private = (GdkWindowPrivate*) window;
+  gc_private = (GdkGCPrivate*) gc;
+  
+  if (!src_private->destroyed && !dest_private->destroyed)
+  {
+    XCopyArea (dest_private->xdisplay, src_private->xwindow, dest_private->xwindow,
+              gc_private->xgc,
+              source_x, source_y,
+              width, height,
+              x, y);
+  }
+}
+
+void
+gdk_window_raise (GdkWindow *window)
+{
+  GdkWindowPrivate *private;
+
+  g_return_if_fail (window != NULL);
+
+  private = (GdkWindowPrivate*) window;
+
+  if (!private->destroyed)
+    XRaiseWindow (private->xdisplay, private->xwindow);
+}
+
+void
+gdk_window_lower (GdkWindow *window)
+{
+  GdkWindowPrivate *private;
+
+  g_return_if_fail (window != NULL);
+
+  private = (GdkWindowPrivate*) window;
+
+  if (!private->destroyed)
+    XLowerWindow (private->xdisplay, private->xwindow);
+}
+
+void
+gdk_window_set_user_data (GdkWindow *window,
+                         gpointer   user_data)
+{
+  g_return_if_fail (window != NULL);
+
+  window->user_data = user_data;
+}
+
+void
+gdk_window_set_hints (GdkWindow *window,
+                     gint       x,
+                     gint       y,
+                     gint       min_width,
+                     gint       min_height,
+                     gint       max_width,
+                     gint       max_height,
+                     gint       flags)
+{
+  GdkWindowPrivate *private;
+  XSizeHints size_hints;
+
+  g_return_if_fail (window != NULL);
+
+  private = (GdkWindowPrivate*) window;
+  size_hints.flags = 0;
+
+  if (flags & GDK_HINT_POS)
+    {
+      size_hints.flags |= PPosition;
+      size_hints.x = x;
+      size_hints.y = y;
+    }
+
+  if (flags & GDK_HINT_MIN_SIZE)
+    {
+      size_hints.flags |= PMinSize;
+      size_hints.min_width = min_width;
+      size_hints.min_height = min_height;
+    }
+
+  if (flags & GDK_HINT_MAX_SIZE)
+    {
+      size_hints.flags |= PMaxSize;
+      size_hints.max_width = max_width;
+      size_hints.max_height = max_height;
+    }
+
+  if (flags)
+    XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
+}
+
+void
+gdk_window_set_title (GdkWindow   *window,
+                     const gchar *title)
+{
+  GdkWindowPrivate *private;
+
+  g_return_if_fail (window != NULL);
+
+  private = (GdkWindowPrivate*) window;
+  XStoreName (private->xdisplay, private->xwindow, title);
+  XSetIconName (private->xdisplay, private->xwindow, title);
+}
+
+void
+gdk_window_set_background (GdkWindow *window,
+                          GdkColor  *color)
+{
+  GdkWindowPrivate *private;
+
+  g_return_if_fail (window != NULL);
+
+  private = (GdkWindowPrivate*) window;
+  XSetWindowBackground (private->xdisplay, private->xwindow, color->pixel);
+}
+
+void
+gdk_window_set_back_pixmap (GdkWindow *window,
+                           GdkPixmap *pixmap,
+                           gint       parent_relative)
+{
+  GdkWindowPrivate *window_private;
+  GdkPixmapPrivate *pixmap_private;
+  Pixmap xpixmap;
+
+  g_return_if_fail (window != NULL);
+
+  window_private = (GdkWindowPrivate*) window;
+  pixmap_private = (GdkPixmapPrivate*) pixmap;
+
+  if (pixmap)
+    xpixmap = pixmap_private->xwindow;
+  else
+    xpixmap = None;
+
+  if (parent_relative)
+    xpixmap = ParentRelative;
+
+  XSetWindowBackgroundPixmap (window_private->xdisplay, window_private->xwindow, xpixmap);
+}
+
+void
+gdk_window_set_cursor (GdkWindow *window,
+                      GdkCursor *cursor)
+{
+  GdkWindowPrivate *window_private;
+  GdkCursorPrivate *cursor_private;
+  Cursor xcursor;
+
+  g_return_if_fail (window != NULL);
+
+  window_private = (GdkWindowPrivate*) window;
+  cursor_private = (GdkCursorPrivate*) cursor;
+
+  if (!cursor)
+    xcursor = None;
+  else
+    xcursor = cursor_private->xcursor;
+
+  XDefineCursor (window_private->xdisplay, window_private->xwindow, xcursor);
+}
+
+void
+gdk_window_set_colormap (GdkWindow   *window,
+                        GdkColormap *colormap)
+{
+  GdkWindowPrivate *window_private;
+  GdkColormapPrivate *colormap_private;
+
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (colormap != NULL);
+
+  window_private = (GdkWindowPrivate*) window;
+  colormap_private = (GdkColormapPrivate*) colormap;
+
+  XSetWindowColormap (window_private->xdisplay,
+                     window_private->xwindow,
+                     colormap_private->xcolormap);
+
+  if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
+    gdk_window_add_colormap_windows (window);
+}
+
+void
+gdk_window_get_user_data (GdkWindow *window,
+                         gpointer  *data)
+{
+  g_return_if_fail (window != NULL);
+
+  *data = window->user_data;
+}
+
+void
+gdk_window_get_geometry (GdkWindow *window,
+                        gint      *x,
+                        gint      *y,
+                        gint      *width,
+                        gint      *height,
+                        gint      *depth)
+{
+  GdkWindowPrivate *window_private;
+  Window root;
+  gint tx;
+  gint ty;
+  guint twidth;
+  guint theight;
+  guint tborder_width;
+  guint tdepth;
+
+  if (!window)
+    window = (GdkWindow*) &gdk_root_parent;
+
+  window_private = (GdkWindowPrivate*) window;
+
+  XGetGeometry (window_private->xdisplay, window_private->xwindow,
+               &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
+
+  if (x)
+    *x = tx;
+  if (y)
+    *y = ty;
+  if (width)
+    *width = twidth;
+  if (height)
+    *height = theight;
+  if (depth)
+    *depth = tdepth;
+}
+
+void
+gdk_window_get_position (GdkWindow *window,
+                        gint      *x,
+                        gint      *y)
+{
+  GdkWindowPrivate *window_private;
+
+  g_return_if_fail (window != NULL);
+
+  window_private = (GdkWindowPrivate*) window;
+
+  if (x)
+    *x = window_private->x;
+  if (y)
+    *y = window_private->y;
+}
+
+void
+gdk_window_get_size (GdkWindow *window,
+                    gint       *width,
+                    gint       *height)
+{
+  GdkWindowPrivate *window_private;
+
+  g_return_if_fail (window != NULL);
+
+  window_private = (GdkWindowPrivate*) window;
+
+  if (width)
+    *width = window_private->width;
+  if (height)
+    *height = window_private->height;
+}
+
+
+GdkVisual*
+gdk_window_get_visual (GdkWindow *window)
+{
+  GdkWindowPrivate *window_private;
+  XWindowAttributes window_attributes;
+
+  g_return_val_if_fail (window != NULL, NULL);
+
+  window_private = (GdkWindowPrivate*) window;
+  while (window_private && (window_private->window_type == GDK_WINDOW_PIXMAP))
+    window_private = (GdkWindowPrivate*) window_private->parent;
+
+  if (window_private)
+    {
+      XGetWindowAttributes (window_private->xdisplay,
+                           window_private->xwindow,
+                           &window_attributes);
+
+      return gdk_visual_lookup (window_attributes.visual);
+    }
+
+  return NULL;
+}
+
+GdkColormap*
+gdk_window_get_colormap (GdkWindow *window)
+{
+  GdkWindowPrivate *window_private;
+  XWindowAttributes window_attributes;
+
+  g_return_val_if_fail (window != NULL, NULL);
+
+  window_private = (GdkWindowPrivate*) window;
+
+  XGetWindowAttributes (window_private->xdisplay,
+                       window_private->xwindow,
+                       &window_attributes);
+
+  return gdk_colormap_lookup (window_attributes.colormap);
+}
+
+GdkWindowType
+gdk_window_get_type (GdkWindow *window)
+{
+  GdkWindowPrivate *window_private;
+
+  g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
+
+  window_private = (GdkWindowPrivate*) window;
+  return window_private->window_type;
+}
+
+gint
+gdk_window_get_origin (GdkWindow *window,
+                      gint      *x,
+                      gint      *y)
+{
+  GdkWindowPrivate *private;
+  gint return_val;
+  Window child;
+  gint tx, ty;
+
+  g_return_val_if_fail (window != NULL, 0);
+
+  private = (GdkWindowPrivate*) window;
+
+  return_val = XTranslateCoordinates (private->xdisplay,
+                                     private->xwindow,
+                                     gdk_root_window,
+                                     0, 0, &tx, &ty,
+                                     &child);
+
+  if (x)
+    *x = tx;
+  if (y)
+    *y = ty;
+
+  return return_val;
+}
+
+GdkWindow*
+gdk_window_get_pointer (GdkWindow       *window,
+                       gint            *x,
+                       gint            *y,
+                       GdkModifierType *mask)
+{
+  GdkWindowPrivate *private;
+  GdkWindow *return_val;
+  Window root;
+  Window child;
+  int rootx, rooty;
+  int winx, winy;
+  unsigned int xmask;
+
+  if (!window)
+    window = (GdkWindow*) &gdk_root_parent;
+
+  private = (GdkWindowPrivate*) window;
+
+  return_val = NULL;
+  if (XQueryPointer (private->xdisplay, private->xwindow, &root, &child,
+                    &rootx, &rooty, &winx, &winy, &xmask))
+    {
+      if (x) *x = winx;
+      if (y) *y = winy;
+      if (mask) *mask = xmask;
+
+      if (child)
+       return_val = gdk_window_lookup (child);
+    }
+
+  return return_val;
+}
+
+GdkWindow*
+gdk_window_get_parent (GdkWindow *window)
+{
+  g_return_val_if_fail (window != NULL, NULL);
+
+  return ((GdkWindowPrivate*) window)->parent;
+}
+
+GdkWindow*
+gdk_window_get_toplevel (GdkWindow *window)
+{
+  GdkWindowPrivate *private;
+
+  g_return_val_if_fail (window != NULL, NULL);
+
+  private = (GdkWindowPrivate*) window;
+
+  while (private->window_type == GDK_WINDOW_CHILD)
+    {
+      window = ((GdkWindowPrivate*) window)->parent;
+      private = (GdkWindowPrivate*) window;
+    }
+
+  return window;
+}
+
+GList*
+gdk_window_get_children (GdkWindow *window)
+{
+  GdkWindowPrivate *private;
+  GdkWindow *child;
+  GList *children;
+  Window root;
+  Window parent;
+  Window *xchildren;
+  unsigned int nchildren;
+  unsigned int i;
+
+  g_return_val_if_fail (window != NULL, NULL);
+
+  private = (GdkWindowPrivate*) window;
+
+  XQueryTree (private->xdisplay, private->xwindow,
+             &root, &parent, &xchildren, &nchildren);
+
+  children = NULL;
+
+  if (nchildren > 0)
+    {
+      for (i = 0; i < nchildren; i++)
+       {
+         child = gdk_window_lookup (xchildren[i]);
+          if (child)
+            children = g_list_prepend (children, child);
+       }
+
+      XFree (xchildren);
+    }
+
+  return children;
+}
+
+GdkEventMask  
+gdk_window_get_events      (GdkWindow       *window)
+{
+  XWindowAttributes attrs;
+  GdkEventMask event_mask;
+  int i;
+
+  XGetWindowAttributes (gdk_display, ((GdkWindowPrivate *)window)->xwindow, 
+                       &attrs);
+
+  event_mask = 0;
+  for (i = 0; i < nevent_masks; i++)
+    {
+      if (attrs.your_event_mask & event_mask_table[i])
+       event_mask |= 1 << (i + 1);
+    }
+
+  return event_mask;
+}
+
+void          
+gdk_window_set_events      (GdkWindow       *window,
+                           GdkEventMask     event_mask)
+{
+  long xevent_mask;
+  int i;
+
+  xevent_mask = StructureNotifyMask;
+  for (i = 0; i < nevent_masks; i++)
+    {
+      if (event_mask & (1 << (i + 1)))
+       xevent_mask |= event_mask_table[i];
+    }
+  
+  XSelectInput (gdk_display, ((GdkWindowPrivate *)window)->xwindow, 
+               xevent_mask);
+}
+
+void
+gdk_window_add_colormap_windows (GdkWindow *window)
+{
+  GdkWindow *toplevel;
+  GdkWindowPrivate *toplevel_private;
+  GdkWindowPrivate *window_private;
+  Window *old_windows;
+  Window *new_windows;
+  int i, count;
+
+  g_return_if_fail (window != NULL);
+
+  toplevel = gdk_window_get_toplevel (window);
+  toplevel_private = (GdkWindowPrivate*) toplevel;
+  window_private = (GdkWindowPrivate*) window;
+
+  if (!XGetWMColormapWindows (toplevel_private->xdisplay,
+                             toplevel_private->xwindow,
+                             &old_windows, &count))
+    {
+      old_windows = NULL;
+      count = 0;
+    }
+
+  for (i = 0; i < count; i++)
+    if (old_windows[i] == window_private->xwindow)
+      return;
+
+  new_windows = g_new (Window, count + 1);
+
+  for (i = 0; i < count; i++)
+    new_windows[i] = old_windows[i];
+  new_windows[count] = window_private->xwindow;
+
+  XSetWMColormapWindows (toplevel_private->xdisplay,
+                        toplevel_private->xwindow,
+                        new_windows, count + 1);
+
+  g_free (new_windows);
+  if (old_windows)
+    XFree (old_windows);
+}
+
+/*
+ * This needs the X11 shape extension.
+ * If not available, simply remove the call to
+ * XShapeCombineMask. Shaped windows will look
+ * ugly, but programs still work.    Stefan Wille
+ */
+void
+gdk_window_shape_combine_mask (GdkWindow *window,
+                              GdkBitmap *mask,
+                              gint x, gint y)
+{
+  GdkWindowPrivate *window_private;
+  GdkWindowPrivate *pixmap_private;
+
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (mask != NULL);
+
+  window_private = (GdkWindowPrivate*) window;
+  pixmap_private = (GdkWindowPrivate*) mask;
+       
+  XShapeCombineMask  (window_private->xdisplay,
+                     window_private->xwindow,
+                     ShapeBounding,
+                     x, y, /* offset */
+                     (Pixmap)pixmap_private->xwindow,
+                     ShapeSet);
+}
+
+void
+gdk_dnd_drag_addwindow (GdkWindow *window)
+{
+  GdkWindowPrivate *window_private;
+  
+  g_return_if_fail (window != NULL);
+  
+  window_private = (GdkWindowPrivate *) window;
+  
+  if (window_private->dnd_drag_enabled == 1 && gdk_dnd.drag_really == 0)
+    {
+      gdk_dnd.drag_numwindows++;
+      gdk_dnd.drag_startwindows = g_realloc (gdk_dnd.drag_startwindows,
+                                            gdk_dnd.drag_numwindows
+                                            * sizeof(GdkWindow *));
+      gdk_dnd.drag_startwindows[gdk_dnd.drag_numwindows - 1] = window;
+      window_private->dnd_drag_accepted = 0;
+    } 
+  else
+    g_warning ("dnd_really is 1 or drag is not enabled! can't addwindow\n");
+}
+
+void
+gdk_window_dnd_drag_set (GdkWindow   *window,
+                        guint8       drag_enable,
+                        gchar      **typelist,
+                        guint        numtypes)
+{
+  GdkWindowPrivate *window_private;
+  int i, wasset = 0;
+  
+  g_return_if_fail (window != NULL);
+  window_private = (GdkWindowPrivate *) window;
+  
+  window_private->dnd_drag_enabled = drag_enable ? 1 : 0;
+  
+  if (drag_enable)
+    {
+      g_return_if_fail(typelist != NULL);
+      
+      if (window_private->dnd_drag_data_numtypesavail > 3)
+       wasset = 1;
+      window_private->dnd_drag_data_numtypesavail = numtypes;
+      
+      window_private->dnd_drag_data_typesavail =
+       g_realloc (window_private->dnd_drag_data_typesavail,
+                  (numtypes + 1) * sizeof (GdkAtom));
+      
+      for (i = 0; i < numtypes; i++)
+       {
+         /* Allow blanket use of ALL to get anything... */
+         if (strcmp (typelist[i], "ALL"))
+           window_private->dnd_drag_data_typesavail[i] =
+             gdk_atom_intern (typelist[i], FALSE);
+         else
+           window_private->dnd_drag_data_typesavail[i] = None;
+       }
+      
+      /* 
+       * set our extended type list if we need to 
+       */
+      if (numtypes > 3)
+       gdk_property_change(window, gdk_dnd.gdk_XdeTypelist,
+                           XA_PRIMARY, 32, GDK_PROP_MODE_REPLACE,
+                           (guchar *)(window_private->dnd_drag_data_typesavail
+                            + (sizeof(GdkAtom) * 3)),
+                           (numtypes - 3) * sizeof(GdkAtom));
+      else if (wasset)
+       gdk_property_delete (window, gdk_dnd.gdk_XdeTypelist);
+    }
+  else
+    {
+      free (window_private->dnd_drag_data_typesavail);
+      window_private->dnd_drag_data_typesavail = NULL;
+      window_private->dnd_drag_data_numtypesavail = 0;
+    }
+}
+
+void
+gdk_window_dnd_drop_set (GdkWindow   *window,
+                        guint8       drop_enable,
+                        gchar      **typelist,
+                        guint        numtypes,
+                        guint8       destructive_op)
+{
+  GdkWindowPrivate *window_private;
+  int i;
+  
+  g_return_if_fail (window != NULL);
+  
+  window_private = (GdkWindowPrivate *) window;
+  
+  window_private->dnd_drop_enabled = drop_enable ? 1 : 0;
+  if (drop_enable)
+    {
+      g_return_if_fail(typelist != NULL);
+      
+      window_private->dnd_drop_data_numtypesavail = numtypes;
+      
+      window_private->dnd_drop_data_typesavail =
+       g_realloc (window_private->dnd_drop_data_typesavail,
+                  (numtypes + 1) * sizeof (GdkAtom));
+      
+      for (i = 0; i < numtypes; i++)
+       window_private->dnd_drop_data_typesavail[i] =
+         gdk_atom_intern (typelist[i], FALSE);
+      
+      window_private->dnd_drop_destructive_op = destructive_op;
+    }
+}
+
+/* 
+ * This is used to reply to a GDK_DRAG_REQUEST event
+ * (which may be generated by XdeRequest or a confirmed drop... 
+ */
+void
+gdk_window_dnd_data_set (GdkWindow       *window,
+                        GdkEvent        *event,
+                        gpointer         data,
+                        gulong           data_numbytes)
+{
+  GdkWindowPrivate *window_private;
+  XEvent sev;
+  GdkEventDropDataAvailable tmp_ev;
+  gchar *tmp;
+  
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (event != NULL);
+  g_return_if_fail (data != NULL);
+  g_return_if_fail (data_numbytes > 0);
+  g_return_if_fail (event->type == GDK_DRAG_REQUEST);
+
+  g_free (event->dragrequest.data_type);
+  event->dragrequest.data_type = NULL;
+  
+  window_private = (GdkWindowPrivate *) window;
+  g_return_if_fail (window_private->dnd_drag_accepted != 0);    
+  
+  /* We set the property on our window... */
+  gdk_property_change (window, window_private->dnd_drag_data_type,
+                      XA_PRIMARY, 8, GDK_PROP_MODE_REPLACE, data,
+                      data_numbytes);
+  tmp = gdk_atom_name(window_private->dnd_drag_data_type);
+  g_print("DnD type %s on window %ld\n", tmp, window_private->xwindow);
+  g_free(tmp);
+  
+  /* 
+   * Then we send the event to tell the receiving window that the
+   * drop has happened 
+   */
+  tmp_ev.u.allflags = 0;
+  tmp_ev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
+  tmp_ev.u.flags.isdrop = event->dragrequest.isdrop;
+  
+  sev.xclient.type = ClientMessage;
+  sev.xclient.format = 32;
+  sev.xclient.window = event->dragrequest.requestor;
+  sev.xclient.message_type = gdk_dnd.gdk_XdeDataAvailable;
+  sev.xclient.data.l[0] = window_private->xwindow;
+  sev.xclient.data.l[1] = tmp_ev.u.allflags;
+  sev.xclient.data.l[2] = window_private->dnd_drag_data_type;
+
+  if (event->dragrequest.isdrop)
+    sev.xclient.data.l[3] = event->dragrequest.drop_coords.x +
+      (event->dragrequest.drop_coords.y << 16);
+  else
+    sev.xclient.data.l[3] = 0;
+  
+  sev.xclient.data.l[4] = 0;
+  
+  XSendEvent (gdk_display, event->dragrequest.requestor, False,
+             NoEventMask, &sev);
+}
diff --git a/gdk/gdkx.h b/gdk/gdkx.h
new file mode 100644 (file)
index 0000000..cb8e33b
--- /dev/null
@@ -0,0 +1,48 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GDK_X_H__
+#define __GDK_X_H__
+
+#include <gdk/gdkprivate.h>
+
+
+#define GDK_ROOT_WINDOW()             gdk_root_window
+#define GDK_ROOT_PARENT()             &gdk_root_parent
+#define GDK_DISPLAY()                 gdk_display
+#define GDK_WINDOW_XDISPLAY(win)      (((GdkWindowPrivate*) win)->xdisplay)
+#define GDK_WINDOW_XWINDOW(win)       (((GdkWindowPrivate*) win)->xwindow)
+#define GDK_IMAGE_XDISPLAY(image)     (((GdkImagePrivate*) image)->xdisplay)
+#define GDK_IMAGE_XIMAGE(image)       (((GdkImagePrivate*) image)->ximage)
+#define GDK_GC_XDISPLAY(gc)           (((GdkGCPrivate*) gc)->xdisplay)
+#define GDK_GC_XGC(gc)                (((GdkGCPrivate*) gc)->xgc)
+#define GDK_COLORMAP_XDISPLAY(cmap)   (((GdkColormapPrivate*) cmap)->xdisplay)
+#define GDK_COLORMAP_XCOLORMAP(cmap)  (((GdkColormapPrivate*) cmap)->xcolormap)
+#define GDK_VISUAL_XVISUAL(vis)       (((GdkVisualPrivate*) vis)->xvisual)
+#define GDK_FONT_XDISPLAY(font)       (((GdkFontPrivate*) font)->xdisplay)
+#define GDK_FONT_XFONT(font)          (((GdkFontPrivate*) font)->xfont)
+
+
+GdkVisual*   gdkx_visual_get   (VisualID xvisualid);
+GdkColormap* gdkx_colormap_get (Colormap xcolormap);
+/* Utility function in gdk.c - not sure where it belongs, but it's
+   needed in more than one place, so make it public */
+Window        gdk_get_client_window      (Display  *dpy,
+                                          Window    win);
+
+
+#endif /* __GDK_X_H__ */
diff --git a/gdk/gdkxid.c b/gdk/gdkxid.c
new file mode 100644 (file)
index 0000000..7ee6075
--- /dev/null
@@ -0,0 +1,74 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gdkprivate.h"
+
+
+static guint gdk_xid_hash    (XID *xid);
+static gint  gdk_xid_compare (XID *a,
+                             XID *b);
+
+
+GHashTable *xid_ht = NULL;
+
+
+void
+gdk_xid_table_insert (XID      *xid,
+                     gpointer  data)
+{
+  g_return_if_fail (xid != NULL);
+
+  if (!xid_ht)
+    xid_ht = g_hash_table_new ((GHashFunc) gdk_xid_hash,
+                              (GCompareFunc) gdk_xid_compare);
+
+  g_hash_table_insert (xid_ht, xid, data);
+}
+
+void
+gdk_xid_table_remove (XID xid)
+{
+  if (!xid_ht)
+    xid_ht = g_hash_table_new ((GHashFunc) gdk_xid_hash,
+                              (GCompareFunc) gdk_xid_compare);
+
+  g_hash_table_remove (xid_ht, &xid);
+}
+
+gpointer
+gdk_xid_table_lookup (XID xid)
+{
+  gpointer data;
+
+  data = g_hash_table_lookup (xid_ht, &xid);
+
+  return data;
+}
+
+
+static guint
+gdk_xid_hash (XID *xid)
+{
+  return *xid;
+}
+
+static gint
+gdk_xid_compare (XID *a,
+                XID *b)
+{
+  return (*a == *b);
+}
diff --git a/gdk/gxid.c b/gdk/gxid.c
new file mode 100644 (file)
index 0000000..219c08b
--- /dev/null
@@ -0,0 +1,844 @@
+/* 
+ * gxid version 0.3
+ *
+ * Copyright 1997 Owen Taylor <owt1@cornell.edu>
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/XInput.h>
+
+#include "gxid_proto.h"
+
+/* #define DEBUG_CLIENTS  */
+/* #define DEBUG_EVENTS */
+
+char *program_name;
+Display *dpy;
+Window root_window;            /* default root window of dpy */
+int port = 0;                  /* port to listen on */
+int socket_fd = 0;             /* file descriptor of socket */
+typedef struct GxidWindow_ GxidWindow;
+
+typedef struct GxidDevice_ GxidDevice;
+struct GxidDevice_ {
+  XID id;
+  int exclusive;
+  int ispointer;
+  
+  XDevice *xdevice;
+  int motionnotify_type;
+  int changenotify_type;
+};
+
+struct GxidWindow_ {
+  Window xwindow;
+  /* Immediate child of root that is ancestor of window */
+  Window root_child;
+  int num_devices;
+  GxidDevice **devices;
+};
+
+GxidDevice **devices = NULL;
+int num_devices = 0;
+GxidWindow **windows = NULL;
+int num_windows = 0;
+
+void
+handler(int signal)
+{
+  fprintf(stderr,"%s: dying on signal %d\n",program_name,signal);
+  if (socket_fd)
+    close(socket_fd);
+  exit(1);
+}
+
+void
+init_socket()
+{
+  struct sockaddr_in sin;
+
+  socket_fd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
+  if (socket_fd < 0)
+    {
+      fprintf (stderr, "%s: error getting socket\n",
+              program_name);
+      exit(1);
+    }
+  
+  sin.sin_family = AF_INET;
+  sin.sin_port = htons(port);
+  sin.sin_addr.s_addr = INADDR_ANY;
+  
+  if (bind(socket_fd,(struct sockaddr *)(&sin),
+          sizeof(struct sockaddr_in)) < 0)
+    {
+      fprintf (stderr,"%s: cannot bind to port %d\n",
+              program_name,port);
+      exit(1);
+    }
+
+  if (listen(socket_fd,5) < 0)
+    {
+      fprintf (stderr,"%s: error listening on socket\n",
+              program_name);
+      exit(1);
+    };
+}
+
+#define NUM_EVENTC 2
+static void
+enable_device(GxidDevice *dev)
+{
+  XEventClass xevc[NUM_EVENTC];
+  int num_eventc = NUM_EVENTC;
+  int i,j;
+
+  if (!dev->xdevice) 
+    {
+      if (dev->ispointer) return;
+
+      dev->xdevice = XOpenDevice(dpy, dev->id);
+      if (!dev->xdevice) return;
+      
+      DeviceMotionNotify (dev->xdevice, dev->motionnotify_type,
+                         xevc[0]);
+      ChangeDeviceNotify (dev->xdevice, dev->changenotify_type,
+                         xevc[1]);
+
+      /* compress out zero event classes */
+      for (i=0,j=0;i<NUM_EVENTC;i++)
+       {
+         if (xevc[i]) {
+           xevc[j] = xevc[i];
+           j++;
+         }
+      }
+      num_eventc = j;
+      
+      XSelectExtensionEvent (dpy, root_window, xevc, num_eventc);
+    }
+}
+
+/* switch the core pointer from whatever it is now to something else,
+   return true on success, false otherwise */
+static int
+switch_core_pointer()
+{
+  GxidDevice *old_pointer = 0;
+  GxidDevice *new_pointer = 0;
+  int result;
+  int i;
+
+  for (i=0;i<num_devices;i++)
+    {
+      if (devices[i]->ispointer)
+       old_pointer = devices[i];
+      else
+       if (!new_pointer && !devices[i]->exclusive)
+         new_pointer = devices[i];
+    }
+
+  if (!old_pointer || !new_pointer)
+    return 0;
+
+#ifdef DEBUG_EVENTS
+  fprintf(stderr,"gxid: Switching core from %ld to %ld\n",
+        old_pointer->id,new_pointer->id);
+#endif
+  result = XChangePointerDevice(dpy,new_pointer->xdevice, 0, 1);
+  if (result != Success)
+    {
+      fprintf(stderr,"gxid: Error %d switching core from %ld to %ld\n",
+             result, old_pointer->id, new_pointer->id);
+    }
+  else
+    {
+      new_pointer->ispointer = 1;
+      old_pointer->ispointer = 0;
+      if (!old_pointer->xdevice)
+       enable_device(old_pointer);
+    }
+
+  return 1;
+}
+
+void
+disable_device(GxidDevice *dev)
+{
+  if (dev->xdevice)
+    {
+      if (dev->ispointer)
+       return;
+      XCloseDevice(dpy,dev->xdevice);
+      dev->xdevice = 0;
+    }
+}
+
+GxidDevice *
+init_device(XDeviceInfo *xdevice)
+{
+  GxidDevice *dev = (GxidDevice *)malloc(sizeof(GxidDevice));
+  XAnyClassPtr class;
+  int num_axes, i;
+
+  dev->id = xdevice->id;
+  dev->exclusive = 0;
+  dev->xdevice = NULL;
+
+  dev->ispointer = (xdevice->use == IsXPointer);
+
+  /* step through the classes */
+
+  num_axes = 0;
+  class = xdevice->inputclassinfo;
+  for (i=0;i<xdevice->num_classes;i++) 
+    {
+      if (class->class == ValuatorClass) 
+       {
+         XValuatorInfo *xvi = (XValuatorInfo *)class;
+         num_axes = xvi->num_axes;
+       }
+      class = (XAnyClassPtr)(((char *)class) + class->length);
+    }
+
+  /* return NULL if insufficient axes */
+  if (num_axes < 2)
+    {
+      free((void *)dev);
+      return NULL;
+    }
+
+  if (!dev->ispointer)
+      enable_device(dev);
+  return dev;
+}
+
+void
+init_xinput()
+{
+  char **extensions;
+  XDeviceInfo   *xdevices;
+  int num_xdevices;
+  int num_extensions;
+  int i;
+
+  extensions = XListExtensions(dpy, &num_extensions);
+  for (i = 0; i < num_extensions &&
+        (strcmp(extensions[i], "XInputExtension") != 0); i++);
+  XFreeExtensionList(extensions);
+  if (i == num_extensions)     /* XInput extension not found */
+    {
+      fprintf(stderr,"XInput extension not found\n");
+      exit(1);
+    }
+
+  xdevices = XListInputDevices(dpy, &num_xdevices);
+  devices = (GxidDevice **)malloc(num_xdevices * sizeof(GxidDevice *));
+
+  num_devices = 0;
+  for(i=0; i<num_xdevices; i++)
+    {
+      GxidDevice *dev = init_device(&xdevices[i]);
+      if (dev)
+         devices[num_devices++] = dev;
+    }
+  XFreeDeviceList(xdevices);
+}
+
+/* If this routine needs fixing, the corresponding routine
+   in gdkinputgxi.h will need it too. */
+
+Window
+gxi_find_root_child(Display *dpy, Window w)
+{
+  Window root,parent;
+  Window *children;
+  int nchildren;
+
+  parent = w;
+  do 
+    {
+      w = parent;
+      XQueryTree(dpy,w,&root,&parent,&children,&nchildren);
+      if (children) XFree(children);
+    } 
+  while (parent != root);
+  
+  return w;
+}
+
+int
+handle_claim_device(GxidClaimDevice *msg)
+{
+  int i,j;
+  XID devid = ntohl(msg->device);
+  XID winid = ntohl(msg->window);
+  int exclusive = ntohl(msg->exclusive);
+  GxidDevice *device = NULL;
+  GxidWindow *window = NULL;
+
+#ifdef DEBUG_CLIENTS
+  fprintf(stderr,"device %ld claimed (window 0x%lx)\n",devid,winid);
+#endif  
+
+  for (i=0;i<num_devices;i++)
+    {
+      if (devices[i]->id == devid)
+       {
+         device = devices[i];
+         break;
+       }
+    }
+  if (!device)
+    {
+      fprintf(stderr,"%s: Unknown device id %ld\n",program_name,devid);
+      return GXID_RETURN_ERROR;
+    }
+
+  if (device->exclusive)
+    {
+      /* already in use */
+      fprintf(stderr,
+             "%s: Device %ld already claimed in exclusive mode\n",
+             program_name,devid);
+      return GXID_RETURN_ERROR;
+    }
+
+  if (exclusive)
+    {
+      for (i=0;i<num_windows;i++)
+       {
+         for (j=0;j<windows[i]->num_devices;j++)
+           if (windows[i]->devices[j]->id == devid)
+             {
+               /* already in use */
+               fprintf(stderr,
+                       "%s: Can't establish exclusive use of device %ld\n",
+                       program_name,devid);
+               return GXID_RETURN_ERROR;
+             }
+       }
+      if (device->ispointer)
+       if (!switch_core_pointer())
+         {
+           fprintf(stderr,
+                   "%s: Can't free up core pointer %ld\n",
+                   program_name,devid);
+           return GXID_RETURN_ERROR;
+         }
+
+      device->exclusive = 1;
+      disable_device(device);
+      XSelectInput(dpy,winid,StructureNotifyMask);
+    }
+  else                         /* !exclusive */
+    {
+      /* FIXME: this is a bit improper. We probably should do this only
+        when a window is first claimed. But we might be fooled if
+        an old client died without releasing it's windows. So until
+        we look for client-window closings, do it here 
+        
+        (We do look for closings now...)
+        */
+      
+      XSelectInput(dpy,winid,EnterWindowMask|StructureNotifyMask);
+    }
+
+  for (i=0;i<num_windows;i++)
+    {
+      if (windows[i]->xwindow == winid)
+        {
+         window = windows[i];
+         break;
+       }
+    }
+
+  /* Create window structure if no devices have been previously
+     claimed on it */
+  if (!window)
+    {
+      num_windows++;
+      windows = (GxidWindow **)realloc(windows,
+                                      sizeof(GxidWindow*)*num_windows);
+      window = (GxidWindow *)malloc(sizeof(GxidWindow));
+      windows[num_windows-1] = window;
+
+      window->xwindow = winid;
+      window->root_child = gxi_find_root_child(dpy,winid);
+      window->num_devices = 0;
+      window->devices = 0;
+    }
+
+  
+  for (i=0;i<window->num_devices;i++)
+    {
+      if (window->devices[i] == device)
+       return GXID_RETURN_OK;
+    }
+  
+  window->num_devices++;
+  window->devices = (GxidDevice **)realloc(window->devices,
+                                           sizeof(GxidDevice*)*num_devices);
+  /* we need add the device to the window */
+  window->devices[i] = device;
+
+  return GXID_RETURN_OK;
+}
+
+int
+handle_release_device(GxidReleaseDevice *msg)
+{
+  int i,j;
+  XID devid = ntohl(msg->device);
+  XID winid = ntohl(msg->window);
+
+  GxidDevice *device = NULL;
+
+#ifdef DEBUG_CLIENTS
+  fprintf(stderr,"device %ld released (window 0x%lx)\n",devid,winid);
+#endif  
+
+  for (i=0;i<num_devices;i++)
+    {
+      if (devices[i]->id == devid)
+       {
+         device = devices[i];
+         break;
+       }
+    }
+  if (!device)
+    {
+      fprintf(stderr,"%s: Unknown device id %ld\n",program_name,devid);
+      return GXID_RETURN_ERROR;
+    }
+
+  for (i=0;i<num_windows;i++)
+    {
+      GxidWindow *w = windows[i];
+      
+      if (w->xwindow == winid)
+       for (j=0;j<w->num_devices;j++)
+         if (w->devices[j]->id == devid)
+           {
+             if (j<w->num_devices-1)
+               w->devices[j] = w->devices[w->num_devices-1];
+             w->num_devices--;
+
+             if (w->num_devices == 0)
+               {
+                 if (i<num_windows-1)
+                   windows[i] = windows[num_windows-1];
+                 num_windows--;
+
+                 free((void *)w);
+                 /* FIXME: should we deselect input? But what
+                    what if window is already destroyed */
+               }
+
+             if (device->exclusive)
+               {
+                 device->exclusive = 0;
+                 enable_device(device);
+               }
+             return GXID_RETURN_OK;
+           }
+    }
+  
+  /* device/window combination not found */
+  fprintf(stderr,
+         "%s: Device %ld not claimed for window 0x%lx\n",
+         program_name,devid,winid);
+  return GXID_RETURN_ERROR;
+}
+
+void
+handle_connection()
+{
+  GxidMessage msg;
+  GxidU32 type;
+  int length;
+  GxidI32 retval;
+
+  int conn_fd;
+  struct sockaddr_in sin;
+  int sin_length;
+  int count;
+
+  sin_length = sizeof(struct sockaddr_in);
+  conn_fd = accept(socket_fd,(struct sockaddr *)&sin,&sin_length);
+  if (conn_fd < 0)
+    {
+      fprintf(stderr,"%s: Error accepting connection\n",
+             program_name);
+      exit(1);
+    }
+
+  /* read type and length of message */
+
+  count = read(conn_fd,(char *)&msg,2*sizeof(GxidU32));
+  if (count != 2*sizeof(GxidU32))
+    {
+      fprintf(stderr,"%s: Error reading message header\n",
+             program_name);
+      close(conn_fd);
+      return;
+    }
+  type = ntohl(msg.any.type);
+  length = ntohl(msg.any.length);
+
+  /* read rest of message */
+
+  if (length > sizeof(GxidMessage)) 
+    {
+      fprintf(stderr,"%s: Bad message length\n",
+             program_name);
+      close(conn_fd);
+      return;
+    }
+
+  count = read(conn_fd,2*sizeof(GxidU32) + (char *)&msg,
+                   length - 2*sizeof(GxidU32));
+  if (count != length - 2*sizeof(GxidU32))
+    {
+      fprintf(stderr,"%s: Error reading message body\n",
+             program_name);
+      close(conn_fd);
+      return;
+    }
+
+  switch (type)
+    {
+    case GXID_CLAIM_DEVICE:
+      retval = handle_claim_device((GxidClaimDevice *)&msg);
+      break;
+    case GXID_RELEASE_DEVICE:
+      retval = handle_release_device((GxidReleaseDevice *)&msg);
+      break;
+    default:
+      fprintf(stderr,"%s: Unknown message type: %ld (ignoring)\n",
+             program_name,type);
+      close(conn_fd);
+      return;
+    }
+
+  count = write(conn_fd,&retval,sizeof(GxidI32));
+  if (count != sizeof(GxidI32))
+    {
+      fprintf(stderr,"%s: Error writing return code\n",
+             program_name);
+    }
+  
+  close(conn_fd);
+}
+
+void
+handle_motion_notify(XDeviceMotionEvent *event)
+{
+  int i,j;
+  GxidDevice *old_device = NULL;
+  GxidDevice *new_device = NULL;
+  Window w, root, child;
+  int root_x, root_y, x, y, mask;
+  
+  for (j=0;j<num_devices;j++)
+    {
+      if (devices[j]->ispointer)
+       old_device = devices[j];
+      if (devices[j]->id == event->deviceid)
+       new_device = devices[j];
+    }
+
+  if (new_device && !new_device->exclusive && !new_device->ispointer)
+    {
+      /* make sure we aren't stealing the pointer back from a slow
+        client */
+      child = root_window;
+      do
+       {
+         w = child;
+         /* FIXME: this fails disasterously if child vanishes between
+            calls. (Which is prone to happening since we get events
+            on root just as the client exits) */
+            
+         XQueryPointer(dpy,w,&root,&child,&root_x,&root_y,
+                       &x,&y,&mask);
+       }
+      while (child != None);
+
+      for (i=0;i<num_windows;i++)
+       if (windows[i]->xwindow == w)
+         for (j=0;j<windows[i]->num_devices;j++)
+           if (windows[i]->devices[j] == new_device)
+               return;
+      
+      /* FIXME: do something smarter with axes */
+      XChangePointerDevice(dpy,new_device->xdevice, 0, 1);
+      new_device->ispointer = 1;
+      
+      old_device->ispointer = 0;
+      if (!old_device->xdevice)
+       enable_device(old_device);
+    }
+}
+
+void
+handle_change_notify(XChangeDeviceNotifyEvent *event)
+{
+  int j;
+  GxidDevice *old_device = NULL;
+  GxidDevice *new_device = NULL;
+
+
+  for (j=0;j<num_devices;j++)
+    {
+      if (devices[j]->ispointer)
+       old_device = devices[j];
+      if (devices[j]->id == event->deviceid)
+       new_device = devices[j];
+    }
+
+#ifdef DEBUG_EVENTS
+  fprintf(stderr,"gxid: ChangeNotify event; old = %ld; new = %ld\n",
+         old_device->id, new_device->id);
+#endif
+
+  if (old_device != new_device)
+    {
+      new_device->ispointer = 1;
+      
+      old_device->ispointer = 0;
+      if (!old_device->xdevice)
+       enable_device(old_device);
+    }
+}
+
+void
+handle_enter_notify(XEnterWindowEvent *event, GxidWindow *window)
+{
+  int i;
+  GxidDevice *old_pointer = NULL;
+  for (i=0;i<num_devices;i++)
+    {
+      if (devices[i]->ispointer)
+       {
+         old_pointer = devices[i];
+         break;
+       }
+    }
+
+#ifdef DEBUG_EVENTS
+  fprintf(stderr,"gxid: Enter event; oldpointer = %ld\n",
+         old_pointer->id);
+#endif
+
+  if (old_pointer)
+    for (i=0;i<window->num_devices;i++)
+      {
+       if (window->devices[i] == old_pointer)
+         {
+           switch_core_pointer();
+           break;
+         }
+      }
+}
+
+void
+handle_destroy_notify(XDestroyWindowEvent *event)
+{
+  int i,j;
+
+  for (i=0;i<num_windows;i++)
+    if (windows[i]->xwindow == event->window)
+      {
+       GxidWindow *w = windows[i];
+       
+       for (j=0;j<w->num_devices;j++)
+         {
+#ifdef DEBUG_CLIENTS
+           fprintf(stderr,"device %ld released on destruction of window 0x%lx.\n",
+                   w->devices[j]->id,w->xwindow);
+#endif  
+
+           if (w->devices[j]->exclusive)
+             {
+               w->devices[j]->exclusive = 0;
+               enable_device(devices[j]);
+             }
+         }
+       
+       if (i<num_windows-1)
+         windows[i] = windows[num_windows-1];
+       num_windows--;
+       
+       if (w->devices)
+         free((void *)w->devices);
+       free((void *)w);
+       /* FIXME: should we deselect input? But what
+          what if window is already destroyed */
+       
+       return;
+      }
+}
+
+void
+handle_xevent()
+{
+  int i;
+  XEvent event;
+       
+  XNextEvent (dpy, &event);
+
+#ifdef DEBUG_EVENTS
+  fprintf(stderr,"Event - type = %d; window = 0x%lx\n",
+         event.type,event.xany.window);
+#endif
+
+  if (event.type == ConfigureNotify)
+    {
+#ifdef DEBUG_EVENTS
+      XConfigureEvent *xce = (XConfigureEvent *)&event;
+      fprintf(stderr," configureNotify: window = 0x%lx\n",xce->window);
+#endif
+    }
+  else if (event.type == EnterNotify)
+    {
+      /* pointer entered a claimed window */
+      for (i=0;i<num_windows;i++)
+       {
+         if (event.xany.window == windows[i]->xwindow)
+           handle_enter_notify((XEnterWindowEvent *)&event,windows[i]);
+       }
+    }
+  else if (event.type == DestroyNotify)
+    {
+      /* A claimed window was destroyed */
+      for (i=0;i<num_windows;i++)
+       {
+         if (event.xany.window == windows[i]->xwindow)
+           handle_destroy_notify((XDestroyWindowEvent *)&event);
+       }
+    }
+  else
+    for (i=0;i<num_devices;i++)
+      {
+       if (event.type == devices[i]->motionnotify_type)
+         {
+           handle_motion_notify((XDeviceMotionEvent *)&event);
+           break;
+         }
+       else if (event.type == devices[i]->changenotify_type)
+         {
+           handle_change_notify((XChangeDeviceNotifyEvent *)&event);
+           break;
+         }
+      }
+}
+
+void 
+usage()
+{
+  fprintf(stderr,"Usage: %s [-d display] [-p --gxid-port port]\n",
+         program_name);
+  exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+  int i;
+  char *display_name = NULL;
+  fd_set readfds;
+
+  program_name = argv[0];
+
+  for (i=1;i<argc;i++)
+    {
+      if (!strcmp(argv[i],"-d"))
+       {
+           if (++i >= argc) usage();
+           display_name = argv[i];
+       }
+      else if (!strcmp(argv[i],"--gxid-port") ||
+              !strcmp(argv[i],"-p"))
+       {
+         if (++i >= argc) usage();
+         port = atoi(argv[i]);
+         break;
+       }
+      else
+       usage();
+    }
+
+  if (!port) 
+    {
+      char *t = getenv("GXID_PORT");
+      if (t)
+       port = atoi(t);
+      else
+       port = 6951;
+    }
+  /* set up a signal handler so we can clean up if killed */
+
+  signal(SIGTERM,handler);
+  signal(SIGINT,handler);
+  
+  /* initialize the X connection */
+  
+  dpy = XOpenDisplay (display_name);
+  if (!dpy)
+    {
+      fprintf (stderr, "%s:  unable to open display '%s'\n",
+              program_name, XDisplayName (display_name));
+      exit (1);
+    }
+  
+  root_window = DefaultRootWindow(dpy);
+
+  /* We'll want to do this in the future if we are to support
+     gxid monitoring visibility information for clients */
+#if 0
+  XSelectInput(dpy,root_window,SubstructureNotifyMask);
+#endif
+  init_xinput();
+  
+  /* set up our server connection */
+  
+  init_socket();
+  
+  /* main loop */
+
+  if (XPending(dpy))           /* this seems necessary to get things
+                                  in sync */
+    handle_xevent();
+  while (1) 
+    {
+
+      FD_ZERO(&readfds);
+      FD_SET(ConnectionNumber(dpy),&readfds);
+      FD_SET(socket_fd,&readfds);
+
+      if (select(8*sizeof(readfds),&readfds,
+                (fd_set *)0,(fd_set *)0, (struct timeval *)0) < 0)
+       {
+         fprintf(stderr,"Error in select\n");
+         exit(1);
+       }
+
+      if (FD_ISSET(socket_fd,&readfds))
+       handle_connection(socket_fd);
+       
+      while (XPending(dpy))
+       handle_xevent();
+    }
+
+  XCloseDisplay (dpy);
+  exit (0);
+}
diff --git a/gdk/gxid_lib.c b/gdk/gxid_lib.c
new file mode 100644 (file)
index 0000000..357b764
--- /dev/null
@@ -0,0 +1,116 @@
+/* 
+ * gxid version 0.3
+ *
+ * Copyright 1997 Owen Taylor <owt1@cornell.edu>
+*/
+
+#include "../config.h"
+
+#ifdef XINPUT_GXI
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+#include "gxid_lib.h"
+
+/* handles mechanics of communicating with a client */
+static int 
+gxid_send_message(char *host, int port, GxidMessage *msg)
+{
+  int socket_fd;
+  struct sockaddr_in sin;
+  int count;
+  GxidI32 retval;
+  struct hostent *he;
+
+  if (!port) port = 6951;
+
+  if (!host || strcmp(host,"localhost") )
+    {
+      /* looking it up as localhost can be _SLOW_ on ppp systems */
+      /* FIXME: Could localhost be anything other than loopback? */
+      host = "127.0.0.1";
+    }
+
+  he = gethostbyname(host);
+  if (!he)
+    {
+      fprintf(stderr,"gxid_lib: error looking up %s\n",host);
+      return GXID_RETURN_ERROR;
+    }
+
+  sin.sin_family = he->h_addrtype;
+  sin.sin_port = htons(port);
+  memcpy(&sin.sin_addr,he->h_addr_list[0],he->h_length);
+
+  socket_fd = socket(AF_INET,SOCK_STREAM,0);
+  if (socket_fd < 0)
+    {
+      fprintf(stderr,"gxid_lib: can't get socket");
+      return GXID_RETURN_ERROR;
+    }
+
+  if (connect(socket_fd, (struct sockaddr *)&sin, 
+             sizeof sin) < 0)
+    {
+      fprintf(stderr,"gxid_lib: can't connect to %s:%d\n",host,port);
+      close(socket_fd);
+      return GXID_RETURN_ERROR;
+    }
+
+  count = write(socket_fd,(char *)msg,ntohl(msg->any.length));
+  if (count != ntohl(msg->any.length))
+    {
+      fprintf(stderr,"gxid_lib: error writing");
+      close(socket_fd);
+      return GXID_RETURN_ERROR;
+    }
+
+  /* now read the return code */
+  count = read(socket_fd,(char *)&retval,sizeof(GxidI32));
+  if (count != sizeof(GxidI32))
+    {
+      fprintf(stderr,"gxid_lib: error reading return code");
+      close(socket_fd);
+      return GXID_RETURN_ERROR;
+    }
+
+  close (socket_fd);
+  return ntohl(retval);
+}
+
+/* claim a device. If exclusive, device is claimed exclusively */
+int 
+gxid_claim_device(char *host, int port, GxidU32 device, GxidU32 window,
+                 int exclusive)
+{
+  GxidClaimDevice msg;
+  msg.type = htonl(GXID_CLAIM_DEVICE);
+  msg.length = htonl(sizeof(GxidClaimDevice));
+  msg.device = htonl(device);
+  msg.window = htonl(window);
+  msg.exclusive = htonl(exclusive);
+
+  return gxid_send_message(host,port,(GxidMessage *)&msg);
+}
+
+/* release a device/window pair */
+int 
+gxid_release_device(char *host, int port, GxidU32 device, GxidU32 window)
+{
+  GxidReleaseDevice msg;
+  msg.type = htonl(GXID_RELEASE_DEVICE);
+  msg.length = htonl(sizeof(GxidReleaseDevice));
+  msg.device = htonl(device);
+  msg.window = htonl(window);
+
+  return gxid_send_message(host,port,(GxidMessage *)&msg);
+}
+
+#endif /* XINPUT_GXI */
+
diff --git a/gdk/gxid_lib.h b/gdk/gxid_lib.h
new file mode 100644 (file)
index 0000000..6a7103b
--- /dev/null
@@ -0,0 +1,6 @@
+#include "gxid_proto.h"
+
+int gxid_claim_device(char *host, int port, 
+                     GxidU32 device, GxidU32 window, int exclusive);
+int gxid_release_device(char *host, int port, GxidU32 device, 
+                       GxidU32 window);
diff --git a/gdk/gxid_proto.h b/gdk/gxid_proto.h
new file mode 100644 (file)
index 0000000..24959b8
--- /dev/null
@@ -0,0 +1,39 @@
+#define GXID_CLAIM_DEVICE       1
+#define GXID_RELEASE_DEVICE     2
+
+#define GXID_RETURN_OK          0
+#define GXID_RETURN_ERROR       -1
+
+typedef struct GxidClaimDevice_ GxidClaimDevice;
+typedef struct GxidReleaseDevice_ GxidReleaseDevice;
+typedef struct GxidMessageAny_ GxidMessageAny;
+typedef union GxidMessage_ GxidMessage;
+
+typedef unsigned long GxidU32;
+typedef long GxidI32;
+
+struct GxidClaimDevice_ {
+  GxidU32 type;
+  GxidU32 length;
+  GxidU32 device;
+  GxidU32 window;
+  GxidU32 exclusive;
+};
+
+struct GxidReleaseDevice_ {
+  GxidU32 type;
+  GxidU32 length;
+  GxidU32 device;
+  GxidU32 window;
+};
+
+struct GxidMessageAny_ {
+  GxidU32 type;
+  GxidU32 length;
+};
+
+union GxidMessage_ {
+  GxidMessageAny any;
+  GxidClaimDevice claim;
+  GxidReleaseDevice release;
+};
diff --git a/gdk/makecursors b/gdk/makecursors
new file mode 100755 (executable)
index 0000000..664776a
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+sed -f makecursors.sed $1 > .makecursors.tmp
+awk '{printf "%s = %s,\n", $1, $2}' .makecursors.tmp
+rm .makecursors.tmp
diff --git a/gdk/makecursors.sed b/gdk/makecursors.sed
new file mode 100644 (file)
index 0000000..107d13f
--- /dev/null
@@ -0,0 +1,3 @@
+/define/ ! d
+/define/ y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
+s/^.*XC_/GDK_/g
diff --git a/gdk/makekeysyms b/gdk/makekeysyms
new file mode 100755 (executable)
index 0000000..40b49d4
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+sed -f makekeysyms.sed $1 > .makekeysms.tmp
+awk '{printf "#define %s %s\n", $1, $2}' .makekeysms.tmp
+rm .makekeysms.tmp
diff --git a/gdk/makekeysyms.sed b/gdk/makekeysyms.sed
new file mode 100644 (file)
index 0000000..bafbf76
--- /dev/null
@@ -0,0 +1,3 @@
+/define/ ! d
+s/^.*XK_/GDK_/g
+s/0X/0x/g
diff --git a/gdk/x11/gdkcolor-x11.c b/gdk/x11/gdkcolor-x11.c
new file mode 100644 (file)
index 0000000..5e66f08
--- /dev/null
@@ -0,0 +1,718 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <X11/Xlib.h>
+#include "gdk.h"
+#include "gdkprivate.h"
+
+
+static gint  gdk_colormap_match_color (GdkColormap *cmap,
+                                      GdkColor    *color,
+                                      const gchar *available);
+static void  gdk_colormap_add         (GdkColormap *cmap);
+static void  gdk_colormap_remove      (GdkColormap *cmap);
+static guint gdk_colormap_hash        (Colormap    *cmap);
+static gint  gdk_colormap_cmp         (Colormap    *a,
+                                      Colormap    *b);
+
+static GHashTable *colormap_hash = NULL;
+
+
+GdkColormap*
+gdk_colormap_new (GdkVisual *visual,
+                 gint       private_cmap)
+{
+  GdkColormap *colormap;
+  GdkColormapPrivate *private;
+  Visual *xvisual;
+  XColor default_colors[256];
+  int size;
+  int i;
+
+  g_return_val_if_fail (visual != NULL, NULL);
+
+  private = g_new (GdkColormapPrivate, 1);
+  colormap = (GdkColormap*) private;
+
+  private->xdisplay = gdk_display;
+  private->visual = visual;
+  private->next_color = 0;
+  private->ref_count = 1;
+  xvisual = ((GdkVisualPrivate*) visual)->xvisual;
+
+  switch (visual->type)
+    {
+    case GDK_VISUAL_GRAYSCALE:
+    case GDK_VISUAL_PSEUDO_COLOR:
+      private->private_val = private_cmap;
+      private->xcolormap = XCreateColormap (private->xdisplay, gdk_root_window,
+                                           xvisual, (private_cmap) ? (AllocAll) : (AllocNone));
+
+      if (private_cmap)
+       {
+         for (i = 0; i < 256; i++)
+           default_colors[i].pixel = i;
+
+         XQueryColors (private->xdisplay,
+                       DefaultColormap (private->xdisplay, gdk_screen),
+                       default_colors, visual->colormap_size);
+
+         for (i = 0; i < visual->colormap_size; i++)
+           {
+             colormap->colors[i].pixel = default_colors[i].pixel;
+             colormap->colors[i].red = default_colors[i].red;
+             colormap->colors[i].green = default_colors[i].green;
+             colormap->colors[i].blue = default_colors[i].blue;
+           }
+
+         gdk_colormap_change (colormap, visual->colormap_size);
+       }
+      break;
+
+    case GDK_VISUAL_DIRECT_COLOR:
+      private->private_val = TRUE;
+      private->xcolormap = XCreateColormap (private->xdisplay, gdk_root_window,
+                                           xvisual, AllocAll);
+
+      size = 1 << visual->red_prec;
+      for (i = 0; i < size; i++)
+       colormap->colors[i].red = i * 65535 / (size - 1);
+
+      size = 1 << visual->green_prec;
+      for (i = 0; i < size; i++)
+       colormap->colors[i].green = i * 65535 / (size - 1);
+
+      size = 1 << visual->blue_prec;
+      for (i = 0; i < size; i++)
+       colormap->colors[i].blue = i * 65535 / (size - 1);
+
+      gdk_colormap_change (colormap, visual->colormap_size);
+      break;
+
+    case GDK_VISUAL_STATIC_GRAY:
+    case GDK_VISUAL_STATIC_COLOR:
+    case GDK_VISUAL_TRUE_COLOR:
+      private->private_val = FALSE;
+      private->xcolormap = XCreateColormap (private->xdisplay, gdk_root_window,
+                                           xvisual, AllocNone);
+      break;
+    }
+
+  gdk_colormap_add (colormap);
+
+  return colormap;
+}
+
+void
+gdk_colormap_real_destroy (GdkColormap *colormap)
+{
+  GdkColormapPrivate *private = (GdkColormapPrivate*) colormap;
+
+  g_return_if_fail (colormap != NULL);
+
+  if (private->ref_count > 0)
+    return;
+
+  gdk_colormap_remove (colormap);
+  XFreeColormap (private->xdisplay, private->xcolormap);
+  g_free (colormap);
+}
+
+void
+gdk_colormap_destroy (GdkColormap *colormap)
+{
+  gdk_colormap_unref (colormap);
+}
+
+GdkColormap*
+gdk_colormap_ref (GdkColormap *cmap)
+{
+  GdkColormapPrivate *private = (GdkColormapPrivate *)cmap;
+  g_return_val_if_fail (cmap != NULL, NULL);
+
+  private->ref_count += 1;
+  return cmap;
+}
+
+void
+gdk_colormap_unref (GdkColormap *cmap)
+{
+  GdkColormapPrivate *private = (GdkColormapPrivate *)cmap;
+  g_return_if_fail (cmap != NULL);
+
+  private->ref_count -= 1;
+  if (private->ref_count == 0)
+    gdk_colormap_real_destroy (cmap);
+}
+
+GdkColormap*
+gdk_colormap_get_system (void)
+{
+  static GdkColormap *colormap = NULL;
+  GdkColormapPrivate *private;
+  XColor xpalette[256];
+  gint i;
+
+  if (!colormap)
+    {
+      private = g_new (GdkColormapPrivate, 1);
+      colormap = (GdkColormap*) private;
+
+      private->xdisplay = gdk_display;
+      private->xcolormap = DefaultColormap (gdk_display, gdk_screen);
+      private->visual = gdk_visual_get_system ();
+      private->private_val = FALSE;
+      private->next_color = 0;
+      private->ref_count = 1;
+
+      for (i = 0; i < 256; i++)
+       {
+         xpalette[i].pixel = i;
+         xpalette[i].red = 0;
+         xpalette[i].green = 0;
+         xpalette[i].blue = 0;
+       }
+
+      XQueryColors (gdk_display, private->xcolormap, xpalette, 256);
+
+      for (i = 0; i < 256; i++)
+       {
+         colormap->colors[i].pixel = xpalette[i].pixel;
+         colormap->colors[i].red = xpalette[i].red;
+         colormap->colors[i].green = xpalette[i].green;
+         colormap->colors[i].blue = xpalette[i].blue;
+       }
+
+      gdk_colormap_add (colormap);
+    }
+
+  return colormap;
+}
+
+gint
+gdk_colormap_get_system_size (void)
+{
+  return DisplayCells (gdk_display, gdk_screen);
+}
+
+void
+gdk_colormap_change (GdkColormap *colormap,
+                    gint         ncolors)
+{
+  GdkColormapPrivate *private;
+  GdkVisual *visual;
+  XColor palette[256];
+  gint shift;
+  int max_colors;
+  int size;
+  int i;
+
+  g_return_if_fail (colormap != NULL);
+
+  private = (GdkColormapPrivate*) colormap;
+  switch (private->visual->type)
+    {
+    case GDK_VISUAL_GRAYSCALE:
+    case GDK_VISUAL_PSEUDO_COLOR:
+      for (i = 0; i < ncolors; i++)
+       {
+         palette[i].pixel = colormap->colors[i].pixel;
+         palette[i].red = colormap->colors[i].red;
+         palette[i].green = colormap->colors[i].green;
+         palette[i].blue = colormap->colors[i].blue;
+         palette[i].flags = DoRed | DoGreen | DoBlue;
+       }
+
+      XStoreColors (private->xdisplay, private->xcolormap, palette, ncolors);
+      private->next_color = MAX (private->next_color, ncolors);
+      break;
+
+    case GDK_VISUAL_DIRECT_COLOR:
+      visual = private->visual;
+
+      shift = visual->red_shift;
+      max_colors = 1 << visual->red_prec;
+      size = (ncolors < max_colors) ? (ncolors) : (max_colors);
+
+      for (i = 0; i < size; i++)
+       {
+         palette[i].pixel = i << shift;
+         palette[i].red = colormap->colors[i].red;
+         palette[i].flags = DoRed;
+       }
+
+      XStoreColors (private->xdisplay, private->xcolormap, palette, size);
+
+      shift = visual->green_shift;
+      max_colors = 1 << visual->green_prec;
+      size = (ncolors < max_colors) ? (ncolors) : (max_colors);
+
+      for (i = 0; i < size; i++)
+       {
+         palette[i].pixel = i << shift;
+         palette[i].green = colormap->colors[i].green;
+         palette[i].flags = DoGreen;
+       }
+
+      XStoreColors (private->xdisplay, private->xcolormap, palette, size);
+
+      shift = visual->blue_shift;
+      max_colors = 1 << visual->blue_prec;
+      size = (ncolors < max_colors) ? (ncolors) : (max_colors);
+
+      for (i = 0; i < size; i++)
+       {
+         palette[i].pixel = i << shift;
+         palette[i].blue = colormap->colors[i].blue;
+         palette[i].flags = DoBlue;
+       }
+
+      XStoreColors (private->xdisplay, private->xcolormap, palette, size);
+      break;
+
+    default:
+      break;
+    }
+}
+
+void
+gdk_colors_store (GdkColormap   *colormap,
+                 GdkColor      *colors,
+                 gint           ncolors)
+{
+  gint i;
+
+  for (i = 0; i < ncolors; i++)
+    {
+      colormap->colors[i].pixel = colors[i].pixel;
+      colormap->colors[i].red = colors[i].red;
+      colormap->colors[i].green = colors[i].green;
+      colormap->colors[i].blue = colors[i].blue;
+    }
+
+  gdk_colormap_change (colormap, ncolors);
+}
+
+gint
+gdk_colors_alloc (GdkColormap   *colormap,
+                 gint           contiguous,
+                 gulong        *planes,
+                 gint           nplanes,
+                 gulong        *pixels,
+                 gint           npixels)
+{
+  GdkColormapPrivate *private;
+  gint return_val;
+
+  g_return_val_if_fail (colormap != NULL, 0);
+
+  private = (GdkColormapPrivate*) colormap;
+
+  return_val = XAllocColorCells (private->xdisplay, private->xcolormap,
+                                contiguous, planes, nplanes, pixels, npixels);
+
+  return return_val;
+}
+
+void
+gdk_colors_free (GdkColormap *colormap,
+                gulong      *pixels,
+                gint         npixels,
+                gulong       planes)
+{
+  GdkColormapPrivate *private;
+
+  g_return_if_fail (colormap != NULL);
+
+  private = (GdkColormapPrivate*) colormap;
+
+  XFreeColors (private->xdisplay, private->xcolormap,
+              pixels, npixels, planes);
+}
+
+gint
+gdk_color_white (GdkColormap *colormap,
+                GdkColor    *color)
+{
+  gint return_val;
+
+  g_return_val_if_fail (colormap != NULL, FALSE);
+
+  if (color)
+    {
+      color->pixel = WhitePixel (gdk_display, gdk_screen);
+      color->red = 65535;
+      color->green = 65535;
+      color->blue = 65535;
+
+      return_val = gdk_color_alloc (colormap, color);
+    }
+  else
+    return_val = FALSE;
+
+  return return_val;
+}
+
+gint
+gdk_color_black (GdkColormap *colormap,
+                GdkColor    *color)
+{
+  gint return_val;
+
+  g_return_val_if_fail (colormap != NULL, FALSE);
+
+  if (color)
+    {
+      color->pixel = BlackPixel (gdk_display, gdk_screen);
+      color->red = 0;
+      color->green = 0;
+      color->blue = 0;
+
+      return_val = gdk_color_alloc (colormap, color);
+    }
+  else
+    return_val = FALSE;
+
+  return return_val;
+}
+
+gint
+gdk_color_parse (const gchar *spec,
+                GdkColor *color)
+{
+  Colormap xcolormap;
+  XColor xcolor;
+  gint return_val;
+
+  g_return_val_if_fail (spec != NULL, FALSE);
+  g_return_val_if_fail (color != NULL, FALSE);
+
+  xcolormap = DefaultColormap (gdk_display, gdk_screen);
+
+  if (XParseColor (gdk_display, xcolormap, spec, &xcolor))
+    {
+      return_val = TRUE;
+      color->red = xcolor.red;
+      color->green = xcolor.green;
+      color->blue = xcolor.blue;
+    }
+  else
+    return_val = FALSE;
+
+  return return_val;
+}
+
+gint
+gdk_color_alloc (GdkColormap *colormap,
+                GdkColor    *color)
+{
+  GdkColormapPrivate *private;
+  GdkVisual *visual;
+  XColor xcolor;
+  gchar available[256];
+  gint available_init;
+  gint return_val;
+  gint i, index;
+
+  g_return_val_if_fail (colormap != NULL, FALSE);
+  g_return_val_if_fail (color != NULL, FALSE);
+
+  xcolor.red = color->red;
+  xcolor.green = color->green;
+  xcolor.blue = color->blue;
+  xcolor.pixel = color->pixel;
+  xcolor.flags = DoRed | DoGreen | DoBlue;
+
+  return_val = FALSE;
+  private = (GdkColormapPrivate*) colormap;
+
+  switch (private->visual->type)
+    {
+    case GDK_VISUAL_GRAYSCALE:
+    case GDK_VISUAL_PSEUDO_COLOR:
+      if (private->private_val)
+       {
+         if (private->next_color > 255)
+           {
+             for (i = 0; i < 256; i++)
+               available[i] = TRUE;
+
+             index = gdk_colormap_match_color (colormap, color, available);
+             if (index != -1)
+               {
+                 available[index] = FALSE;
+                 *color = colormap->colors[index];
+                 return_val = TRUE;
+               }
+             else
+               {
+                 return_val = FALSE;
+               }
+           }
+         else
+           {
+             xcolor.pixel = 255 - private->next_color;
+             color->pixel = xcolor.pixel;
+             private->next_color += 1;
+
+             XStoreColor (private->xdisplay, private->xcolormap, &xcolor);
+             return_val = TRUE;
+           }
+       }
+      else
+       {
+         available_init = 1;
+
+         while (1)
+           {
+             if (XAllocColor (private->xdisplay, private->xcolormap, &xcolor))
+               {
+                 color->pixel = xcolor.pixel;
+                 color->red = xcolor.red;
+                 color->green = xcolor.green;
+                 color->blue = xcolor.blue;
+
+                 colormap->colors[color->pixel] = *color;
+
+                 return_val = TRUE;
+                 break;
+               }
+             else
+               {
+                 if (available_init)
+                   {
+                     available_init = 0;
+                     for (i = 0; i < 256; i++)
+                       available[i] = TRUE;
+                   }
+
+                 index = gdk_colormap_match_color (colormap, color, available);
+                 if (index != -1)
+                   {
+                     available[index] = FALSE;
+                     xcolor.red = colormap->colors[index].red;
+                     xcolor.green = colormap->colors[index].green;
+                     xcolor.blue = colormap->colors[index].blue;
+                   }
+                 else
+                   {
+                     return_val = FALSE;
+                     break;
+                   }
+               }
+           }
+       }
+      break;
+
+    case GDK_VISUAL_DIRECT_COLOR:
+      visual = private->visual;
+      xcolor.pixel = (((xcolor.red >> (16 - visual->red_prec)) << visual->red_shift) +
+                     ((xcolor.green >> (16 - visual->green_prec)) << visual->green_shift) +
+                     ((xcolor.blue >> (16 - visual->blue_prec)) << visual->blue_shift));
+      color->pixel = xcolor.pixel;
+      return_val = TRUE;
+      break;
+
+    case GDK_VISUAL_STATIC_GRAY:
+    case GDK_VISUAL_STATIC_COLOR:
+    case GDK_VISUAL_TRUE_COLOR:
+      if (XAllocColor (private->xdisplay, private->xcolormap, &xcolor))
+       {
+         color->pixel = xcolor.pixel;
+         return_val = TRUE;
+       }
+      else
+       return_val = FALSE;
+      break;
+    }
+
+  return return_val;
+}
+
+gint
+gdk_color_change (GdkColormap *colormap,
+                 GdkColor    *color)
+{
+  GdkColormapPrivate *private;
+  XColor xcolor;
+
+  g_return_val_if_fail (colormap != NULL, FALSE);
+  g_return_val_if_fail (color != NULL, FALSE);
+
+  xcolor.pixel = color->pixel;
+  xcolor.red = color->red;
+  xcolor.green = color->green;
+  xcolor.blue = color->blue;
+  xcolor.flags = DoRed | DoGreen | DoBlue;
+
+  private = (GdkColormapPrivate*) colormap;
+  XStoreColor (private->xdisplay, private->xcolormap, &xcolor);
+
+  return TRUE;
+}
+
+gint
+gdk_color_equal (GdkColor *colora,
+                GdkColor *colorb)
+{
+  g_return_val_if_fail (colora != NULL, FALSE);
+  g_return_val_if_fail (colorb != NULL, FALSE);
+
+  return ((colora->red == colorb->red) &&
+         (colora->green == colorb->green) &&
+         (colora->blue == colorb->blue));
+}
+
+GdkColormap*
+gdkx_colormap_get (Colormap xcolormap)
+{
+  GdkColormap *colormap;
+  GdkColormapPrivate *private;
+  XColor xpalette[256];
+  gint i;
+
+  colormap = gdk_colormap_lookup (xcolormap);
+  if (colormap)
+    return colormap;
+
+  if (xcolormap == DefaultColormap (gdk_display, gdk_screen))
+    return gdk_colormap_get_system ();
+
+  private = g_new (GdkColormapPrivate, 1);
+  colormap = (GdkColormap*) private;
+
+  private->xdisplay = gdk_display;
+  private->xcolormap = xcolormap;
+  private->visual = NULL;
+  private->private_val = TRUE;
+  private->next_color = 0;
+
+  for (i = 0; i < 256; i++)
+    {
+      xpalette[i].pixel = i;
+      xpalette[i].red = 0;
+      xpalette[i].green = 0;
+      xpalette[i].blue = 0;
+    }
+
+  XQueryColors (gdk_display, private->xcolormap, xpalette, 256);
+
+  for (i = 0; i < 256; i++)
+    {
+      colormap->colors[i].pixel = xpalette[i].pixel;
+      colormap->colors[i].red = xpalette[i].red;
+      colormap->colors[i].green = xpalette[i].green;
+      colormap->colors[i].blue = xpalette[i].blue;
+    }
+
+  gdk_colormap_add (colormap);
+
+  return colormap;
+}
+
+
+static gint
+gdk_colormap_match_color (GdkColormap *cmap,
+                         GdkColor    *color,
+                         const gchar *available)
+{
+  GdkColor *colors;
+  guint sum, max;
+  gint rdiff, gdiff, bdiff;
+  gint i, index;
+
+  g_return_val_if_fail (cmap != NULL, 0);
+  g_return_val_if_fail (color != NULL, 0);
+
+  colors = cmap->colors;
+  max = 3 * (65536);
+  index = -1;
+
+  for (i = 0; i < 256; i++)
+    {
+      if ((!available) || (available && available[i]))
+       {
+         rdiff = (color->red - colors[i].red);
+         gdiff = (color->green - colors[i].green);
+         bdiff = (color->blue - colors[i].blue);
+
+         sum = ABS (rdiff) + ABS (gdiff) + ABS (bdiff);
+
+         if (sum < max)
+           {
+             index = i;
+             max = sum;
+           }
+       }
+    }
+
+  return index;
+}
+
+
+GdkColormap*
+gdk_colormap_lookup (Colormap xcolormap)
+{
+  GdkColormap *cmap;
+
+  if (!colormap_hash)
+    return NULL;
+
+  cmap = g_hash_table_lookup (colormap_hash, &xcolormap);
+  return cmap;
+}
+
+static void
+gdk_colormap_add (GdkColormap *cmap)
+{
+  GdkColormapPrivate *private;
+
+  if (!colormap_hash)
+    colormap_hash = g_hash_table_new ((GHashFunc) gdk_colormap_hash,
+                                     (GCompareFunc) gdk_colormap_cmp);
+
+  private = (GdkColormapPrivate*) cmap;
+
+  g_hash_table_insert (colormap_hash, &private->xcolormap, cmap);
+}
+
+static void
+gdk_colormap_remove (GdkColormap *cmap)
+{
+  GdkColormapPrivate *private;
+
+  if (!colormap_hash)
+    colormap_hash = g_hash_table_new ((GHashFunc) gdk_colormap_hash,
+                                     (GCompareFunc) gdk_colormap_cmp);
+
+  private = (GdkColormapPrivate*) cmap;
+
+  g_hash_table_remove (colormap_hash, &private->xcolormap);
+}
+
+static guint
+gdk_colormap_hash (Colormap *cmap)
+{
+  return *cmap;
+}
+
+static gint
+gdk_colormap_cmp (Colormap *a,
+                 Colormap *b)
+{
+  return (*a == *b);
+}
diff --git a/gdk/x11/gdkcursor-x11.c b/gdk/x11/gdkcursor-x11.c
new file mode 100644 (file)
index 0000000..22bfd25
--- /dev/null
@@ -0,0 +1,52 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <X11/Xlib.h>
+#include <X11/cursorfont.h>
+#include "gdk.h"
+#include "gdkprivate.h"
+
+
+GdkCursor*
+gdk_cursor_new (GdkCursorType cursor_type)
+{
+  GdkCursorPrivate *private;
+  GdkCursor *cursor;
+  Cursor xcursor;
+
+  xcursor = XCreateFontCursor (gdk_display, cursor_type);
+  private = g_new (GdkCursorPrivate, 1);
+  private->xdisplay = gdk_display;
+  private->xcursor = xcursor;
+  cursor = (GdkCursor*) private;
+  cursor->type = cursor_type;
+
+  return cursor;
+}
+
+void
+gdk_cursor_destroy (GdkCursor *cursor)
+{
+  GdkCursorPrivate *private;
+
+  g_return_if_fail (cursor != NULL);
+
+  private = (GdkCursorPrivate *) cursor;
+  XFreeCursor (private->xdisplay, private->xcursor);
+
+  g_free (private);
+}
diff --git a/gdk/x11/gdkfont-x11.c b/gdk/x11/gdkfont-x11.c
new file mode 100644 (file)
index 0000000..e1b1e72
--- /dev/null
@@ -0,0 +1,379 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <X11/Xlib.h>
+#include <X11/Xos.h>
+#include "gdk.h"
+#include "gdkprivate.h"
+
+GdkFont*
+gdk_font_load (const gchar *font_name)
+{
+  GdkFont *font;
+  GdkFontPrivate *private;
+
+  private = g_new (GdkFontPrivate, 1);
+  font = (GdkFont*) private;
+
+  private->xdisplay = gdk_display;
+  private->xfont = XLoadQueryFont (private->xdisplay, font_name);
+  private->ref_count = 1;
+
+  if (!private->xfont)
+    {
+      g_free (font);
+      return NULL;
+    }
+  else
+    {
+      font->type = GDK_FONT_FONT;
+      font->ascent =  ((XFontStruct *) private->xfont)->ascent;
+      font->descent = ((XFontStruct *) private->xfont)->descent;
+    }
+
+  gdk_xid_table_insert (&((XFontStruct *) private->xfont)->fid, font);
+
+  return font;
+}
+
+GdkFont*
+gdk_fontset_load(gchar *fontset_name)
+{
+  GdkFont *font;
+  GdkFontPrivate *private;
+  XFontSet fontset;
+  gint  missing_charset_count;
+  gchar **missing_charset_list;
+  gchar *def_string;
+
+  private = g_new (GdkFontPrivate, 1);
+  font = (GdkFont*) private;
+
+  private->xdisplay = gdk_display;
+  fontset = XCreateFontSet (gdk_display, fontset_name,
+                           &missing_charset_list, &missing_charset_count,
+                           &def_string);
+
+  if (missing_charset_count)
+    {
+      g_print ("Missing charsets in FontSet creation");
+      XFreeStringList (missing_charset_list);
+    }
+
+  private->ref_count = 1;
+
+  if (!fontset)
+    {
+      g_free (font);
+      return NULL;
+    }
+  else
+    {
+      XFontSetExtents *extent = XExtentsOfFontSet(fontset);
+
+      private->xfont = fontset;
+      font->type = GDK_FONT_FONTSET;
+      /* how to define ascent and descent for fontset ??? */
+      font->ascent =  extent->max_logical_extent.height;
+      font->descent = font->ascent / 4 ;
+    }
+  return font;
+}
+void
+gdk_font_free (GdkFont *font)
+{
+  GdkFontPrivate *private;
+
+  g_return_if_fail (font != NULL);
+
+  private = (GdkFontPrivate*) font;
+
+  private->ref_count -= 1;
+  if (private->ref_count == 0)
+    {
+      gdk_xid_table_remove (((XFontStruct *) private->xfont)->fid);
+      XFreeFont (private->xdisplay, (XFontStruct *) private->xfont);
+      g_free (font);
+    }
+}
+
+void
+gdk_fontset_free (GdkFont *font)
+{
+  GdkFontPrivate *private;
+
+  g_return_if_fail (font != NULL);
+
+  private = (GdkFontPrivate*) font;
+
+  private->ref_count -= 1;
+  if (private->ref_count == 0)
+    {
+      XFreeFontSet (private->xdisplay, (XFontSet) private->xfont);
+      g_free (font);
+    }
+}
+
+GdkFont*
+gdk_font_ref (GdkFont *font)
+{
+  GdkFontPrivate *private;
+
+  g_return_val_if_fail (font != NULL, NULL);
+
+  private = (GdkFontPrivate*) font;
+  private->ref_count += 1;
+  return font;
+}
+
+gint
+gdk_font_id (GdkFont *font)
+{
+  GdkFontPrivate *font_private;
+
+  g_return_val_if_fail (font != NULL, 0);
+
+  font_private = (GdkFontPrivate*) font;
+
+  if (font->type == GDK_FONT_FONT)
+    {
+      return ((XFontStruct *) font_private->xfont)->fid;
+    }
+  else
+    {
+      return 0;
+    }
+}
+
+gint
+gdk_font_equal (GdkFont *fonta,
+                GdkFont *fontb)
+{
+  GdkFontPrivate *privatea;
+  GdkFontPrivate *privateb;
+
+  g_return_val_if_fail (fonta != NULL, FALSE);
+  g_return_val_if_fail (fontb != NULL, FALSE);
+
+  privatea = (GdkFontPrivate*) fonta;
+  privateb = (GdkFontPrivate*) fontb;
+
+  if (fonta->type == GDK_FONT_FONT && fontb->type == GDK_FONT_FONT)
+    {
+      return (((XFontStruct *) privatea->xfont)->fid ==
+             ((XFontStruct *) privateb->xfont)->fid);
+    }
+  else if (fonta->type == GDK_FONT_FONTSET && fontb->type == GDK_FONT_FONTSET)
+    {
+      /* how to compare two fontsets ?? by basename or XFontSet ?? */
+      return (((XFontSet) privatea->xfont) == ((XFontSet) privateb->xfont));
+    }
+  else
+    /* fontset != font */
+    return 0;
+}
+
+gint
+gdk_string_width (GdkFont     *font,
+                 const gchar *string)
+{
+  GdkFontPrivate *font_private;
+  gint width;
+  XFontStruct *xfont;
+  XFontSet fontset;
+
+  g_return_val_if_fail (font != NULL, -1);
+  g_return_val_if_fail (string != NULL, -1);
+
+  font_private = (GdkFontPrivate*) font;
+
+  switch (font->type)
+    {
+    case GDK_FONT_FONT:
+      xfont = (XFontStruct *) font_private->xfont;
+      if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
+       {
+         width = XTextWidth (xfont, string, strlen (string));
+       }
+      else
+       {
+         width = XTextWidth16 (xfont, (XChar2b *) string, strlen (string) / 2);
+       }
+      break;
+    case GDK_FONT_FONTSET:
+      fontset = (XFontSet) font_private->xfont;
+      width = XmbTextEscapement (fontset, string, strlen(string));
+      break;
+    default:
+      width = 0;
+    }
+
+  return width;
+}
+
+gint
+gdk_text_width (GdkFont      *font,
+               const gchar  *text,
+               gint          text_length)
+{
+  GdkFontPrivate *private;
+  gint width;
+  XFontStruct *xfont;
+  XFontSet fontset;
+
+  g_return_val_if_fail (font != NULL, -1);
+  g_return_val_if_fail (text != NULL, -1);
+
+  private = (GdkFontPrivate*) font;
+
+  switch (font->type)
+    {
+    case GDK_FONT_FONT:
+      xfont = (XFontStruct *) private->xfont;
+      if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
+       {
+         width = XTextWidth (xfont, text, text_length);
+       }
+      else
+       {
+         width = XTextWidth16 (xfont, (XChar2b *) text, text_length / 2);
+       }
+      break;
+    case GDK_FONT_FONTSET:
+      fontset = (XFontSet) private->xfont;
+      width = XmbTextEscapement (fontset, text, text_length);
+      break;
+    default:
+      width = 0;
+    }
+  return width;
+}
+
+/* Problem: What if a character is a 16 bits character ?? */
+gint
+gdk_char_width (GdkFont *font,
+               gchar    character)
+{
+  GdkFontPrivate *private;
+  XCharStruct *chars;
+  gint width;
+  guint ch = character & 0xff;  /* get rid of sign-extension */
+  XFontStruct *xfont;
+  XFontSet fontset;
+
+  g_return_val_if_fail (font != NULL, -1);
+
+  private = (GdkFontPrivate*) font;
+
+  switch (font->type)
+    {
+    case GDK_FONT_FONT:
+      /* only 8 bits characters are considered here */
+      xfont = (XFontStruct *) private->xfont;
+      if ((xfont->min_byte1 == 0) &&
+         (xfont->max_byte1 == 0) &&
+         (ch >= xfont->min_char_or_byte2) &&
+         (ch <= xfont->max_char_or_byte2))
+       {
+         chars = xfont->per_char;
+         if (chars)
+           width = chars[ch - xfont->min_char_or_byte2].width;
+         else
+           width = xfont->min_bounds.width;
+       }
+      else
+       {
+         width = XTextWidth (xfont, &character, 1);
+       }
+      break;
+    case GDK_FONT_FONTSET:
+      fontset = (XFontSet) private->xfont;
+      width = XmbTextEscapement (fontset, &character, 1) ;
+      break;
+    default:
+      width = 0;
+    }
+  return width;
+}
+
+gint
+gdk_string_measure (GdkFont     *font,
+                    const gchar *string)
+{
+  g_return_val_if_fail (font != NULL, -1);
+  g_return_val_if_fail (string != NULL, -1);
+
+  return gdk_text_measure (font, string, strlen (string));
+}
+
+gint
+gdk_text_measure (GdkFont     *font,
+                  const gchar *text,
+                  gint         text_length)
+{
+  GdkFontPrivate *private;
+  XCharStruct overall;
+  XFontStruct *xfont;
+  XFontSet    fontset;
+  XRectangle  ink, log;
+  int direction;
+  int font_ascent;
+  int font_descent;
+  gint width;
+
+  g_return_val_if_fail (font != NULL, -1);
+  g_return_val_if_fail (text != NULL, -1);
+
+  private = (GdkFontPrivate*) font;
+
+  switch (font->type)
+    {
+    case GDK_FONT_FONT:
+      xfont = (XFontStruct *) private->xfont;
+      if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
+       {
+         XTextExtents (xfont, text, text_length,
+                       &direction, &font_ascent, &font_descent,
+                       &overall);
+       }
+      else
+       {
+         XTextExtents16 (xfont, (XChar2b *) text, text_length / 2,
+                         &direction, &font_ascent, &font_descent,
+                         &overall);
+       }
+      width = overall.rbearing;
+      break;
+    case GDK_FONT_FONTSET:
+      fontset = (XFontSet) private->xfont;
+      XmbTextExtents (fontset, text, text_length, &ink, &log);
+      width = log.width;
+      break;
+    default:
+      width = 0;
+    }
+  return width;
+}
+
+gint
+gdk_char_measure (GdkFont *font,
+                  gchar    character)
+{
+  g_return_val_if_fail (font != NULL, -1);
+
+  return gdk_text_measure (font, &character, 1);
+}
diff --git a/gdk/x11/gdkglobals-x11.c b/gdk/x11/gdkglobals-x11.c
new file mode 100644 (file)
index 0000000..58f7bf8
--- /dev/null
@@ -0,0 +1,47 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdio.h>
+#include <X11/Xlib.h>
+#include "gdktypes.h"
+#include "gdkprivate.h"
+
+gint              gdk_debug_level = 0;
+gint              gdk_show_events = FALSE;
+gint              gdk_use_xshm = TRUE;
+gchar            *gdk_display_name = NULL;
+Display          *gdk_display = NULL;
+gint              gdk_screen;
+Window            gdk_root_window;
+Window            gdk_leader_window;
+GdkWindowPrivate  gdk_root_parent;
+Atom              gdk_wm_delete_window;
+Atom              gdk_wm_take_focus;
+Atom              gdk_wm_protocols;
+Atom              gdk_wm_window_protocols[2];
+Atom              gdk_selection_property;
+GdkDndGlobals     gdk_dnd = {None,None,None,
+                            None,None,None,
+                            None,
+                            None,None,
+                            NULL,
+                            0, 0,
+                            {0,0}};
+gchar            *gdk_progname = NULL;
+gchar            *gdk_progclass = NULL;
+gint              gdk_error_code;
+gint              gdk_error_warnings = TRUE;
diff --git a/gdk/x11/gdkimage-x11.c b/gdk/x11/gdkimage-x11.c
new file mode 100644 (file)
index 0000000..bcda311
--- /dev/null
@@ -0,0 +1,492 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "../config.h"
+
+#include <sys/types.h>
+
+#if defined (HAVE_IPC_H) && defined (HAVE_SHM_H) && defined (HAVE_XSHM_H)
+#define USE_SHM
+#endif
+
+#ifdef USE_SHM
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#endif /* USE_SHM */
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#ifdef USE_SHM
+#include <X11/extensions/XShm.h>
+#endif /* USE_SHM */
+
+#include "gdk.h"
+#include "gdkprivate.h"
+
+
+static void gdk_image_put_normal (GdkDrawable *drawable,
+                                 GdkGC       *gc,
+                                 GdkImage    *image,
+                                 gint         xsrc,
+                                 gint         ysrc,
+                                 gint         xdest,
+                                 gint         ydest,
+                                 gint         width,
+                                 gint         height);
+static void gdk_image_put_shared (GdkDrawable *drawable,
+                                 GdkGC       *gc,
+                                 GdkImage    *image,
+                                 gint         xsrc,
+                                 gint         ysrc,
+                                 gint         xdest,
+                                 gint         ydest,
+                                 gint         width,
+                                 gint         height);
+
+
+static GList *image_list = NULL;
+
+
+void
+gdk_image_exit ()
+{
+  GdkImage *image;
+
+  while (image_list)
+    {
+      image = image_list->data;
+      gdk_image_destroy (image);
+    }
+}
+
+GdkImage *
+gdk_image_new_bitmap(GdkVisual *visual, gpointer data, gint w, gint h)
+/*
+ * Desc: create a new bitmap image
+ */
+{
+        Visual *xvisual;
+        GdkImage *image;
+        GdkImagePrivate *private;
+        private = g_new(GdkImagePrivate, 1);
+        image = (GdkImage *) private;
+        private->xdisplay = gdk_display;
+        private->image_put = gdk_image_put_normal;
+        image->type = GDK_IMAGE_NORMAL;
+        image->visual = visual;
+        image->width = w;
+        image->height = h;
+        image->depth = 1;
+        xvisual = ((GdkVisualPrivate*) visual)->xvisual;
+        private->ximage = XCreateImage(private->xdisplay, xvisual, 1, XYBitmap,
+                                      0, 0, w ,h, 8, 0);
+        private->ximage->data = data;
+        private->ximage->bitmap_bit_order = MSBFirst;
+        private->ximage->byte_order = MSBFirst;
+        image->byte_order = MSBFirst;
+        image->mem =  private->ximage->data;
+        image->bpl = private->ximage->bytes_per_line;
+        image->bpp = 1;
+       return(image);
+} /* gdk_image_new_bitmap() */
+
+static int
+gdk_image_check_xshm(Display *display)
+/* 
+ * Desc: query the server for support for the MIT_SHM extension
+ * Return:  0 = not available
+ *          1 = shared XImage support available
+ *          2 = shared Pixmap support available also
+ */
+{
+#ifdef USE_SHM
+  int major, minor, ignore;
+  Bool pixmaps;
+  
+  if (XQueryExtension(display, "MIT-SHM", &ignore, &ignore, &ignore)) 
+    {
+      if (XShmQueryVersion(display, &major, &minor, &pixmaps )==True) 
+       {
+         return (pixmaps==True) ? 2 : 1;
+       }
+    }
+#endif /* USE_SHM */
+  return 0;
+}
+
+void
+gdk_image_init ()
+{
+  if (gdk_use_xshm)
+    {
+      if (!gdk_image_check_xshm (gdk_display))
+       {
+         g_warning ("MIT-SHM Extension not availible on server");
+         gdk_use_xshm = False;
+       }
+    }
+}
+
+GdkImage*
+gdk_image_new (GdkImageType  type,
+              GdkVisual    *visual,
+              gint          width,
+              gint          height)
+{
+  GdkImage *image;
+  GdkImagePrivate *private;
+#ifdef USE_SHM
+  XShmSegmentInfo *x_shm_info;
+#endif /* USE_SHM */
+  Visual *xvisual;
+
+  switch (type)
+    {
+    case GDK_IMAGE_FASTEST:
+      image = gdk_image_new (GDK_IMAGE_SHARED, visual, width, height);
+
+      if (!image)
+       image = gdk_image_new (GDK_IMAGE_NORMAL, visual, width, height);
+      break;
+
+    default:
+      private = g_new (GdkImagePrivate, 1);
+      image = (GdkImage*) private;
+
+      private->xdisplay = gdk_display;
+      private->image_put = NULL;
+
+      image->type = type;
+      image->visual = visual;
+      image->width = width;
+      image->height = height;
+      image->depth = visual->depth;
+
+      xvisual = ((GdkVisualPrivate*) visual)->xvisual;
+
+      switch (type)
+       {
+       case GDK_IMAGE_SHARED:
+#ifdef USE_SHM
+         if (gdk_use_xshm)
+           {
+             private->image_put = gdk_image_put_shared;
+
+             private->x_shm_info = g_new (XShmSegmentInfo, 1);
+             x_shm_info = private->x_shm_info;
+
+             private->ximage = XShmCreateImage (private->xdisplay, xvisual, visual->depth,
+                                                ZPixmap, NULL, x_shm_info, width, height);
+             if (private->ximage == NULL)
+               {
+                 g_warning ("XShmCreateImage failed");
+                 
+                 g_free (image);
+                 gdk_use_xshm = False;
+                 return NULL;
+               }
+
+             x_shm_info->shmid = shmget (IPC_PRIVATE,
+                                         private->ximage->bytes_per_line * private->ximage->height,
+                                         IPC_CREAT | 0777);
+
+             if (x_shm_info->shmid == -1)
+               {
+                 g_warning ("shmget failed!");
+
+                 XDestroyImage (private->ximage);
+                 g_free (private->x_shm_info);
+                 g_free (image);
+
+                 gdk_use_xshm = False;
+                 gdk_use_xshm = False;
+                 return NULL;
+               }
+
+             x_shm_info->readOnly = False;
+             x_shm_info->shmaddr = shmat (x_shm_info->shmid, 0, 0);
+             private->ximage->data = x_shm_info->shmaddr;
+
+             if (x_shm_info->shmaddr == (char*) -1)
+               {
+                 g_warning ("shmat failed!");
+
+                 XDestroyImage (private->ximage);
+                 shmctl (x_shm_info->shmid, IPC_RMID, 0);
+                 
+                 g_free (private->x_shm_info);
+                 g_free (image);
+
+                 return NULL;
+               }
+
+#ifdef IPC_RMID_DEFERRED_RELEASE
+             if (x_shm_info->shmaddr != (char*) -1)
+               shmctl (x_shm_info->shmid, IPC_RMID, 0);                      
+#endif
+
+             gdk_error_code = 0;
+             gdk_error_warnings = 0;
+
+             XShmAttach (private->xdisplay, x_shm_info);
+             XSync (private->xdisplay, False);
+
+             gdk_error_warnings = 1;
+             if (gdk_error_code == -1)
+               {
+                 g_warning ("XShmAttach failed!");
+
+                 XDestroyImage (private->ximage);
+                 shmdt (x_shm_info->shmaddr);
+                 shmctl (x_shm_info->shmid, IPC_RMID, 0);
+                  
+                 g_free (private->x_shm_info);
+                 g_free (image);
+
+                 gdk_use_xshm = False;
+                 return NULL;
+               }
+
+             if (image)
+               image_list = g_list_prepend (image_list, image);
+           }
+         else
+           {
+             g_free (image);
+             return NULL;
+           }
+         break;
+#else /* USE_SHM */
+         g_free (image);
+         return NULL;
+#endif /* USE_SHM */
+       case GDK_IMAGE_NORMAL:
+         private->image_put = gdk_image_put_normal;
+
+         private->ximage = XCreateImage (private->xdisplay, xvisual, visual->depth,
+                                         ZPixmap, 0, 0, width, height, 32, 0);
+
+         private->ximage->data = g_new (char, private->ximage->bytes_per_line *
+                                         private->ximage->height);
+         break;
+
+       case GDK_IMAGE_FASTEST:
+         g_assert_not_reached ();
+       }
+
+      if (image)
+       {
+         image->byte_order = private->ximage->byte_order;
+         image->mem = private->ximage->data;
+         image->bpl = private->ximage->bytes_per_line;
+
+         switch (private->ximage->bits_per_pixel)
+           {
+           case 8:
+             image->bpp = 1;
+             break;
+           case 16:
+             image->bpp = 2;
+             break;
+           case 24:
+             image->bpp = 3;
+             break;
+           case 32:
+             image->bpp = 4;
+             break;
+           }
+       }
+    }
+
+  return image;
+}
+
+GdkImage*
+gdk_image_get (GdkWindow *window,
+              gint       x,
+              gint       y,
+              gint       width,
+              gint       height)
+{
+  GdkImage *image;
+  GdkImagePrivate *private;
+  GdkWindowPrivate *win_private;
+
+  g_return_val_if_fail (window != NULL, NULL);
+
+  win_private = (GdkWindowPrivate *) window;
+
+  private = g_new (GdkImagePrivate, 1);
+  image = (GdkImage*) private;
+
+  private->xdisplay = gdk_display;
+  private->image_put = gdk_image_put_normal;
+  private->ximage = XGetImage (private->xdisplay,
+                              win_private->xwindow,
+                              x, y, width, height,
+                              AllPlanes, ZPixmap);
+
+  image->type = GDK_IMAGE_NORMAL;
+  image->visual = gdk_window_get_visual (window);
+  image->width = width;
+  image->height = height;
+  image->depth = private->ximage->depth;
+
+  image->mem = private->ximage->data;
+  image->bpl = private->ximage->bytes_per_line;
+  image->bpp = 1;
+
+  return image;
+}
+
+guint32
+gdk_image_get_pixel (GdkImage *image,
+                    gint x,
+                    gint y)
+{
+  guint32 pixel;
+  GdkImagePrivate *private;
+
+  g_return_val_if_fail (image != NULL, 0);
+
+  private = (GdkImagePrivate *) image;
+
+  pixel = XGetPixel (private->ximage, x, y);
+
+  return pixel;
+}
+
+void
+gdk_image_put_pixel (GdkImage *image,
+                    gint x,
+                    gint y,
+                    guint32 pixel)
+{
+  GdkImagePrivate *private;
+
+  g_return_if_fail (image != NULL);
+
+  private = (GdkImagePrivate *) image;
+
+  pixel = XPutPixel (private->ximage, x, y, pixel);
+}
+
+void
+gdk_image_destroy (GdkImage *image)
+{
+  GdkImagePrivate *private;
+#ifdef USE_SHM
+  XShmSegmentInfo *x_shm_info;
+#endif /* USE_SHM */
+
+  g_return_if_fail (image != NULL);
+
+  private = (GdkImagePrivate*) image;
+  switch (image->type)
+    {
+    case GDK_IMAGE_NORMAL:
+      XDestroyImage (private->ximage);
+      break;
+
+    case GDK_IMAGE_SHARED:
+#ifdef USE_SHM
+      XShmDetach (private->xdisplay, private->x_shm_info);
+      XDestroyImage (private->ximage);
+
+      x_shm_info = private->x_shm_info;
+      shmdt (x_shm_info->shmaddr);
+      shmctl (x_shm_info->shmid, IPC_RMID, 0);
+      
+      g_free (private->x_shm_info);
+
+      image_list = g_list_remove (image_list, image);
+#else /* USE_SHM */
+      g_error ("trying to destroy shared memory image when gdk was compiled without shared memory support");
+#endif /* USE_SHM */
+      break;
+
+    case GDK_IMAGE_FASTEST:
+      g_assert_not_reached ();
+    }
+
+  g_free (image);
+}
+
+static void
+gdk_image_put_normal (GdkDrawable *drawable,
+                     GdkGC       *gc,
+                     GdkImage    *image,
+                     gint         xsrc,
+                     gint         ysrc,
+                     gint         xdest,
+                     gint         ydest,
+                     gint         width,
+                     gint         height)
+{
+  GdkWindowPrivate *drawable_private;
+  GdkImagePrivate *image_private;
+  GdkGCPrivate *gc_private;
+
+  g_return_if_fail (drawable != NULL);
+  g_return_if_fail (image != NULL);
+  g_return_if_fail (gc != NULL);
+
+  drawable_private = (GdkWindowPrivate*) drawable;
+  image_private = (GdkImagePrivate*) image;
+  gc_private = (GdkGCPrivate*) gc;
+
+  g_return_if_fail (image->type == GDK_IMAGE_NORMAL);
+
+  XPutImage (drawable_private->xdisplay, drawable_private->xwindow,
+            gc_private->xgc, image_private->ximage,
+            xsrc, ysrc, xdest, ydest, width, height);
+}
+
+static void
+gdk_image_put_shared (GdkDrawable *drawable,
+                     GdkGC       *gc,
+                     GdkImage    *image,
+                     gint         xsrc,
+                     gint         ysrc,
+                     gint         xdest,
+                     gint         ydest,
+                     gint         width,
+                     gint         height)
+{
+#ifdef USE_SHM
+  GdkWindowPrivate *drawable_private;
+  GdkImagePrivate *image_private;
+  GdkGCPrivate *gc_private;
+
+  g_return_if_fail (drawable != NULL);
+  g_return_if_fail (image != NULL);
+  g_return_if_fail (gc != NULL);
+
+  drawable_private = (GdkWindowPrivate*) drawable;
+  image_private = (GdkImagePrivate*) image;
+  gc_private = (GdkGCPrivate*) gc;
+
+  g_return_if_fail (image->type == GDK_IMAGE_SHARED);
+
+  XShmPutImage (drawable_private->xdisplay, drawable_private->xwindow,
+               gc_private->xgc, image_private->ximage,
+               xsrc, ysrc, xdest, ydest, width, height, False);
+#else /* USE_SHM */
+  g_error ("trying to draw shared memory image when gdk was compiled without shared memory support");
+#endif /* USE_SHM */
+}
diff --git a/gdk/x11/gdkinput-gxi.c b/gdk/x11/gdkinput-gxi.c
new file mode 100644 (file)
index 0000000..a30e05f
--- /dev/null
@@ -0,0 +1,628 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef XINPUT_GXI
+
+/* #define DEBUG_SWITCHING */
+
+#include <gxid_lib.h>
+
+/* Forward declarations */
+static void gdk_input_gxi_select_notify (GdkDevicePrivate *gdkdev);
+static gint gdk_input_gxi_set_mode (guint32 deviceid, GdkInputMode mode);
+static gint gdk_input_is_extension_device (guint32 deviceid);
+static void gdk_input_gxi_configure_event (XConfigureEvent *xevent, 
+                                          GdkWindow *window);
+static void gdk_input_gxi_enter_event (XCrossingEvent *xevent, 
+                                      GdkWindow *window);
+static gint gdk_input_gxi_other_event (GdkEvent *event, 
+                                      XEvent *xevent, 
+                                      GdkWindow *window);
+static void gdk_input_gxi_update_device (GdkDevicePrivate *gdkdev);
+
+static gint gdk_input_gxi_window_none_event (GdkEvent *event, XEvent *xevent);
+static gint gdk_input_gxi_enable_window (GdkWindow *window, 
+                                        GdkDevicePrivate *gdkdev);
+static gint gdk_input_gxi_disable_window (GdkWindow *window, 
+                                         GdkDevicePrivate *gdkdev);
+static Window gdk_input_find_root_child(Display *dpy, Window w);
+static void gdk_input_compute_obscuring(GdkInputWindow *input_window);
+static gint gdk_input_is_obscured(GdkInputWindow *input_window, gdouble x, 
+                                 gdouble y);
+static GdkTimeCoord *gdk_input_gxi_motion_events (GdkWindow *window,
+                                                 guint32 deviceid,
+                                                 guint32 start,
+                                                 guint32 stop,
+                                                 gint *nevents_return);
+static void gdk_input_gxi_get_pointer (GdkWindow       *window,
+                                      guint32     deviceid,
+                                      gdouble         *x,
+                                      gdouble         *y,
+                                      gdouble         *pressure,
+                                      gdouble         *xtilt,
+                                      gdouble         *ytilt,
+                                      GdkModifierType *mask);
+static gint gdk_input_gxi_grab_pointer (GdkWindow *     window,
+                                       gint            owner_events,
+                                       GdkEventMask    event_mask,
+                                       GdkWindow *     confine_to,
+                                       guint32         time);
+static void gdk_input_gxi_ungrab_pointer (guint32 time);
+
+/* Local variables */
+
+static GdkDevicePrivate *gdk_input_current_device;
+static GdkDevicePrivate *gdk_input_core_pointer;
+
+void
+gdk_input_init(void)
+{
+  GList *tmp_list;
+  
+  gdk_input_vtable.set_mode           = gdk_input_gxi_set_mode;
+  gdk_input_vtable.set_axes        = gdk_input_common_set_axes;
+  gdk_input_vtable.motion_events      = gdk_input_gxi_motion_events;
+  gdk_input_vtable.get_pointer       = gdk_input_gxi_get_pointer;
+  gdk_input_vtable.grab_pointer              = gdk_input_gxi_grab_pointer;
+  gdk_input_vtable.ungrab_pointer     = gdk_input_gxi_ungrab_pointer;
+  gdk_input_vtable.configure_event    = gdk_input_gxi_configure_event;
+  gdk_input_vtable.enter_event        = gdk_input_gxi_enter_event;
+  gdk_input_vtable.other_event        = gdk_input_gxi_other_event;
+  gdk_input_vtable.window_none_event  = gdk_input_gxi_window_none_event;
+  gdk_input_vtable.enable_window      = gdk_input_gxi_enable_window;
+  gdk_input_vtable.disable_window     = gdk_input_gxi_disable_window;
+
+  gdk_input_ignore_core = FALSE;
+  gdk_input_core_pointer = NULL;
+
+  if (!gdk_input_gxid_host) 
+    {
+      gdk_input_gxid_host = getenv("GXID_HOST");
+    }
+  if (!gdk_input_gxid_port) 
+    {
+      char *t = getenv("GXID_PORT");
+      if (t)
+       gdk_input_gxid_port = atoi(t);
+    }
+  
+  gdk_input_common_init(TRUE);
+
+  /* find initial core pointer */
+  
+  for (tmp_list = gdk_input_devices; tmp_list; tmp_list = tmp_list->next) 
+    {
+      GdkDevicePrivate *gdkdev = (GdkDevicePrivate *)tmp_list->data;
+      if (gdk_input_is_extension_device(gdkdev->info.deviceid))
+       {
+         gdk_input_gxi_select_notify (gdkdev);
+       }
+      else
+       {
+         if (gdkdev->info.deviceid != GDK_CORE_POINTER)
+           gdk_input_core_pointer = gdkdev;
+       }
+    }
+}
+
+static void
+gdk_input_gxi_select_notify (GdkDevicePrivate *gdkdev)
+{
+  XEventClass class;
+
+  ChangeDeviceNotify  (gdkdev->xdevice, gdkdev->changenotify_type, class);
+
+  XSelectExtensionEvent (gdk_display, gdk_root_window, &class, 1);
+}
+
+/* Set the core pointer. Device should already be enabled. */
+static gint
+gdk_input_gxi_set_core_pointer(GdkDevicePrivate *gdkdev)
+{
+  int x_axis,y_axis;
+
+  g_return_val_if_fail(gdkdev->xdevice,FALSE);
+
+  x_axis = gdkdev->axis_for_use[GDK_AXIS_X];
+  y_axis = gdkdev->axis_for_use[GDK_AXIS_Y];
+
+  g_return_val_if_fail(x_axis != -1 && y_axis != -1,FALSE);
+
+  /* core_pointer might not be up to date so we check with the server
+     before change the pointer */
+
+  if ( !gdk_input_is_extension_device(gdkdev->info.deviceid) )
+    {
+#if 0
+      if (gdkdev != gdk_input_core_pointer)
+       g_warning("core pointer inconsistency");
+#endif      
+      return TRUE;
+    }
+
+  if ( XChangePointerDevice(gdk_display,gdkdev->xdevice, x_axis, y_axis) 
+       != Success )
+    {
+      return FALSE;
+    }
+  else
+    {
+      gdk_input_gxi_update_device (gdk_input_core_pointer);
+      gdk_input_core_pointer = gdkdev;
+      return TRUE;
+    }
+}
+
+
+/* FIXME, merge with gdk_input_xfree_set_mode */
+
+static gint
+gdk_input_gxi_set_mode (guint32 deviceid, GdkInputMode mode)
+{
+  GList *tmp_list;
+  GdkDevicePrivate *gdkdev;
+  GdkInputMode old_mode;
+  GdkInputWindow *input_window;
+
+  gdkdev = gdk_input_find_device(deviceid);
+  g_return_val_if_fail (gdkdev != NULL,FALSE);
+  old_mode = gdkdev->info.mode;
+
+  if (gdkdev->info.mode == mode)
+    return TRUE;
+  
+  gdkdev->info.mode = mode;
+
+  if (old_mode != GDK_MODE_DISABLED)
+    {
+      for (tmp_list = gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
+       {
+         input_window = (GdkInputWindow *)tmp_list->data;
+         if (input_window->mode != GDK_EXTENSION_EVENTS_CURSOR)
+           gdk_input_disable_window (input_window->window, gdkdev);
+       }
+    }
+  
+  if (mode != GDK_MODE_DISABLED)
+    {
+      for (tmp_list = gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
+       {
+         input_window = (GdkInputWindow *)tmp_list->data;
+         if (input_window->mode != GDK_EXTENSION_EVENTS_CURSOR)
+           if (!gdk_input_enable_window(input_window->window, gdkdev))
+             {
+               gdk_input_set_mode(deviceid, old_mode);
+               return FALSE;
+             }
+       }
+    }
+
+  return TRUE;
+
+}
+
+gint
+gdk_input_is_extension_device (guint32 deviceid)
+{
+  XDeviceInfo   *devices;
+  int num_devices, loop;
+
+  if (deviceid == GDK_CORE_POINTER)
+    return FALSE;
+  
+  devices = XListInputDevices(gdk_display, &num_devices);
+  for(loop=0; loop<num_devices; loop++)
+    {
+      if ((devices[loop].id == deviceid) && (devices[loop].use == IsXExtensionDevice)) 
+       {
+         XFreeDeviceList(devices);
+         return TRUE;
+       }
+    }
+
+  XFreeDeviceList(devices);
+  return FALSE;
+}
+
+static void
+gdk_input_gxi_configure_event (XConfigureEvent *xevent, GdkWindow *window)
+{
+  GdkInputWindow *input_window;
+  gint root_x, root_y;
+
+  input_window = gdk_input_window_find(window);
+  g_return_if_fail (input_window != NULL);
+
+  gdk_input_get_root_relative_geometry(gdk_display,GDK_WINDOW_XWINDOW(window),
+                                &root_x, &root_y, NULL, NULL);
+  input_window->root_x = root_x;
+  input_window->root_y = root_y;
+  gdk_input_compute_obscuring(input_window);
+}
+
+static void
+gdk_input_gxi_enter_event (XCrossingEvent *xevent, GdkWindow *window)
+{
+  GdkInputWindow *input_window;
+
+  input_window = gdk_input_window_find(window);
+  g_return_if_fail (input_window != NULL);
+
+  gdk_input_compute_obscuring(input_window);
+}
+
+static gint 
+gdk_input_gxi_other_event (GdkEvent *event, 
+                          XEvent *xevent, 
+                          GdkWindow *window)
+{
+  GdkInputWindow *input_window;
+
+  GdkDevicePrivate *gdkdev;
+  gint return_val;
+
+  input_window = gdk_input_window_find(window);
+  g_return_val_if_fail (window != NULL, -1);
+
+  /* This is a sort of a hack, as there isn't any XDeviceAnyEvent -
+     but it's potentially faster than scanning through the types of
+     every device. If we were deceived, then it won't match any of
+     the types for the device anyways */
+  gdkdev = gdk_input_find_device(((XDeviceButtonEvent *)xevent)->deviceid);
+
+  if (!gdkdev) {
+    return -1;                 /* we don't handle it - not an XInput event */
+  }
+
+  if (gdkdev->info.mode == GDK_MODE_DISABLED ||
+      input_window->mode == GDK_EXTENSION_EVENTS_CURSOR)
+    return FALSE;
+  
+  if (gdkdev != gdk_input_current_device &&
+      xevent->type != gdkdev->changenotify_type)
+    {
+      gdk_input_current_device = gdkdev;
+    }
+
+  return_val = gdk_input_common_other_event (event, xevent, 
+                                            input_window, gdkdev);
+
+  if (return_val > 0 && event->type == GDK_MOTION_NOTIFY &&
+      (!gdkdev->button_state) && (!input_window->grabbed) &&
+      ((event->motion.x < 0) || (event->motion.y < 0) ||
+       (event->motion.x > ((GdkWindowPrivate *)window)->width) || 
+       (event->motion.y > ((GdkWindowPrivate *)window)->height) ||
+       gdk_input_is_obscured(input_window,event->motion.x,event->motion.y)))
+    {
+#ifdef DEBUG_SWITCHING
+      g_print("gdkinput: Setting core pointer to %d on motion at (%f,%f)\n",
+             gdkdev->info.deviceid,event->motion.x,event->motion.y);
+      g_print("   window geometry is: %dx%d\n",
+             ((GdkWindowPrivate *)window)->width,
+             ((GdkWindowPrivate *)window)->height);
+#endif      
+      gdk_input_gxi_set_core_pointer(gdkdev);
+      return FALSE;
+    }
+  else
+    return return_val;
+
+}
+
+static void
+gdk_input_gxi_update_device (GdkDevicePrivate *gdkdev)
+{
+  GList *t;
+
+  if (gdk_input_is_extension_device (gdkdev->info.deviceid))
+    {
+      if (!gdkdev->xdevice)
+       {
+         gdkdev->xdevice = XOpenDevice(gdk_display, gdkdev->info.deviceid);
+         gdk_input_gxi_select_notify (gdkdev);
+         gdkdev->needs_update = 1;
+       }
+      if (gdkdev->needs_update && gdkdev->xdevice)
+       {
+         for (t = gdk_input_windows; t; t = t->next)
+           gdk_input_common_select_events (((GdkInputWindow *)t->data)->window,
+                                        gdkdev);
+         gdkdev->needs_update = 0;
+       }
+    }
+}
+
+static gint 
+gdk_input_gxi_window_none_event (GdkEvent *event, XEvent *xevent)
+{
+  GdkDevicePrivate *gdkdev = 
+    gdk_input_find_device(((XDeviceButtonEvent *)xevent)->deviceid);
+
+  if (!gdkdev) {
+    return -1;                 /* we don't handle it - not an XInput event */
+  }
+
+  if (xevent->type == gdkdev->changenotify_type)
+    {
+      if (gdk_input_core_pointer != gdkdev)
+       {
+#ifdef DEBUG_SWITCHING
+         g_print("ChangeNotify from %d to %d:\n",
+                 gdk_input_core_pointer->info.deviceid,
+                 gdkdev->info.deviceid);
+#endif
+         gdk_input_gxi_update_device (gdk_input_core_pointer);
+         gdk_input_core_pointer = gdkdev;
+       }
+    }
+               
+  return FALSE;
+}
+
+static gint
+gdk_input_gxi_enable_window (GdkWindow *window, GdkDevicePrivate *gdkdev)
+{
+  GdkInputWindow *input_window;
+
+  input_window = gdk_input_window_find (window);
+  g_return_val_if_fail (input_window != NULL, FALSE);
+
+  if (!gdkdev->claimed)
+    {
+      if (gxid_claim_device(gdk_input_gxid_host, gdk_input_gxid_port,
+                           gdkdev->info.deviceid,
+                           GDK_WINDOW_XWINDOW(window), FALSE) !=
+         GXID_RETURN_OK)
+       {
+         g_warning("Could not get device (is gxid running?)\n");
+         return FALSE;
+       }
+      gdkdev->claimed = TRUE;
+    }
+
+  if (gdkdev->xdevice && gdkdev != gdk_input_core_pointer)
+    gdk_input_common_select_events(window, gdkdev);
+  else
+    gdkdev->needs_update = TRUE;
+  
+  return TRUE;
+}
+
+static gint
+gdk_input_gxi_disable_window(GdkWindow *window, GdkDevicePrivate *gdkdev)
+{
+  GdkInputWindow *input_window;
+
+  input_window = gdk_input_window_find (window);
+  g_return_val_if_fail (input_window != NULL, FALSE);
+
+  if (gdkdev->claimed)
+    {
+      gxid_release_device(gdk_input_gxid_host, gdk_input_gxid_port,
+                         gdkdev->info.deviceid,
+                         GDK_WINDOW_XWINDOW(window));
+
+      gdkdev->claimed = FALSE;
+    }
+
+  if (gdkdev->xdevice && gdkdev != gdk_input_core_pointer)
+    gdk_input_common_select_events(window, gdkdev);
+  else
+    gdkdev->needs_update = TRUE;
+  
+  return TRUE;
+}
+
+static gint
+gdk_input_is_obscured(GdkInputWindow *input_window, gdouble x, gdouble y)
+{
+  int i;
+  for (i=0;i<input_window->num_obscuring;i++)
+    {
+      GdkRectangle *rect = &input_window->obscuring[i];
+      if ((x >= rect->x) &&
+         (y >= rect->y) &&
+         (x < rect->x + rect->width) &&
+         (y < rect->y + rect->height))
+       return TRUE;
+    }
+  return FALSE;
+}
+
+/* If this routine needs fixing, the corresponding routine
+   in gxid.c will need it too. */
+
+static Window 
+gdk_input_find_root_child(Display *dpy, Window w)
+{
+  Window root,parent;
+  Window *children;
+  int nchildren;
+
+  parent = w;
+  do 
+    {
+      w = parent;
+      XQueryTree(dpy,w,&root,&parent,&children,&nchildren);
+      if (children) XFree(children);
+    } 
+  while (parent != root);
+  
+  return w;
+}
+
+void
+gdk_input_compute_obscuring(GdkInputWindow *input_window)
+{
+  int i;
+  int x,y,width,height;
+  int xc,yc,widthc,heightc,border_widthc,depthc;
+
+  Window root,parent;
+  Window *children;
+  int nchildren;
+
+  Window w = GDK_WINDOW_XWINDOW(input_window->window);
+  Window root_child = gdk_input_find_root_child(gdk_display,w);
+  gdk_input_get_root_relative_geometry(gdk_display,w,&x,&y,&width,&height);
+
+  input_window->root_x = x;
+  input_window->root_y = y;
+
+  XQueryTree(gdk_display,GDK_ROOT_WINDOW(),
+            &root,&parent,&children,&nchildren);
+
+
+  if (input_window->obscuring)
+    g_free(input_window->obscuring);
+  input_window->obscuring = 0;
+  input_window->num_obscuring = 0;
+
+  for (i=0;i<nchildren;i++)
+    if (children[i] == root_child)
+      break;
+
+  if (i>=nchildren-1)
+    {
+      if (nchildren)
+       XFree(children);
+      return;
+    }
+
+  input_window->obscuring = g_new(GdkRectangle,(nchildren-i-1));
+
+  for (i=i+1;i<nchildren;i++)
+    {
+      int xmin, xmax, ymin, ymax;
+      XGetGeometry(gdk_display,children[i],&root,&xc,&yc,&widthc,&heightc,
+                  &border_widthc, &depthc);
+      xmin = xc>x ? xc : x;
+      xmax = (xc+widthc)<(x+width) ? xc+widthc : x+width;
+      ymin = yc>y ? yc : y;
+      ymax = (yc+heightc)<(y+height) ? yc+heightc : y+height;
+      if ((xmin < xmax) && (ymin < ymax))
+       {
+         XWindowAttributes attributes;
+         XGetWindowAttributes(gdk_display,children[i],&attributes);
+         if (attributes.map_state == IsViewable)
+           {
+             GdkRectangle *rect = &input_window->obscuring[input_window->num_obscuring];
+             
+             /* we store the whole window, not just the obscuring part */
+             rect->x = xc - x;
+             rect->y = yc - y;
+             rect->width = widthc;
+             rect->height = heightc;
+             input_window->num_obscuring++;
+           }
+       }
+    }
+
+  if (nchildren)
+    XFree(children);
+}
+
+static void 
+gdk_input_gxi_get_pointer     (GdkWindow       *window,
+                              guint32     deviceid,
+                              gdouble         *x,
+                              gdouble         *y,
+                              gdouble         *pressure,
+                              gdouble         *xtilt,
+                              gdouble         *ytilt,
+                              GdkModifierType *mask)
+{
+  GdkDevicePrivate *gdkdev;
+
+  gdkdev = gdk_input_find_device (deviceid);
+  g_return_if_fail (gdkdev != NULL);
+
+  if (gdkdev == gdk_input_core_pointer)
+    gdk_input_common_get_pointer (window, GDK_CORE_POINTER, x, y,
+                                 pressure, xtilt, ytilt, mask);
+  else
+    gdk_input_common_get_pointer (window, deviceid, x, y,
+                                 pressure, xtilt, ytilt, mask);
+}
+
+static GdkTimeCoord *
+gdk_input_gxi_motion_events (GdkWindow *window,
+                            guint32 deviceid,
+                            guint32 start,
+                            guint32 stop,
+                            gint *nevents_return)
+{
+  GdkDevicePrivate *gdkdev;
+
+  gdkdev = gdk_input_find_device (deviceid);
+  g_return_val_if_fail (gdkdev != NULL, NULL);
+  
+
+  if (gdkdev == gdk_input_core_pointer)
+    return gdk_input_motion_events (window, GDK_CORE_POINTER, start, stop,
+                                   nevents_return);
+  else
+    return gdk_input_common_motion_events (window, deviceid, start, stop,
+                                          nevents_return);
+  
+}
+
+static gint 
+gdk_input_gxi_grab_pointer (GdkWindow *     window,
+                           gint            owner_events,
+                           GdkEventMask    event_mask,
+                           GdkWindow *     confine_to,
+                           guint32         time)
+{
+  GdkInputWindow *input_window, *new_window;
+  GList *tmp_list;
+
+  tmp_list = gdk_input_windows;
+  while (tmp_list)
+    {
+      input_window = (GdkInputWindow *)tmp_list->data;
+      if (input_window->grabbed)
+       return AlreadyGrabbed;
+
+      if (input_window->window == window)
+       new_window = input_window;
+      
+      tmp_list = tmp_list->next;
+    }
+
+  new_window->grabbed = TRUE;
+  return Success;
+}
+
+static void 
+gdk_input_gxi_ungrab_pointer (guint32 time)
+{
+  GdkInputWindow *input_window;
+  GList *tmp_list;
+
+  tmp_list = gdk_input_windows;
+  while (tmp_list)
+    {
+      input_window = (GdkInputWindow *)tmp_list->data;
+      if (input_window->grabbed)
+       input_window->grabbed = FALSE;
+      tmp_list = tmp_list->next;
+    }
+}
+
+#endif /* XINPUT_GXI */
diff --git a/gdk/x11/gdkinput-none.c b/gdk/x11/gdkinput-none.c
new file mode 100644 (file)
index 0000000..8ae8c41
--- /dev/null
@@ -0,0 +1,72 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef XINPUT_NONE
+
+static void gdk_input_none_get_pointer (GdkWindow       *window,
+                                       guint32   deviceid,
+                                       gdouble         *x,
+                                       gdouble         *y,
+                                       gdouble         *pressure,
+                                       gdouble         *xtilt,
+                                       gdouble         *ytilt,
+                                       GdkModifierType *mask);
+
+void
+gdk_input_init ()
+{
+  gdk_input_vtable.set_mode           = NULL;
+  gdk_input_vtable.set_axes           = NULL;
+  gdk_input_vtable.motion_events      = NULL;
+  gdk_input_vtable.get_pointer        = gdk_input_none_get_pointer;
+  gdk_input_vtable.grab_pointer       = NULL;
+  gdk_input_vtable.ungrab_pointer     = NULL;
+  gdk_input_vtable.configure_event    = NULL;
+  gdk_input_vtable.enter_event        = NULL;
+  gdk_input_vtable.other_event        = NULL;
+  gdk_input_vtable.window_none_event  = NULL;
+  gdk_input_vtable.enable_window      = NULL;
+  gdk_input_vtable.disable_window     = NULL;
+
+  gdk_input_devices = g_list_append (NULL, &gdk_input_core_info);
+
+  gdk_input_ignore_core = FALSE;
+}
+
+static void
+gdk_input_none_get_pointer (GdkWindow       *window,
+                           guint32          deviceid,
+                           gdouble         *x,
+                           gdouble         *y,
+                           gdouble         *pressure,
+                           gdouble         *xtilt,
+                           gdouble         *ytilt,
+                           GdkModifierType *mask)
+{
+  gint x_int, y_int;
+
+  gdk_window_get_pointer (window, &x_int, &y_int, mask);
+
+  if (x) *x = x_int;
+  if (y) *y = y_int;
+  if (pressure) *pressure = 0.5;
+  if (xtilt) *xtilt = 0;
+  if (ytilt) *ytilt = 0;
+}
+
+#endif /* XINPUT_NONE */
diff --git a/gdk/x11/gdkinput-x11.c b/gdk/x11/gdkinput-x11.c
new file mode 100644 (file)
index 0000000..5e457e0
--- /dev/null
@@ -0,0 +1,687 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#if defined(XINPUT_GXI) || defined(XINPUT_XFREE)
+
+/* Forward declarations */
+static void gdk_input_get_root_relative_geometry (Display *dpy, Window w, 
+                                                 int *x_ret, int *y_ret,
+                                                 int *width_ret, 
+                                                 int *height_ret);
+static GdkDevicePrivate *gdk_input_device_new(XDeviceInfo *device, 
+                                             gint include_core);
+static void gdk_input_common_find_events(GdkWindow *window,
+                                        GdkDevicePrivate *gdkdev,
+                                        gint mask,
+                                        XEventClass *classes,
+                                        int *num_classes);
+static void gdk_input_common_select_events(GdkWindow *window,
+                                          GdkDevicePrivate *gdkdev);
+static void gdk_input_translate_coordinates(GdkDevicePrivate *gdkdev,
+                                           GdkInputWindow *input_window,
+                                           gint *axis_data,
+                                           gdouble *x, gdouble *y,
+                                           gdouble *pressure,
+                                           gdouble *xtilt, gdouble *ytilt);
+static guint gdk_input_translate_state(guint state, guint device_state);
+static gint gdk_input_common_init(gint include_core);
+static gint  gdk_input_common_other_event (GdkEvent *event, 
+                                          XEvent *xevent, 
+                                          GdkInputWindow *input_window,
+                                          GdkDevicePrivate *gdkdev);
+static void gdk_input_common_set_axes (guint32 deviceid, GdkAxisUse *axes);
+static GdkTimeCoord * gdk_input_common_motion_events (GdkWindow *window,
+                                                     guint32 deviceid,
+                                                     guint32 start,
+                                                     guint32 stop,
+                                                     gint *nevents_return);
+static void  gdk_input_common_get_pointer     (GdkWindow       *window,
+                                              guint32     deviceid,
+                                              gdouble         *x,
+                                              gdouble         *y,
+                                              gdouble         *pressure,
+                                              gdouble         *xtilt,
+                                              gdouble         *ytilt,
+                                              GdkModifierType *mask);
+
+/* Global variables */
+
+static gint gdk_input_root_width;
+static gint gdk_input_root_height;
+
+static void
+gdk_input_get_root_relative_geometry(Display *dpy, Window w, int *x_ret, int *y_ret,
+                              int *width_ret, int *height_ret)
+{
+  Window root,parent;
+  Window *children;
+  int nchildren;
+  int x,y,width,height;
+  int xc,yc,widthc,heightc,border_widthc,depthc;
+  
+  XQueryTree(dpy,w,&root,&parent,&children,&nchildren);
+  if (children) XFree(children);
+  XGetGeometry(dpy,w,&root,&x,&y,&width,&height,&border_widthc,
+              &depthc);
+  x += border_widthc;
+  y += border_widthc;
+
+  while (root != parent)
+    {
+      w = parent;
+      XQueryTree(dpy,w,&root,&parent,&children,&nchildren);
+      if (children) XFree(children);
+      XGetGeometry(dpy,w,&root,&xc,&yc,&widthc,&heightc,
+                  &border_widthc,&depthc);
+      x += xc + border_widthc;
+      y += yc + border_widthc;
+    }
+
+  if (x_ret)
+    *x_ret = x;
+  if (y_ret)
+    *y_ret = y;
+  if (width_ret)
+    *width_ret = width;
+  if (height_ret)
+    *height_ret = height;
+}
+
+static GdkDevicePrivate *
+gdk_input_device_new(XDeviceInfo *device, gint include_core)
+{
+  GdkDevicePrivate *gdkdev;
+  gchar *tmp_name, *p;
+  XAnyClassPtr class;
+  gint i,j;
+
+  gdkdev = g_new(GdkDevicePrivate,1);
+
+  gdkdev->info.deviceid = device->id;
+  if (device->name[0]) {
+    gdkdev->info.name = g_new(char, strlen(device->name)+1);
+    strcpy(gdkdev->info.name,device->name);
+  } else {
+    /* XFree86 3.2 gives an empty name to the default core devices,
+       (fixed in 3.2A) */
+    gdkdev->info.name = g_strdup("pointer");
+    strcpy(gdkdev->info.name,"pointer");
+    gdkdev->info.source = GDK_SOURCE_MOUSE;
+  }
+
+  gdkdev->info.mode = GDK_MODE_DISABLED;
+
+  /* Try to figure out what kind of device this is by its name -
+     could invite a very, very, long list... Lowercase name
+     for comparison purposes */
+
+  tmp_name = g_strdup(gdkdev->info.name);
+  for (p = tmp_name; *p; p++)
+    {
+      if (*p >= 'A' && *p <= 'Z')
+       *p += 'a' - 'A';
+    }
+  
+  if (!strcmp (tmp_name, "pointer"))
+    gdkdev->info.source = GDK_SOURCE_MOUSE;
+  else if (!strcmp (tmp_name, "wacom") ||
+          !strcmp (tmp_name, "pen"))
+    gdkdev->info.source = GDK_SOURCE_PEN;
+  else if (!strcmp (tmp_name, "eraser"))
+    gdkdev->info.source = GDK_SOURCE_ERASER;
+  else if (!strcmp (tmp_name, "cursor"))
+    gdkdev->info.source = GDK_SOURCE_CURSOR;
+  else
+    gdkdev->info.source = GDK_SOURCE_PEN;
+
+  g_free(tmp_name);
+
+  gdkdev->xdevice = NULL;
+
+  /* step through the classes */
+
+  gdkdev->info.num_axes = 0;
+  gdkdev->axes = 0;
+  gdkdev->info.has_cursor = 0;
+  gdkdev->needs_update = FALSE;
+  gdkdev->claimed = FALSE;
+  gdkdev->button_state = 0;
+
+  class = device->inputclassinfo;
+  for (i=0;i<device->num_classes;i++) 
+    {
+      switch (class->class) {
+      case ButtonClass:
+       {
+         break;
+       }
+      case ValuatorClass:
+       {
+         XValuatorInfo *xvi = (XValuatorInfo *)class;
+         gdkdev->info.num_axes = xvi->num_axes;
+         gdkdev->axes = g_new(GdkAxisInfo, xvi->num_axes);
+         gdkdev->info.axes = g_new(GdkAxisUse, xvi->num_axes);
+         for (j=0;j<xvi->num_axes;j++)
+           {
+             gdkdev->axes[j].resolution = 
+               gdkdev->axes[j].xresolution = xvi->axes[j].resolution;
+             gdkdev->axes[j].min_value =
+               gdkdev->axes[j].xmin_value = xvi->axes[j].min_value;
+             gdkdev->axes[j].max_value =
+               gdkdev->axes[j].xmax_value = xvi->axes[j].max_value;
+             gdkdev->info.axes[j] = GDK_AXIS_IGNORE;
+           }
+         j=0;
+         if (j<xvi->num_axes)
+           gdkdev->info.axes[j++] = GDK_AXIS_X;
+         if (j<xvi->num_axes)
+           gdkdev->info.axes[j++] = GDK_AXIS_Y;
+         if (j<xvi->num_axes)
+           gdkdev->info.axes[j++] = GDK_AXIS_PRESSURE;
+         if (j<xvi->num_axes)
+           gdkdev->info.axes[j++] = GDK_AXIS_XTILT;
+         if (j<xvi->num_axes)
+           gdkdev->info.axes[j++] = GDK_AXIS_YTILT;
+         
+         /* set up reverse lookup on axis use */
+         for (j=GDK_AXIS_IGNORE;j<GDK_AXIS_LAST;j++)
+           gdkdev->axis_for_use[j] = -1;
+         
+         for (j=0;j<xvi->num_axes;j++)
+           if (gdkdev->info.axes[j] != GDK_AXIS_IGNORE)
+             gdkdev->axis_for_use[gdkdev->info.axes[j]] = j;
+                      
+         break;
+       }
+      }
+      class = (XAnyClassPtr)(((char *)class) + class->length);
+    }
+  /* return NULL if no axes */
+  if (!gdkdev->info.num_axes || !gdkdev->axes ||
+      (!include_core && device->use == IsXPointer))
+    {
+      g_free(gdkdev->info.name);
+      if (gdkdev->axes)
+       g_free(gdkdev->axes);
+      g_free(gdkdev);
+      return NULL;
+    }
+
+  if (device->use != IsXPointer)
+      gdkdev->xdevice = XOpenDevice(gdk_display, gdkdev->info.deviceid);
+
+  return gdkdev;
+}
+
+static void
+gdk_input_common_find_events(GdkWindow *window,
+                            GdkDevicePrivate *gdkdev,
+                            gint mask,
+                            XEventClass *classes,
+                            int *num_classes)
+{
+  gint i;
+  XEventClass class;
+  
+  i = 0;
+  /* We have to track press and release events in pairs to keep
+     track of button state correctly and implement grabbing */
+  if (mask & GDK_BUTTON_PRESS_MASK || mask & GDK_BUTTON_RELEASE_MASK)
+    {
+      DeviceButtonPress   (gdkdev->xdevice, gdkdev->buttonpress_type,
+                          class);
+      if (class != 0)
+         classes[i++] = class;
+      DeviceButtonRelease (gdkdev->xdevice, gdkdev->buttonrelease_type,
+                          class);
+      if (class != 0)
+         classes[i++] = class;
+    }
+  if (mask & GDK_POINTER_MOTION_MASK)
+    {
+      DeviceMotionNotify  (gdkdev->xdevice, gdkdev->motionnotify_type, class);
+      if (class != 0)
+         classes[i++] = class;
+    }
+  if (mask & GDK_POINTER_MOTION_HINT_MASK)
+    {
+      /* We'll get into trouble if the macros change, but at least we'll
+        know about it, and we avoid warnings now */
+      DevicePointerMotionHint (gdkdev->xdevice, 0, class);
+      if (class != 0)
+         classes[i++] = class;
+    }
+  if (mask & GDK_PROXIMITY_IN_MASK)
+    {
+      ProximityIn   (gdkdev->xdevice, gdkdev->proximityin_type, class);
+      if (class != 0)
+         classes[i++] = class;
+    }
+  if (mask & GDK_PROXIMITY_OUT_MASK)
+    {
+      ProximityOut  (gdkdev->xdevice, gdkdev->proximityout_type, class);
+      if (class != 0)
+         classes[i++] = class;
+    }
+
+  *num_classes = i;
+}
+
+static void
+gdk_input_common_select_events(GdkWindow *window,
+                              GdkDevicePrivate *gdkdev)
+{
+  XEventClass classes[6];
+  gint num_classes;
+
+  if (gdkdev->info.mode == GDK_MODE_DISABLED)
+    gdk_input_common_find_events(window, gdkdev, 0, classes, &num_classes);
+  else
+    gdk_input_common_find_events(window, gdkdev, 
+                                ((GdkWindowPrivate *)window)->extension_events,
+                                classes, &num_classes);
+  
+  XSelectExtensionEvent (gdk_display,
+                        GDK_WINDOW_XWINDOW(window),
+                        classes, num_classes);
+}
+
+gint 
+gdk_input_common_init(gint include_core)
+{
+  char **extensions;
+  XDeviceInfo   *devices;
+  int num_devices;
+  int num_extensions, loop;
+  Display *display = gdk_display;
+
+  /* Init global vars */
+  gdk_window_get_geometry(NULL,        /* use root window */
+                         NULL,NULL,
+                         &gdk_input_root_width,&gdk_input_root_height, 
+                         NULL);
+
+  /* Init XInput extension */
+  
+  extensions = XListExtensions(display, &num_extensions);
+  for (loop = 0; loop < num_extensions &&
+        (strcmp(extensions[loop], "XInputExtension") != 0); loop++);
+  XFreeExtensionList(extensions);
+  if (loop == num_extensions)  /* XInput extension not found */
+    return FALSE;
+
+  gdk_input_devices = 0;
+  devices = XListInputDevices(display, &num_devices);
+  
+  for(loop=0; loop<num_devices; loop++)
+    {
+      GdkDevicePrivate *gdkdev = gdk_input_device_new(&devices[loop],
+                                                     include_core);
+      if (gdkdev)
+       gdk_input_devices = g_list_append(gdk_input_devices, gdkdev);
+    }
+  XFreeDeviceList(devices);
+
+  gdk_input_devices = g_list_append (gdk_input_devices, &gdk_input_core_info);
+
+  return TRUE;
+}
+
+static void
+gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
+                                GdkInputWindow *input_window,
+                                gint *axis_data,
+                                gdouble *x, gdouble *y, gdouble *pressure,
+                                gdouble *xtilt, gdouble *ytilt)
+{
+  GdkWindowPrivate *win_priv;
+
+  int x_axis, y_axis, pressure_axis, xtilt_axis, ytilt_axis;
+
+  double device_width, device_height;
+  double x_offset, y_offset, x_scale, y_scale;
+
+  win_priv = (GdkWindowPrivate *) input_window->window;
+
+  x_axis = gdkdev->axis_for_use[GDK_AXIS_X];
+  y_axis = gdkdev->axis_for_use[GDK_AXIS_Y];
+  pressure_axis = gdkdev->axis_for_use[GDK_AXIS_PRESSURE];
+  xtilt_axis = gdkdev->axis_for_use[GDK_AXIS_XTILT];
+  ytilt_axis = gdkdev->axis_for_use[GDK_AXIS_YTILT];
+
+  device_width = gdkdev->axes[x_axis].max_value - 
+                  gdkdev->axes[x_axis].min_value;
+  device_height = gdkdev->axes[y_axis].max_value - 
+                    gdkdev->axes[y_axis].min_value;
+
+  if (gdkdev->info.mode == GDK_MODE_SCREEN) 
+    {
+      x_scale = gdk_input_root_width / device_width;
+      y_scale = gdk_input_root_height / device_height;
+
+      x_offset = - input_window->root_x;
+      y_offset = - input_window->root_y;
+    }
+  else                         /* GDK_MODE_WINDOW */
+    {
+      double device_aspect = (device_height*gdkdev->axes[y_axis].resolution) /
+       (device_width*gdkdev->axes[x_axis].resolution);
+
+      if (device_aspect * win_priv->width >= win_priv->height)
+       {
+         /* device taller than window */
+         x_scale = win_priv->width / device_width;
+         y_scale = (x_scale * gdkdev->axes[x_axis].resolution)
+           / gdkdev->axes[y_axis].resolution;
+
+         x_offset = 0;
+         y_offset = -(device_height * y_scale - 
+                              win_priv->height)/2;
+       }
+      else
+       {
+         /* window taller than device */
+         y_scale = win_priv->height / device_height;
+         x_scale = (y_scale * gdkdev->axes[y_axis].resolution)
+           / gdkdev->axes[x_axis].resolution;
+
+         y_offset = 0;
+         x_offset = - (device_width * x_scale - win_priv->width)/2;
+       }
+    }
+  
+  if (x) *x = x_offset + x_scale*axis_data[x_axis];
+  if (y) *y = y_offset + y_scale*axis_data[y_axis];
+
+  if (pressure)
+    {
+      if (pressure_axis != -1)
+       *pressure = ((double)axis_data[pressure_axis] 
+                    - gdkdev->axes[pressure_axis].min_value) 
+         / (gdkdev->axes[pressure_axis].max_value 
+            - gdkdev->axes[pressure_axis].min_value);
+      else
+       *pressure = 0.5;
+    }
+
+  if (xtilt)
+    {
+      if (xtilt_axis != -1)
+       {
+         *xtilt = 2. * (double)(axis_data[xtilt_axis] - 
+                                (gdkdev->axes[xtilt_axis].min_value +
+                                 gdkdev->axes[xtilt_axis].max_value)/2) /
+           (gdkdev->axes[xtilt_axis].max_value -
+            gdkdev->axes[xtilt_axis].min_value);
+       }
+      else *xtilt = 0;
+    }
+  
+  if (ytilt)
+    {
+      if (ytilt_axis != -1)
+       {
+         *ytilt = 2. * (double)(axis_data[ytilt_axis] - 
+                                (gdkdev->axes[ytilt_axis].min_value +
+                                 gdkdev->axes[ytilt_axis].max_value)/2) /
+           (gdkdev->axes[ytilt_axis].max_value -
+            gdkdev->axes[ytilt_axis].min_value);
+       }
+      else
+       *ytilt = 0;
+    }
+}
+
+/* combine the state of the core device and the device state
+   into one - for now we do this in a simple-minded manner -
+   we just take the keyboard portion of the core device and
+   the button portion (all of?) the device state.
+   Any button remapping should go on here. */
+static guint
+gdk_input_translate_state(guint state, guint device_state)
+{
+  return device_state | (state & 0xFF);
+}
+
+static gint 
+gdk_input_common_other_event (GdkEvent *event, 
+                             XEvent *xevent, 
+                             GdkInputWindow *input_window,
+                             GdkDevicePrivate *gdkdev)
+{
+  if ((xevent->type == gdkdev->buttonpress_type) ||
+      (xevent->type == gdkdev->buttonrelease_type)) 
+    {
+      XDeviceButtonEvent *xdbe = (XDeviceButtonEvent *)(xevent);
+
+      if (xdbe->type == gdkdev->buttonpress_type)
+       {
+         event->button.type = GDK_BUTTON_PRESS;
+         gdkdev->button_state |= 1 << xdbe->button;
+       }
+      else
+       {
+         event->button.type = GDK_BUTTON_RELEASE;
+         gdkdev->button_state &= ~(1 << xdbe->button);
+       }
+      event->button.window = input_window->window;
+      event->button.time = xdbe->time;
+      event->button.source = gdkdev->info.source;
+      event->button.deviceid = xdbe->deviceid;
+
+      gdk_input_translate_coordinates (gdkdev,input_window, xdbe->axis_data,
+                                      &event->button.x,&event->button.y,
+                                      &event->button.pressure,
+                                      &event->button.xtilt, 
+                                      &event->button.ytilt);
+      event->button.state = gdk_input_translate_state(xdbe->state,xdbe->device_state);
+      event->button.button = xdbe->button;
+
+      return TRUE;
+  }
+
+  if (xevent->type == gdkdev->motionnotify_type) 
+    {
+      XDeviceMotionEvent *xdme = (XDeviceMotionEvent *)(xevent);
+
+      gdk_input_translate_coordinates(gdkdev,input_window,xdme->axis_data,
+                                     &event->motion.x,&event->motion.y,
+                                     &event->motion.pressure,
+                                     &event->motion.xtilt, 
+                                     &event->motion.ytilt);
+
+      event->motion.type = GDK_MOTION_NOTIFY;
+      event->motion.window = input_window->window;
+      event->motion.time = xdme->time;
+      event->motion.deviceid = xdme->deviceid;
+      event->motion.state = gdk_input_translate_state(xdme->state,
+                                                     xdme->device_state);
+      event->motion.source = gdkdev->info.source;
+      event->motion.deviceid = xdme->deviceid;
+
+      if (gdk_show_events)
+       g_print ("motion notify:\t\twindow: %ld  device: %ld  x,y: %f %f  hint: %s\n",
+                xdme->window,
+                xdme->deviceid,
+                event->motion.x, event->motion.y,
+                (xevent->xmotion.is_hint) ? "true" : "false");
+      
+      
+      return TRUE;
+    }
+
+  if (xevent->type == gdkdev->proximityin_type ||
+      xevent->type == gdkdev->proximityout_type)
+    {
+      XProximityNotifyEvent *xpne = (XProximityNotifyEvent *)(xevent);
+
+      event->proximity.type = (xevent->type == gdkdev->proximityin_type)?
+       GDK_PROXIMITY_IN:GDK_PROXIMITY_OUT;
+      event->proximity.window = input_window->window;
+      event->proximity.time = xpne->time;
+      event->proximity.source = gdkdev->info.source;
+      event->proximity.deviceid = xpne->deviceid;
+      
+      return TRUE;
+  }
+
+  return -1;                   /* wasn't one of our event types */
+}
+
+static void
+gdk_input_common_set_axes (guint32 deviceid, GdkAxisUse *axes)
+{
+  int i;
+  GdkDevicePrivate *gdkdev = gdk_input_find_device(deviceid);
+  g_return_if_fail (gdkdev != NULL);
+
+  for (i=GDK_AXIS_IGNORE;i<GDK_AXIS_LAST;i++)
+    {
+      gdkdev->axis_for_use[i] = -1;
+    }
+
+  for (i=0;i<gdkdev->info.num_axes;i++)
+    {
+      gdkdev->info.axes[i] = axes[i];
+      gdkdev->axis_for_use[axes[i]] = i;
+    }
+}
+
+static GdkTimeCoord *
+gdk_input_common_motion_events (GdkWindow *window,
+                               guint32 deviceid,
+                               guint32 start,
+                               guint32 stop,
+                               gint *nevents_return)
+{
+  GdkTimeCoord *coords;
+  XDeviceTimeCoord *device_coords;
+  GdkInputWindow *input_window;
+  GdkDevicePrivate *gdkdev;
+
+  int mode_return;
+  int axis_count_return;
+  int i;
+
+  gdkdev = gdk_input_find_device (deviceid);
+  input_window = gdk_input_window_find (window);
+
+  g_return_val_if_fail (gdkdev != NULL, NULL);
+  g_return_val_if_fail (gdkdev->xdevice != NULL, NULL);
+  g_return_val_if_fail (input_window != NULL, NULL);
+
+  device_coords = XGetDeviceMotionEvents (gdk_display,
+                                         gdkdev->xdevice,
+                                         start, stop,
+                                         nevents_return, &mode_return,
+                                         &axis_count_return);
+
+  if (device_coords)
+    {
+      coords = g_new (GdkTimeCoord, *nevents_return);
+      
+      for (i=0; i<*nevents_return; i++)
+       {
+         gdk_input_translate_coordinates (gdkdev, input_window,
+                                          device_coords[i].data,
+                                          &coords[i].x, &coords[i].y,
+                                          &coords[i].pressure,
+                                          &coords[i].xtilt, &coords[i].ytilt);
+       }
+      XFreeDeviceMotionEvents (device_coords);
+
+      return coords;
+    }
+  else
+    return NULL;
+}
+
+static void 
+gdk_input_common_get_pointer     (GdkWindow       *window,
+                                 guint32          deviceid,
+                                 gdouble         *x,
+                                 gdouble         *y,
+                                 gdouble         *pressure,
+                                 gdouble         *xtilt,
+                                 gdouble         *ytilt,
+                                 GdkModifierType *mask)
+{
+  GdkDevicePrivate *gdkdev;
+  GdkInputWindow *input_window;
+  XDeviceState *state;
+  XInputClass *input_class;
+  gint x_int, y_int;
+  gint i;
+
+  /* we probably need to get the mask in any case */
+
+  if (deviceid == GDK_CORE_POINTER)
+    {
+      gdk_window_get_pointer (window, &x_int, &y_int, mask);
+      if (x) *x = x_int;
+      if (y) *y = y_int;
+      if (pressure) *pressure = 0.5;
+      if (xtilt) *xtilt = 0;
+      if (ytilt) *ytilt = 0;
+    }
+  else
+    {
+      if (mask)
+       gdk_window_get_pointer (window, NULL, NULL, mask);
+      
+      gdkdev = gdk_input_find_device (deviceid);
+      input_window = gdk_input_window_find (window);
+
+      g_return_if_fail (gdkdev != NULL);
+      g_return_if_fail (gdkdev->xdevice != NULL);
+      g_return_if_fail (input_window != NULL);
+
+      state = XQueryDeviceState (gdk_display, gdkdev->xdevice);
+      input_class = state->data;
+      for (i=0; i<state->num_classes; i++)
+       {
+         switch (input_class->class)
+           {
+           case ValuatorClass:
+             gdk_input_translate_coordinates(gdkdev, input_window,
+                                             ((XValuatorState *)input_class)->valuators,
+                                             x, y, pressure,
+                                             xtilt, ytilt);
+                                                      
+                                                      
+               break;
+           case ButtonClass:
+             if (mask)
+               {
+                 *mask &= ~(GDK_BUTTON1_MASK | GDK_BUTTON2_MASK |
+                            GDK_BUTTON3_MASK | GDK_BUTTON4_MASK |
+                            GDK_BUTTON5_MASK);
+                 for (i=0; i < ((XButtonState *)input_class)->num_buttons; i++)
+                   {
+                     if (((XButtonState *)input_class)->buttons[i])
+                       *mask |= GDK_BUTTON1_MASK << i;
+                   }
+               }
+             break;
+           }
+         input_class = (XInputClass *)(((char *)input_class)+input_class->length);
+       }
+    }
+}
+
+#endif
diff --git a/gdk/x11/gdkinput-xfree.c b/gdk/x11/gdkinput-xfree.c
new file mode 100644 (file)
index 0000000..f742490
--- /dev/null
@@ -0,0 +1,368 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef XINPUT_XFREE
+
+/* forward declarations */
+
+static gint gdk_input_xfree_set_mode (guint32 deviceid, GdkInputMode mode);
+static void gdk_input_check_proximity();
+static void gdk_input_xfree_configure_event (XConfigureEvent *xevent, 
+                                            GdkWindow *window);
+static void gdk_input_xfree_enter_event (XCrossingEvent *xevent, 
+                                      GdkWindow *window);
+static gint gdk_input_xfree_other_event (GdkEvent *event, 
+                                        XEvent *xevent, 
+                                        GdkWindow *window);
+static gint gdk_input_xfree_enable_window(GdkWindow *window, 
+                                         GdkDevicePrivate *gdkdev);
+static gint gdk_input_xfree_disable_window(GdkWindow *window,
+                                          GdkDevicePrivate *gdkdev);
+static gint gdk_input_xfree_grab_pointer (GdkWindow *     window,
+                                       gint            owner_events,
+                                       GdkEventMask    event_mask,
+                                       GdkWindow *     confine_to,
+                                       guint32         time);
+static void gdk_input_xfree_ungrab_pointer (guint32 time);
+
+void 
+gdk_input_init(void)
+{
+  gdk_input_vtable.set_mode           = gdk_input_xfree_set_mode;
+  gdk_input_vtable.set_axes        = gdk_input_common_set_axes;
+  gdk_input_vtable.motion_events      = gdk_input_common_motion_events;
+  gdk_input_vtable.get_pointer       = gdk_input_common_get_pointer;
+  gdk_input_vtable.grab_pointer              = gdk_input_xfree_grab_pointer;
+  gdk_input_vtable.ungrab_pointer     = gdk_input_xfree_ungrab_pointer;
+  gdk_input_vtable.configure_event    = gdk_input_xfree_configure_event;
+  gdk_input_vtable.enter_event        = gdk_input_xfree_enter_event;
+  gdk_input_vtable.other_event        = gdk_input_xfree_other_event;
+  gdk_input_vtable.window_none_event  = NULL;
+  gdk_input_vtable.enable_window      = gdk_input_xfree_enable_window;
+  gdk_input_vtable.disable_window     = gdk_input_xfree_disable_window;
+
+  gdk_input_ignore_core = FALSE;
+  gdk_input_common_init(FALSE);
+}
+
+static gint
+gdk_input_xfree_set_mode (guint32 deviceid, GdkInputMode mode)
+{
+  GList *tmp_list;
+  GdkDevicePrivate *gdkdev;
+  GdkInputMode old_mode;
+  GdkInputWindow *input_window;
+
+  gdkdev = gdk_input_find_device(deviceid);
+  g_return_val_if_fail (gdkdev != NULL,FALSE);
+  old_mode = gdkdev->info.mode;
+
+  if (gdkdev->info.mode == mode)
+    return TRUE;
+
+  gdkdev->info.mode = mode;
+
+  if (mode == GDK_MODE_WINDOW)
+    {
+      gdkdev->info.has_cursor = FALSE;
+      for (tmp_list = gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
+       {
+         input_window = (GdkInputWindow *)tmp_list->data;
+         if (input_window->mode != GDK_EXTENSION_EVENTS_CURSOR)
+           gdk_input_enable_window (input_window->window, gdkdev);
+         else
+           if (old_mode != GDK_MODE_DISABLED)
+             gdk_input_disable_window (input_window->window, gdkdev);
+       }
+    }
+  else if (mode == GDK_MODE_SCREEN)
+    {
+      gdkdev->info.has_cursor = TRUE;
+      for (tmp_list = gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
+       gdk_input_enable_window (((GdkInputWindow *)tmp_list->data)->window,
+                                gdkdev);
+    }
+  else  /* mode == GDK_MODE_DISABLED */
+    {
+      for (tmp_list = gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
+       {
+         input_window = (GdkInputWindow *)tmp_list->data;
+         if (old_mode != GDK_MODE_WINDOW ||
+             input_window->mode != GDK_EXTENSION_EVENTS_CURSOR)
+           gdk_input_disable_window (input_window->window, gdkdev);
+       }
+    }
+
+  return TRUE;
+  
+}
+
+static void
+gdk_input_check_proximity()
+{
+  gint new_proximity = 0;
+  GList *tmp_list = gdk_input_devices;
+
+  while (tmp_list && !new_proximity) 
+    {
+      GdkDevicePrivate *gdkdev = (GdkDevicePrivate *)(tmp_list->data);
+
+      if (gdkdev->info.mode != GDK_MODE_DISABLED 
+         && gdkdev->info.deviceid != GDK_CORE_POINTER
+         && gdkdev->xdevice)
+       {
+         XDeviceState *state = XQueryDeviceState(GDK_DISPLAY(),
+                                                 gdkdev->xdevice);
+         XInputClass *xic;
+         int i;
+         
+         xic = state->data;
+         for (i=0; i<state->num_classes; i++)
+           {
+             if (xic->class == ValuatorClass)
+               {
+                 XValuatorState *xvs = (XValuatorState *)xic;
+                 if ((xvs->mode & ProximityState) == InProximity)
+                   {
+                     new_proximity = TRUE;
+                   }
+                 break;
+               }
+             xic = (XInputClass *)((char *)xic + xic->length);
+           }
+       }
+      tmp_list = tmp_list->next;
+    }
+
+  gdk_input_ignore_core = new_proximity;
+}
+
+static void
+gdk_input_xfree_configure_event (XConfigureEvent *xevent, GdkWindow *window)
+{
+  GdkInputWindow *input_window;
+  gint root_x, root_y;
+
+  input_window = gdk_input_window_find(window);
+  g_return_if_fail (window != NULL);
+
+  gdk_input_get_root_relative_geometry(GDK_DISPLAY(),GDK_WINDOW_XWINDOW(window),
+                                &root_x, 
+                                &root_y, NULL, NULL);
+
+  input_window->root_x = root_x;
+  input_window->root_y = root_y;
+}
+
+static void 
+gdk_input_xfree_enter_event (XCrossingEvent *xevent, 
+                                      GdkWindow *window)
+{
+  GdkInputWindow *input_window;
+  gint root_x, root_y;
+
+  input_window = gdk_input_window_find(window);
+  g_return_if_fail (window != NULL);
+
+  gdk_input_check_proximity();
+
+  gdk_input_get_root_relative_geometry(GDK_DISPLAY(),GDK_WINDOW_XWINDOW(window),
+                                &root_x, 
+                                &root_y, NULL, NULL);
+
+  input_window->root_x = root_x;
+  input_window->root_y = root_y;
+}
+
+static gint 
+gdk_input_xfree_other_event (GdkEvent *event, 
+                            XEvent *xevent, 
+                            GdkWindow *window)
+{
+  GdkInputWindow *input_window;
+
+  GdkDevicePrivate *gdkdev;
+  gint return_val;
+
+  input_window = gdk_input_window_find(window);
+  g_return_val_if_fail (window != NULL, -1);
+
+  /* This is a sort of a hack, as there isn't any XDeviceAnyEvent -
+     but it's potentially faster than scanning through the types of
+     every device. If we were deceived, then it won't match any of
+     the types for the device anyways */
+  gdkdev = gdk_input_find_device(((XDeviceButtonEvent *)xevent)->deviceid);
+
+  if (!gdkdev) {
+    return -1;                 /* we don't handle it - not an XInput event */
+  }
+
+  /* FIXME: It would be nice if we could just get rid of the events 
+     entirely, instead of having to ignore them */
+  if (gdkdev->info.mode == GDK_MODE_DISABLED ||
+      (gdkdev->info.mode == GDK_MODE_WINDOW 
+       && input_window->mode == GDK_EXTENSION_EVENTS_CURSOR))
+    return FALSE;
+  
+  if (!gdk_input_ignore_core)
+    gdk_input_check_proximity();
+
+  return_val = gdk_input_common_other_event (event, xevent, 
+                                            input_window, gdkdev);
+
+  if (return_val > 0 && event->type == GDK_PROXIMITY_OUT &&
+      gdk_input_ignore_core)
+    gdk_input_check_proximity();
+
+  /* Do a passive button grab. We have to be careful not to release
+     an explicit grab, if any. Doubling the grab should be harmless,
+     but we check anyways. */
+
+  /* FIXME, finding the proper events here is going to be SLOW - but
+     we might have different sets for each window/device combination */
+  
+  if (return_val> 0 && !input_window->grabbed)
+    {
+      if (event->type == GDK_BUTTON_PRESS)
+       {
+         XEventClass event_classes[6];
+         gint num_classes;
+         
+         gdk_input_common_find_events (window, gdkdev, 
+                                       ((GdkWindowPrivate *)window)->extension_events, 
+                                       event_classes, &num_classes);
+         
+       XGrabDevice( GDK_DISPLAY(), gdkdev->xdevice,
+                    GDK_WINDOW_XWINDOW (window),
+                    TRUE, num_classes, event_classes,
+                    GrabModeAsync, GrabModeAsync, event->button.time);
+       }
+      else if (event->type == GDK_BUTTON_RELEASE)
+       XUngrabDevice( GDK_DISPLAY(), gdkdev->xdevice, event->button.time);
+    }
+
+  return return_val;
+}
+
+static gint
+gdk_input_xfree_enable_window(GdkWindow *window, GdkDevicePrivate *gdkdev)
+{
+  /* FIXME: watchout, gdkdev might be core pointer, never opened */
+  gdk_input_common_select_events (window, gdkdev);
+  return TRUE;
+}
+
+static gint
+gdk_input_xfree_disable_window(GdkWindow *window, GdkDevicePrivate *gdkdev)
+{
+  gdk_input_common_select_events (window, gdkdev);
+  return TRUE;
+}
+
+static gint 
+gdk_input_xfree_grab_pointer (GdkWindow *     window,
+                             gint            owner_events,
+                             GdkEventMask    event_mask,
+                             GdkWindow *     confine_to,
+                             guint32         time)
+{
+  GdkInputWindow *input_window, *new_window;
+  GdkDevicePrivate *gdkdev;
+  GList *tmp_list;
+  XEventClass event_classes[6];
+  gint num_classes;
+
+  tmp_list = gdk_input_windows;
+  new_window = NULL;
+  while (tmp_list)
+    {
+      input_window = (GdkInputWindow *)tmp_list->data;
+      if (input_window->grabbed)
+       return AlreadyGrabbed;
+
+      if (input_window->window == window)
+       {
+         new_window = input_window;
+         break;
+       }
+      
+      tmp_list = tmp_list->next;
+    }
+  
+  g_return_if_fail (new_window == NULL);
+  
+  new_window->grabbed = TRUE;
+
+  tmp_list = gdk_input_devices;
+  while (tmp_list)
+    {
+      gdkdev = (GdkDevicePrivate *)tmp_list->data;
+      if (gdkdev->info.deviceid != GDK_CORE_POINTER &&
+         gdkdev->xdevice && !gdkdev->button_state)
+       {
+         gdk_input_common_find_events (window, gdkdev, 
+                                       ((GdkWindowPrivate *)window)->extension_events, 
+                                       event_classes, &num_classes);
+
+         /* FIXME: we should do something on failure */
+         XGrabDevice( GDK_DISPLAY(), gdkdev->xdevice,
+                      GDK_WINDOW_XWINDOW (window),
+                      TRUE, num_classes, event_classes,
+                      GrabModeAsync, GrabModeAsync, time);
+       }
+      tmp_list = tmp_list->next;
+    }
+  
+  return Success;
+}
+
+static void 
+gdk_input_xfree_ungrab_pointer (guint32 time)
+{
+  GdkInputWindow *input_window;
+  GdkDevicePrivate *gdkdev;
+  GList *tmp_list;
+
+  tmp_list = gdk_input_windows;
+  while (tmp_list)
+    {
+      input_window = (GdkInputWindow *)tmp_list->data;
+      if (input_window->grabbed)
+       break;
+      tmp_list = tmp_list->next;
+    }
+
+  if (tmp_list)                        /* we found a grabbed window */
+    {
+      input_window->grabbed = FALSE;
+
+      tmp_list = gdk_input_devices;
+      while (tmp_list)
+       {
+         gdkdev = (GdkDevicePrivate *)tmp_list->data;
+         if (gdkdev->info.deviceid != GDK_CORE_POINTER &&
+             gdkdev->xdevice && !gdkdev->button_state)
+           {
+             XUngrabDevice( gdk_display, gdkdev->xdevice, time);
+           }
+         tmp_list = tmp_list->next;
+       }
+    }
+}
+
+#endif /* XINPUT_XFREE */
diff --git a/gdk/x11/gdkinput.c b/gdk/x11/gdkinput.c
new file mode 100644 (file)
index 0000000..ad4b1fc
--- /dev/null
@@ -0,0 +1,324 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdlib.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include "../config.h"
+#include "gdk.h"
+#include "gdkx.h"
+#include "gdkprivate.h"
+#include "gdkinput.h"
+
+
+/* Forward declarations */
+
+static gint gdk_input_enable_window (GdkWindow *window,
+                                    GdkDevicePrivate *gdkdev);
+static gint gdk_input_disable_window (GdkWindow *window,
+                                     GdkDevicePrivate *gdkdev);
+static GdkInputWindow *gdk_input_window_find (GdkWindow *window);
+static GdkDevicePrivate *gdk_input_find_device (guint32 id);
+
+
+/* Incorporate the specific routines depending on compilation options */
+
+static GdkAxisUse gdk_input_core_axes[] = { GDK_AXIS_X, GDK_AXIS_Y };
+
+static GdkDeviceInfo gdk_input_core_info =
+{
+  GDK_CORE_POINTER,
+  "Core Pointer",
+  GDK_SOURCE_MOUSE,
+  GDK_MODE_SCREEN,
+  TRUE,
+  2,
+  gdk_input_core_axes
+};
+
+/* Global variables  */
+
+GdkInputVTable    gdk_input_vtable;
+/* information about network port and host for gxid daemon */
+gchar            *gdk_input_gxid_host;
+gint              gdk_input_gxid_port;
+gint              gdk_input_ignore_core;
+
+/* Local variables */
+
+static GList            *gdk_input_devices;
+static GList            *gdk_input_windows;
+
+#include "gdkinputnone.h"
+#include "gdkinputcommon.h"
+#include "gdkinputxfree.h"
+#include "gdkinputgxi.h"
+
+GList *
+gdk_input_list_devices ()
+{
+  return gdk_input_devices;
+}
+
+void
+gdk_input_set_source (guint32 deviceid, GdkInputSource source)
+{
+  GdkDevicePrivate *gdkdev = gdk_input_find_device(deviceid);
+  g_return_if_fail (gdkdev != NULL);
+
+  gdkdev->info.source = source;
+}
+
+gint
+gdk_input_set_mode (guint32 deviceid, GdkInputMode mode)
+{
+  if (deviceid == GDK_CORE_POINTER)
+    return FALSE;
+
+  if (gdk_input_vtable.set_mode)
+    return gdk_input_vtable.set_mode(deviceid,mode);
+  else
+    return FALSE;
+}
+
+void
+gdk_input_set_axes (guint32 deviceid, GdkAxisUse *axes)
+{
+  if (deviceid != GDK_CORE_POINTER && gdk_input_vtable.set_axes)
+    gdk_input_vtable.set_axes (deviceid, axes);
+}
+
+GdkTimeCoord *
+gdk_input_motion_events (GdkWindow *window,
+                        guint32 deviceid,
+                        guint32 start,
+                        guint32 stop,
+                        gint *nevents_return)
+{
+  XTimeCoord *xcoords;
+  GdkTimeCoord *coords;
+  int i;
+
+  if (deviceid == GDK_CORE_POINTER)
+    {
+      xcoords = XGetMotionEvents (gdk_display,
+                                 ((GdkWindowPrivate *)window)->xwindow,
+                                 start, stop, nevents_return);
+      if (xcoords)
+       {
+         coords = g_new (GdkTimeCoord, *nevents_return);
+         for (i=0; i<*nevents_return; i++)
+           {
+             coords[i].time = xcoords[i].time;
+             coords[i].x = xcoords[i].x;
+             coords[i].y = xcoords[i].y;
+             coords[i].pressure = 0.5;
+             coords[i].xtilt = 0.0;
+             coords[i].ytilt = 0.0;
+           }
+
+         XFree(xcoords);
+
+         return coords;
+       }
+      else
+       return NULL;
+    }
+  else
+    {
+      if (gdk_input_vtable.motion_events)
+       {
+         return gdk_input_vtable.motion_events(window,
+                                               deviceid, start, stop,
+                                               nevents_return);
+       }
+      else
+       {
+         *nevents_return = 0;
+         return NULL;
+       }
+    }
+}
+
+static gint
+gdk_input_enable_window (GdkWindow *window, GdkDevicePrivate *gdkdev)
+{
+  if (gdk_input_vtable.enable_window)
+    return gdk_input_vtable.enable_window (window, gdkdev);
+  else
+    return TRUE;
+}
+
+static gint
+gdk_input_disable_window (GdkWindow *window, GdkDevicePrivate *gdkdev)
+{
+  if (gdk_input_vtable.disable_window)
+    return gdk_input_vtable.disable_window(window,gdkdev);
+  else
+    return TRUE;
+}
+
+
+static GdkInputWindow *
+gdk_input_window_find(GdkWindow *window)
+{
+  GList *tmp_list;
+
+  for (tmp_list=gdk_input_windows; tmp_list; tmp_list=tmp_list->next)
+    if (((GdkInputWindow *)(tmp_list->data))->window == window)
+      return (GdkInputWindow *)(tmp_list->data);
+
+  return NULL;      /* Not found */
+}
+
+/* FIXME: this routine currently needs to be called between creation
+   and the corresponding configure event (because it doesn't get the
+   root_relative_geometry).  This should work with
+   gtk_window_set_extension_events, but will likely fail in other
+   cases */
+
+void
+gdk_input_set_extension_events (GdkWindow *window, gint mask,
+                               GdkExtensionMode mode)
+{
+  GList *tmp_list;
+  GdkInputWindow *iw;
+
+  g_return_if_fail (window != NULL);
+
+  if (mode == GDK_EXTENSION_EVENTS_NONE)
+    mask = 0;
+
+  if (mask != 0)
+    {
+      iw = g_new(GdkInputWindow,1);
+
+      iw->window = window;
+      iw->mode = mode;
+
+      iw->obscuring = NULL;
+      iw->num_obscuring = 0;
+      iw->grabbed = FALSE;
+
+      gdk_input_windows = g_list_append(gdk_input_windows,iw);
+      ((GdkWindowPrivate *)window)->extension_events = mask;
+
+      /* Add enter window events to the event mask */
+      /* FIXME, this is not needed for XINPUT_NONE */
+      gdk_window_set_events (window,
+                            gdk_window_get_events (window) | 
+                            GDK_ENTER_NOTIFY_MASK);
+    }
+  else
+    {
+      iw = gdk_input_window_find (window);
+      if (iw)
+       {
+         gdk_input_windows = g_list_remove(gdk_input_windows,iw);
+         g_free(iw);
+       }
+
+      ((GdkWindowPrivate *)window)->extension_events = 0;
+    }
+
+  for (tmp_list = gdk_input_devices; tmp_list; tmp_list = tmp_list->next)
+    {
+      GdkDevicePrivate *gdkdev = (GdkDevicePrivate *)(tmp_list->data);
+
+      if (gdkdev->info.deviceid != GDK_CORE_POINTER)
+       {
+         if (mask != 0 && gdkdev->info.mode != GDK_MODE_DISABLED
+             && (gdkdev->info.has_cursor || mode == GDK_EXTENSION_EVENTS_ALL))
+           gdk_input_enable_window(window,gdkdev);
+         else
+           gdk_input_disable_window(window,gdkdev);
+       }
+    }
+}
+
+void
+gdk_input_window_destroy (GdkWindow *window)
+{
+  GdkInputWindow *input_window;
+
+  input_window = gdk_input_window_find (window);
+  g_return_if_fail (input_window != NULL);
+
+  gdk_input_windows = g_list_remove(gdk_input_windows,input_window);
+  g_free(input_window);
+}
+
+void
+gdk_input_exit (void)
+{
+  GList *tmp_list;
+  GdkDevicePrivate *gdkdev;
+
+  for (tmp_list = gdk_input_devices; tmp_list; tmp_list = tmp_list->next)
+    {
+      gdkdev = (GdkDevicePrivate *)(tmp_list->data);
+      if (gdkdev->info.deviceid != GDK_CORE_POINTER)
+       {
+         gdk_input_set_mode(gdkdev->info.deviceid,GDK_MODE_DISABLED);
+
+         g_free(gdkdev->info.name);
+#ifndef XINPUT_NONE      
+         g_free(gdkdev->axes);
+#endif   
+         g_free(gdkdev->info.axes);
+         g_free(gdkdev);
+       }
+    }
+
+  g_list_free(gdk_input_devices);
+
+  for (tmp_list = gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
+    {
+      g_free(tmp_list->data);
+    }
+  g_list_free(gdk_input_windows);
+}
+
+static GdkDevicePrivate *
+gdk_input_find_device(guint32 id)
+{
+  GList *tmp_list = gdk_input_devices;
+  GdkDevicePrivate *gdkdev;
+  while (tmp_list)
+    {
+      gdkdev = (GdkDevicePrivate *)(tmp_list->data);
+      if (gdkdev->info.deviceid == id)
+       return gdkdev;
+      tmp_list = tmp_list->next;
+    }
+  return NULL;
+}
+
+void
+gdk_input_window_get_pointer (GdkWindow       *window,
+                             guint32     deviceid,
+                             gdouble         *x,
+                             gdouble         *y,
+                             gdouble         *pressure,
+                             gdouble         *xtilt,
+                             gdouble         *ytilt,
+                             GdkModifierType *mask)
+{
+  if (gdk_input_vtable.get_pointer)
+    gdk_input_vtable.get_pointer (window, deviceid, x, y, pressure,
+                                 xtilt, ytilt, mask);
+}
diff --git a/gdk/x11/gdkmain-x11.c b/gdk/x11/gdkmain-x11.c
new file mode 100644 (file)
index 0000000..d5f85dd
--- /dev/null
@@ -0,0 +1,2897 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "../config.h"
+
+#include <ctype.h>
+#include <locale.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif /* HAVE_SYS_SELECT_H_ */
+
+#define XLIB_ILLEGAL_ACCESS
+#include <X11/Xatom.h>
+#include <X11/Xlib.h>
+#include <X11/Xos.h>
+#include <X11/Xutil.h>
+#include <X11/Xmu/WinUtil.h>
+#include <X11/cursorfont.h>
+#include "gdk.h"
+#include "gdkprivate.h"
+#include "gdkinput.h"
+
+
+#ifndef X_GETTIMEOFDAY
+#define X_GETTIMEOFDAY(tv)  gettimeofday (tv, NULL)
+#endif /* X_GETTIMEOFDAY */
+
+
+#define DOUBLE_CLICK_TIME      250
+#define TRIPLE_CLICK_TIME      500
+#define DOUBLE_CLICK_DIST      5
+#define TRIPLE_CLICK_DIST      5
+
+
+#ifndef NO_FD_SET
+#  define SELECT_MASK fd_set
+#else
+#  ifndef _AIX
+     typedef long fd_mask;
+#  endif
+#  if defined(_IBMR2)
+#    define SELECT_MASK void
+#  else
+#    define SELECT_MASK int
+#  endif
+#endif
+
+
+typedef struct _GdkInput      GdkInput;
+typedef struct _GdkPredicate  GdkPredicate;
+
+struct _GdkInput
+{
+  gint tag;
+  gint source;
+  GdkInputCondition condition;
+  GdkInputFunction function;
+  gpointer data;
+};
+
+struct _GdkPredicate
+{
+  GdkEventFunc func;
+  gpointer data;
+};
+
+/* 
+ * Private function declarations
+ */
+static gint      gdk_event_wait         (void);
+static gint      gdk_event_translate    (GdkEvent     *event, 
+                                        XEvent       *xevent);
+static Bool      gdk_event_get_type     (Display      *display, 
+                                        XEvent       *xevent, 
+                                        XPointer      arg);
+static void      gdk_synthesize_click   (GdkEvent     *event, 
+                                        gint          nclicks);
+
+static void      gdk_dnd_drag_begin     (GdkWindow    *initial_window);
+static void      gdk_dnd_drag_enter     (Window        dest);
+static void      gdk_dnd_drag_leave     (Window        dest);
+static void      gdk_dnd_drag_end       (Window        dest, 
+                                        GdkPoint      coords);
+static GdkAtom   gdk_dnd_check_types    (GdkWindow    *window,
+                                        XEvent       *xevent);
+static void      gdk_print_atom         (GdkAtom       anatom);
+
+/* 
+ * old junk from offix, we might use it though so leave it 
+ */
+static Window       gdk_drop_get_client_window   (Display     *dpy, 
+                                                 Window       win);
+static GdkWindow *  gdk_drop_get_real_window     (GdkWindow   *w, 
+                                                 guint16     *x,
+                                                 guint16     *y);
+static void         gdk_exit_func                (void);
+static int          gdk_x_error                  (Display     *display, 
+                                                 XErrorEvent *error);
+static int          gdk_x_io_error               (Display     *display);
+static RETSIGTYPE   gdk_signal                   (int          signum);
+
+
+/* Private variable declarations
+ */
+static int initialized = 0;                         /* 1 if the library is initialized,
+                                                    * 0 otherwise.
+                                                    */
+static int connection_number = 0;                   /* The file descriptor number of our
+                                                    *  connection to the X server. This
+                                                    *  is used so that we may determine
+                                                    *  when events are pending by using
+                                                    *  the "select" system call.
+                                                    */
+
+static gint received_destroy_notify = FALSE;        /* Did we just receive a destroy notify
+                                                    *  event? If so, we need to actually
+                                                    *  destroy the window which received
+                                                    *  it now.
+                                                    */
+static GdkWindow *window_to_destroy = NULL;         /* If we previously received a destroy
+                                                    *  notify event then this is the window
+                                                    *  which received that event.
+                                                    */
+
+static struct timeval start;                        /* The time at which the library was
+                                                    *  last initialized.
+                                                    */
+static struct timeval timer;                        /* Timeout interval to use in the call
+                                                    *  to "select". This is used in
+                                                    *  conjunction with "timerp" to create
+                                                    *  a maximum time to wait for an event
+                                                    *  to arrive.
+                                                    */
+static struct timeval *timerp;                      /* The actual timer passed to "select"
+                                                    *  This may be NULL, in which case
+                                                    *  "select" will block until an event
+                                                    *  arrives.
+                                                    */
+static guint32 timer_val;                           /* The timeout length as specified by
+                                                    *  the user in milliseconds.
+                                                    */
+static GList *inputs;                               /* A list of the input file descriptors
+                                                    *  that we care about. Each list node
+                                                    *  contains a GdkInput struct that describes
+                                                    *  when we are interested in the specified
+                                                    *  file descriptor. That is, when it is
+                                                    *  available for read, write or has an
+                                                    *  exception pending.
+                                                    */
+static guint32 button_click_time[2];                /* The last 2 button click times. Used
+                                                    *  to determine if the latest button click
+                                                    *  is part of a double or triple click.
+                                                    */
+static GdkWindow *button_window[2];                 /* The last 2 windows to receive button presses.
+                                                    *  Also used to determine if the latest button
+                                                    *  click is part of a double or triple click.
+                                                    */
+static guint button_number[2];                      /* The last 2 buttons to be pressed.
+                                                    */
+
+#define OTHER_XEVENT_BUFSIZE 4
+static XEvent other_xevent[OTHER_XEVENT_BUFSIZE];   /* XEvents passed along to user  */
+static int other_xevent_i = 0;
+static GList *putback_events = NULL;
+
+static gulong base_id;
+static gint autorepeat;
+
+
+/*
+ *--------------------------------------------------------------
+ * gdk_init
+ *
+ *   Initialize the library for use.
+ *
+ * Arguments:
+ *   "argc" is the number of arguments.
+ *   "argv" is an array of strings.
+ *
+ * Results:
+ *   "argc" and "argv" are modified to reflect any arguments
+ *   which were not handled. (Such arguments should either
+ *   be handled by the application or dismissed).
+ *
+ * Side effects:
+ *   The library is initialized.
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+gdk_init (int    *argc,
+         char ***argv)
+{
+  XKeyboardState keyboard_state;
+  int synchronize;
+  int i, j, k;
+  XClassHint *class_hint;
+  int argc_orig = *argc;
+  char **argv_orig;
+
+  argv_orig = malloc ((argc_orig + 1) * sizeof (char*));
+  for (i = 0; i < argc_orig; i++)
+    argv_orig[i] = g_strdup ((*argv)[i]);
+  argv_orig[argc_orig] = NULL;
+
+  X_GETTIMEOFDAY (&start);
+
+  signal (SIGHUP, gdk_signal);
+  signal (SIGINT, gdk_signal);
+  signal (SIGQUIT, gdk_signal);
+  signal (SIGBUS, gdk_signal);
+  signal (SIGSEGV, gdk_signal);
+  signal (SIGPIPE, gdk_signal);
+  signal (SIGTERM, gdk_signal);
+
+  gdk_display_name = NULL;
+
+  XSetErrorHandler (gdk_x_error);
+  XSetIOErrorHandler (gdk_x_io_error);
+
+  synchronize = FALSE;
+
+  if (argc && argv)
+    {
+      if (*argc > 0)
+       gdk_progname = (*argv)[0];
+
+      for (i = 1; i < *argc;)
+       {
+         if (strcmp ("--display", (*argv)[i]) == 0)
+           {
+             (*argv)[i] = NULL;
+
+             if ((i + 1) < *argc)
+               {
+                 gdk_display_name = g_strdup ((*argv)[i + 1]);
+                 (*argv)[i + 1] = NULL;
+                 i += 1;
+               }
+           }
+         else if (strcmp ("--sync", (*argv)[i]) == 0)
+           {
+             (*argv)[i] = NULL;
+             synchronize = TRUE;
+           }
+         else if (strcmp ("--show-events", (*argv)[i]) == 0)
+           {
+             (*argv)[i] = NULL;
+             gdk_show_events = TRUE;
+           }
+         else if (strcmp ("--no-show-events", (*argv)[i]) == 0)
+           {
+             (*argv)[i] = NULL;
+             gdk_show_events = FALSE;
+           }
+         else if (strcmp ("--no-xshm", (*argv)[i]) == 0)
+           {
+             (*argv)[i] = NULL;
+             gdk_use_xshm = FALSE;
+           }
+         else if (strcmp ("--debug-level", (*argv)[i]) == 0)
+           {
+             if ((i + 1) < *argc)
+               {
+                 (*argv)[i++] = NULL;
+                 gdk_debug_level = atoi ((*argv)[i]);
+                 (*argv)[i] = NULL;
+               }
+           }
+         else if (strcmp ("-name", (*argv)[i]) == 0)
+           {
+             if ((i + 1) < *argc)
+               {
+                 (*argv)[i++] = NULL;
+                 gdk_progname = (*argv)[i];
+                 (*argv)[i] = NULL;
+               }
+           }
+         else if (strcmp ("-class", (*argv)[i]) == 0)
+           {
+             if ((i + 1) < *argc)
+               {
+                 (*argv)[i++] = NULL;
+                 gdk_progclass = (*argv)[i];
+                 (*argv)[i] = NULL;
+               }
+           }
+#ifdef XINPUT_GXI
+         else if (strcmp ("--gxid_host", (*argv)[i]) == 0)
+           {
+             if ((i + 1) < *argc)
+               {
+                 (*argv)[i++] = NULL;
+                 gdk_input_gxid_host = ((*argv)[i]);
+                 (*argv)[i] = NULL;
+               }
+           }
+         else if (strcmp ("--gxid_port", (*argv)[i]) == 0)
+           {
+             if ((i + 1) < *argc)
+               {
+                 (*argv)[i++] = NULL;
+                 gdk_input_gxid_port = atoi ((*argv)[i]);
+                 (*argv)[i] = NULL;
+               }
+           }
+#endif
+         i += 1;
+       }
+
+      for (i = 1; i < *argc; i++)
+       {
+         for (k = i; k < *argc; k++)
+           if ((*argv)[k] != NULL)
+             break;
+
+         if (k > i)
+           {
+             k -= i;
+             for (j = i + k; j < *argc; j++)
+               (*argv)[j-k] = (*argv)[j];
+             *argc -= k;
+           }
+       }
+    }
+  else
+    {
+      gdk_progname = "<unknown>";
+    }
+
+  gdk_display = XOpenDisplay (gdk_display_name);
+  if (!gdk_display)
+    g_error ("cannot open display: %s", XDisplayName (gdk_display_name));
+
+  /* This is really crappy. We have to look into the display structure
+   *  to find the base resource id. This is only needed for recording
+   *  and playback of events.
+   */
+  /* base_id = RESOURCE_BASE; */
+  base_id = 0;
+  if (gdk_show_events)
+    g_print ("base id: %lu\n", base_id);
+
+  connection_number = ConnectionNumber (gdk_display);
+  if (gdk_debug_level >= 1)
+    g_print ("connection number: %d\n", connection_number);
+
+  if (synchronize)
+    XSynchronize (gdk_display, True);
+
+  gdk_screen = DefaultScreen (gdk_display);
+  gdk_root_window = RootWindow (gdk_display, gdk_screen);
+
+  gdk_leader_window = XCreateSimpleWindow(gdk_display, gdk_root_window,
+                                         10, 10, 10, 10, 0, 0 , 0);
+  class_hint = XAllocClassHint();
+  class_hint->res_name = gdk_progname;
+  class_hint->res_class = gdk_progclass;
+  XSetClassHint(gdk_display, gdk_leader_window, class_hint);
+  XSetCommand(gdk_display, gdk_leader_window, argv_orig, argc_orig);
+  XFree (class_hint);
+
+  gdk_wm_delete_window = XInternAtom (gdk_display, "WM_DELETE_WINDOW", True);
+  gdk_wm_take_focus = XInternAtom (gdk_display, "WM_TAKE_FOCUS", True);
+  gdk_wm_protocols = XInternAtom (gdk_display, "WM_PROTOCOLS", True);
+  gdk_wm_window_protocols[0] = gdk_wm_delete_window;
+  gdk_wm_window_protocols[1] = gdk_wm_take_focus;
+  gdk_selection_property = XInternAtom (gdk_display, "GDK_SELECTION", False);
+
+  gdk_dnd.gdk_XdeEnter = gdk_atom_intern("_XDE_ENTER", FALSE);
+  gdk_dnd.gdk_XdeLeave = gdk_atom_intern("_XDE_LEAVE", FALSE);
+  gdk_dnd.gdk_XdeRequest = gdk_atom_intern("_XDE_REQUEST", FALSE);
+  gdk_dnd.gdk_XdeDataAvailable = gdk_atom_intern("_XDE_DATA_AVAILABLE", FALSE);
+  gdk_dnd.gdk_XdeTypelist = gdk_atom_intern("_XDE_TYPELIST", FALSE);
+  gdk_dnd.gdk_cursor_dragdefault = XCreateFontCursor(gdk_display, XC_bogosity);
+  gdk_dnd.gdk_cursor_dragok = XCreateFontCursor(gdk_display, XC_heart);
+
+  XGetKeyboardControl (gdk_display, &keyboard_state);
+  autorepeat = keyboard_state.global_auto_repeat;
+
+  timer.tv_sec = 0;
+  timer.tv_usec = 0;
+  timerp = NULL;
+
+  button_click_time[0] = 0;
+  button_click_time[1] = 0;
+  button_window[0] = NULL;
+  button_window[1] = NULL;
+  button_number[0] = -1;
+  button_number[1] = -1;
+
+  if (ATEXIT (gdk_exit_func))
+    g_warning ("unable to register exit function");
+
+  gdk_visual_init ();
+  gdk_window_init ();
+  gdk_image_init ();
+  gdk_input_init ();
+
+  initialized = 1;
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_exit
+ *
+ *   Restores the library to an un-itialized state and exits
+ *   the program using the "exit" system call.
+ *
+ * Arguments:
+ *   "errorcode" is the error value to pass to "exit".
+ *
+ * Results:
+ *   Allocated structures are freed and the program exits
+ *   cleanly.
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+gdk_exit (int errorcode)
+{
+ /* de-initialisation is done by the gdk_exit_funct(),
+    no need to do this here (Alex J.) */
+ exit (errorcode);
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_set_locale
+ *
+ * Arguments:
+ *
+ * Results:
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+gchar*
+gdk_set_locale ()
+{
+  if (!setlocale (LC_ALL,""))
+    g_print ("locale not supported by C library\n");
+
+  if (!XSupportsLocale ())
+    {
+      g_print ("locale not supported by Xlib, locale set to C\n");
+      setlocale (LC_ALL, "C");
+    }
+
+  if (!XSetLocaleModifiers (""))
+    {
+      g_print ("can not set locale modifiers\n");
+    }
+
+  return setlocale (LC_ALL,NULL);
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_events_pending
+ *
+ *   Returns the number of events pending on the queue.
+ *   These events have already been read from the server
+ *   connection.
+ *
+ * Arguments:
+ *
+ * Results:
+ *   Returns the number of events on XLib's event queue.
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+gint
+gdk_events_pending ()
+{
+  return XPending (gdk_display);
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_event_get
+ *
+ *   Gets the next event.
+ *
+ * Arguments:
+ *   "event" is used to hold the received event.
+ *   If "event" is NULL an event is received as normal
+ *   however it is not placed in "event" (and thus no
+ *   error occurs).
+ *
+ * Results:
+ *   Returns TRUE if an event was received that we care about
+ *   and FALSE otherwise. This function will also return
+ *   before an event is received if the timeout interval
+ *   runs out.
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+gint
+gdk_event_get (GdkEvent     *event,
+              GdkEventFunc  pred,
+              gpointer      data)
+{
+  GdkEvent *temp_event;
+  GdkPredicate event_pred;
+  GList *temp_list;
+  XEvent xevent;
+
+  /* If the last event we received was a destroy notify
+   *  event then we will actually destroy the "gdk" data
+   *  structures now. We don't want to destroy them at the
+   *  time of receiving the event since the main program
+   *  may try to access them and may need to destroy user
+   *  data that has been attached to the window
+   */
+  if (received_destroy_notify)
+    {
+      if (gdk_show_events)
+       g_print ("destroying window:\twindow: %ld\n",
+                ((GdkWindowPrivate*) window_to_destroy)->xwindow - base_id);
+
+      gdk_window_real_destroy (window_to_destroy);
+      received_destroy_notify = FALSE;
+      window_to_destroy = NULL;
+    }
+
+  /* Initially we haven't received an event and want to
+   *  return FALSE. If "event" is non-NULL, then initialize
+   *  it to the nothing event.
+   */
+  if (event)
+    {
+      event->any.type = GDK_NOTHING;
+      event->any.window = NULL;
+      event->any.send_event = FALSE;
+    }
+
+  if (pred)
+    {
+      temp_list = putback_events;
+      while (temp_list)
+       {
+         temp_event = temp_list->data;
+
+         if ((* pred) (temp_event, data))
+           {
+             if (event)
+               *event = *temp_event;
+             putback_events = g_list_remove_link (putback_events, temp_list);
+             g_list_free (temp_list);
+             return TRUE;
+           }
+
+         temp_list = temp_list->next;
+       }
+
+      event_pred.func = pred;
+      event_pred.data = data;
+
+      if (XCheckIfEvent (gdk_display, &xevent, gdk_event_get_type, (XPointer) &event_pred))
+       if (event)
+         return gdk_event_translate (event, &xevent);
+    }
+  else
+    {
+      if (putback_events)
+       {
+         temp_event = putback_events->data;
+         *event = *temp_event;
+
+         temp_list = putback_events;
+         putback_events = putback_events->next;
+         if (putback_events)
+           putback_events->prev = NULL;
+
+         temp_list->next = NULL;
+         temp_list->prev = NULL;
+         g_list_free (temp_list);
+         g_free (temp_event);
+
+         return TRUE;
+       }
+
+      /* Wait for an event to occur or the timeout to elapse.
+       * If an event occurs "gdk_event_wait" will return TRUE.
+       *  If the timeout elapses "gdk_event_wait" will return
+       *  FALSE.
+       */
+      if (gdk_event_wait ())
+       {
+         /* If we get here we can rest assurred that an event
+          *  has occurred. Read it.
+          */
+         XNextEvent (gdk_display, &xevent);
+
+         event->any.send_event = xevent.xany.send_event;
+
+         /* If "event" non-NULL.
+          */
+         if (event)
+           return gdk_event_translate (event, &xevent);
+       }
+    }
+
+  return FALSE;
+}
+
+void
+gdk_event_put (GdkEvent *event)
+{
+  GdkEvent *new_event;
+
+  g_return_if_fail (event != NULL);
+
+  new_event = g_new (GdkEvent, 1);
+  *new_event = *event;
+
+  putback_events = g_list_prepend (putback_events, new_event);
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_event_copy
+ *
+ *   Copy a event structure into new storage.
+ *
+ * Arguments:
+ *   "event" is the event struct to copy.
+ *
+ * Results:
+ *   A new event structure.  Free it with gdk_event_free.
+ *
+ * Side effects:
+ *   The reference count of the window in the event is increased.
+ *
+ *--------------------------------------------------------------
+ */
+
+static GMemChunk *event_chunk;
+
+GdkEvent*
+gdk_event_copy (GdkEvent *event)
+{
+  GdkEvent *new_event;
+  
+  g_return_val_if_fail (event != NULL, NULL);
+
+  if (event_chunk == NULL)
+    event_chunk = g_mem_chunk_new ("events",
+                                  sizeof (GdkEvent),
+                                  4096,
+                                  G_ALLOC_AND_FREE);
+
+  new_event = g_chunk_new (GdkEvent, event_chunk);
+  *new_event = *event;
+  gdk_window_ref (new_event->any.window);
+  return new_event;
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_event_free
+ *
+ *   Free a event structure obtained from gdk_event_copy.  Do not use
+ *   with other event structures.
+ *
+ * Arguments:
+ *   "event" is the event struct to free.
+ *
+ * Results:
+ *
+ * Side effects:
+ *   The reference count of the window in the event is decreased and
+ *   might be freed, too.
+ *
+ *-------------------------------------------------------------- */
+
+void
+gdk_event_free (GdkEvent *event)
+{
+  g_assert (event_chunk != NULL);
+  g_return_if_fail (event != NULL);
+
+  gdk_window_unref (event->any.window);
+  g_mem_chunk_free (event_chunk, event);
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_set_debug_level
+ *
+ *   Sets the debugging level.
+ *
+ * Arguments:
+ *   "level" is the new debugging level.
+ *
+ * Results:
+ *
+ * Side effects:
+ *   Other function calls to "gdk" use the debugging
+ *   level to determine what kind of debugging information
+ *   to print out.
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+gdk_set_debug_level (int level)
+{
+  gdk_debug_level = level;
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_set_show_events
+ *
+ *   Turns on/off the showing of events.
+ *
+ * Arguments:
+ *   "show_events" is a boolean describing whether or
+ *   not to show the events gdk receives.
+ *
+ * Results:
+ *
+ * Side effects:
+ *   When "show_events" is TRUE, calls to "gdk_event_get"
+ *   will output debugging informatin regarding the event
+ *   received to stdout.
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+gdk_set_show_events (int show_events)
+{
+  gdk_show_events = show_events;
+}
+
+void
+gdk_set_use_xshm (gint use_xshm)
+{
+  gdk_use_xshm = use_xshm;
+}
+
+gint
+gdk_get_debug_level ()
+{
+  return gdk_debug_level;
+}
+
+gint
+gdk_get_show_events ()
+{
+  return gdk_show_events;
+}
+
+gint
+gdk_get_use_xshm ()
+{
+  return gdk_use_xshm;
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_time_get
+ *
+ *   Get the number of milliseconds since the library was
+ *   initialized.
+ *
+ * Arguments:
+ *
+ * Results:
+ *   The time since the library was initialized is returned.
+ *   This time value is accurate to milliseconds even though
+ *   a more accurate time down to the microsecond could be
+ *   returned.
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+guint32
+gdk_time_get ()
+{
+  struct timeval end;
+  struct timeval elapsed;
+  guint32 milliseconds;
+
+  X_GETTIMEOFDAY (&end);
+
+  if (start.tv_usec > end.tv_usec)
+    {
+      end.tv_usec += 1000000;
+      end.tv_sec--;
+    }
+  elapsed.tv_sec = end.tv_sec - start.tv_sec;
+  elapsed.tv_usec = end.tv_usec - start.tv_usec;
+
+  milliseconds = (elapsed.tv_sec * 1000) + (elapsed.tv_usec / 1000);
+
+  return milliseconds;
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_timer_get
+ *
+ *   Returns the current timer.
+ *
+ * Arguments:
+ *
+ * Results:
+ *   Returns the current timer interval. This interval is
+ *   in units of milliseconds.
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+guint32
+gdk_timer_get ()
+{
+  return timer_val;
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_timer_set
+ *
+ *   Sets the timer interval.
+ *
+ * Arguments:
+ *   "milliseconds" is the new value for the timer.
+ *
+ * Results:
+ *
+ * Side effects:
+ *   Calls to "gdk_event_get" will last for a maximum
+ *   of time of "milliseconds". However, a value of 0
+ *   milliseconds will cause "gdk_event_get" to block
+ *   indefinately until an event is received.
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+gdk_timer_set (guint32 milliseconds)
+{
+  timer_val = milliseconds;
+  timer.tv_sec = milliseconds / 1000;
+  timer.tv_usec = (milliseconds % 1000) * 1000;
+
+}
+
+void
+gdk_timer_enable ()
+{
+  timerp = &timer;
+}
+
+void
+gdk_timer_disable ()
+{
+  timerp = NULL;
+}
+
+gint
+gdk_input_add (gint              source,
+              GdkInputCondition condition,
+              GdkInputFunction  function,
+              gpointer          data)
+{
+  static gint next_tag = 1;
+  GList *list;
+  GdkInput *input;
+  gint tag;
+
+  tag = 0;
+  list = inputs;
+
+  while (list)
+    {
+      input = list->data;
+      list = list->next;
+
+      if ((input->source == source) && (input->condition == condition))
+       {
+         input->function = function;
+         input->data = data;
+         tag = input->tag;
+       }
+    }
+
+  if (!tag)
+    {
+      input = g_new (GdkInput, 1);
+      input->tag = next_tag++;
+      input->source = source;
+      input->condition = condition;
+      input->function = function;
+      input->data = data;
+      tag = input->tag;
+
+      inputs = g_list_prepend (inputs, input);
+    }
+
+  return tag;
+}
+
+void
+gdk_input_remove (gint tag)
+{
+  GList *list;
+  GList *temp_list;
+  GdkInput *input;
+
+  list = inputs;
+  while (list)
+    {
+      input = list->data;
+
+      if (input->tag == tag)
+       {
+         temp_list = list;
+
+         if (list->next)
+           list->next->prev = list->prev;
+         if (list->prev)
+           list->prev->next = list->next;
+         if (inputs == list)
+           inputs = list->next;
+
+         temp_list->next = NULL;
+         temp_list->prev = NULL;
+
+         g_free (temp_list->data);
+         g_list_free (temp_list);
+         break;
+       }
+
+      list = list->next;
+    }
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_pointer_grab
+ *
+ *   Grabs the pointer to a specific window
+ *
+ * Arguments:
+ *   "window" is the window which will receive the grab
+ *   "owner_events" specifies whether events will be reported as is,
+ *     or relative to "window"
+ *   "event_mask" masks only interesting events
+ *   "confine_to" limits the cursor movement to the specified window
+ *   "cursor" changes the cursor for the duration of the grab
+ *   "time" specifies the time
+ *
+ * Results:
+ *
+ * Side effects:
+ *   requires a corresponding call to gdk_pointer_ungrab
+ *
+ *--------------------------------------------------------------
+ */
+
+gint
+gdk_pointer_grab (GdkWindow *     window,
+                 gint            owner_events,
+                 GdkEventMask    event_mask,
+                 GdkWindow *     confine_to,
+                 GdkCursor *     cursor,
+                 guint32         time)
+{
+  /*  From gdkwindow.c  */
+  extern int nevent_masks;
+  extern int event_mask_table[];
+
+  gint return_val;
+  GdkWindowPrivate *window_private;
+  GdkWindowPrivate *confine_to_private;
+  GdkCursorPrivate *cursor_private;
+  guint xevent_mask;
+  Window xwindow;
+  Window xconfine_to;
+  Cursor xcursor;
+  int i;
+
+  g_return_val_if_fail (window != NULL, 0);
+
+  window_private = (GdkWindowPrivate*) window;
+  confine_to_private = (GdkWindowPrivate*) confine_to;
+  cursor_private = (GdkCursorPrivate*) cursor;
+
+  xwindow = window_private->xwindow;
+
+  if (!confine_to)
+    xconfine_to = None;
+  else
+    xconfine_to = confine_to_private->xwindow;
+
+  if (!cursor)
+    xcursor = None;
+  else
+    xcursor = cursor_private->xcursor;
+
+
+  xevent_mask = 0;
+  for (i = 0; i < nevent_masks; i++)
+    {
+      if (event_mask & (1 << (i + 1)))
+       xevent_mask |= event_mask_table[i];
+    }
+
+  if (((GdkWindowPrivate *)window)->extension_events &&
+      gdk_input_vtable.grab_pointer)
+    return_val = gdk_input_vtable.grab_pointer (window,
+                                               owner_events,
+                                               event_mask,
+                                               confine_to,
+                                               time);
+  else
+    return_val = Success;;
+
+  if (return_val == Success)
+    return_val = XGrabPointer (window_private->xdisplay,
+                              xwindow,
+                              owner_events,
+                              xevent_mask,
+                              GrabModeAsync, GrabModeAsync,
+                              xconfine_to,
+                              xcursor,
+                              time);
+
+  return return_val;
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_pointer_ungrab
+ *
+ *   Releases any pointer grab
+ *
+ * Arguments:
+ *
+ * Results:
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+gdk_pointer_ungrab (guint32 time)
+{
+  if (gdk_input_vtable.ungrab_pointer)
+    gdk_input_vtable.ungrab_pointer (time);
+
+  XUngrabPointer (gdk_display, time);
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_keyboard_grab
+ *
+ *   Grabs the keyboard to a specific window
+ *
+ * Arguments:
+ *   "window" is the window which will receive the grab
+ *   "owner_events" specifies whether events will be reported as is,
+ *     or relative to "window"
+ *   "time" specifies the time
+ *
+ * Results:
+ *
+ * Side effects:
+ *   requires a corresponding call to gdk_keyboard_ungrab
+ *
+ *--------------------------------------------------------------
+ */
+
+gint
+gdk_keyboard_grab (GdkWindow *     window,
+                   gint            owner_events,
+                   guint32         time)
+{
+  GdkWindowPrivate *window_private;
+  Window xwindow;
+
+  g_return_val_if_fail (window != NULL, 0);
+
+  window_private = (GdkWindowPrivate*) window;
+  xwindow = window_private->xwindow;
+
+  return XGrabKeyboard (window_private->xdisplay,
+                       xwindow,
+                       owner_events,
+                       GrabModeAsync, GrabModeAsync,
+                       time);
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_keyboard_ungrab
+ *
+ *   Releases any keyboard grab
+ *
+ * Arguments:
+ *
+ * Results:
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+gdk_keyboard_ungrab (guint32 time)
+{
+  XUngrabKeyboard (gdk_display, time);
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_screen_width
+ *
+ *   Return the width of the screen.
+ *
+ * Arguments:
+ *
+ * Results:
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+gint
+gdk_screen_width ()
+{
+  gint return_val;
+
+  return_val = DisplayWidth (gdk_display, gdk_screen);
+
+  return return_val;
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_screen_height
+ *
+ *   Return the height of the screen.
+ *
+ * Arguments:
+ *
+ * Results:
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+gint
+gdk_screen_height ()
+{
+  gint return_val;
+
+  return_val = DisplayHeight (gdk_display, gdk_screen);
+
+  return return_val;
+}
+
+void
+gdk_key_repeat_disable ()
+{
+  XAutoRepeatOff (gdk_display);
+}
+
+void
+gdk_key_repeat_restore ()
+{
+  if (autorepeat)
+    XAutoRepeatOn (gdk_display);
+  else
+    XAutoRepeatOff (gdk_display);
+}
+
+
+/*
+ *--------------------------------------------------------------
+ * gdk_flush
+ *
+ *   Flushes the Xlib output buffer and then waits
+ *   until all requests have been received and processed
+ *   by the X server. The only real use for this function
+ *   is in dealing with XShm.
+ *
+ * Arguments:
+ *
+ * Results:
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+void gdk_flush ()
+{
+  XSync (gdk_display, False);
+}
+
+
+void
+gdk_beep ()
+{
+  XBell(gdk_display, 100);
+}
+
+
+/*
+ *--------------------------------------------------------------
+ * gdk_event_wait
+ *
+ *   Waits until an event occurs or the timer runs out.
+ *
+ * Arguments:
+ *
+ * Results:
+ *   Returns TRUE if an event is ready to be read and FALSE
+ *   if the timer ran out.
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+static gint
+gdk_event_wait ()
+{
+  GList *list;
+  GdkInput *input;
+  GdkInputCondition condition;
+  SELECT_MASK readfds;
+  SELECT_MASK writefds;
+  SELECT_MASK exceptfds;
+  int max_input;
+  int nfd;
+
+  /* If there are no events pending we will wait for an event.
+   * The time we wait is dependant on the "timer". If no timer
+   *  has been specified then we'll block until an event arrives.
+   *  If a timer has been specified we'll block until an event
+   *  arrives or the timer expires. (This is all done using the
+   *  "select" system call).
+   */
+
+  if (XPending (gdk_display) == 0)
+    {
+      FD_ZERO (&readfds);
+      FD_ZERO (&writefds);
+      FD_ZERO (&exceptfds);
+
+      FD_SET (connection_number, &readfds);
+      max_input = connection_number;
+
+      list = inputs;
+      while (list)
+       {
+         input = list->data;
+         list = list->next;
+
+         if (input->condition & GDK_INPUT_READ)
+           FD_SET (input->source, &readfds);
+         if (input->condition & GDK_INPUT_WRITE)
+           FD_SET (input->source, &writefds);
+         if (input->condition & GDK_INPUT_EXCEPTION)
+           FD_SET (input->source, &exceptfds);
+
+         max_input = MAX (max_input, input->source);
+       }
+
+      nfd = select (max_input+1, &readfds, &writefds, &exceptfds, timerp);
+
+      timerp = NULL;
+      timer_val = 0;
+
+      if (nfd > 0)
+       {
+         if (FD_ISSET (connection_number, &readfds))
+           {
+             if (XPending (gdk_display) == 0)
+               {
+                 if (nfd == 1)
+                   {
+                     XNoOp (gdk_display);
+                     XFlush (gdk_display);
+                   }
+                 return FALSE;
+               }
+             else
+               return TRUE;
+           }
+
+         list = inputs;
+         while (list)
+           {
+             input = list->data;
+             list = list->next;
+
+             condition = 0;
+             if (FD_ISSET (input->source, &readfds))
+               condition |= GDK_INPUT_READ;
+             if (FD_ISSET (input->source, &writefds))
+               condition |= GDK_INPUT_WRITE;
+             if (FD_ISSET (input->source, &exceptfds))
+               condition |= GDK_INPUT_EXCEPTION;
+
+             if (condition && input->function)
+               (* input->function) (input->data, input->source, condition);
+           }
+       }
+    }
+  else
+    return TRUE;
+
+  return FALSE;
+}
+
+static gint
+gdk_event_translate (GdkEvent *event,
+                    XEvent   *xevent)
+{
+
+  GdkWindow *window;
+  GdkWindowPrivate *window_private;
+  XComposeStatus compose;
+  int charcount;
+  char buf[16];
+  gint return_val;
+
+  /* Are static variables used for this purpose thread-safe? */
+  static GdkPoint dnd_drag_start = {0,0},
+                 dnd_drag_oldpos = {0,0};
+  static GdkRectangle dnd_drag_dropzone = {0,0,0,0};
+  static gint dnd_drag_perhaps = 0;
+  static GdkWindowPrivate *real_sw = NULL;
+  static Window dnd_drag_curwin = None, dnd_drag_target = None;
+
+  return_val = FALSE;
+
+  /* Find the GdkWindow that this event occurred in.
+   * All events occur in some GdkWindow (otherwise, why
+   *  would we be receiving them). It really is an error
+   *  to receive an event for which we cannot find the
+   *  corresponding GdkWindow. We handle events with window=None
+   *  specially - they are generated by XFree86's XInput under
+   *  some circumstances.
+   */
+
+  if ((xevent->xany.window == None) &&
+      gdk_input_vtable.window_none_event)
+    {
+      return_val = gdk_input_vtable.window_none_event (event,xevent);
+
+      if (return_val >= 0)     /* was handled */
+       return return_val;
+      else
+       return_val = FALSE;
+    }
+
+  window = gdk_window_lookup (xevent->xany.window);
+  window_private = (GdkWindowPrivate *) window;
+
+  /* We do a "manual" conversion of the XEvent to a
+   *  GdkEvent. The structures are mostly the same so
+   *  the conversion is fairly straightforward. We also
+   *  optionally print debugging info regarding events
+   *  received.
+   */
+  /* Addendum:
+   * During drag & drop you get events where the pointer is
+   * in other windows. Need to just do finer-grained checking
+   */
+  switch (xevent->type)
+    {
+    case KeyPress:
+      /* Lookup the string corresponding to the given keysym.
+       */
+      charcount = XLookupString (&xevent->xkey, buf, 16,
+                                (KeySym*) &event->key.keyval,
+                                &compose);
+
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("key press:\t\twindow: %ld  key: %12s  %d\n",
+                xevent->xkey.window - base_id,
+                XKeysymToString (event->key.keyval),
+                event->key.keyval);
+
+      event->key.type = GDK_KEY_PRESS;
+      event->key.window = window;
+      event->key.time = xevent->xkey.time;
+      event->key.state = (GdkModifierType) xevent->xkey.state;
+
+      return_val = !window_private->destroyed;
+      break;
+
+    case KeyRelease:
+      /* Lookup the string corresponding to the given keysym.
+       */
+      charcount = XLookupString (&xevent->xkey, buf, 16,
+                                (KeySym*) &event->key.keyval,
+                                &compose);
+
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("key release:\t\twindow: %ld  key: %12s  %d\n",
+                xevent->xkey.window - base_id,
+                XKeysymToString (event->key.keyval),
+                event->key.keyval);
+
+      event->key.type = GDK_KEY_RELEASE;
+      event->key.window = window;
+      event->key.time = xevent->xkey.time;
+      event->key.state = (GdkModifierType) xevent->xkey.state;
+
+      return_val = !window_private->destroyed;
+      break;
+
+    case ButtonPress:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("button press[%d]:\t\twindow: %ld  x,y: %d %d  button: %d\n",
+                window_private?window_private->dnd_drag_enabled:0,
+                xevent->xbutton.window - base_id,
+                xevent->xbutton.x, xevent->xbutton.y,
+                xevent->xbutton.button);
+
+      if (window_private &&
+         (window_private->extension_events != 0) &&
+         gdk_input_ignore_core)
+       break;
+
+      event->button.type = GDK_BUTTON_PRESS;
+      event->button.window = window;
+      event->button.time = xevent->xbutton.time;
+      event->button.x = xevent->xbutton.x;
+      event->button.y = xevent->xbutton.y;
+      event->button.pressure = 0.5;
+      event->button.xtilt = 0;
+      event->button.ytilt = 0;
+      event->button.state = (GdkModifierType) xevent->xbutton.state;
+      event->button.button = xevent->xbutton.button;
+      event->button.source = GDK_SOURCE_MOUSE;
+      event->button.deviceid = GDK_CORE_POINTER;
+
+      if ((event->button.time < (button_click_time[1] + TRIPLE_CLICK_TIME)) &&
+         (event->button.window == button_window[1]) &&
+         (event->button.button == button_number[1]))
+       {
+         gdk_synthesize_click (event, 3);
+
+         button_click_time[1] = 0;
+         button_click_time[0] = 0;
+         button_window[1] = NULL;
+         button_window[0] = 0;
+         button_number[1] = -1;
+         button_number[0] = -1;
+       }
+      else if ((event->button.time < (button_click_time[0] + DOUBLE_CLICK_TIME)) &&
+              (event->button.window == button_window[0]) &&
+              (event->button.button == button_number[0]))
+       {
+         gdk_synthesize_click (event, 2);
+
+         button_click_time[1] = button_click_time[0];
+         button_click_time[0] = event->button.time;
+         button_window[1] = button_window[0];
+         button_window[0] = event->button.window;
+         button_number[1] = button_number[0];
+         button_number[0] = event->button.button;
+       }
+      else
+       {
+         button_click_time[1] = 0;
+         button_click_time[0] = event->button.time;
+         button_window[1] = NULL;
+         button_window[0] = event->button.window;
+         button_number[1] = -1;
+         button_number[0] = event->button.button;
+       }
+      if(window_private
+        && window_private->dnd_drag_enabled
+        && !dnd_drag_perhaps
+        && !gdk_dnd.drag_really)
+       {
+         dnd_drag_perhaps = 1;
+         dnd_drag_start.x = xevent->xbutton.x_root;
+         dnd_drag_start.y = xevent->xbutton.y_root;
+         real_sw = window_private;
+         
+         if(gdk_dnd.drag_startwindows)
+           {
+             g_free(gdk_dnd.drag_startwindows);
+             gdk_dnd.drag_startwindows = NULL;
+           }
+         gdk_dnd.drag_numwindows = gdk_dnd.drag_really = 0;
+
+         {
+           /* Set motion mask for first DnD'd window, since it
+              will be the one that is actually dragged */
+           XWindowAttributes dnd_winattr;
+           XSetWindowAttributes dnd_setwinattr;
+           Status rv;
+
+           /* We need to get motion events while the button is down, so
+              we can know whether to really start dragging or not... */
+           XGetWindowAttributes(gdk_display, (Window)window_private->xwindow,
+                                &dnd_winattr);
+           
+           window_private->dnd_drag_savedeventmask = dnd_winattr.your_event_mask;
+           dnd_setwinattr.event_mask = 
+             window_private->dnd_drag_eventmask = ButtonMotionMask;
+           XChangeWindowAttributes(gdk_display, window_private->xwindow,
+                                   CWEventMask, &dnd_setwinattr);
+       }
+      }
+      return_val = window_private?(!window_private->destroyed):FALSE;
+      break;
+
+    case ButtonRelease:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("button release[%d]:\twindow: %ld  x,y: %d %d  button: %d\n",
+                window_private?window_private->dnd_drag_enabled:0,
+                xevent->xbutton.window - base_id,
+                xevent->xbutton.x, xevent->xbutton.y,
+                xevent->xbutton.button);
+
+      if (window_private &&
+         (window_private->extension_events != 0) &&
+         gdk_input_ignore_core)
+       break;
+
+      event->button.type = GDK_BUTTON_RELEASE;
+      event->button.window = window;
+      event->button.time = xevent->xbutton.time;
+      event->button.x = xevent->xbutton.x;
+      event->button.y = xevent->xbutton.y;
+      event->button.pressure = 0.5;
+      event->button.xtilt = 0;
+      event->button.ytilt = 0;
+      event->button.state = (GdkModifierType) xevent->xbutton.state;
+      event->button.button = xevent->xbutton.button;
+      event->button.source = GDK_SOURCE_MOUSE;
+      event->button.deviceid = GDK_CORE_POINTER;
+
+      if(dnd_drag_perhaps)
+       {
+       if(gdk_dnd.drag_really)
+         {
+         GdkPoint foo = {xevent->xbutton.x_root,
+                         xevent->xbutton.y_root};
+         XUngrabPointer(gdk_display, CurrentTime);
+
+         if(dnd_drag_target != None)
+           gdk_dnd_drag_end(dnd_drag_target, foo);
+         gdk_dnd.drag_really = 0;
+
+         if(gdk_dnd.drag_numwindows)
+           {
+             XSetWindowAttributes attrs;
+             /* Reset event mask to pre-drag value, assuming event_mask
+                doesn't change during drag */
+             attrs.event_mask = real_sw->dnd_drag_savedeventmask;
+             XChangeWindowAttributes(gdk_display, real_sw->xwindow,
+                                     CWEventMask, &attrs);
+           }
+
+         gdk_dnd.drag_numwindows = 0;
+         if(gdk_dnd.drag_startwindows)
+           {
+           g_free(gdk_dnd.drag_startwindows);
+           gdk_dnd.drag_startwindows = NULL;
+           }
+
+         real_sw = NULL;
+         }
+
+       dnd_drag_perhaps = 0;
+       dnd_drag_start.x = dnd_drag_start.y = 0;
+       dnd_drag_dropzone.x = dnd_drag_dropzone.y = 0;
+       dnd_drag_dropzone.width = dnd_drag_dropzone.height = 0;
+       dnd_drag_curwin = None;
+      }
+      return_val = window ? (!window_private->destroyed) : FALSE;
+      break;
+
+    case MotionNotify:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("motion notify:\t\twindow: %ld  x,y: %d %d  hint: %s d:%d r%d\n",
+                xevent->xmotion.window - base_id,
+                xevent->xmotion.x, xevent->xmotion.y,
+                (xevent->xmotion.is_hint) ? "true" : "false",
+                dnd_drag_perhaps, gdk_dnd.drag_really);
+
+      if (window_private &&
+         (window_private->extension_events != 0) &&
+         gdk_input_ignore_core)
+       break;
+
+      event->motion.type = GDK_MOTION_NOTIFY;
+      event->motion.window = window;
+      event->motion.time = xevent->xmotion.time;
+      event->motion.x = xevent->xmotion.x;
+      event->motion.y = xevent->xmotion.y;
+      event->motion.pressure = 0.5;
+      event->motion.xtilt = 0;
+      event->motion.ytilt = 0;
+      event->motion.state = (GdkModifierType) xevent->xmotion.state;
+      event->motion.is_hint = xevent->xmotion.is_hint;
+      event->motion.source = GDK_SOURCE_MOUSE;
+      event->motion.deviceid = GDK_CORE_POINTER;
+
+#define IS_IN_ZONE(cx, cy) (cx >= dnd_drag_dropzone.x \
+     && cy >= dnd_drag_dropzone.y \
+     && cx < (dnd_drag_dropzone.x + dnd_drag_dropzone.width) \
+     && cy < (dnd_drag_dropzone.y + dnd_drag_dropzone.height))
+
+      if(dnd_drag_perhaps && gdk_dnd.drag_really)
+       {
+         /* First, we have to find what window the motion was in... */
+         /* XXX there has to be a better way to do this, perhaps with
+            XTranslateCoordinates or XQueryTree - I don't know how,
+            and this sort of works */
+         Window curwin, childwin = gdk_root_window, rootwinret;
+         int x, y;
+         unsigned int mask;
+         while(childwin != None)
+           {
+             curwin = childwin;
+             XQueryPointer(gdk_display, curwin, &rootwinret, &childwin,
+                           &x, &y, &x, &y, &mask);
+           }
+         if(curwin != dnd_drag_curwin)
+           {
+             /* We have left one window and entered another
+                (do leave & enter bits) */
+             if(dnd_drag_curwin != real_sw->xwindow && dnd_drag_curwin != None)
+               gdk_dnd_drag_leave(dnd_drag_curwin);
+             dnd_drag_curwin = curwin;
+             gdk_dnd_drag_enter(dnd_drag_curwin);
+             dnd_drag_dropzone.x = dnd_drag_dropzone.y = 0;
+             dnd_drag_dropzone.width = dnd_drag_dropzone.height = 0;
+             dnd_drag_target = None;
+             XChangeActivePointerGrab(gdk_display,
+                                      ButtonMotionMask |
+                                      ButtonPressMask | ButtonReleaseMask |
+                                      EnterWindowMask | LeaveWindowMask,
+                                      gdk_dnd.gdk_cursor_dragdefault,
+                                      CurrentTime);
+           }
+         else if(dnd_drag_dropzone.width > 0
+                 && dnd_drag_dropzone.height > 0)
+           {
+             /* Handle all that dropzone stuff - thanks John ;-) */
+             if(dnd_drag_target != None
+                && IS_IN_ZONE(dnd_drag_oldpos.x, dnd_drag_oldpos.y)
+                && !IS_IN_ZONE(xevent->xmotion.x_root,
+                               xevent->xmotion.y_root))
+               {
+                 /* We were in the drop zone and moved out */
+                 dnd_drag_target = None;
+                 gdk_dnd_drag_leave(curwin);
+               }
+             else
+               {
+                 /* We were outside drop zone but in the window
+                    - have to send enter events */
+                 gdk_dnd_drag_enter(curwin);
+                 dnd_drag_curwin = curwin;
+                 dnd_drag_dropzone.x = dnd_drag_dropzone.y = 0;
+                 dnd_drag_target = None;
+               }
+           } else
+             dnd_drag_curwin = None;
+         return_val = FALSE;
+       }
+      else
+      return_val = window?(!window_private->destroyed):FALSE;
+      break;
+
+    case EnterNotify:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("enter notify:\t\twindow: %ld  detail: %d subwin: %ld\n",
+                xevent->xcrossing.window - base_id,
+                xevent->xcrossing.detail,
+                xevent->xcrossing.subwindow - base_id);
+
+      /* Tell XInput stuff about it if appropriate */
+      if (window_private &&
+         (window_private->extension_events != 0) &&
+         gdk_input_vtable.enter_event)
+       gdk_input_vtable.enter_event (&xevent->xcrossing, window);
+
+      event->crossing.type = GDK_ENTER_NOTIFY;
+      event->crossing.window = window;
+
+      /* If the subwindow field of the XEvent is non-NULL, then
+       *  lookup the corresponding GdkWindow.
+       */
+      if (xevent->xcrossing.subwindow != None)
+       event->crossing.subwindow = gdk_window_lookup (xevent->xcrossing.subwindow);
+      else
+       event->crossing.subwindow = NULL;
+
+      /* Translate the crossing detail into Gdk terms.
+       */
+      switch (xevent->xcrossing.detail)
+       {
+       case NotifyInferior:
+         event->crossing.detail = GDK_NOTIFY_INFERIOR;
+         break;
+       case NotifyAncestor:
+         event->crossing.detail = GDK_NOTIFY_ANCESTOR;
+         break;
+       case NotifyVirtual:
+         event->crossing.detail = GDK_NOTIFY_VIRTUAL;
+         break;
+       case NotifyNonlinear:
+         event->crossing.detail = GDK_NOTIFY_NONLINEAR;
+         break;
+       case NotifyNonlinearVirtual:
+         event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL;
+         break;
+       default:
+         event->crossing.detail = GDK_NOTIFY_UNKNOWN;
+         break;
+       }
+
+      if(dnd_drag_perhaps
+        && gdk_dnd.drag_really
+        && xevent->xcrossing.window == real_sw->xwindow)
+       {
+         gdk_dnd.drag_really = 0;
+         XUngrabPointer(gdk_display, CurrentTime);
+       }
+
+      return_val = (window ? !window_private->destroyed : FALSE);
+      break;
+
+    case LeaveNotify:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("leave notify:\t\twindow: %ld  detail: %d subwin: %ld\n",
+                xevent->xcrossing.window - base_id,
+                xevent->xcrossing.detail, xevent->xcrossing.subwindow - base_id);
+
+      event->crossing.type = GDK_LEAVE_NOTIFY;
+      event->crossing.window = window;
+
+      /* Translate the crossing detail into Gdk terms.
+       */
+      switch (xevent->xcrossing.detail)
+       {
+       case NotifyInferior:
+         event->crossing.detail = GDK_NOTIFY_INFERIOR;
+         break;
+       case NotifyAncestor:
+         event->crossing.detail = GDK_NOTIFY_ANCESTOR;
+         break;
+       case NotifyVirtual:
+         event->crossing.detail = GDK_NOTIFY_VIRTUAL;
+         break;
+       case NotifyNonlinear:
+         event->crossing.detail = GDK_NOTIFY_NONLINEAR;
+         break;
+       case NotifyNonlinearVirtual:
+         event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL;
+         break;
+       default:
+         event->crossing.detail = GDK_NOTIFY_UNKNOWN;
+         break;
+       }
+      if(dnd_drag_perhaps
+        && !gdk_dnd.drag_really)
+       {
+         gdk_dnd_drag_addwindow((GdkWindow *) real_sw);
+         gdk_dnd_drag_begin((GdkWindow *) real_sw);
+         XGrabPointer(gdk_display, real_sw->xwindow, False,
+                      ButtonMotionMask |
+                      ButtonPressMask | ButtonReleaseMask |
+                      EnterWindowMask | LeaveWindowMask,
+                      GrabModeAsync, GrabModeAsync, gdk_root_window,
+                      gdk_dnd.gdk_cursor_dragdefault, CurrentTime);
+         gdk_dnd.drag_really = 1;
+      }
+      return_val = window ? (!window_private->destroyed) : FALSE;
+      break;
+
+    case FocusIn:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("focus in:\t\twindow: %ld\n",
+                xevent->xfocus.window - base_id);
+
+      event->focus_change.type = GDK_FOCUS_CHANGE;
+      event->focus_change.window = window;
+      event->focus_change.in = TRUE;
+
+      return_val = !window_private->destroyed;
+      break;
+
+    case FocusOut:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("focus out:\t\twindow: %ld\n",
+                xevent->xfocus.window - base_id);
+
+      event->focus_change.type = GDK_FOCUS_CHANGE;
+      event->focus_change.window = window;
+      event->focus_change.in = FALSE;
+
+      return_val = !window_private->destroyed;
+      break;
+
+    case KeymapNotify:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("keymap notify\n");
+
+      /* Not currently handled */
+      break;
+
+    case Expose:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("expose:\t\twindow: %ld  %d  x,y: %d %d  w,h: %d %d\n",
+                xevent->xexpose.window - base_id, xevent->xexpose.count,
+                xevent->xexpose.x, xevent->xexpose.y,
+                xevent->xexpose.width, xevent->xexpose.height);
+
+      event->expose.type = GDK_EXPOSE;
+      event->expose.window = window;
+      event->expose.area.x = xevent->xexpose.x;
+      event->expose.area.y = xevent->xexpose.y;
+      event->expose.area.width = xevent->xexpose.width;
+      event->expose.area.height = xevent->xexpose.height;
+      event->expose.count = xevent->xexpose.count;
+
+      return_val = !window_private->destroyed;
+      break;
+
+    case GraphicsExpose:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("graphics expose:\tdrawable: %ld\n",
+                xevent->xgraphicsexpose.drawable - base_id);
+
+      event->expose.type = GDK_EXPOSE;
+      event->expose.window = window;
+      event->expose.area.x = xevent->xgraphicsexpose.x;
+      event->expose.area.y = xevent->xgraphicsexpose.y;
+      event->expose.area.width = xevent->xgraphicsexpose.width;
+      event->expose.area.height = xevent->xgraphicsexpose.height;
+      event->expose.count = xevent->xexpose.count;
+
+      return_val = !window_private->destroyed;
+      break;
+
+    case NoExpose:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("no expose:\t\tdrawable: %ld\n",
+                xevent->xnoexpose.drawable - base_id);
+
+      /* Not currently handled */
+      break;
+
+    case VisibilityNotify:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       switch (xevent->xvisibility.state)
+         {
+         case VisibilityFullyObscured:
+           g_print ("visibility notify:\twindow: %ld  none\n",
+                    xevent->xvisibility.window - base_id);
+           break;
+         case VisibilityPartiallyObscured:
+           g_print ("visibility notify:\twindow: %ld  partial\n",
+                    xevent->xvisibility.window - base_id);
+           break;
+         case VisibilityUnobscured:
+           g_print ("visibility notify:\twindow: %ld  full\n",
+                    xevent->xvisibility.window - base_id);
+           break;
+         }
+
+      /* Not currently handled */
+      break;
+
+    case CreateNotify:
+      /* Not currently handled */
+      break;
+
+    case DestroyNotify:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("destroy notify:\twindow: %ld\n",
+                xevent->xdestroywindow.window - base_id);
+
+      event->any.type = GDK_DESTROY;
+      event->any.window = window;
+
+      /* Remeber which window received the destroy notify
+       *  event so that we can destroy our associated
+       *  data structures the next time the user asks
+       *  us for an event.
+       */
+      received_destroy_notify = TRUE;
+      window_to_destroy = window;
+
+      return_val = !window_private->destroyed;
+      break;
+
+    case UnmapNotify:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("unmap notify:\t\twindow: %ld\n",
+                xevent->xmap.window - base_id);
+
+      event->any.type = GDK_UNMAP;
+      event->any.window = window;
+
+      return_val = !window_private->destroyed;
+      break;
+
+    case MapNotify:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("map notify:\t\twindow: %ld\n",
+                xevent->xmap.window - base_id);
+
+      event->any.type = GDK_MAP;
+      event->any.window = window;
+
+      return_val = !window_private->destroyed;
+      break;
+
+    case ReparentNotify:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("reparent notify:\twindow: %ld\n",
+                xevent->xreparent.window - base_id);
+
+      /* Not currently handled */
+      break;
+
+    case ConfigureNotify:
+      /* Print debugging info.
+       */
+      while ((XPending(gdk_display) > 0) &&
+               XCheckTypedWindowEvent(gdk_display, xevent->xany.window,
+                                      ConfigureNotify, xevent))
+         /*XSync(gdk_display, 0)*/;
+
+      if (gdk_show_events)
+       g_print ("configure notify:\twindow: %ld  x,y: %d %d  w,h: %d %d\n",
+                xevent->xconfigure.window - base_id,
+                xevent->xconfigure.x, xevent->xconfigure.y,
+                xevent->xconfigure.width, xevent->xconfigure.height);
+
+      if (window_private &&
+         (window_private->extension_events != 0) &&
+         gdk_input_vtable.configure_event)
+       gdk_input_vtable.configure_event (&xevent->xconfigure, window);
+
+      if ((window_private->window_type != GDK_WINDOW_CHILD) &&
+         ((window_private->width != xevent->xconfigure.width) ||
+          (window_private->height != xevent->xconfigure.height)))
+       {
+         event->configure.type = GDK_CONFIGURE;
+         event->configure.window = window;
+         event->configure.x = xevent->xconfigure.x;
+         event->configure.y = xevent->xconfigure.y;
+         event->configure.width = xevent->xconfigure.width;
+         event->configure.height = xevent->xconfigure.height;
+
+         window_private->x = xevent->xconfigure.x;
+         window_private->y = xevent->xconfigure.y;
+         window_private->width = xevent->xconfigure.width;
+         window_private->height = xevent->xconfigure.height;
+         if (window_private->resize_count > 1)
+           window_private->resize_count -= 1;
+
+         return_val = !window_private->destroyed;
+       }
+      break;
+
+    case PropertyNotify:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("property notify:\twindow: %ld\n",
+                xevent->xproperty.window - base_id);
+
+      event->property.type = GDK_PROPERTY_NOTIFY;
+      event->property.window = window;
+      event->property.atom = xevent->xproperty.atom;
+      event->property.time = xevent->xproperty.time;
+      event->property.state = xevent->xproperty.state;
+
+      return_val = !window_private->destroyed;
+      break;
+
+    case SelectionClear:
+      if (gdk_show_events)
+       g_print ("selection clear:\twindow: %ld\n",
+                xevent->xproperty.window - base_id);
+
+      event->selection.type = GDK_SELECTION_CLEAR;
+      event->selection.window = window;
+      event->selection.selection = xevent->xselectionclear.selection;
+      event->selection.time = xevent->xselectionclear.time;
+
+      return_val = !((GdkWindowPrivate*) window)->destroyed;
+      break;
+
+    case SelectionRequest:
+      if (gdk_show_events)
+       g_print ("selection request:\twindow: %ld\n",
+                xevent->xproperty.window - base_id);
+
+      event->selection.type = GDK_SELECTION_REQUEST;
+      event->selection.window = window;
+      event->selection.selection = xevent->xselectionrequest.selection;
+      event->selection.target = xevent->xselectionrequest.target;
+      event->selection.property = xevent->xselectionrequest.property;
+      event->selection.requestor = xevent->xselectionrequest.requestor;
+      event->selection.time = xevent->xselectionrequest.time;
+
+      return_val = !((GdkWindowPrivate*) window)->destroyed;
+      break;
+
+    case SelectionNotify:
+      if (gdk_show_events)
+       g_print ("selection notify:\twindow: %ld\n",
+                xevent->xproperty.window - base_id);
+
+
+      event->selection.type = GDK_SELECTION_NOTIFY;
+      event->selection.window = window;
+      event->selection.selection = xevent->xselection.selection;
+      event->selection.target = xevent->xselection.target;
+      event->selection.property = xevent->xselection.property;
+      event->selection.time = xevent->xselection.time;
+
+      return_val = !((GdkWindowPrivate*) window)->destroyed;
+      break;
+
+    case ColormapNotify:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("colormap notify:\twindow: %ld\n",
+                xevent->xcolormap.window - base_id);
+
+      /* Not currently handled */
+      break;
+
+    case ClientMessage:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("client message:\twindow: %ld\n",
+                xevent->xclient.window - base_id);
+
+      /* Client messages are the means of the window manager
+       *  communicating with a program. We'll first check to
+       *  see if this is really the window manager talking
+       *  to us.
+       */
+      if (xevent->xclient.message_type == gdk_wm_protocols)
+       {
+         if ((Atom) xevent->xclient.data.l[0] == gdk_wm_delete_window)
+           {
+             /* The delete window request specifies a window
+              *  to delete. We don't actually destroy the
+              *  window because "it is only a request". (The
+              *  window might contain vital data that the
+              *  program does not want destroyed). Instead
+              *  the event is passed along to the program,
+              *  which should then destroy the window.
+              */
+
+             /* Print debugging info.
+              */
+             if (gdk_show_events)
+               g_print ("delete window:\t\twindow: %ld\n",
+                        xevent->xclient.window - base_id);
+
+             event->any.type = GDK_DELETE;
+             event->any.window = window;
+
+             return_val = !window_private->destroyed;
+           }
+         else if ((Atom) xevent->xclient.data.l[0] == gdk_wm_take_focus)
+           {
+           }
+       }
+      else if (xevent->xclient.message_type == gdk_dnd.gdk_XdeEnter)
+       {
+         Atom reptype = 0;
+
+         event->dropenter.u.allflags = xevent->xclient.data.l[1];
+         if (gdk_show_events)
+           g_print ("GDK_DROP_ENTER\n");
+         return_val = FALSE;
+
+         /* Now figure out if we really want this drop...
+          * If someone is trying funky clipboard stuff, ignore 
+          */
+         if (window_private
+             && window_private->dnd_drop_enabled
+             && event->dropenter.u.flags.sendreply
+             && (reptype = gdk_dnd_check_types (window, xevent)))
+           {
+             XEvent replyev;
+
+             replyev.xclient.type = ClientMessage;
+             replyev.xclient.window = xevent->xclient.data.l[0];
+             replyev.xclient.format = 32;
+             replyev.xclient.message_type = gdk_dnd.gdk_XdeRequest;
+             replyev.xclient.data.l[0] = window_private->xwindow;
+
+             event->dragrequest.u.allflags = 0;
+             event->dragrequest.u.flags.protocol_version =
+               DND_PROTOCOL_VERSION;
+             event->dragrequest.u.flags.willaccept = 1;
+             event->dragrequest.u.flags.delete_data =
+               (window_private->dnd_drop_destructive_op) ? 1 : 0;
+
+             replyev.xclient.data.l[1] = event->dragrequest.u.allflags;
+             replyev.xclient.data.l[2] = replyev.xclient.data.l[3] = 0;
+             replyev.xclient.data.l[4] = reptype;
+
+             XSendEvent (gdk_display, replyev.xclient.window,
+                         False, NoEventMask, &replyev);
+
+             event->any.type = GDK_DROP_ENTER;
+             event->dropenter.requestor = replyev.xclient.window;
+             event->dropenter.u.allflags = xevent->xclient.data.l[1];
+           }
+       }
+      else if (xevent->xclient.message_type == gdk_dnd.gdk_XdeLeave)
+       {
+         if (gdk_show_events)
+           g_print ("GDK_DROP_LEAVE\n");
+         if (window_private && window_private->dnd_drop_enabled)
+           {
+             event->dropleave.type = GDK_DROP_LEAVE;
+             event->dropleave.window = window;
+             event->dropleave.requestor = xevent->xclient.data.l[0];
+             event->dropleave.u.allflags = xevent->xclient.data.l[1];
+             return_val = TRUE;
+           }
+         else
+           return_val = FALSE;
+       }
+      else if (xevent->xclient.message_type == gdk_dnd.gdk_XdeRequest)
+       {
+         /* 
+          * make sure to only handle requests from the window the cursor is
+          * over 
+          */
+         if (gdk_show_events)
+           g_print ("GDK_DRAG_REQUEST\n");
+         event->dragrequest.u.allflags = xevent->xclient.data.l[1];
+         return_val = FALSE;
+
+         if (window && gdk_dnd.drag_really &&
+             xevent->xclient.data.l[0] == dnd_drag_curwin &&
+             event->dragrequest.u.flags.sendreply == 0)
+           {
+             /* Got request - do we need to ask user? */
+             if (!event->dragrequest.u.flags.willaccept
+                 && event->dragrequest.u.flags.senddata)
+               {
+                 /* Yes we do :) */
+                 event->dragrequest.type = GDK_DRAG_REQUEST;
+                 event->dragrequest.window = window;
+                 event->dragrequest.requestor = xevent->xclient.data.l[0];
+                 event->dragrequest.isdrop = 0;
+                 event->dragrequest.drop_coords.x =
+                   event->dragrequest.drop_coords.y = 0;
+                 return_val = TRUE;
+               }
+             else if (event->dragrequest.u.flags.willaccept)
+               {
+                 window_private->dnd_drag_destructive_op =
+                   event->dragrequest.u.flags.delete_data;
+                 window_private->dnd_drag_accepted = 1;
+                 window_private->dnd_drag_data_type =
+                   xevent->xclient.data.l[4];
+
+                 dnd_drag_target = dnd_drag_curwin;
+                 XChangeActivePointerGrab (gdk_display,
+                                           ButtonMotionMask |
+                                           ButtonPressMask |
+                                           ButtonReleaseMask |
+                                           EnterWindowMask | LeaveWindowMask,
+                                           gdk_dnd.gdk_cursor_dragok,
+                                           CurrentTime);
+               }
+             dnd_drag_dropzone.x = xevent->xclient.data.l[2] & 65535;
+             dnd_drag_dropzone.y =
+               (xevent->xclient.data.l[2] >> 16) & 65535;
+             dnd_drag_dropzone.width = xevent->xclient.data.l[3] & 65535;
+             dnd_drag_dropzone.height =
+               (xevent->xclient.data.l[3] >> 16) & 65535;
+           }
+       }
+      else if(xevent->xclient.message_type == gdk_dnd.gdk_XdeDataAvailable)
+         {
+           gint tmp_int; Atom tmp_atom;
+           gulong tmp_long;
+           guchar *tmp_charptr;
+           gpointer tmp_ptr;
+           
+           if(gdk_show_events)
+             g_print("GDK_DROP_DATA_AVAIL\n");
+           event->dropdataavailable.u.allflags = xevent->xclient.data.l[1];
+           if(window
+              /* No preview of data ATM */
+              && event->dropdataavailable.u.flags.isdrop)
+             {
+               event->dropdataavailable.type = GDK_DROP_DATA_AVAIL;
+               event->dropdataavailable.window = window;
+               event->dropdataavailable.requestor = xevent->xclient.data.l[0];
+               event->dropdataavailable.data_type =
+                       gdk_atom_name(xevent->xclient.data.l[2]);
+               if(XGetWindowProperty (gdk_display,
+                                   event->dropdataavailable.requestor,
+                                   xevent->xclient.data.l[2],
+                                   0, LONG_MAX - 1,
+                                   False, XA_PRIMARY, &tmp_atom,
+                                   &tmp_int,
+                                   &event->dropdataavailable.data_numbytes,
+                                   &tmp_long,
+                                   &tmp_charptr)
+                  != Success)
+                 {
+                   g_warning("XGetWindowProperty on %#x may have failed\n",
+                           event->dropdataavailable.requestor);
+                           event->dropdataavailable.data = NULL;
+                 }
+               else
+                 {
+                   g_print("XGetWindowProperty got us %d bytes\n",
+                           event->dropdataavailable.data_numbytes);
+                   event->dropdataavailable.data =
+                       g_malloc(event->dropdataavailable.data_numbytes);
+                   memcpy(event->dropdataavailable.data,
+                       tmp_charptr, event->dropdataavailable.data_numbytes);
+                   XFree(tmp_charptr);
+                   return_val = TRUE;
+                 }
+             return_val = TRUE;
+           }
+       } else {
+         /* Send unknown ClientMessage's on to Gtk for it to use */
+         event->client.type = GDK_CLIENT_EVENT;
+         event->client.window = window;
+         event->client.message_type = xevent->xclient.message_type;
+         event->client.data_format = xevent->xclient.format;
+         memcpy(&event->client.data, &xevent->xclient.data,
+                sizeof(event->client.data));
+         return_val = TRUE;
+       }
+      return_val = return_val && !window_private->destroyed;
+      break;
+      
+    case MappingNotify:
+      /* Print debugging info.
+       */
+      if (gdk_show_events)
+       g_print ("mapping notify\n");
+
+      /* Let XLib know that there is a new keyboard mapping.
+       */
+      XRefreshKeyboardMapping (&xevent->xmapping);
+      break;
+
+    default:
+      /* something else - (e.g., a Xinput event) */
+
+      if (window_private &&
+         (window_private->extension_events != 0) &&
+         gdk_input_vtable.other_event)
+       return_val = gdk_input_vtable.other_event(event, xevent, window);
+
+      if (return_val < 0)      /* not an XInput event, convert */
+       {
+         event->other.type = GDK_OTHER_EVENT;
+         event->other.window = window;
+         event->other.xevent = &other_xevent[other_xevent_i];
+         memcpy (&other_xevent[other_xevent_i], xevent, sizeof (XEvent));
+         other_xevent_i = (other_xevent_i+1) % OTHER_XEVENT_BUFSIZE;
+         return_val = TRUE;
+       }
+
+      return_val = return_val && !window_private->destroyed;
+      break;
+    }
+
+  return return_val;
+}
+
+static Bool
+gdk_event_get_type (Display  *display,
+                   XEvent   *xevent,
+                   XPointer  arg)
+{
+  GdkEvent event;
+  GdkPredicate *pred;
+
+  if (gdk_event_translate (&event, xevent))
+    {
+      pred = (GdkPredicate*) arg;
+      return (* pred->func) (&event, pred->data);
+    }
+
+  return FALSE;
+}
+
+static void
+gdk_synthesize_click (GdkEvent *event,
+                     gint      nclicks)
+{
+  GdkEvent temp_event;
+
+  g_return_if_fail (event != NULL);
+
+  temp_event = *event;
+  temp_event.type = (nclicks == 2) ? GDK_2BUTTON_PRESS : GDK_3BUTTON_PRESS;
+
+  gdk_event_put (&temp_event);
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_exit_func
+ *
+ *   This is the "atexit" function that makes sure the
+ *   library gets a chance to cleanup.
+ *
+ * Arguments:
+ *
+ * Results:
+ *
+ * Side effects:
+ *   The library is un-initialized and the program exits.
+ *
+ *--------------------------------------------------------------
+ */
+
+static void
+gdk_exit_func ()
+{
+  if (initialized)
+    {
+      gdk_image_exit ();
+      gdk_input_exit ();
+      gdk_key_repeat_restore ();
+
+      XCloseDisplay (gdk_display);
+      initialized = 0;
+    }
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_x_error
+ *
+ *   The X error handling routine.
+ *
+ * Arguments:
+ *   "display" is the X display the error orignated from.
+ *   "error" is the XErrorEvent that we are handling.
+ *
+ * Results:
+ *   Either we were expecting some sort of error to occur,
+ *   in which case we set the "gdk_error_code" flag, or this
+ *   error was unexpected, in which case we will print an
+ *   error message and exit. (Since trying to continue will
+ *   most likely simply lead to more errors).
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+static int
+gdk_x_error (Display     *display,
+            XErrorEvent *error)
+{
+  char buf[64];
+
+  if (gdk_error_warnings)
+    {
+      XGetErrorText (display, error->error_code, buf, 63);
+      g_error ("%s", buf);
+    }
+
+  gdk_error_code = -1;
+  return 0;
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_x_io_error
+ *
+ *   The X I/O error handling routine.
+ *
+ * Arguments:
+ *   "display" is the X display the error orignated from.
+ *
+ * Results:
+ *   An X I/O error basically means we lost our connection
+ *   to the X server. There is not much we can do to
+ *   continue, so simply print an error message and exit.
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+static int
+gdk_x_io_error (Display *display)
+{
+  g_error ("an x io error occurred");
+  return 0;
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_signal
+ *
+ *   The signal handler.
+ *
+ * Arguments:
+ *   "sig_num" is the number of the signal we received.
+ *
+ * Results:
+ *   The signals we catch are all fatal. So we simply build
+ *   up a nice little error message and print it and exit.
+ *   If in the process of doing so another signal is received
+ *   we notice that we are already exiting and simply kill
+ *   our process.
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+static RETSIGTYPE
+gdk_signal (int sig_num)
+{
+  static int caught_fatal_sig = 0;
+  char *sig;
+
+  if (caught_fatal_sig)
+    kill (getpid (), sig_num);
+  caught_fatal_sig = 1;
+
+  switch (sig_num)
+    {
+    case SIGHUP:
+      sig = "sighup";
+      break;
+    case SIGINT:
+      sig = "sigint";
+      break;
+    case SIGQUIT:
+      sig = "sigquit";
+      break;
+    case SIGBUS:
+      sig = "sigbus";
+      break;
+    case SIGSEGV:
+      sig = "sigsegv";
+      break;
+    case SIGPIPE:
+      sig = "sigpipe";
+      break;
+    case SIGTERM:
+      sig = "sigterm";
+      break;
+    default:
+      sig = "unknown signal";
+      break;
+    }
+
+  g_print ("\n** ERROR **: %s caught\n", sig);
+  gdk_exit (1);
+}
+
+static void
+gdk_dnd_drag_begin (GdkWindow *initial_window)
+{
+  GdkEventDragBegin tev;
+  tev.type = GDK_DRAG_BEGIN;
+  tev.window = initial_window;
+  tev.u.allflags = 0;
+  tev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
+
+  gdk_event_put ((GdkEvent *) &tev);
+}
+
+static void
+gdk_dnd_drag_enter (Window dest)
+{
+  XEvent sev;
+  GdkEventDropEnter tev;
+  int i;
+  GdkWindowPrivate *wp;
+  
+  sev.xclient.type = ClientMessage;
+  sev.xclient.format = 32;
+  sev.xclient.message_type = gdk_dnd.gdk_XdeEnter;
+  sev.xclient.window = dest;
+
+  tev.u.allflags = 0;
+  tev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
+  tev.u.flags.sendreply = 1;
+  for (i = 0; i < gdk_dnd.drag_numwindows; i++)
+    {
+      wp = (GdkWindowPrivate *) gdk_dnd.drag_startwindows[i];
+      if (wp->dnd_drag_data_numtypesavail)
+       {
+         sev.xclient.data.l[0] = wp->xwindow;
+         tev.u.flags.extended_typelist = (wp->dnd_drag_data_numtypesavail > 3)?1:0;
+         sev.xclient.data.l[1] = tev.u.allflags;
+         sev.xclient.data.l[2] = wp->dnd_drag_data_typesavail[0];
+         if (wp->dnd_drag_data_numtypesavail > 1)
+           {
+             sev.xclient.data.l[3] = wp->dnd_drag_data_typesavail[1];
+             if (wp->dnd_drag_data_numtypesavail > 2)
+               {
+                 sev.xclient.data.l[4] = wp->dnd_drag_data_typesavail[2];
+               }
+             else
+               sev.xclient.data.l[4] = None;
+           }
+         else
+           sev.xclient.data.l[3] = sev.xclient.data.l[4] = None;
+         XSendEvent (gdk_display, dest, False, NoEventMask, &sev);
+       }
+
+    }
+}
+
+static void
+gdk_dnd_drag_leave (Window dest)
+{
+  XEvent sev;
+  GdkEventDropLeave tev;
+  int i;
+  GdkWindowPrivate *wp;
+
+  tev.u.allflags = 0;
+
+  tev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
+  sev.xclient.type = ClientMessage;
+  sev.xclient.window = dest;
+  sev.xclient.format = 32;
+  sev.xclient.message_type = gdk_dnd.gdk_XdeLeave;
+  sev.xclient.data.l[1] = tev.u.allflags;
+  for (i = 0; i < gdk_dnd.drag_numwindows; i++)
+    {
+      wp = (GdkWindowPrivate *) gdk_dnd.drag_startwindows[i];
+      sev.xclient.data.l[0] = wp->xwindow;
+      XSendEvent(gdk_display, dest, False, NoEventMask, &sev);
+      wp->dnd_drag_accepted = 0;
+    }
+}
+
+/* 
+ * when a drop occurs, we go through the list of windows being dragged and
+ * tell them that it has occurred, so that they can set things up and reply
+ * to 'dest' window 
+ */
+static void
+gdk_dnd_drag_end (Window     dest, 
+                 GdkPoint   coords)
+{
+  GdkWindowPrivate *wp;
+  GdkEventDragRequest tev;
+  gchar *tmp_cptr;
+  int i;
+
+  tev.type = GDK_DRAG_REQUEST;
+  tev.drop_coords = coords;
+  tev.requestor = dest;
+  tev.u.allflags = 0;
+  tev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
+  tev.isdrop = 1;
+
+  for (i = 0; i < gdk_dnd.drag_numwindows; i++)
+    {
+      wp = (GdkWindowPrivate *) gdk_dnd.drag_startwindows[i];
+      if (wp->dnd_drag_accepted)
+       {
+         tev.window = (GdkWindow *) wp;
+         tev.u.flags.delete_data = wp->dnd_drag_destructive_op;
+         tev.data_type = 
+               gdk_atom_name(wp->dnd_drag_data_type);
+
+         gdk_event_put((GdkEvent *) &tev);
+       }
+    }
+}
+
+static GdkAtom
+gdk_dnd_check_types (GdkWindow   *window, 
+                    XEvent      *xevent)
+{
+  GdkWindowPrivate *wp = (GdkWindowPrivate *) window;
+  int i, j;
+  GdkEventDropEnter event;
+
+  g_return_val_if_fail(window != NULL, 0);
+  g_return_val_if_fail(xevent != NULL, 0);
+  g_return_val_if_fail(xevent->type == ClientMessage, 0);
+  g_return_val_if_fail(xevent->xclient.message_type == gdk_dnd.gdk_XdeEnter, 0);
+
+  if(wp->dnd_drop_data_numtypesavail <= 0 ||
+     !wp->dnd_drop_data_typesavail)
+    return 0;
+
+  for (i = 2; i <= 4; i++)
+    {
+      for (j = 0; j < wp->dnd_drop_data_numtypesavail; j++)
+       {
+         if (xevent->xclient.data.l[i] == wp->dnd_drop_data_typesavail[j])
+           return xevent->xclient.data.l[i];
+       }
+    }
+
+  /* Now we get the extended type list if it's available */
+  event.u.allflags = xevent->xclient.data.l[1];
+  if (event.u.flags.extended_typelist)
+    {
+      Atom *exttypes, realtype;
+      gulong nitems, nbar;
+      gint realfmt;
+
+      if (XGetWindowProperty(gdk_display, xevent->xclient.data.l[0],
+                            gdk_dnd.gdk_XdeTypelist, 0L, LONG_MAX - 1,
+                            False, AnyPropertyType, &realtype, &realfmt,
+                            &nitems, &nbar, (unsigned char **) &exttypes)
+        != Success)
+       return 0;
+
+      if (realfmt != (sizeof(Atom) * 8))
+       {
+         g_warning("XdeTypelist property had format of %d instead of the expected %d, on window %#lx\n",
+                   realfmt, sizeof(Atom) * 8, xevent->xclient.data.l[0]);
+         return 0;
+       }
+
+      for (i = 0; i <= nitems; i++)
+       {
+         for (j = 0; j < wp->dnd_drop_data_numtypesavail; j++)
+           {
+             if (exttypes[i] == wp->dnd_drop_data_typesavail[j])
+               {
+                 XFree (exttypes);
+                 return exttypes[i];
+               }
+           }
+       }
+      XFree (exttypes);
+    }
+  return 0;
+}
+
+/* 
+ * used for debugging only 
+ */
+static void
+gdk_print_atom (GdkAtom anatom)
+{
+  gchar *tmpstr = NULL;
+  tmpstr = (anatom!=None)?gdk_atom_name(anatom):"(none)";
+  g_print("Atom %lu has name %s\n", anatom, tmpstr);
+  if(tmpstr)
+    g_free(tmpstr);
+}
+
+/* 
+ * used only by below routine and itself 
+ */
+static Window 
+getchildren (Display     *dpy, 
+            Window       win, 
+            Atom         WM_STATE)
+{
+  Window root, parent, *children, inf = 0;
+  Atom type = None;
+  unsigned int nchildren, i;
+  int format;
+  unsigned long nitems, after;
+  unsigned char *data;
+
+  if (XQueryTree(dpy, win, &root, &parent, &children, &nchildren) == 0)
+    return 0;
+
+  for (i = 0; !inf && (i < nchildren); i++)
+    {
+      XGetWindowProperty (dpy, children[i], WM_STATE, 0, 0, False,
+                         AnyPropertyType, &type, &format, &nitems,
+                         &after, &data);
+      if (type != 0)
+       inf = children[i];
+    }
+
+  for (i = 0; !inf && (i < nchildren); i++)
+    inf = getchildren (dpy, children[i], WM_STATE);
+
+  if (children != 0) 
+    XFree ((char *) children);
+
+  return inf;
+}
+
+/* 
+ * find a window with WM_STATE, else return win itself, as per ICCCM
+ *
+ * modification of the XmuClientWindow() routine from X11R6.3
+ */
+Window
+gdk_get_client_window (Display  *dpy, 
+                      Window    win)
+{
+  Atom WM_STATE;
+  Atom type = None;
+  int format;
+  unsigned long nitems, after;
+  unsigned char *data;
+  Window inf;
+
+  if (win == 0)
+    return DefaultRootWindow(dpy);
+
+  if ((WM_STATE = XInternAtom (dpy, "WM_STATE", True)) == 0)
+    return win;
+
+  XGetWindowProperty (dpy, win, WM_STATE, 0, 0, False, AnyPropertyType,
+                     &type, &format, &nitems, &after, &data);
+  if (type)
+    return win;
+
+  inf = getchildren (dpy, win, WM_STATE);
+
+  if (inf == 0)
+    return win;
+  else
+    return inf;
+}
+
+static GdkWindow *
+gdk_drop_get_real_window (GdkWindow   *w, 
+                         guint16     *x, 
+                         guint16     *y)
+{
+  GdkWindow *retval = w;
+  GdkWindowPrivate *awin;
+  GList *children;
+  gint16 myx = *x, myy = *y;
+
+  g_return_val_if_fail(w != NULL && x != NULL && y != NULL, NULL);
+
+  myx = *x; 
+  myy = *y;
+
+descend:
+  for (children = gdk_window_get_children(retval); 
+       children && children->next;
+       children = children->next)
+    {
+      awin = (GdkWindowPrivate *) children->data;
+      if ((myx >= awin->x) && (myy >= awin->y)
+         && (myx < (awin->x + awin->width))
+         && (myy < (awin->y + awin->height)))
+       {
+         retval = (GdkWindow *) awin;
+         myx -= awin->x;
+         myy -= awin->y;
+         goto descend;
+       }
+    }
+
+  *x = myx; 
+  *y = myy;
+
+  return retval;
+}
+
+/* Sends a ClientMessage to all toplevel client windows */
+void
+gdk_event_send_clientmessage_toall(GdkEvent *event)
+{
+  XEvent sev;
+  Window *ret_children, ret_root, ret_parent, curwin;
+  unsigned int ret_nchildren;
+  int i;
+
+  g_return_if_fail(event != NULL);
+
+  /* Set up our event to send, with the exception of its target window */
+  sev.xclient.type = ClientMessage;
+  sev.xclient.display = gdk_display;
+  sev.xclient.format = event->client.data_format;
+  sev.xclient.serial = CurrentTime;
+  memcpy(&sev.xclient.data, &event->client.data, sizeof(sev.xclient.data));
+  sev.xclient.message_type = event->client.message_type;
+
+  /* OK, we're all set, now let's find some windows to send this to */
+  if(XQueryTree(gdk_display, gdk_root_window, &ret_root, &ret_parent,
+               &ret_children, &ret_nchildren) != True)
+    return;
+
+  /* foreach true child window of the root window, send an event to it */
+  for(i = 0; i < ret_nchildren; i++) {
+    curwin = gdk_get_client_window(gdk_display, ret_children[i]);
+    sev.xclient.window = curwin;
+    XSendEvent(gdk_display, curwin, False, NoEventMask, &sev);
+  }
+
+  XFree(ret_children);
+}
diff --git a/gdk/x11/gdkpixmap-x11.c b/gdk/x11/gdkpixmap-x11.c
new file mode 100644 (file)
index 0000000..d2d96b6
--- /dev/null
@@ -0,0 +1,657 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "../config.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <X11/Xlib.h>
+
+#include "gdk.h"
+#include "gdkprivate.h"
+
+typedef struct
+{
+  gchar *color_string;
+  GdkColor color;
+  gint transparent;
+} _GdkPixmapColor;
+
+GdkPixmap*
+gdk_pixmap_new (GdkWindow *window,
+               gint       width,
+               gint       height,
+               gint       depth)
+{
+  GdkPixmap *pixmap;
+  GdkWindowPrivate *private;
+  GdkWindowPrivate *window_private;
+
+  if (!window)
+    window = (GdkWindow*) &gdk_root_parent;
+
+  if (depth == -1)
+    gdk_window_get_geometry (window, NULL, NULL, NULL, NULL, &depth);
+
+  private = g_new (GdkWindowPrivate, 1);
+  pixmap = (GdkPixmap*) private;
+
+  window_private = (GdkWindowPrivate*) window;
+
+  private->xdisplay = window_private->xdisplay;
+  private->window_type = GDK_WINDOW_PIXMAP;
+  private->xwindow = XCreatePixmap (private->xdisplay, window_private->xwindow,
+                                   width, height, depth);
+  private->parent = NULL;
+  private->x = 0;
+  private->y = 0;
+  private->width = width;
+  private->height = height;
+  private->resize_count = 0;
+  private->ref_count = 1;
+  private->destroyed = 0;
+
+  gdk_xid_table_insert (&private->xwindow, pixmap);
+
+  return pixmap;
+}
+
+GdkPixmap *
+gdk_bitmap_create_from_data (GdkWindow *window,
+                            gchar     *data,
+                            gint       width,
+                            gint       height)
+{
+  GdkPixmap *pixmap;
+  GdkWindowPrivate *private;
+  GdkWindowPrivate *window_private;
+
+  g_return_val_if_fail (data != NULL, NULL);
+
+  if (!window)
+    window = (GdkWindow*) &gdk_root_parent;
+
+  private = g_new (GdkWindowPrivate, 1);
+  pixmap = (GdkPixmap*) private;
+
+  window_private = (GdkWindowPrivate*) window;
+
+  private->parent = NULL;
+  private->xdisplay = window_private->xdisplay;
+  private->window_type = GDK_WINDOW_PIXMAP;
+  private->x = 0;
+  private->y = 0;
+  private->width = width;
+  private->height = height;
+  private->resize_count = 0;
+  private->ref_count = 1;
+  private->destroyed = FALSE;
+
+  private->xwindow = XCreateBitmapFromData (private->xdisplay,
+                                           window_private->xwindow,
+                                           data, width, height);
+
+  gdk_xid_table_insert (&private->xwindow, pixmap);
+
+  return pixmap;
+}
+
+GdkPixmap*
+gdk_pixmap_create_from_data (GdkWindow *window,
+                            gchar     *data,
+                            gint       width,
+                            gint       height,
+                            gint       depth,
+                            GdkColor  *fg,
+                            GdkColor  *bg)
+{
+  GdkPixmap *pixmap;
+  GdkWindowPrivate *private;
+  GdkWindowPrivate *window_private;
+
+  g_return_val_if_fail (data != NULL, NULL);
+  g_return_val_if_fail (fg != NULL, NULL);
+  g_return_val_if_fail (bg != NULL, NULL);
+
+  if (!window)
+    window = (GdkWindow*) &gdk_root_parent;
+
+  if (depth == -1)
+    gdk_window_get_geometry (window, NULL, NULL, NULL, NULL, &depth);
+
+  private = g_new (GdkWindowPrivate, 1);
+  pixmap = (GdkPixmap*) private;
+
+  window_private = (GdkWindowPrivate*) window;
+
+  private->parent = NULL;
+  private->xdisplay = window_private->xdisplay;
+  private->window_type = GDK_WINDOW_PIXMAP;
+  private->x = 0;
+  private->y = 0;
+  private->width = width;
+  private->height = height;
+  private->resize_count = 0;
+  private->ref_count = 1;
+  private->destroyed = FALSE;
+
+  private->xwindow = XCreatePixmapFromBitmapData (private->xdisplay,
+                                                 window_private->xwindow,
+                                                 data, width, height,
+                                                 fg->pixel, bg->pixel, depth);
+
+  gdk_xid_table_insert (&private->xwindow, pixmap);
+
+  return pixmap;
+}
+
+gint
+gdk_pixmap_seek_string (FILE  *infile,
+                        const gchar *str,
+                        gint   skip_comments)
+{
+  char instr[1024];
+
+  while (!feof (infile))
+    {
+      fscanf (infile, "%s", instr);
+      if (skip_comments == TRUE && strcmp (instr, "/*") == 0)
+        {
+          fscanf (infile, "%s", instr);
+          while (!feof (infile) && strcmp (instr, "*/") != 0)
+            fscanf (infile, "%s", instr);
+          fscanf(infile, "%s", instr);
+        }
+      if (strcmp (instr, str)==0)
+        return TRUE;
+    }
+
+  return FALSE;
+}
+
+gint
+gdk_pixmap_seek_char (FILE  *infile,
+                      gchar  c)
+{
+  gchar b, oldb;
+
+  while (!feof (infile))
+    {
+      fscanf(infile, "%c", &b);
+      if (c != b && b == '/')
+        {
+          fscanf (infile, "%c", &b);
+          if (b == '*')
+            {
+              oldb = b;
+              while (!feof (infile) && !(oldb == '*' && b == '/'))
+                {
+                  oldb = b;
+                  fscanf (infile, "%c", &b);
+                }
+              fscanf (infile, "%c", &b);
+            }
+        }
+      if (c == b)
+        return TRUE;
+    }
+
+  return FALSE;
+}
+
+gint
+gdk_pixmap_read_string (FILE  *infile,
+                        gchar **buffer,
+                       int *buffer_size)
+{
+  gchar c;
+  gint cnt = 0;
+
+  if ((*buffer) == NULL)
+    {
+      (*buffer_size) = 10 * sizeof (gchar);
+      (*buffer) = (gchar *) malloc (*buffer_size);
+    }
+
+  do
+    fscanf (infile, "%c", &c);
+  while (!feof (infile) && c != '"');
+
+  if (c != '"')
+    return FALSE;
+
+  while (!feof (infile))
+    {
+      fscanf (infile, "%c", &c);
+
+      if (cnt == (*buffer_size))
+       {
+         (*buffer_size) *= 2;
+         (*buffer) = (gchar *) realloc ((*buffer), *buffer_size);        
+       }
+
+      if (c != '"')
+        (*buffer)[cnt++] = c;
+      else
+        {
+          (*buffer)[cnt++] = 0;
+          return TRUE;
+        }
+    }
+
+  return FALSE;
+}
+
+gchar*
+gdk_pixmap_skip_whitespaces (gchar *buffer)
+{
+  gint32 index = 0;
+
+  while (buffer[index] != 0 && (buffer[index] == 0x20 || buffer[index] == 0x09))
+    index++;
+
+  return &buffer[index];
+}
+
+gchar*
+gdk_pixmap_skip_string (gchar *buffer)
+{
+  gint32 index = 0;
+
+  while (buffer[index] != 0 && buffer[index] != 0x20 && buffer[index] != 0x09)
+    index++;
+
+  return &buffer[index];
+}
+
+gchar*
+gdk_pixmap_extract_color (gchar *buffer)
+{
+  gint counter, finished = FALSE, numnames;
+  gchar *ptr = NULL, ch, temp[128];
+  gchar color[128], *retcol;
+
+  counter = 0;
+  while (ptr == NULL)
+    {
+      if (buffer[counter] == 'c')
+        {
+          ch = buffer[counter + 1];
+          if (ch == 0x20 || ch == 0x09)
+            ptr = &buffer[counter + 1];
+        }
+      else if (buffer[counter] == 0)
+        return NULL;
+
+      counter++;
+    }
+
+  if (ptr == NULL)
+    return NULL;
+
+  ptr = gdk_pixmap_skip_whitespaces (ptr);
+
+  if (ptr[0] == 0)
+    return NULL;
+  else if (ptr[0] == '#')
+    {
+      retcol = g_new(gchar, strlen (ptr) + 1);
+      strcpy (retcol, ptr);
+      return retcol;
+    }
+
+  color[0] = 0;
+  numnames = 0;
+
+  while (finished == FALSE)
+    {
+      sscanf (ptr, "%s", temp);
+
+      if ((gint)ptr[0] == 0 || strcmp ("s", temp) == 0 || strcmp ("m", temp) == 0 ||
+          strcmp ("g", temp) == 0 || strcmp ("g4", temp) == 0)
+       finished = TRUE;
+      else
+        {
+          if (numnames > 0)
+            strcat (color, " ");
+          strcat (color, temp);
+          ptr = gdk_pixmap_skip_string (ptr);
+          ptr = gdk_pixmap_skip_whitespaces (ptr);
+          numnames++;
+        }
+    }
+
+  retcol = g_new(gchar, strlen (color) + 1);
+  strcpy (retcol, color);
+  return retcol;
+}
+
+
+GdkPixmap*
+gdk_pixmap_create_from_xpm (GdkWindow  *window,
+                           GdkBitmap **mask,
+                           GdkColor   *transparent_color,
+                           const gchar *filename)
+{
+  FILE *infile = NULL;
+  GdkPixmap *pixmap = NULL;
+  GdkImage *image = NULL;
+  GdkColormap *colormap;
+  GdkVisual *visual;
+  GdkGC *gc;
+  GdkColor tmp_color;
+  gint width, height, num_cols, cpp, cnt, n, ns, xcnt, ycnt;
+  gchar *buffer = NULL, *color_name = NULL, pixel_str[32];
+  guint buffer_size = 0;
+  _GdkPixmapColor *colors = NULL, *color = NULL;
+  gulong index;
+
+  if (!window)
+    window = (GdkWindow*) &gdk_root_parent;
+
+  infile = fopen (filename, "rb");
+  if (infile != NULL)
+    {
+      if (gdk_pixmap_seek_string (infile, "XPM", FALSE) == TRUE)
+        {
+          if (gdk_pixmap_seek_char (infile,'{') == TRUE)
+            {
+              gdk_pixmap_seek_char (infile, '"');
+              fseek (infile, -1, SEEK_CUR);
+              gdk_pixmap_read_string (infile, &buffer, &buffer_size);
+
+              sscanf (buffer,"%d %d %d %d", &width, &height, &num_cols, &cpp);
+
+              colors = g_new(_GdkPixmapColor, num_cols);
+
+              colormap = gdk_window_get_colormap (window);
+              visual = gdk_window_get_visual (window);
+
+             if (transparent_color == NULL) 
+               {
+                 gdk_color_white (colormap, &tmp_color);
+                 transparent_color = &tmp_color;
+               }
+
+              for (cnt = 0; cnt < num_cols; cnt++)
+                {
+                  gdk_pixmap_seek_char (infile, '"');
+                  fseek (infile, -1, SEEK_CUR);
+                  gdk_pixmap_read_string (infile, &buffer, &buffer_size);
+
+                  colors[cnt].color_string = g_new(gchar, cpp + 1);
+                  for (n = 0; n < cpp; n++)
+                    colors[cnt].color_string[n] = buffer[n];
+                  colors[cnt].color_string[n] = 0;
+                 colors[cnt].transparent = FALSE;
+
+                  if (color_name != NULL)
+                    g_free (color_name);
+
+                  color_name = gdk_pixmap_extract_color (&buffer[cpp]);
+
+                  if (color_name != NULL)
+                    {
+                      if (gdk_color_parse (color_name, &colors[cnt].color) == FALSE)
+                       {
+                         colors[cnt].color = *transparent_color;
+                         colors[cnt].transparent = TRUE;
+                       }
+                    }
+                  else
+                   {
+                     colors[cnt].color = *transparent_color;
+                     colors[cnt].transparent = TRUE;
+                   }
+
+                  gdk_color_alloc (colormap, &colors[cnt].color);
+                }
+
+              index = 0;
+              image = gdk_image_new (GDK_IMAGE_FASTEST, visual, width, height);
+
+             gc = NULL;
+             if (mask)
+               {
+                 *mask = gdk_pixmap_new (window, width, height, 1);
+                 gc = gdk_gc_new (*mask);
+
+                 gdk_color_black (colormap, &tmp_color);
+                 gdk_gc_set_foreground (gc, &tmp_color);
+                 gdk_draw_rectangle (*mask, gc, TRUE, 0, 0, -1, -1);
+
+                 gdk_color_white (colormap, &tmp_color);
+                 gdk_gc_set_foreground (gc, &tmp_color);
+               }
+
+              for (ycnt = 0; ycnt < height; ycnt++)
+                {
+                  gdk_pixmap_read_string (infile, &buffer, &buffer_size);
+
+                  for (n = 0, cnt = 0, xcnt = 0; n < (width * cpp); n += cpp, xcnt++)
+                    {
+                      strncpy (pixel_str, &buffer[n], cpp);
+                      pixel_str[cpp] = 0;
+                      color = NULL;
+                      ns = 0;
+
+                      while (color == NULL)
+                        {
+                          if (strcmp (pixel_str, colors[ns].color_string) == 0)
+                            color = &colors[ns];
+                          else
+                            ns++;
+                        }
+
+                      gdk_image_put_pixel (image, xcnt, ycnt, color->color.pixel);
+
+                     if (mask && color->transparent)
+                       {
+                         if (cnt < xcnt)
+                           gdk_draw_line (*mask, gc, cnt, ycnt, xcnt - 1, ycnt);
+                         cnt = xcnt + 1;
+                       }
+                    }
+
+                 if (mask && (cnt < xcnt))
+                   gdk_draw_line (*mask, gc, cnt, ycnt, xcnt - 1, ycnt);
+                }
+
+             if (mask)
+               gdk_gc_destroy (gc);
+
+              pixmap = gdk_pixmap_new (window, width, height, visual->depth);
+
+              gc = gdk_gc_new (pixmap);
+              gdk_gc_set_foreground (gc, transparent_color);
+              gdk_draw_image (pixmap, gc, image, 0, 0, 0, 0, image->width, image->height);
+              gdk_gc_destroy (gc);
+              gdk_image_destroy (image);
+            }
+        }
+
+      fclose (infile);
+      free (buffer);
+
+      if (colors != NULL)
+        {
+          for (cnt = 0; cnt < num_cols; cnt++)
+            g_free (colors[cnt].color_string);
+          g_free (colors);
+        }
+    }
+
+  return pixmap;
+}
+
+GdkPixmap*
+gdk_pixmap_create_from_xpm_d (GdkWindow  *window,
+                             GdkBitmap **mask,
+                             GdkColor   *transparent_color,
+                             gchar     **data)
+{
+  GdkPixmap *pixmap = NULL;
+  GdkImage *image = NULL;
+  GdkColormap *colormap;
+  GdkVisual *visual;
+  GdkGC *gc;
+  GdkColor tmp_color;
+  gint width, height, num_cols, cpp, cnt, n, ns, xcnt, ycnt, i;
+  gchar *buffer, *color_name = NULL, pixel_str[32];
+  _GdkPixmapColor *colors = NULL, *color = NULL;
+  gulong index;
+
+  if (!window)
+    window = (GdkWindow*) &gdk_root_parent;
+
+  i = 0;
+  buffer = data[i++];
+  sscanf (buffer,"%d %d %d %d", &width, &height, &num_cols, &cpp);
+
+  colors = g_new(_GdkPixmapColor, num_cols);
+
+  colormap = gdk_window_get_colormap (window);
+  visual = gdk_window_get_visual (window);
+
+  if (transparent_color == NULL) 
+    {
+      gdk_color_white (colormap, &tmp_color);
+      transparent_color = &tmp_color;
+    }
+
+  for (cnt = 0; cnt < num_cols; cnt++)
+    {
+      buffer = data[i++];
+
+      colors[cnt].color_string = g_new(gchar, cpp + 1);
+      for (n = 0; n < cpp; n++)
+       colors[cnt].color_string[n] = buffer[n];
+      colors[cnt].color_string[n] = 0;
+      colors[cnt].transparent = FALSE;
+
+      if (color_name != NULL)
+       g_free (color_name);
+
+      color_name = gdk_pixmap_extract_color (&buffer[cpp]);
+
+      if (color_name != NULL)
+       {
+         if (gdk_color_parse (color_name, &colors[cnt].color) == FALSE)
+           {
+             colors[cnt].color = *transparent_color;
+             colors[cnt].transparent = TRUE;
+           }
+       }
+      else
+       {
+         colors[cnt].color = *transparent_color;
+         colors[cnt].transparent = TRUE;
+       }
+
+      gdk_color_alloc (colormap, &colors[cnt].color);
+    }
+
+  index = 0;
+  image = gdk_image_new (GDK_IMAGE_FASTEST, visual, width, height);
+
+  gc = NULL;
+  if (mask)
+    {
+      *mask = gdk_pixmap_new (window, width, height, 1);
+      gc = gdk_gc_new (*mask);
+
+      gdk_color_black (colormap, &tmp_color);
+      gdk_gc_set_foreground (gc, &tmp_color);
+      gdk_draw_rectangle (*mask, gc, TRUE, 0, 0, -1, -1);
+
+      gdk_color_white (colormap, &tmp_color);
+      gdk_gc_set_foreground (gc, &tmp_color);
+    }
+
+  for (ycnt = 0; ycnt < height; ycnt++)
+    {
+      buffer = data[i++];
+
+      for (n = 0, cnt = 0, xcnt = 0; n < (width * cpp); n += cpp, xcnt++)
+       {
+         strncpy (pixel_str, &buffer[n], cpp);
+         pixel_str[cpp] = 0;
+         color = NULL;
+         ns = 0;
+
+         while (color == NULL)
+           {
+             if (strcmp (pixel_str, colors[ns].color_string) == 0)
+               color = &colors[ns];
+             else
+               ns++;
+           }
+
+         gdk_image_put_pixel (image, xcnt, ycnt, color->color.pixel);
+
+         if (mask && color->transparent)
+           {
+             if (cnt < xcnt)
+               gdk_draw_line (*mask, gc, cnt, ycnt, xcnt - 1, ycnt);
+             cnt = xcnt + 1;
+           }
+       }
+
+      if (mask && (cnt < xcnt))
+       gdk_draw_line (*mask, gc, cnt, ycnt, xcnt - 1, ycnt);
+    }
+
+  if (mask)
+    gdk_gc_destroy (gc);
+
+  pixmap = gdk_pixmap_new (window, width, height, visual->depth);
+
+  gc = gdk_gc_new (pixmap);
+  gdk_gc_set_foreground (gc, transparent_color);
+  gdk_draw_image (pixmap, gc, image, 0, 0, 0, 0, image->width, image->height);
+  gdk_gc_destroy (gc);
+  gdk_image_destroy (image);
+
+  if (colors != NULL)
+    {
+      for (cnt = 0; cnt < num_cols; cnt++)
+       g_free (colors[cnt].color_string);
+      g_free (colors);
+    }
+
+  return pixmap;
+}
+
+void
+gdk_pixmap_destroy (GdkPixmap *pixmap)
+{
+  GdkWindowPrivate *private;
+
+  g_return_if_fail (pixmap != NULL);
+
+  private = (GdkPixmapPrivate*) pixmap;
+  if (private->ref_count <= 0)
+    {
+      XFreePixmap (private->xdisplay, private->xwindow);
+      gdk_xid_table_remove (private->xwindow);
+      g_free (pixmap);
+    }
+  else
+    {
+      private->ref_count -= 1;
+    }
+}
diff --git a/gdk/x11/gdkproperty-x11.c b/gdk/x11/gdkproperty-x11.c
new file mode 100644 (file)
index 0000000..35d8a50
--- /dev/null
@@ -0,0 +1,194 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <string.h>
+#include "gdk.h"
+#include "gdkprivate.h"
+
+
+GdkAtom
+gdk_atom_intern (const gchar *atom_name,
+                gint         only_if_exists)
+{
+  return XInternAtom (gdk_display, atom_name, only_if_exists);
+}
+
+gchar *
+gdk_atom_name (GdkAtom atom)
+{
+  gchar *t;
+  gchar *name;
+
+  /* If this atom doesn't exist, we'll die with an X error unless
+     we take precautions */
+
+  gdk_error_warnings = 0;
+  t = XGetAtomName (gdk_display, atom);
+  gdk_error_warnings = 1;
+
+  if (gdk_error_code == -1)
+    {
+      return NULL;
+    }
+  else
+    {
+      name = g_strdup (t);
+      XFree (t);
+      
+      return name;
+    }
+}
+
+gint
+gdk_property_get (GdkWindow   *window,
+                 GdkAtom      property,
+                 GdkAtom      type,
+                 gulong       offset,
+                 gulong       length,
+                 gint         pdelete,
+                 GdkAtom     *actual_property_type,
+                 gint        *actual_format_type,
+                 gint        *actual_length,
+                 guchar     **data)
+{
+  GdkWindowPrivate *private;
+  Display *xdisplay;
+  Window xwindow;
+  Atom ret_prop_type;
+  gint ret_format;
+  gulong ret_nitems;
+  gulong ret_bytes_after;
+  gulong ret_length;
+  guchar *ret_data;
+
+  if (window)
+    {
+      private = (GdkWindowPrivate*) window;
+      xdisplay = private->xdisplay;
+      xwindow = private->xwindow;
+    }
+  else
+    {
+      xdisplay = gdk_display;
+      xwindow = gdk_root_window;
+    }
+
+  XGetWindowProperty (xdisplay, xwindow, property,
+                     offset, (length + 3) / 4, pdelete,
+                     type, &ret_prop_type, &ret_format,
+                     &ret_nitems, &ret_bytes_after,
+                     &ret_data);
+
+  if ((ret_prop_type == None) && (ret_format == 0))
+    return FALSE;
+
+  if (actual_property_type)
+    *actual_property_type = ret_prop_type;
+  if (actual_format_type)
+    *actual_format_type = ret_format;
+
+  if (ret_prop_type != property)
+    {
+      XFree (ret_data);
+      return FALSE;
+    }
+
+  /* FIXME: ignoring bytes_after could have very bad effects */
+
+  if (data)
+    {
+      switch (ret_format)
+       {
+       case 8:
+         ret_length = ret_nitems;
+         break;
+       case 16:
+         ret_length = 2 * ret_nitems;
+         break;
+       case 32:
+         ret_length = 4 * ret_nitems;
+         break;
+       default:
+         g_warning ("unknown property return format: %d", ret_format);
+         XFree (ret_data);
+         return FALSE;
+       }
+
+      *data = g_new (guchar, ret_length);
+      memcpy (*data, ret_data, ret_length);
+      if (actual_length)
+       *actual_length = ret_length;
+    }
+
+  XFree (ret_data);
+
+  return TRUE;
+}
+
+void
+gdk_property_change (GdkWindow   *window,
+                    GdkAtom      property,
+                    GdkAtom      type,
+                    gint         format,
+                    GdkPropMode  mode,
+                    guchar      *data,
+                    gint         nelements)
+{
+  GdkWindowPrivate *private;
+  Display *xdisplay;
+  Window xwindow;
+
+  if (window)
+    {
+      private = (GdkWindowPrivate*) window;
+      xdisplay = private->xdisplay;
+      xwindow = private->xwindow;
+    }
+  else
+    {
+      xdisplay = gdk_display;
+      xwindow = gdk_root_window;
+    }
+
+  XChangeProperty (xdisplay, xwindow, property, type,
+                  format, mode, data, nelements);
+}
+
+void
+gdk_property_delete (GdkWindow *window,
+                    GdkAtom    property)
+{
+  GdkWindowPrivate *private;
+  Display *xdisplay;
+  Window xwindow;
+
+  if (window)
+    {
+      private = (GdkWindowPrivate*) window;
+      xdisplay = private->xdisplay;
+      xwindow = private->xwindow;
+    }
+  else
+    {
+      xdisplay = gdk_display;
+      xwindow = gdk_root_window;
+    }
+
+  XDeleteProperty (xdisplay, xwindow, property);
+}
diff --git a/gdk/x11/gdkselection-x11.c b/gdk/x11/gdkselection-x11.c
new file mode 100644 (file)
index 0000000..6bd4251
--- /dev/null
@@ -0,0 +1,168 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <string.h>
+#include "gdk.h"
+#include "gdkprivate.h"
+
+
+gint
+gdk_selection_owner_set (GdkWindow *owner,
+                        GdkAtom    selection,
+                        guint32    time,
+                        gint       send_event)
+{
+  GdkWindowPrivate *private;
+  Display *xdisplay;
+  Window xwindow;
+
+  if (owner)
+    {
+      private = (GdkWindowPrivate*) owner;
+      xdisplay = private->xdisplay;
+      xwindow = private->xwindow;
+    }
+  else
+    {
+      xdisplay = gdk_display;
+      xwindow = None;
+    }
+
+  XSetSelectionOwner (xdisplay, selection, xwindow, time);
+
+  return (XGetSelectionOwner (xdisplay, selection) == xwindow);
+}
+
+GdkWindow*
+gdk_selection_owner_get (GdkAtom selection)
+{
+  Window xwindow;
+
+  xwindow = XGetSelectionOwner (gdk_display, selection);
+  if (xwindow == None)
+    return NULL;
+
+  return gdk_window_lookup (xwindow);
+}
+
+void
+gdk_selection_convert (GdkWindow *requestor,
+                      GdkAtom    selection,
+                      GdkAtom    target,
+                      guint32    time)
+{
+  GdkWindowPrivate *private;
+
+  g_return_if_fail (requestor != NULL);
+
+  private = (GdkWindowPrivate*) requestor;
+
+  XConvertSelection (private->xdisplay, selection, target,
+                    gdk_selection_property, private->xwindow, time);
+}
+
+gint
+gdk_selection_property_get (GdkWindow  *requestor,
+                           guchar    **data,
+                           GdkAtom    *ret_type,
+                           gint       *ret_format)
+{
+  GdkWindowPrivate *private;
+  gulong nitems;
+  gulong nbytes;
+  gulong length;
+  GdkAtom prop_type;
+  gint prop_format;
+  guchar *t;
+
+  g_return_val_if_fail (requestor != NULL, 0);
+
+  /* If retrieved chunks are typically small, (and the ICCM says the
+     should be) it would be a win to try first with a buffer of
+     moderate length, to avoid two round trips to the server */
+
+  private = (GdkWindowPrivate*) requestor;
+
+  XGetWindowProperty (private->xdisplay, private->xwindow,
+                     gdk_selection_property, 0, 0, False,
+                     AnyPropertyType, &prop_type, &prop_format,
+                     &nitems, &nbytes, &t);
+
+  if (ret_type)
+    *ret_type = prop_type;
+  if (ret_format)
+    *ret_format = prop_format;
+
+  if (prop_type == None)
+    {
+      *data = NULL;
+      return 0;
+    }
+    
+  XFree (t);
+
+  /* Add on an extra byte to handle null termination.  X guarantees
+     that t will be 1 longer than nbytes and null terminated */
+  length = nbytes + 1;
+
+  /* We can't delete the selection here, because it might be the INCR
+     protocol, in which case the client has to make sure they'll be
+     notified of PropertyChange events _before_ the property is deleted.
+     Otherwise there's no guarantee we'll win the race ... */
+  XGetWindowProperty (private->xdisplay, private->xwindow,
+                     gdk_selection_property, 0, (nbytes + 3) / 4, False,
+                     AnyPropertyType, &prop_type, &prop_format,
+                     &nitems, &nbytes, &t);
+
+  if (prop_type != None)
+    {
+      *data = g_new (guchar, length);
+      memcpy (*data, t, length);
+      XFree (t);
+      return length-1;
+    }
+  else
+    {
+      *data = NULL;
+      return 0;
+    }
+}
+
+
+void
+gdk_selection_send_notify (guint32  requestor,
+                          GdkAtom  selection,
+                          GdkAtom  target,
+                          GdkAtom  property,
+                          guint32  time)
+{
+  XSelectionEvent xevent;
+
+  xevent.type = SelectionNotify;
+  xevent.serial = 0;
+  xevent.send_event = True;
+  xevent.display = gdk_display;
+  xevent.requestor = requestor;
+  xevent.selection = selection;
+  xevent.target = target;
+  xevent.property = property;
+  xevent.time = time;
+
+  XSendEvent (gdk_display, requestor, False, NoEventMask, (XEvent*) &xevent);
+}
diff --git a/gdk/x11/gdkvisual-x11.c b/gdk/x11/gdkvisual-x11.c
new file mode 100644 (file)
index 0000000..22acee6
--- /dev/null
@@ -0,0 +1,431 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include "gdk.h"
+#include "gdkprivate.h"
+
+
+static void  gdk_visual_add            (GdkVisual *visual);
+static void  gdk_visual_decompose_mask (gulong     mask,
+                                       gint      *shift,
+                                       gint      *prec);
+static guint gdk_visual_hash           (Visual    *key);
+static gint  gdk_visual_compare        (Visual    *a,
+                                       Visual    *b);
+
+
+static GdkVisualPrivate *system_visual;
+static GdkVisualPrivate *visuals;
+static gint nvisuals;
+
+static gint available_depths[4];
+static gint navailable_depths;
+
+static GdkVisualType available_types[6];
+static gint navailable_types;
+
+static char* visual_names[] =
+{
+  "static gray",
+  "grayscale",
+  "static color",
+  "pseudo color",
+  "true color",
+  "direct color",
+};
+
+static GHashTable *visual_hash = NULL;
+
+void
+gdk_visual_init ()
+{
+  static gint possible_depths[5] = { 32, 24, 16, 15, 8 };
+  static GdkVisualType possible_types[6] =
+    {
+      GDK_VISUAL_DIRECT_COLOR,
+      GDK_VISUAL_TRUE_COLOR,
+      GDK_VISUAL_PSEUDO_COLOR,
+      GDK_VISUAL_STATIC_COLOR,
+      GDK_VISUAL_GRAYSCALE,
+      GDK_VISUAL_STATIC_GRAY
+    };
+
+  static gint npossible_depths = 5;
+  static gint npossible_types = 6;
+
+  XVisualInfo *visual_list;
+  XVisualInfo visual_template;
+  GdkVisualPrivate temp_visual;
+  Visual *default_xvisual;
+  int nxvisuals;
+  int i, j;
+
+  visual_template.screen = gdk_screen;
+  visual_list = XGetVisualInfo (gdk_display, VisualScreenMask, &visual_template, &nxvisuals);
+  visuals = g_new (GdkVisualPrivate, nxvisuals);
+
+  default_xvisual = DefaultVisual (gdk_display, gdk_screen);
+
+  nvisuals = 0;
+  for (i = 0; i < nxvisuals; i++)
+    {
+      if (visual_list[i].depth >= 8)
+       {
+#ifdef __cplusplus
+         switch (visual_list[i].c_class)
+#else /* __cplusplus */
+         switch (visual_list[i].class)
+#endif /* __cplusplus */
+           {
+           case StaticGray:
+             visuals[nvisuals].visual.type = GDK_VISUAL_STATIC_GRAY;
+             break;
+           case GrayScale:
+             visuals[nvisuals].visual.type = GDK_VISUAL_GRAYSCALE;
+             break;
+           case StaticColor:
+             visuals[nvisuals].visual.type = GDK_VISUAL_STATIC_COLOR;
+             break;
+           case PseudoColor:
+             visuals[nvisuals].visual.type = GDK_VISUAL_PSEUDO_COLOR;
+             break;
+           case TrueColor:
+             visuals[nvisuals].visual.type = GDK_VISUAL_TRUE_COLOR;
+             break;
+           case DirectColor:
+             visuals[nvisuals].visual.type = GDK_VISUAL_DIRECT_COLOR;
+             break;
+           }
+
+         visuals[nvisuals].visual.depth = visual_list[i].depth;
+         visuals[nvisuals].visual.byte_order =
+           (ImageByteOrder(gdk_display) == LSBFirst) ?
+           GDK_LSB_FIRST : GDK_MSB_FIRST;
+         visuals[nvisuals].visual.red_mask = visual_list[i].red_mask;
+         visuals[nvisuals].visual.green_mask = visual_list[i].green_mask;
+         visuals[nvisuals].visual.blue_mask = visual_list[i].blue_mask;
+         visuals[nvisuals].visual.colormap_size = visual_list[i].colormap_size;
+         visuals[nvisuals].visual.bits_per_rgb = visual_list[i].bits_per_rgb;
+         visuals[nvisuals].xvisual = visual_list[i].visual;
+
+         if ((visuals[nvisuals].visual.type == GDK_VISUAL_TRUE_COLOR) ||
+             (visuals[nvisuals].visual.type == GDK_VISUAL_DIRECT_COLOR))
+           {
+             gdk_visual_decompose_mask (visuals[nvisuals].visual.red_mask,
+                                        &visuals[nvisuals].visual.red_shift,
+                                        &visuals[nvisuals].visual.red_prec);
+
+             gdk_visual_decompose_mask (visuals[nvisuals].visual.green_mask,
+                                        &visuals[nvisuals].visual.green_shift,
+                                        &visuals[nvisuals].visual.green_prec);
+
+             gdk_visual_decompose_mask (visuals[nvisuals].visual.blue_mask,
+                                        &visuals[nvisuals].visual.blue_shift,
+                                        &visuals[nvisuals].visual.blue_prec);
+           }
+         else
+           {
+             visuals[nvisuals].visual.red_mask = 0;
+             visuals[nvisuals].visual.red_shift = 0;
+             visuals[nvisuals].visual.red_prec = 0;
+
+             visuals[nvisuals].visual.green_mask = 0;
+             visuals[nvisuals].visual.green_shift = 0;
+             visuals[nvisuals].visual.green_prec = 0;
+
+             visuals[nvisuals].visual.blue_mask = 0;
+             visuals[nvisuals].visual.blue_shift = 0;
+             visuals[nvisuals].visual.blue_prec = 0;
+           }
+
+         nvisuals += 1;
+       }
+    }
+
+  XFree (visual_list);
+
+  for (i = 0; i < nvisuals; i++)
+    {
+      for (j = i+1; j < nvisuals; j++)
+       {
+         if (visuals[j].visual.depth >= visuals[i].visual.depth)
+           {
+             if ((visuals[j].visual.depth == 8) && (visuals[i].visual.depth == 8))
+               {
+                 if (visuals[j].visual.type == GDK_VISUAL_PSEUDO_COLOR)
+                   {
+                     temp_visual = visuals[j];
+                     visuals[j] = visuals[i];
+                     visuals[i] = temp_visual;
+                   }
+                 else if ((visuals[i].visual.type != GDK_VISUAL_PSEUDO_COLOR) &&
+                          visuals[j].visual.type > visuals[i].visual.type)
+                   {
+                     temp_visual = visuals[j];
+                     visuals[j] = visuals[i];
+                     visuals[i] = temp_visual;
+                   }
+               }
+             else if ((visuals[j].visual.depth > visuals[i].visual.depth) ||
+                      ((visuals[j].visual.depth == visuals[i].visual.depth) &&
+                       (visuals[j].visual.type > visuals[i].visual.type)))
+               {
+                 temp_visual = visuals[j];
+                 visuals[j] = visuals[i];
+                 visuals[i] = temp_visual;
+               }
+           }
+       }
+    }
+
+  for (i = 0; i < nvisuals; i++)
+    if (default_xvisual->visualid == visuals[i].xvisual->visualid)
+      {
+       system_visual = &visuals[i];
+       break;
+      }
+
+  if (gdk_debug_level >= 1)
+    for (i = 0; i < nvisuals; i++)
+      g_print ("visual: %s: %d\n",
+              visual_names[visuals[i].visual.type],
+              visuals[i].visual.depth);
+
+  navailable_depths = 0;
+  for (i = 0; i < npossible_depths; i++)
+    {
+      for (j = 0; j < nvisuals; j++)
+       {
+         if (visuals[j].visual.depth == possible_depths[i])
+           {
+             available_depths[navailable_depths++] = visuals[j].visual.depth;
+             break;
+           }
+       }
+    }
+
+  if (navailable_depths == 0)
+    g_error ("unable to find a usable depth");
+
+  navailable_types = 0;
+  for (i = 0; i < npossible_types; i++)
+    {
+      for (j = 0; j < nvisuals; j++)
+       {
+         if (visuals[j].visual.type == possible_types[i])
+           {
+             available_types[navailable_types++] = visuals[j].visual.type;
+             break;
+           }
+       }
+    }
+
+  for (i = 0; i < nvisuals; i++)
+    gdk_visual_add ((GdkVisual*) &visuals[i]);
+
+  if (npossible_types == 0)
+    g_error ("unable to find a usable visual type");
+}
+
+GdkVisual*
+gdk_visual_ref (GdkVisual *visual)
+{
+  return visual;
+}
+
+void
+gdk_visual_unref (GdkVisual *visual)
+{
+  return;
+}
+
+gint
+gdk_visual_get_best_depth ()
+{
+  return available_depths[0];
+}
+
+GdkVisualType
+gdk_visual_get_best_type ()
+{
+  return available_types[0];
+}
+
+GdkVisual*
+gdk_visual_get_system ()
+{
+  return ((GdkVisual*) system_visual);
+}
+
+GdkVisual*
+gdk_visual_get_best ()
+{
+  return ((GdkVisual*) &(visuals[0]));
+}
+
+GdkVisual*
+gdk_visual_get_best_with_depth (gint depth)
+{
+  GdkVisual *return_val;
+  int i;
+
+  return_val = NULL;
+  for (i = 0; i < nvisuals; i++)
+    if (depth == visuals[i].visual.depth)
+      {
+       return_val = (GdkVisual*) &(visuals[i]);
+       break;
+      }
+
+  return return_val;
+}
+
+GdkVisual*
+gdk_visual_get_best_with_type (GdkVisualType visual_type)
+{
+  GdkVisual *return_val;
+  int i;
+
+  return_val = NULL;
+  for (i = 0; i < nvisuals; i++)
+    if (visual_type == visuals[i].visual.type)
+      {
+       return_val = (GdkVisual*) &(visuals[i]);
+       break;
+      }
+
+  return return_val;
+}
+
+GdkVisual*
+gdk_visual_get_best_with_both (gint          depth,
+                              GdkVisualType visual_type)
+{
+  GdkVisual *return_val;
+  int i;
+
+  return_val = NULL;
+  for (i = 0; i < nvisuals; i++)
+    if ((depth == visuals[i].visual.depth) &&
+       (visual_type == visuals[i].visual.type))
+      {
+       return_val = (GdkVisual*) &(visuals[i]);
+       break;
+      }
+
+  return return_val;
+}
+
+void
+gdk_query_depths  (gint **depths,
+                  gint  *count)
+{
+  *count = navailable_depths;
+  *depths = available_depths;
+}
+
+void
+gdk_query_visual_types (GdkVisualType **visual_types,
+                       gint           *count)
+{
+  *count = navailable_types;
+  *visual_types = available_types;
+}
+
+void
+gdk_query_visuals (GdkVisual **visual_return,
+                  gint       *count)
+{
+  *count = nvisuals;
+  *visual_return = (GdkVisual*) visuals;
+}
+
+
+GdkVisual*
+gdk_visual_lookup (Visual *xvisual)
+{
+  GdkVisual *visual;
+
+  if (!visual_hash)
+    return NULL;
+
+  visual = g_hash_table_lookup (visual_hash, xvisual);
+  return visual;
+}
+
+GdkVisual*
+gdkx_visual_get (VisualID xvisualid)
+{
+  int i;
+
+  for (i = 0; i < nvisuals; i++)
+    if (xvisualid == visuals[i].xvisual->visualid)
+      return (GdkVisual*) &visuals[i];
+
+  return NULL;
+}
+
+
+static void
+gdk_visual_add (GdkVisual *visual)
+{
+  GdkVisualPrivate *private;
+
+  if (!visual_hash)
+    visual_hash = g_hash_table_new ((GHashFunc) gdk_visual_hash,
+                                   (GCompareFunc) gdk_visual_compare);
+
+  private = (GdkVisualPrivate*) visual;
+
+  g_hash_table_insert (visual_hash, private->xvisual, visual);
+}
+
+static void
+gdk_visual_decompose_mask (gulong  mask,
+                          gint   *shift,
+                          gint   *prec)
+{
+  *shift = 0;
+  *prec = 0;
+
+  while (!(mask & 0x1))
+    {
+      (*shift)++;
+      mask >>= 1;
+    }
+
+  while (mask & 0x1)
+    {
+      (*prec)++;
+      mask >>= 1;
+    }
+}
+
+static guint
+gdk_visual_hash (Visual *key)
+{
+  return key->visualid;
+}
+
+static gint
+gdk_visual_compare (Visual *a,
+                   Visual *b)
+{
+  return (a->visualid == b->visualid);
+}
diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c
new file mode 100644 (file)
index 0000000..aef1367
--- /dev/null
@@ -0,0 +1,1358 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <X11/extensions/shape.h>
+#include <netinet/in.h>
+#include "gdk.h"
+#include "gdkinput.h"
+#include "gdkprivate.h"
+#include <stdlib.h>
+
+int nevent_masks = 16;
+int event_mask_table[18] =
+{
+  ExposureMask,
+  PointerMotionMask,
+  PointerMotionHintMask,
+  ButtonMotionMask,
+  Button1MotionMask,
+  Button2MotionMask,
+  Button3MotionMask,
+  ButtonPressMask | OwnerGrabButtonMask,
+  ButtonReleaseMask | OwnerGrabButtonMask,
+  KeyPressMask,
+  KeyReleaseMask,
+  EnterWindowMask,
+  LeaveWindowMask,
+  FocusChangeMask,
+  StructureNotifyMask,
+  PropertyChangeMask,
+  0,                           /* PROXIMITY_IN */
+  0                            /* PROXIMTY_OUT */
+};
+
+
+void
+gdk_window_init ()
+{
+  XWindowAttributes xattributes;
+  unsigned int width;
+  unsigned int height;
+  unsigned int border_width;
+  unsigned int depth;
+  int x, y;
+
+  XGetGeometry (gdk_display, gdk_root_window, &gdk_root_window,
+               &x, &y, &width, &height, &border_width, &depth);
+  XGetWindowAttributes (gdk_display, gdk_root_window, &xattributes);
+
+  gdk_root_parent.xdisplay = gdk_display;
+  gdk_root_parent.xwindow = gdk_root_window;
+  gdk_root_parent.window_type = GDK_WINDOW_ROOT;
+  gdk_root_parent.window.user_data = NULL;
+}
+
+GdkWindow*
+gdk_window_new (GdkWindow     *parent,
+               GdkWindowAttr *attributes,
+               gint           attributes_mask)
+{
+  GdkWindow *window;
+  GdkWindowPrivate *private;
+  GdkWindowPrivate *parent_private;
+  GdkVisual *visual;
+  GdkColormap *colormap;
+  Display *parent_display;
+  Window xparent;
+  Visual *xvisual;
+  XSetWindowAttributes xattributes;
+  long xattributes_mask;
+  XSizeHints size_hints;
+  XWMHints wm_hints;
+  XTextProperty text_property;
+  XClassHint *class_hint;
+  int x, y, depth;
+  unsigned int class;
+  char *title;
+  int i;
+
+  g_return_val_if_fail (attributes != NULL, NULL);
+
+  if (!parent)
+    parent = (GdkWindow*) &gdk_root_parent;
+
+  parent_private = (GdkWindowPrivate*) parent;
+  xparent = parent_private->xwindow;
+  parent_display = parent_private->xdisplay;
+
+  private = g_new (GdkWindowPrivate, 1);
+  window = (GdkWindow*) private;
+
+  private->parent = parent;
+  private->xdisplay = parent_display;
+  private->destroyed = FALSE;
+  private->resize_count = 0;
+  private->ref_count = 1;
+  xattributes_mask = 0;
+
+  if (attributes_mask & GDK_WA_X)
+    x = attributes->x;
+  else
+    x = 0;
+
+  if (attributes_mask & GDK_WA_Y)
+    y = attributes->y;
+  else
+    y = 0;
+
+  private->x = x;
+  private->y = y;
+  private->width = (attributes->width > 1) ? (attributes->width) : (1);
+  private->height = (attributes->height > 1) ? (attributes->height) : (1);
+  private->window_type = attributes->window_type;
+  private->extension_events = FALSE;
+  private->dnd_drag_data_type = None;
+  private->dnd_drag_data_typesavail =
+    private->dnd_drop_data_typesavail = NULL;
+  private->dnd_drop_enabled = private->dnd_drag_enabled =
+    private->dnd_drag_accepted = private->dnd_drag_datashow =
+    private->dnd_drop_data_numtypesavail =
+    private->dnd_drag_data_numtypesavail = 0;
+  private->dnd_drag_eventmask = private->dnd_drag_savedeventmask = 0;
+
+  window->user_data = NULL;
+
+  if (attributes_mask & GDK_WA_VISUAL)
+    visual = attributes->visual;
+  else
+    visual = gdk_visual_get_system ();
+  xvisual = ((GdkVisualPrivate*) visual)->xvisual;
+
+  xattributes.event_mask = StructureNotifyMask;
+  for (i = 0; i < nevent_masks; i++)
+    {
+      if (attributes->event_mask & (1 << (i + 1)))
+       xattributes.event_mask |= event_mask_table[i];
+    }
+
+  if (xattributes.event_mask)
+    xattributes_mask |= CWEventMask;
+
+  if (attributes->wclass == GDK_INPUT_OUTPUT)
+    {
+      class = InputOutput;
+      depth = visual->depth;
+
+      if (attributes_mask & GDK_WA_COLORMAP)
+       colormap = attributes->colormap;
+      else
+       colormap = gdk_colormap_get_system ();
+
+      xattributes.background_pixel = BlackPixel (gdk_display, gdk_screen);
+      xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);
+      xattributes_mask |= CWBorderPixel | CWBackPixel;
+
+      switch (private->window_type)
+       {
+       case GDK_WINDOW_TOPLEVEL:
+         xattributes.colormap = ((GdkColormapPrivate*) colormap)->xcolormap;
+         xattributes_mask |= CWColormap;
+
+         xparent = gdk_root_window;
+         break;
+
+       case GDK_WINDOW_CHILD:
+         xattributes.colormap = ((GdkColormapPrivate*) colormap)->xcolormap;
+         xattributes_mask |= CWColormap;
+         break;
+
+       case GDK_WINDOW_DIALOG:
+         xattributes.colormap = ((GdkColormapPrivate*) colormap)->xcolormap;
+         xattributes_mask |= CWColormap;
+
+         xparent = gdk_root_window;
+         break;
+
+       case GDK_WINDOW_TEMP:
+         xattributes.colormap = ((GdkColormapPrivate*) colormap)->xcolormap;
+         xattributes_mask |= CWColormap;
+
+         xparent = gdk_root_window;
+
+         xattributes.save_under = True;
+         xattributes.override_redirect = True;
+         xattributes.cursor = None;
+         xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
+         break;
+       case GDK_WINDOW_ROOT:
+         g_error ("cannot make windows of type GDK_WINDOW_ROOT");
+         break;
+       case GDK_WINDOW_PIXMAP:
+         g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
+         break;
+       }
+    }
+  else
+    {
+      depth = 1;
+      class = InputOnly;
+      colormap = NULL;
+    }
+
+  private->xwindow = XCreateWindow (private->xdisplay, xparent,
+                                   x, y, private->width, private->height,
+                                   0, depth, class, xvisual,
+                                   xattributes_mask, &xattributes);
+  gdk_xid_table_insert (&private->xwindow, window);
+
+  switch (private->window_type)
+    {
+    case GDK_WINDOW_DIALOG:
+      XSetTransientForHint (private->xdisplay, private->xwindow, xparent);
+    case GDK_WINDOW_TOPLEVEL:
+    case GDK_WINDOW_TEMP:
+      XSetWMProtocols (private->xdisplay, private->xwindow, gdk_wm_window_protocols, 2);
+      break;
+    case GDK_WINDOW_CHILD:
+      if ((attributes->wclass == GDK_INPUT_OUTPUT) &&
+         (colormap != gdk_colormap_get_system ()) &&
+         (colormap != gdk_window_get_colormap (gdk_window_get_toplevel (window))))
+       {
+         g_print ("adding colormap window\n");
+         gdk_window_add_colormap_windows (window);
+       }
+      break;
+    default:
+      break;
+    }
+
+  size_hints.flags = PSize | PBaseSize;
+  size_hints.width = private->width;
+  size_hints.height = private->height;
+  size_hints.base_width = private->width;
+  size_hints.base_height = private->height;
+
+  wm_hints.flags = InputHint | StateHint | WindowGroupHint;
+  wm_hints.window_group = gdk_leader_window;
+  wm_hints.input = True;
+  wm_hints.initial_state = NormalState;
+
+  XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
+  XSetWMHints (private->xdisplay, private->xwindow, &wm_hints);
+
+  if (attributes_mask & GDK_WA_TITLE)
+    title = attributes->title;
+  else
+    title = gdk_progname;
+
+  if (XStringListToTextProperty (&title, 1, &text_property))
+    {
+      XSetWMName (private->xdisplay, private->xwindow, &text_property);
+      XSetWMIconName (private->xdisplay, private->xwindow, &text_property);
+      XFree (text_property.value);
+    }
+
+  if (attributes_mask & GDK_WA_WMCLASS)
+    {
+      class_hint = XAllocClassHint ();
+      class_hint->res_name = attributes->wmclass_name;
+      class_hint->res_class = attributes->wmclass_class;
+      XSetClassHint (private->xdisplay, private->xwindow, class_hint);
+      XFree (class_hint);
+    }
+
+  gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
+                                 (attributes->cursor) :
+                                 NULL));
+
+  return window;
+}
+
+GdkWindow *
+gdk_window_foreign_new (guint32 anid)
+{
+  GdkWindow *window;
+  GdkWindowPrivate *private;
+  XWindowAttributes attrs;
+
+  private = g_new (GdkWindowPrivate, 1);
+  window = (GdkWindow*) private;
+
+  XGetWindowAttributes (gdk_display, anid, &attrs);
+
+  private->parent = NULL;
+  private->xwindow = anid;
+  private->xdisplay = gdk_display;
+  private->x = attrs.x;
+  private->y = attrs.y;
+  private->width = attrs.width;
+  private->height = attrs.height;
+  private->resize_count = 0;
+  private->ref_count = 1;
+  if (anid == attrs.root)
+    private->window_type = GDK_WINDOW_ROOT;
+  else
+    private->window_type = GDK_WINDOW_TOPLEVEL;
+  /* the above is probably wrong, but it may not be worth the extra
+     X call to get it right */
+    
+  private->destroyed = FALSE;
+  private->extension_events = 0;
+
+  window->user_data = NULL;
+
+  gdk_xid_table_insert (&private->xwindow, window);
+
+  return window;
+}
+
+void
+gdk_window_destroy (GdkWindow *window)
+{
+  GdkWindowPrivate *private;
+  GdkWindowPrivate *temp_private;
+  GdkWindow *temp_window;
+  GList *children;
+  GList *tmp;
+
+  g_return_if_fail (window != NULL);
+
+  private = (GdkWindowPrivate*) window;
+  if(private->dnd_drag_data_numtypesavail > 0) 
+    {
+      free(private->dnd_drag_data_typesavail);
+      private->dnd_drag_data_typesavail = NULL;
+    }
+  if(private->dnd_drop_data_numtypesavail > 0) 
+    {
+      free(private->dnd_drop_data_typesavail);
+      private->dnd_drop_data_typesavail = NULL;
+    }
+  
+  switch (private->window_type)
+    {
+    case GDK_WINDOW_TOPLEVEL:
+    case GDK_WINDOW_CHILD:
+    case GDK_WINDOW_DIALOG:
+    case GDK_WINDOW_TEMP:
+      if (private->ref_count >= 1)
+       private->ref_count -= 1;
+
+      if (!private->destroyed || (private->destroyed == 2))
+       {
+         children = gdk_window_get_children (window);
+         tmp = children;
+
+         while (tmp)
+           {
+             temp_window = tmp->data;
+             tmp = tmp->next;
+
+             temp_private = (GdkWindowPrivate*) temp_window;
+             if (temp_private && !temp_private->destroyed)
+               /* Removes some nice coredumps... /David */
+               {
+                 temp_private->destroyed = 2;
+                 temp_private->ref_count += 1;
+                 gdk_window_destroy (temp_window);
+               }
+           }
+
+         g_list_free (children);
+
+         if (!private->destroyed)
+           XDestroyWindow (private->xdisplay, private->xwindow);
+         private->destroyed = TRUE;
+       }
+      break;
+
+    case GDK_WINDOW_ROOT:
+      g_error ("attempted to destroy root window");
+      break;
+
+    case GDK_WINDOW_PIXMAP:
+      g_warning ("called gdk_window_destroy on a pixmap (use gdk_pixmap_destroy)");
+      gdk_pixmap_destroy (window);
+      break;
+    }
+}
+
+void
+gdk_window_real_destroy (GdkWindow *window)
+{
+  GdkWindowPrivate *private;
+
+  g_return_if_fail (window != NULL);
+
+  private = (GdkWindowPrivate*) window;
+
+  if (private->extension_events != 0)
+    gdk_input_window_destroy (window);
+
+  if (private->ref_count == 0)
+    {
+      gdk_xid_table_remove (private->xwindow);
+      g_free (window);
+    }
+}
+
+GdkWindow*
+gdk_window_ref (GdkWindow *window)
+{
+  GdkWindowPrivate *private = (GdkWindowPrivate *)window;
+  g_return_if_fail (window != NULL);
+
+  private->ref_count += 1;
+  return window;
+}
+
+void
+gdk_window_unref (GdkWindow *window)
+{
+  GdkWindowPrivate *private = (GdkWindowPrivate *)window;
+  g_return_if_fail (window != NULL);
+
+  private->ref_count -= 1;
+  if (private->ref_count == 0)
+    gdk_window_real_destroy (window);
+}
+
+void
+gdk_window_show (GdkWindow *window)
+{
+  GdkWindowPrivate *private;
+
+  g_return_if_fail (window != NULL);
+
+  private = (GdkWindowPrivate*) window;
+  if (!private->destroyed)
+    {
+      XRaiseWindow (private->xdisplay, private->xwindow);
+      XMapWindow (private->xdisplay, private->xwindow);
+    }
+}
+
+void
+gdk_window_hide (GdkWindow *window)
+{
+  GdkWindowPrivate *private;
+
+  g_return_if_fail (window != NULL);
+
+  private = (GdkWindowPrivate*) window;
+  if (!private->destroyed)
+    XUnmapWindow (private->xdisplay, private->xwindow);
+}
+
+void
+gdk_window_move (GdkWindow *window,
+                gint       x,
+                gint       y)
+{
+  GdkWindowPrivate *private;
+
+  g_return_if_fail (window != NULL);
+
+  private = (GdkWindowPrivate*) window;
+  XMoveWindow (private->xdisplay, private->xwindow, x, y);
+
+  if (private->window_type == GDK_WINDOW_CHILD)
+    {
+      private->x = x;
+      private->y = y;
+    }
+}
+
+void
+gdk_window_resize (GdkWindow *window,
+                  gint       width,
+                  gint       height)
+{
+  GdkWindowPrivate *private;
+
+  g_return_if_fail (window != NULL);
+
+  if (width < 1)
+    width = 1;
+  if (height < 1)
+    height = 1;
+
+  private = (GdkWindowPrivate*) window;
+
+  if (!private->destroyed &&
+      ((private->resize_count > 0) ||
+       (private->width != (guint16) width) ||
+       (private->height != (guint16) height)))
+    {
+      XResizeWindow (private->xdisplay, private->xwindow, width, height);
+      private->resize_count += 1;
+
+      if (private->window_type == GDK_WINDOW_CHILD)
+       {
+         private->width = width;
+         private->height = height;
+       }
+    }
+}
+
+void
+gdk_window_move_resize (GdkWindow *window,
+                       gint       x,
+                       gint       y,
+                       gint       width,
+                       gint       height)
+{
+  GdkWindowPrivate *private;
+
+  g_return_if_fail (window != NULL);
+
+  if (width < 1)
+    width = 1;
+  if (height < 1)
+    height = 1;
+
+  private = (GdkWindowPrivate*) window;
+  XMoveResizeWindow (private->xdisplay, private->xwindow, x, y, width, height);
+
+  if (!private->destroyed &&
+      (private->window_type == GDK_WINDOW_CHILD))
+    {
+      private->x = x;
+      private->y = y;
+      private->width = width;
+      private->height = height;
+    }
+}
+
+void
+gdk_window_reparent (GdkWindow *window,
+                    GdkWindow *new_parent,
+                    gint       x,
+                    gint       y)
+{
+  GdkWindowPrivate *window_private;
+  GdkWindowPrivate *parent_private;
+
+  g_return_if_fail (window != NULL);
+
+  if (!new_parent)
+    new_parent = (GdkWindow*) &gdk_root_parent;
+
+  window_private = (GdkWindowPrivate*) window;
+  parent_private = (GdkWindowPrivate*) new_parent;
+
+  XReparentWindow (window_private->xdisplay,
+                  window_private->xwindow,
+                  parent_private->xwindow,
+                  x, y);
+}
+
+void
+gdk_window_clear (GdkWindow *window)
+{
+  GdkWindowPrivate *private;
+
+  g_return_if_fail (window != NULL);
+
+  private = (GdkWindowPrivate*) window;
+
+  XClearWindow (private->xdisplay, private->xwindow);
+}
+
+void
+gdk_window_clear_area (GdkWindow *window,
+                      gint       x,
+                      gint       y,
+                      gint       width,
+                      gint       height)
+{
+  GdkWindowPrivate *private;
+
+  g_return_if_fail (window != NULL);
+
+  private = (GdkWindowPrivate*) window;
+
+  if (!private->destroyed)
+    XClearArea (private->xdisplay, private->xwindow,
+               x, y, width, height, False);
+}
+
+void
+gdk_window_clear_area_e (GdkWindow *window,
+                        gint       x,
+                        gint       y,
+                        gint       width,
+                        gint       height)
+{
+  GdkWindowPrivate *private;
+
+  g_return_if_fail (window != NULL);
+
+  private = (GdkWindowPrivate*) window;
+
+  if (!private->destroyed)
+    XClearArea (private->xdisplay, private->xwindow,
+               x, y, width, height, True);
+}
+
+void
+gdk_window_copy_area (GdkWindow    *window,
+                     GdkGC        *gc,
+                     gint          x,
+                     gint          y,
+                     GdkWindow    *source_window,
+                     gint          source_x,
+                     gint          source_y,
+                     gint          width,
+                     gint          height)
+{
+  GdkWindowPrivate *src_private;
+  GdkWindowPrivate *dest_private;
+  GdkGCPrivate *gc_private;
+
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (gc != NULL);
+  
+  if (source_window == NULL)
+    source_window = window;
+
+  src_private = (GdkWindowPrivate*) source_window;
+  dest_private = (GdkWindowPrivate*) window;
+  gc_private = (GdkGCPrivate*) gc;
+  
+  if (!src_private->destroyed && !dest_private->destroyed)
+  {
+    XCopyArea (dest_private->xdisplay, src_private->xwindow, dest_private->xwindow,
+              gc_private->xgc,
+              source_x, source_y,
+              width, height,
+              x, y);
+  }
+}
+
+void
+gdk_window_raise (GdkWindow *window)
+{
+  GdkWindowPrivate *private;
+
+  g_return_if_fail (window != NULL);
+
+  private = (GdkWindowPrivate*) window;
+
+  if (!private->destroyed)
+    XRaiseWindow (private->xdisplay, private->xwindow);
+}
+
+void
+gdk_window_lower (GdkWindow *window)
+{
+  GdkWindowPrivate *private;
+
+  g_return_if_fail (window != NULL);
+
+  private = (GdkWindowPrivate*) window;
+
+  if (!private->destroyed)
+    XLowerWindow (private->xdisplay, private->xwindow);
+}
+
+void
+gdk_window_set_user_data (GdkWindow *window,
+                         gpointer   user_data)
+{
+  g_return_if_fail (window != NULL);
+
+  window->user_data = user_data;
+}
+
+void
+gdk_window_set_hints (GdkWindow *window,
+                     gint       x,
+                     gint       y,
+                     gint       min_width,
+                     gint       min_height,
+                     gint       max_width,
+                     gint       max_height,
+                     gint       flags)
+{
+  GdkWindowPrivate *private;
+  XSizeHints size_hints;
+
+  g_return_if_fail (window != NULL);
+
+  private = (GdkWindowPrivate*) window;
+  size_hints.flags = 0;
+
+  if (flags & GDK_HINT_POS)
+    {
+      size_hints.flags |= PPosition;
+      size_hints.x = x;
+      size_hints.y = y;
+    }
+
+  if (flags & GDK_HINT_MIN_SIZE)
+    {
+      size_hints.flags |= PMinSize;
+      size_hints.min_width = min_width;
+      size_hints.min_height = min_height;
+    }
+
+  if (flags & GDK_HINT_MAX_SIZE)
+    {
+      size_hints.flags |= PMaxSize;
+      size_hints.max_width = max_width;
+      size_hints.max_height = max_height;
+    }
+
+  if (flags)
+    XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
+}
+
+void
+gdk_window_set_title (GdkWindow   *window,
+                     const gchar *title)
+{
+  GdkWindowPrivate *private;
+
+  g_return_if_fail (window != NULL);
+
+  private = (GdkWindowPrivate*) window;
+  XStoreName (private->xdisplay, private->xwindow, title);
+  XSetIconName (private->xdisplay, private->xwindow, title);
+}
+
+void
+gdk_window_set_background (GdkWindow *window,
+                          GdkColor  *color)
+{
+  GdkWindowPrivate *private;
+
+  g_return_if_fail (window != NULL);
+
+  private = (GdkWindowPrivate*) window;
+  XSetWindowBackground (private->xdisplay, private->xwindow, color->pixel);
+}
+
+void
+gdk_window_set_back_pixmap (GdkWindow *window,
+                           GdkPixmap *pixmap,
+                           gint       parent_relative)
+{
+  GdkWindowPrivate *window_private;
+  GdkPixmapPrivate *pixmap_private;
+  Pixmap xpixmap;
+
+  g_return_if_fail (window != NULL);
+
+  window_private = (GdkWindowPrivate*) window;
+  pixmap_private = (GdkPixmapPrivate*) pixmap;
+
+  if (pixmap)
+    xpixmap = pixmap_private->xwindow;
+  else
+    xpixmap = None;
+
+  if (parent_relative)
+    xpixmap = ParentRelative;
+
+  XSetWindowBackgroundPixmap (window_private->xdisplay, window_private->xwindow, xpixmap);
+}
+
+void
+gdk_window_set_cursor (GdkWindow *window,
+                      GdkCursor *cursor)
+{
+  GdkWindowPrivate *window_private;
+  GdkCursorPrivate *cursor_private;
+  Cursor xcursor;
+
+  g_return_if_fail (window != NULL);
+
+  window_private = (GdkWindowPrivate*) window;
+  cursor_private = (GdkCursorPrivate*) cursor;
+
+  if (!cursor)
+    xcursor = None;
+  else
+    xcursor = cursor_private->xcursor;
+
+  XDefineCursor (window_private->xdisplay, window_private->xwindow, xcursor);
+}
+
+void
+gdk_window_set_colormap (GdkWindow   *window,
+                        GdkColormap *colormap)
+{
+  GdkWindowPrivate *window_private;
+  GdkColormapPrivate *colormap_private;
+
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (colormap != NULL);
+
+  window_private = (GdkWindowPrivate*) window;
+  colormap_private = (GdkColormapPrivate*) colormap;
+
+  XSetWindowColormap (window_private->xdisplay,
+                     window_private->xwindow,
+                     colormap_private->xcolormap);
+
+  if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
+    gdk_window_add_colormap_windows (window);
+}
+
+void
+gdk_window_get_user_data (GdkWindow *window,
+                         gpointer  *data)
+{
+  g_return_if_fail (window != NULL);
+
+  *data = window->user_data;
+}
+
+void
+gdk_window_get_geometry (GdkWindow *window,
+                        gint      *x,
+                        gint      *y,
+                        gint      *width,
+                        gint      *height,
+                        gint      *depth)
+{
+  GdkWindowPrivate *window_private;
+  Window root;
+  gint tx;
+  gint ty;
+  guint twidth;
+  guint theight;
+  guint tborder_width;
+  guint tdepth;
+
+  if (!window)
+    window = (GdkWindow*) &gdk_root_parent;
+
+  window_private = (GdkWindowPrivate*) window;
+
+  XGetGeometry (window_private->xdisplay, window_private->xwindow,
+               &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
+
+  if (x)
+    *x = tx;
+  if (y)
+    *y = ty;
+  if (width)
+    *width = twidth;
+  if (height)
+    *height = theight;
+  if (depth)
+    *depth = tdepth;
+}
+
+void
+gdk_window_get_position (GdkWindow *window,
+                        gint      *x,
+                        gint      *y)
+{
+  GdkWindowPrivate *window_private;
+
+  g_return_if_fail (window != NULL);
+
+  window_private = (GdkWindowPrivate*) window;
+
+  if (x)
+    *x = window_private->x;
+  if (y)
+    *y = window_private->y;
+}
+
+void
+gdk_window_get_size (GdkWindow *window,
+                    gint       *width,
+                    gint       *height)
+{
+  GdkWindowPrivate *window_private;
+
+  g_return_if_fail (window != NULL);
+
+  window_private = (GdkWindowPrivate*) window;
+
+  if (width)
+    *width = window_private->width;
+  if (height)
+    *height = window_private->height;
+}
+
+
+GdkVisual*
+gdk_window_get_visual (GdkWindow *window)
+{
+  GdkWindowPrivate *window_private;
+  XWindowAttributes window_attributes;
+
+  g_return_val_if_fail (window != NULL, NULL);
+
+  window_private = (GdkWindowPrivate*) window;
+  while (window_private && (window_private->window_type == GDK_WINDOW_PIXMAP))
+    window_private = (GdkWindowPrivate*) window_private->parent;
+
+  if (window_private)
+    {
+      XGetWindowAttributes (window_private->xdisplay,
+                           window_private->xwindow,
+                           &window_attributes);
+
+      return gdk_visual_lookup (window_attributes.visual);
+    }
+
+  return NULL;
+}
+
+GdkColormap*
+gdk_window_get_colormap (GdkWindow *window)
+{
+  GdkWindowPrivate *window_private;
+  XWindowAttributes window_attributes;
+
+  g_return_val_if_fail (window != NULL, NULL);
+
+  window_private = (GdkWindowPrivate*) window;
+
+  XGetWindowAttributes (window_private->xdisplay,
+                       window_private->xwindow,
+                       &window_attributes);
+
+  return gdk_colormap_lookup (window_attributes.colormap);
+}
+
+GdkWindowType
+gdk_window_get_type (GdkWindow *window)
+{
+  GdkWindowPrivate *window_private;
+
+  g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
+
+  window_private = (GdkWindowPrivate*) window;
+  return window_private->window_type;
+}
+
+gint
+gdk_window_get_origin (GdkWindow *window,
+                      gint      *x,
+                      gint      *y)
+{
+  GdkWindowPrivate *private;
+  gint return_val;
+  Window child;
+  gint tx, ty;
+
+  g_return_val_if_fail (window != NULL, 0);
+
+  private = (GdkWindowPrivate*) window;
+
+  return_val = XTranslateCoordinates (private->xdisplay,
+                                     private->xwindow,
+                                     gdk_root_window,
+                                     0, 0, &tx, &ty,
+                                     &child);
+
+  if (x)
+    *x = tx;
+  if (y)
+    *y = ty;
+
+  return return_val;
+}
+
+GdkWindow*
+gdk_window_get_pointer (GdkWindow       *window,
+                       gint            *x,
+                       gint            *y,
+                       GdkModifierType *mask)
+{
+  GdkWindowPrivate *private;
+  GdkWindow *return_val;
+  Window root;
+  Window child;
+  int rootx, rooty;
+  int winx, winy;
+  unsigned int xmask;
+
+  if (!window)
+    window = (GdkWindow*) &gdk_root_parent;
+
+  private = (GdkWindowPrivate*) window;
+
+  return_val = NULL;
+  if (XQueryPointer (private->xdisplay, private->xwindow, &root, &child,
+                    &rootx, &rooty, &winx, &winy, &xmask))
+    {
+      if (x) *x = winx;
+      if (y) *y = winy;
+      if (mask) *mask = xmask;
+
+      if (child)
+       return_val = gdk_window_lookup (child);
+    }
+
+  return return_val;
+}
+
+GdkWindow*
+gdk_window_get_parent (GdkWindow *window)
+{
+  g_return_val_if_fail (window != NULL, NULL);
+
+  return ((GdkWindowPrivate*) window)->parent;
+}
+
+GdkWindow*
+gdk_window_get_toplevel (GdkWindow *window)
+{
+  GdkWindowPrivate *private;
+
+  g_return_val_if_fail (window != NULL, NULL);
+
+  private = (GdkWindowPrivate*) window;
+
+  while (private->window_type == GDK_WINDOW_CHILD)
+    {
+      window = ((GdkWindowPrivate*) window)->parent;
+      private = (GdkWindowPrivate*) window;
+    }
+
+  return window;
+}
+
+GList*
+gdk_window_get_children (GdkWindow *window)
+{
+  GdkWindowPrivate *private;
+  GdkWindow *child;
+  GList *children;
+  Window root;
+  Window parent;
+  Window *xchildren;
+  unsigned int nchildren;
+  unsigned int i;
+
+  g_return_val_if_fail (window != NULL, NULL);
+
+  private = (GdkWindowPrivate*) window;
+
+  XQueryTree (private->xdisplay, private->xwindow,
+             &root, &parent, &xchildren, &nchildren);
+
+  children = NULL;
+
+  if (nchildren > 0)
+    {
+      for (i = 0; i < nchildren; i++)
+       {
+         child = gdk_window_lookup (xchildren[i]);
+          if (child)
+            children = g_list_prepend (children, child);
+       }
+
+      XFree (xchildren);
+    }
+
+  return children;
+}
+
+GdkEventMask  
+gdk_window_get_events      (GdkWindow       *window)
+{
+  XWindowAttributes attrs;
+  GdkEventMask event_mask;
+  int i;
+
+  XGetWindowAttributes (gdk_display, ((GdkWindowPrivate *)window)->xwindow, 
+                       &attrs);
+
+  event_mask = 0;
+  for (i = 0; i < nevent_masks; i++)
+    {
+      if (attrs.your_event_mask & event_mask_table[i])
+       event_mask |= 1 << (i + 1);
+    }
+
+  return event_mask;
+}
+
+void          
+gdk_window_set_events      (GdkWindow       *window,
+                           GdkEventMask     event_mask)
+{
+  long xevent_mask;
+  int i;
+
+  xevent_mask = StructureNotifyMask;
+  for (i = 0; i < nevent_masks; i++)
+    {
+      if (event_mask & (1 << (i + 1)))
+       xevent_mask |= event_mask_table[i];
+    }
+  
+  XSelectInput (gdk_display, ((GdkWindowPrivate *)window)->xwindow, 
+               xevent_mask);
+}
+
+void
+gdk_window_add_colormap_windows (GdkWindow *window)
+{
+  GdkWindow *toplevel;
+  GdkWindowPrivate *toplevel_private;
+  GdkWindowPrivate *window_private;
+  Window *old_windows;
+  Window *new_windows;
+  int i, count;
+
+  g_return_if_fail (window != NULL);
+
+  toplevel = gdk_window_get_toplevel (window);
+  toplevel_private = (GdkWindowPrivate*) toplevel;
+  window_private = (GdkWindowPrivate*) window;
+
+  if (!XGetWMColormapWindows (toplevel_private->xdisplay,
+                             toplevel_private->xwindow,
+                             &old_windows, &count))
+    {
+      old_windows = NULL;
+      count = 0;
+    }
+
+  for (i = 0; i < count; i++)
+    if (old_windows[i] == window_private->xwindow)
+      return;
+
+  new_windows = g_new (Window, count + 1);
+
+  for (i = 0; i < count; i++)
+    new_windows[i] = old_windows[i];
+  new_windows[count] = window_private->xwindow;
+
+  XSetWMColormapWindows (toplevel_private->xdisplay,
+                        toplevel_private->xwindow,
+                        new_windows, count + 1);
+
+  g_free (new_windows);
+  if (old_windows)
+    XFree (old_windows);
+}
+
+/*
+ * This needs the X11 shape extension.
+ * If not available, simply remove the call to
+ * XShapeCombineMask. Shaped windows will look
+ * ugly, but programs still work.    Stefan Wille
+ */
+void
+gdk_window_shape_combine_mask (GdkWindow *window,
+                              GdkBitmap *mask,
+                              gint x, gint y)
+{
+  GdkWindowPrivate *window_private;
+  GdkWindowPrivate *pixmap_private;
+
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (mask != NULL);
+
+  window_private = (GdkWindowPrivate*) window;
+  pixmap_private = (GdkWindowPrivate*) mask;
+       
+  XShapeCombineMask  (window_private->xdisplay,
+                     window_private->xwindow,
+                     ShapeBounding,
+                     x, y, /* offset */
+                     (Pixmap)pixmap_private->xwindow,
+                     ShapeSet);
+}
+
+void
+gdk_dnd_drag_addwindow (GdkWindow *window)
+{
+  GdkWindowPrivate *window_private;
+  
+  g_return_if_fail (window != NULL);
+  
+  window_private = (GdkWindowPrivate *) window;
+  
+  if (window_private->dnd_drag_enabled == 1 && gdk_dnd.drag_really == 0)
+    {
+      gdk_dnd.drag_numwindows++;
+      gdk_dnd.drag_startwindows = g_realloc (gdk_dnd.drag_startwindows,
+                                            gdk_dnd.drag_numwindows
+                                            * sizeof(GdkWindow *));
+      gdk_dnd.drag_startwindows[gdk_dnd.drag_numwindows - 1] = window;
+      window_private->dnd_drag_accepted = 0;
+    } 
+  else
+    g_warning ("dnd_really is 1 or drag is not enabled! can't addwindow\n");
+}
+
+void
+gdk_window_dnd_drag_set (GdkWindow   *window,
+                        guint8       drag_enable,
+                        gchar      **typelist,
+                        guint        numtypes)
+{
+  GdkWindowPrivate *window_private;
+  int i, wasset = 0;
+  
+  g_return_if_fail (window != NULL);
+  window_private = (GdkWindowPrivate *) window;
+  
+  window_private->dnd_drag_enabled = drag_enable ? 1 : 0;
+  
+  if (drag_enable)
+    {
+      g_return_if_fail(typelist != NULL);
+      
+      if (window_private->dnd_drag_data_numtypesavail > 3)
+       wasset = 1;
+      window_private->dnd_drag_data_numtypesavail = numtypes;
+      
+      window_private->dnd_drag_data_typesavail =
+       g_realloc (window_private->dnd_drag_data_typesavail,
+                  (numtypes + 1) * sizeof (GdkAtom));
+      
+      for (i = 0; i < numtypes; i++)
+       {
+         /* Allow blanket use of ALL to get anything... */
+         if (strcmp (typelist[i], "ALL"))
+           window_private->dnd_drag_data_typesavail[i] =
+             gdk_atom_intern (typelist[i], FALSE);
+         else
+           window_private->dnd_drag_data_typesavail[i] = None;
+       }
+      
+      /* 
+       * set our extended type list if we need to 
+       */
+      if (numtypes > 3)
+       gdk_property_change(window, gdk_dnd.gdk_XdeTypelist,
+                           XA_PRIMARY, 32, GDK_PROP_MODE_REPLACE,
+                           (guchar *)(window_private->dnd_drag_data_typesavail
+                            + (sizeof(GdkAtom) * 3)),
+                           (numtypes - 3) * sizeof(GdkAtom));
+      else if (wasset)
+       gdk_property_delete (window, gdk_dnd.gdk_XdeTypelist);
+    }
+  else
+    {
+      free (window_private->dnd_drag_data_typesavail);
+      window_private->dnd_drag_data_typesavail = NULL;
+      window_private->dnd_drag_data_numtypesavail = 0;
+    }
+}
+
+void
+gdk_window_dnd_drop_set (GdkWindow   *window,
+                        guint8       drop_enable,
+                        gchar      **typelist,
+                        guint        numtypes,
+                        guint8       destructive_op)
+{
+  GdkWindowPrivate *window_private;
+  int i;
+  
+  g_return_if_fail (window != NULL);
+  
+  window_private = (GdkWindowPrivate *) window;
+  
+  window_private->dnd_drop_enabled = drop_enable ? 1 : 0;
+  if (drop_enable)
+    {
+      g_return_if_fail(typelist != NULL);
+      
+      window_private->dnd_drop_data_numtypesavail = numtypes;
+      
+      window_private->dnd_drop_data_typesavail =
+       g_realloc (window_private->dnd_drop_data_typesavail,
+                  (numtypes + 1) * sizeof (GdkAtom));
+      
+      for (i = 0; i < numtypes; i++)
+       window_private->dnd_drop_data_typesavail[i] =
+         gdk_atom_intern (typelist[i], FALSE);
+      
+      window_private->dnd_drop_destructive_op = destructive_op;
+    }
+}
+
+/* 
+ * This is used to reply to a GDK_DRAG_REQUEST event
+ * (which may be generated by XdeRequest or a confirmed drop... 
+ */
+void
+gdk_window_dnd_data_set (GdkWindow       *window,
+                        GdkEvent        *event,
+                        gpointer         data,
+                        gulong           data_numbytes)
+{
+  GdkWindowPrivate *window_private;
+  XEvent sev;
+  GdkEventDropDataAvailable tmp_ev;
+  gchar *tmp;
+  
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (event != NULL);
+  g_return_if_fail (data != NULL);
+  g_return_if_fail (data_numbytes > 0);
+  g_return_if_fail (event->type == GDK_DRAG_REQUEST);
+
+  g_free (event->dragrequest.data_type);
+  event->dragrequest.data_type = NULL;
+  
+  window_private = (GdkWindowPrivate *) window;
+  g_return_if_fail (window_private->dnd_drag_accepted != 0);    
+  
+  /* We set the property on our window... */
+  gdk_property_change (window, window_private->dnd_drag_data_type,
+                      XA_PRIMARY, 8, GDK_PROP_MODE_REPLACE, data,
+                      data_numbytes);
+  tmp = gdk_atom_name(window_private->dnd_drag_data_type);
+  g_print("DnD type %s on window %ld\n", tmp, window_private->xwindow);
+  g_free(tmp);
+  
+  /* 
+   * Then we send the event to tell the receiving window that the
+   * drop has happened 
+   */
+  tmp_ev.u.allflags = 0;
+  tmp_ev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
+  tmp_ev.u.flags.isdrop = event->dragrequest.isdrop;
+  
+  sev.xclient.type = ClientMessage;
+  sev.xclient.format = 32;
+  sev.xclient.window = event->dragrequest.requestor;
+  sev.xclient.message_type = gdk_dnd.gdk_XdeDataAvailable;
+  sev.xclient.data.l[0] = window_private->xwindow;
+  sev.xclient.data.l[1] = tmp_ev.u.allflags;
+  sev.xclient.data.l[2] = window_private->dnd_drag_data_type;
+
+  if (event->dragrequest.isdrop)
+    sev.xclient.data.l[3] = event->dragrequest.drop_coords.x +
+      (event->dragrequest.drop_coords.y << 16);
+  else
+    sev.xclient.data.l[3] = 0;
+  
+  sev.xclient.data.l[4] = 0;
+  
+  XSendEvent (gdk_display, event->dragrequest.requestor, False,
+             NoEventMask, &sev);
+}
diff --git a/gdk/x11/gdkx.h b/gdk/x11/gdkx.h
new file mode 100644 (file)
index 0000000..cb8e33b
--- /dev/null
@@ -0,0 +1,48 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GDK_X_H__
+#define __GDK_X_H__
+
+#include <gdk/gdkprivate.h>
+
+
+#define GDK_ROOT_WINDOW()             gdk_root_window
+#define GDK_ROOT_PARENT()             &gdk_root_parent
+#define GDK_DISPLAY()                 gdk_display
+#define GDK_WINDOW_XDISPLAY(win)      (((GdkWindowPrivate*) win)->xdisplay)
+#define GDK_WINDOW_XWINDOW(win)       (((GdkWindowPrivate*) win)->xwindow)
+#define GDK_IMAGE_XDISPLAY(image)     (((GdkImagePrivate*) image)->xdisplay)
+#define GDK_IMAGE_XIMAGE(image)       (((GdkImagePrivate*) image)->ximage)
+#define GDK_GC_XDISPLAY(gc)           (((GdkGCPrivate*) gc)->xdisplay)
+#define GDK_GC_XGC(gc)                (((GdkGCPrivate*) gc)->xgc)
+#define GDK_COLORMAP_XDISPLAY(cmap)   (((GdkColormapPrivate*) cmap)->xdisplay)
+#define GDK_COLORMAP_XCOLORMAP(cmap)  (((GdkColormapPrivate*) cmap)->xcolormap)
+#define GDK_VISUAL_XVISUAL(vis)       (((GdkVisualPrivate*) vis)->xvisual)
+#define GDK_FONT_XDISPLAY(font)       (((GdkFontPrivate*) font)->xdisplay)
+#define GDK_FONT_XFONT(font)          (((GdkFontPrivate*) font)->xfont)
+
+
+GdkVisual*   gdkx_visual_get   (VisualID xvisualid);
+GdkColormap* gdkx_colormap_get (Colormap xcolormap);
+/* Utility function in gdk.c - not sure where it belongs, but it's
+   needed in more than one place, so make it public */
+Window        gdk_get_client_window      (Display  *dpy,
+                                          Window    win);
+
+
+#endif /* __GDK_X_H__ */
diff --git a/gdk/x11/gdkxid.c b/gdk/x11/gdkxid.c
new file mode 100644 (file)
index 0000000..7ee6075
--- /dev/null
@@ -0,0 +1,74 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gdkprivate.h"
+
+
+static guint gdk_xid_hash    (XID *xid);
+static gint  gdk_xid_compare (XID *a,
+                             XID *b);
+
+
+GHashTable *xid_ht = NULL;
+
+
+void
+gdk_xid_table_insert (XID      *xid,
+                     gpointer  data)
+{
+  g_return_if_fail (xid != NULL);
+
+  if (!xid_ht)
+    xid_ht = g_hash_table_new ((GHashFunc) gdk_xid_hash,
+                              (GCompareFunc) gdk_xid_compare);
+
+  g_hash_table_insert (xid_ht, xid, data);
+}
+
+void
+gdk_xid_table_remove (XID xid)
+{
+  if (!xid_ht)
+    xid_ht = g_hash_table_new ((GHashFunc) gdk_xid_hash,
+                              (GCompareFunc) gdk_xid_compare);
+
+  g_hash_table_remove (xid_ht, &xid);
+}
+
+gpointer
+gdk_xid_table_lookup (XID xid)
+{
+  gpointer data;
+
+  data = g_hash_table_lookup (xid_ht, &xid);
+
+  return data;
+}
+
+
+static guint
+gdk_xid_hash (XID *xid)
+{
+  return *xid;
+}
+
+static gint
+gdk_xid_compare (XID *a,
+                XID *b)
+{
+  return (*a == *b);
+}
diff --git a/gdk/x11/gxid.c b/gdk/x11/gxid.c
new file mode 100644 (file)
index 0000000..219c08b
--- /dev/null
@@ -0,0 +1,844 @@
+/* 
+ * gxid version 0.3
+ *
+ * Copyright 1997 Owen Taylor <owt1@cornell.edu>
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/XInput.h>
+
+#include "gxid_proto.h"
+
+/* #define DEBUG_CLIENTS  */
+/* #define DEBUG_EVENTS */
+
+char *program_name;
+Display *dpy;
+Window root_window;            /* default root window of dpy */
+int port = 0;                  /* port to listen on */
+int socket_fd = 0;             /* file descriptor of socket */
+typedef struct GxidWindow_ GxidWindow;
+
+typedef struct GxidDevice_ GxidDevice;
+struct GxidDevice_ {
+  XID id;
+  int exclusive;
+  int ispointer;
+  
+  XDevice *xdevice;
+  int motionnotify_type;
+  int changenotify_type;
+};
+
+struct GxidWindow_ {
+  Window xwindow;
+  /* Immediate child of root that is ancestor of window */
+  Window root_child;
+  int num_devices;
+  GxidDevice **devices;
+};
+
+GxidDevice **devices = NULL;
+int num_devices = 0;
+GxidWindow **windows = NULL;
+int num_windows = 0;
+
+void
+handler(int signal)
+{
+  fprintf(stderr,"%s: dying on signal %d\n",program_name,signal);
+  if (socket_fd)
+    close(socket_fd);
+  exit(1);
+}
+
+void
+init_socket()
+{
+  struct sockaddr_in sin;
+
+  socket_fd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
+  if (socket_fd < 0)
+    {
+      fprintf (stderr, "%s: error getting socket\n",
+              program_name);
+      exit(1);
+    }
+  
+  sin.sin_family = AF_INET;
+  sin.sin_port = htons(port);
+  sin.sin_addr.s_addr = INADDR_ANY;
+  
+  if (bind(socket_fd,(struct sockaddr *)(&sin),
+          sizeof(struct sockaddr_in)) < 0)
+    {
+      fprintf (stderr,"%s: cannot bind to port %d\n",
+              program_name,port);
+      exit(1);
+    }
+
+  if (listen(socket_fd,5) < 0)
+    {
+      fprintf (stderr,"%s: error listening on socket\n",
+              program_name);
+      exit(1);
+    };
+}
+
+#define NUM_EVENTC 2
+static void
+enable_device(GxidDevice *dev)
+{
+  XEventClass xevc[NUM_EVENTC];
+  int num_eventc = NUM_EVENTC;
+  int i,j;
+
+  if (!dev->xdevice) 
+    {
+      if (dev->ispointer) return;
+
+      dev->xdevice = XOpenDevice(dpy, dev->id);
+      if (!dev->xdevice) return;
+      
+      DeviceMotionNotify (dev->xdevice, dev->motionnotify_type,
+                         xevc[0]);
+      ChangeDeviceNotify (dev->xdevice, dev->changenotify_type,
+                         xevc[1]);
+
+      /* compress out zero event classes */
+      for (i=0,j=0;i<NUM_EVENTC;i++)
+       {
+         if (xevc[i]) {
+           xevc[j] = xevc[i];
+           j++;
+         }
+      }
+      num_eventc = j;
+      
+      XSelectExtensionEvent (dpy, root_window, xevc, num_eventc);
+    }
+}
+
+/* switch the core pointer from whatever it is now to something else,
+   return true on success, false otherwise */
+static int
+switch_core_pointer()
+{
+  GxidDevice *old_pointer = 0;
+  GxidDevice *new_pointer = 0;
+  int result;
+  int i;
+
+  for (i=0;i<num_devices;i++)
+    {
+      if (devices[i]->ispointer)
+       old_pointer = devices[i];
+      else
+       if (!new_pointer && !devices[i]->exclusive)
+         new_pointer = devices[i];
+    }
+
+  if (!old_pointer || !new_pointer)
+    return 0;
+
+#ifdef DEBUG_EVENTS
+  fprintf(stderr,"gxid: Switching core from %ld to %ld\n",
+        old_pointer->id,new_pointer->id);
+#endif
+  result = XChangePointerDevice(dpy,new_pointer->xdevice, 0, 1);
+  if (result != Success)
+    {
+      fprintf(stderr,"gxid: Error %d switching core from %ld to %ld\n",
+             result, old_pointer->id, new_pointer->id);
+    }
+  else
+    {
+      new_pointer->ispointer = 1;
+      old_pointer->ispointer = 0;
+      if (!old_pointer->xdevice)
+       enable_device(old_pointer);
+    }
+
+  return 1;
+}
+
+void
+disable_device(GxidDevice *dev)
+{
+  if (dev->xdevice)
+    {
+      if (dev->ispointer)
+       return;
+      XCloseDevice(dpy,dev->xdevice);
+      dev->xdevice = 0;
+    }
+}
+
+GxidDevice *
+init_device(XDeviceInfo *xdevice)
+{
+  GxidDevice *dev = (GxidDevice *)malloc(sizeof(GxidDevice));
+  XAnyClassPtr class;
+  int num_axes, i;
+
+  dev->id = xdevice->id;
+  dev->exclusive = 0;
+  dev->xdevice = NULL;
+
+  dev->ispointer = (xdevice->use == IsXPointer);
+
+  /* step through the classes */
+
+  num_axes = 0;
+  class = xdevice->inputclassinfo;
+  for (i=0;i<xdevice->num_classes;i++) 
+    {
+      if (class->class == ValuatorClass) 
+       {
+         XValuatorInfo *xvi = (XValuatorInfo *)class;
+         num_axes = xvi->num_axes;
+       }
+      class = (XAnyClassPtr)(((char *)class) + class->length);
+    }
+
+  /* return NULL if insufficient axes */
+  if (num_axes < 2)
+    {
+      free((void *)dev);
+      return NULL;
+    }
+
+  if (!dev->ispointer)
+      enable_device(dev);
+  return dev;
+}
+
+void
+init_xinput()
+{
+  char **extensions;
+  XDeviceInfo   *xdevices;
+  int num_xdevices;
+  int num_extensions;
+  int i;
+
+  extensions = XListExtensions(dpy, &num_extensions);
+  for (i = 0; i < num_extensions &&
+        (strcmp(extensions[i], "XInputExtension") != 0); i++);
+  XFreeExtensionList(extensions);
+  if (i == num_extensions)     /* XInput extension not found */
+    {
+      fprintf(stderr,"XInput extension not found\n");
+      exit(1);
+    }
+
+  xdevices = XListInputDevices(dpy, &num_xdevices);
+  devices = (GxidDevice **)malloc(num_xdevices * sizeof(GxidDevice *));
+
+  num_devices = 0;
+  for(i=0; i<num_xdevices; i++)
+    {
+      GxidDevice *dev = init_device(&xdevices[i]);
+      if (dev)
+         devices[num_devices++] = dev;
+    }
+  XFreeDeviceList(xdevices);
+}
+
+/* If this routine needs fixing, the corresponding routine
+   in gdkinputgxi.h will need it too. */
+
+Window
+gxi_find_root_child(Display *dpy, Window w)
+{
+  Window root,parent;
+  Window *children;
+  int nchildren;
+
+  parent = w;
+  do 
+    {
+      w = parent;
+      XQueryTree(dpy,w,&root,&parent,&children,&nchildren);
+      if (children) XFree(children);
+    } 
+  while (parent != root);
+  
+  return w;
+}
+
+int
+handle_claim_device(GxidClaimDevice *msg)
+{
+  int i,j;
+  XID devid = ntohl(msg->device);
+  XID winid = ntohl(msg->window);
+  int exclusive = ntohl(msg->exclusive);
+  GxidDevice *device = NULL;
+  GxidWindow *window = NULL;
+
+#ifdef DEBUG_CLIENTS
+  fprintf(stderr,"device %ld claimed (window 0x%lx)\n",devid,winid);
+#endif  
+
+  for (i=0;i<num_devices;i++)
+    {
+      if (devices[i]->id == devid)
+       {
+         device = devices[i];
+         break;
+       }
+    }
+  if (!device)
+    {
+      fprintf(stderr,"%s: Unknown device id %ld\n",program_name,devid);
+      return GXID_RETURN_ERROR;
+    }
+
+  if (device->exclusive)
+    {
+      /* already in use */
+      fprintf(stderr,
+             "%s: Device %ld already claimed in exclusive mode\n",
+             program_name,devid);
+      return GXID_RETURN_ERROR;
+    }
+
+  if (exclusive)
+    {
+      for (i=0;i<num_windows;i++)
+       {
+         for (j=0;j<windows[i]->num_devices;j++)
+           if (windows[i]->devices[j]->id == devid)
+             {
+               /* already in use */
+               fprintf(stderr,
+                       "%s: Can't establish exclusive use of device %ld\n",
+                       program_name,devid);
+               return GXID_RETURN_ERROR;
+             }
+       }
+      if (device->ispointer)
+       if (!switch_core_pointer())
+         {
+           fprintf(stderr,
+                   "%s: Can't free up core pointer %ld\n",
+                   program_name,devid);
+           return GXID_RETURN_ERROR;
+         }
+
+      device->exclusive = 1;
+      disable_device(device);
+      XSelectInput(dpy,winid,StructureNotifyMask);
+    }
+  else                         /* !exclusive */
+    {
+      /* FIXME: this is a bit improper. We probably should do this only
+        when a window is first claimed. But we might be fooled if
+        an old client died without releasing it's windows. So until
+        we look for client-window closings, do it here 
+        
+        (We do look for closings now...)
+        */
+      
+      XSelectInput(dpy,winid,EnterWindowMask|StructureNotifyMask);
+    }
+
+  for (i=0;i<num_windows;i++)
+    {
+      if (windows[i]->xwindow == winid)
+        {
+         window = windows[i];
+         break;
+       }
+    }
+
+  /* Create window structure if no devices have been previously
+     claimed on it */
+  if (!window)
+    {
+      num_windows++;
+      windows = (GxidWindow **)realloc(windows,
+                                      sizeof(GxidWindow*)*num_windows);
+      window = (GxidWindow *)malloc(sizeof(GxidWindow));
+      windows[num_windows-1] = window;
+
+      window->xwindow = winid;
+      window->root_child = gxi_find_root_child(dpy,winid);
+      window->num_devices = 0;
+      window->devices = 0;
+    }
+
+  
+  for (i=0;i<window->num_devices;i++)
+    {
+      if (window->devices[i] == device)
+       return GXID_RETURN_OK;
+    }
+  
+  window->num_devices++;
+  window->devices = (GxidDevice **)realloc(window->devices,
+                                           sizeof(GxidDevice*)*num_devices);
+  /* we need add the device to the window */
+  window->devices[i] = device;
+
+  return GXID_RETURN_OK;
+}
+
+int
+handle_release_device(GxidReleaseDevice *msg)
+{
+  int i,j;
+  XID devid = ntohl(msg->device);
+  XID winid = ntohl(msg->window);
+
+  GxidDevice *device = NULL;
+
+#ifdef DEBUG_CLIENTS
+  fprintf(stderr,"device %ld released (window 0x%lx)\n",devid,winid);
+#endif  
+
+  for (i=0;i<num_devices;i++)
+    {
+      if (devices[i]->id == devid)
+       {
+         device = devices[i];
+         break;
+       }
+    }
+  if (!device)
+    {
+      fprintf(stderr,"%s: Unknown device id %ld\n",program_name,devid);
+      return GXID_RETURN_ERROR;
+    }
+
+  for (i=0;i<num_windows;i++)
+    {
+      GxidWindow *w = windows[i];
+      
+      if (w->xwindow == winid)
+       for (j=0;j<w->num_devices;j++)
+         if (w->devices[j]->id == devid)
+           {
+             if (j<w->num_devices-1)
+               w->devices[j] = w->devices[w->num_devices-1];
+             w->num_devices--;
+
+             if (w->num_devices == 0)
+               {
+                 if (i<num_windows-1)
+                   windows[i] = windows[num_windows-1];
+                 num_windows--;
+
+                 free((void *)w);
+                 /* FIXME: should we deselect input? But what
+                    what if window is already destroyed */
+               }
+
+             if (device->exclusive)
+               {
+                 device->exclusive = 0;
+                 enable_device(device);
+               }
+             return GXID_RETURN_OK;
+           }
+    }
+  
+  /* device/window combination not found */
+  fprintf(stderr,
+         "%s: Device %ld not claimed for window 0x%lx\n",
+         program_name,devid,winid);
+  return GXID_RETURN_ERROR;
+}
+
+void
+handle_connection()
+{
+  GxidMessage msg;
+  GxidU32 type;
+  int length;
+  GxidI32 retval;
+
+  int conn_fd;
+  struct sockaddr_in sin;
+  int sin_length;
+  int count;
+
+  sin_length = sizeof(struct sockaddr_in);
+  conn_fd = accept(socket_fd,(struct sockaddr *)&sin,&sin_length);
+  if (conn_fd < 0)
+    {
+      fprintf(stderr,"%s: Error accepting connection\n",
+             program_name);
+      exit(1);
+    }
+
+  /* read type and length of message */
+
+  count = read(conn_fd,(char *)&msg,2*sizeof(GxidU32));
+  if (count != 2*sizeof(GxidU32))
+    {
+      fprintf(stderr,"%s: Error reading message header\n",
+             program_name);
+      close(conn_fd);
+      return;
+    }
+  type = ntohl(msg.any.type);
+  length = ntohl(msg.any.length);
+
+  /* read rest of message */
+
+  if (length > sizeof(GxidMessage)) 
+    {
+      fprintf(stderr,"%s: Bad message length\n",
+             program_name);
+      close(conn_fd);
+      return;
+    }
+
+  count = read(conn_fd,2*sizeof(GxidU32) + (char *)&msg,
+                   length - 2*sizeof(GxidU32));
+  if (count != length - 2*sizeof(GxidU32))
+    {
+      fprintf(stderr,"%s: Error reading message body\n",
+             program_name);
+      close(conn_fd);
+      return;
+    }
+
+  switch (type)
+    {
+    case GXID_CLAIM_DEVICE:
+      retval = handle_claim_device((GxidClaimDevice *)&msg);
+      break;
+    case GXID_RELEASE_DEVICE:
+      retval = handle_release_device((GxidReleaseDevice *)&msg);
+      break;
+    default:
+      fprintf(stderr,"%s: Unknown message type: %ld (ignoring)\n",
+             program_name,type);
+      close(conn_fd);
+      return;
+    }
+
+  count = write(conn_fd,&retval,sizeof(GxidI32));
+  if (count != sizeof(GxidI32))
+    {
+      fprintf(stderr,"%s: Error writing return code\n",
+             program_name);
+    }
+  
+  close(conn_fd);
+}
+
+void
+handle_motion_notify(XDeviceMotionEvent *event)
+{
+  int i,j;
+  GxidDevice *old_device = NULL;
+  GxidDevice *new_device = NULL;
+  Window w, root, child;
+  int root_x, root_y, x, y, mask;
+  
+  for (j=0;j<num_devices;j++)
+    {
+      if (devices[j]->ispointer)
+       old_device = devices[j];
+      if (devices[j]->id == event->deviceid)
+       new_device = devices[j];
+    }
+
+  if (new_device && !new_device->exclusive && !new_device->ispointer)
+    {
+      /* make sure we aren't stealing the pointer back from a slow
+        client */
+      child = root_window;
+      do
+       {
+         w = child;
+         /* FIXME: this fails disasterously if child vanishes between
+            calls. (Which is prone to happening since we get events
+            on root just as the client exits) */
+            
+         XQueryPointer(dpy,w,&root,&child,&root_x,&root_y,
+                       &x,&y,&mask);
+       }
+      while (child != None);
+
+      for (i=0;i<num_windows;i++)
+       if (windows[i]->xwindow == w)
+         for (j=0;j<windows[i]->num_devices;j++)
+           if (windows[i]->devices[j] == new_device)
+               return;
+      
+      /* FIXME: do something smarter with axes */
+      XChangePointerDevice(dpy,new_device->xdevice, 0, 1);
+      new_device->ispointer = 1;
+      
+      old_device->ispointer = 0;
+      if (!old_device->xdevice)
+       enable_device(old_device);
+    }
+}
+
+void
+handle_change_notify(XChangeDeviceNotifyEvent *event)
+{
+  int j;
+  GxidDevice *old_device = NULL;
+  GxidDevice *new_device = NULL;
+
+
+  for (j=0;j<num_devices;j++)
+    {
+      if (devices[j]->ispointer)
+       old_device = devices[j];
+      if (devices[j]->id == event->deviceid)
+       new_device = devices[j];
+    }
+
+#ifdef DEBUG_EVENTS
+  fprintf(stderr,"gxid: ChangeNotify event; old = %ld; new = %ld\n",
+         old_device->id, new_device->id);
+#endif
+
+  if (old_device != new_device)
+    {
+      new_device->ispointer = 1;
+      
+      old_device->ispointer = 0;
+      if (!old_device->xdevice)
+       enable_device(old_device);
+    }
+}
+
+void
+handle_enter_notify(XEnterWindowEvent *event, GxidWindow *window)
+{
+  int i;
+  GxidDevice *old_pointer = NULL;
+  for (i=0;i<num_devices;i++)
+    {
+      if (devices[i]->ispointer)
+       {
+         old_pointer = devices[i];
+         break;
+       }
+    }
+
+#ifdef DEBUG_EVENTS
+  fprintf(stderr,"gxid: Enter event; oldpointer = %ld\n",
+         old_pointer->id);
+#endif
+
+  if (old_pointer)
+    for (i=0;i<window->num_devices;i++)
+      {
+       if (window->devices[i] == old_pointer)
+         {
+           switch_core_pointer();
+           break;
+         }
+      }
+}
+
+void
+handle_destroy_notify(XDestroyWindowEvent *event)
+{
+  int i,j;
+
+  for (i=0;i<num_windows;i++)
+    if (windows[i]->xwindow == event->window)
+      {
+       GxidWindow *w = windows[i];
+       
+       for (j=0;j<w->num_devices;j++)
+         {
+#ifdef DEBUG_CLIENTS
+           fprintf(stderr,"device %ld released on destruction of window 0x%lx.\n",
+                   w->devices[j]->id,w->xwindow);
+#endif  
+
+           if (w->devices[j]->exclusive)
+             {
+               w->devices[j]->exclusive = 0;
+               enable_device(devices[j]);
+             }
+         }
+       
+       if (i<num_windows-1)
+         windows[i] = windows[num_windows-1];
+       num_windows--;
+       
+       if (w->devices)
+         free((void *)w->devices);
+       free((void *)w);
+       /* FIXME: should we deselect input? But what
+          what if window is already destroyed */
+       
+       return;
+      }
+}
+
+void
+handle_xevent()
+{
+  int i;
+  XEvent event;
+       
+  XNextEvent (dpy, &event);
+
+#ifdef DEBUG_EVENTS
+  fprintf(stderr,"Event - type = %d; window = 0x%lx\n",
+         event.type,event.xany.window);
+#endif
+
+  if (event.type == ConfigureNotify)
+    {
+#ifdef DEBUG_EVENTS
+      XConfigureEvent *xce = (XConfigureEvent *)&event;
+      fprintf(stderr," configureNotify: window = 0x%lx\n",xce->window);
+#endif
+    }
+  else if (event.type == EnterNotify)
+    {
+      /* pointer entered a claimed window */
+      for (i=0;i<num_windows;i++)
+       {
+         if (event.xany.window == windows[i]->xwindow)
+           handle_enter_notify((XEnterWindowEvent *)&event,windows[i]);
+       }
+    }
+  else if (event.type == DestroyNotify)
+    {
+      /* A claimed window was destroyed */
+      for (i=0;i<num_windows;i++)
+       {
+         if (event.xany.window == windows[i]->xwindow)
+           handle_destroy_notify((XDestroyWindowEvent *)&event);
+       }
+    }
+  else
+    for (i=0;i<num_devices;i++)
+      {
+       if (event.type == devices[i]->motionnotify_type)
+         {
+           handle_motion_notify((XDeviceMotionEvent *)&event);
+           break;
+         }
+       else if (event.type == devices[i]->changenotify_type)
+         {
+           handle_change_notify((XChangeDeviceNotifyEvent *)&event);
+           break;
+         }
+      }
+}
+
+void 
+usage()
+{
+  fprintf(stderr,"Usage: %s [-d display] [-p --gxid-port port]\n",
+         program_name);
+  exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+  int i;
+  char *display_name = NULL;
+  fd_set readfds;
+
+  program_name = argv[0];
+
+  for (i=1;i<argc;i++)
+    {
+      if (!strcmp(argv[i],"-d"))
+       {
+           if (++i >= argc) usage();
+           display_name = argv[i];
+       }
+      else if (!strcmp(argv[i],"--gxid-port") ||
+              !strcmp(argv[i],"-p"))
+       {
+         if (++i >= argc) usage();
+         port = atoi(argv[i]);
+         break;
+       }
+      else
+       usage();
+    }
+
+  if (!port) 
+    {
+      char *t = getenv("GXID_PORT");
+      if (t)
+       port = atoi(t);
+      else
+       port = 6951;
+    }
+  /* set up a signal handler so we can clean up if killed */
+
+  signal(SIGTERM,handler);
+  signal(SIGINT,handler);
+  
+  /* initialize the X connection */
+  
+  dpy = XOpenDisplay (display_name);
+  if (!dpy)
+    {
+      fprintf (stderr, "%s:  unable to open display '%s'\n",
+              program_name, XDisplayName (display_name));
+      exit (1);
+    }
+  
+  root_window = DefaultRootWindow(dpy);
+
+  /* We'll want to do this in the future if we are to support
+     gxid monitoring visibility information for clients */
+#if 0
+  XSelectInput(dpy,root_window,SubstructureNotifyMask);
+#endif
+  init_xinput();
+  
+  /* set up our server connection */
+  
+  init_socket();
+  
+  /* main loop */
+
+  if (XPending(dpy))           /* this seems necessary to get things
+                                  in sync */
+    handle_xevent();
+  while (1) 
+    {
+
+      FD_ZERO(&readfds);
+      FD_SET(ConnectionNumber(dpy),&readfds);
+      FD_SET(socket_fd,&readfds);
+
+      if (select(8*sizeof(readfds),&readfds,
+                (fd_set *)0,(fd_set *)0, (struct timeval *)0) < 0)
+       {
+         fprintf(stderr,"Error in select\n");
+         exit(1);
+       }
+
+      if (FD_ISSET(socket_fd,&readfds))
+       handle_connection(socket_fd);
+       
+      while (XPending(dpy))
+       handle_xevent();
+    }
+
+  XCloseDisplay (dpy);
+  exit (0);
+}
diff --git a/gdk/x11/gxid_lib.c b/gdk/x11/gxid_lib.c
new file mode 100644 (file)
index 0000000..357b764
--- /dev/null
@@ -0,0 +1,116 @@
+/* 
+ * gxid version 0.3
+ *
+ * Copyright 1997 Owen Taylor <owt1@cornell.edu>
+*/
+
+#include "../config.h"
+
+#ifdef XINPUT_GXI
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+#include "gxid_lib.h"
+
+/* handles mechanics of communicating with a client */
+static int 
+gxid_send_message(char *host, int port, GxidMessage *msg)
+{
+  int socket_fd;
+  struct sockaddr_in sin;
+  int count;
+  GxidI32 retval;
+  struct hostent *he;
+
+  if (!port) port = 6951;
+
+  if (!host || strcmp(host,"localhost") )
+    {
+      /* looking it up as localhost can be _SLOW_ on ppp systems */
+      /* FIXME: Could localhost be anything other than loopback? */
+      host = "127.0.0.1";
+    }
+
+  he = gethostbyname(host);
+  if (!he)
+    {
+      fprintf(stderr,"gxid_lib: error looking up %s\n",host);
+      return GXID_RETURN_ERROR;
+    }
+
+  sin.sin_family = he->h_addrtype;
+  sin.sin_port = htons(port);
+  memcpy(&sin.sin_addr,he->h_addr_list[0],he->h_length);
+
+  socket_fd = socket(AF_INET,SOCK_STREAM,0);
+  if (socket_fd < 0)
+    {
+      fprintf(stderr,"gxid_lib: can't get socket");
+      return GXID_RETURN_ERROR;
+    }
+
+  if (connect(socket_fd, (struct sockaddr *)&sin, 
+             sizeof sin) < 0)
+    {
+      fprintf(stderr,"gxid_lib: can't connect to %s:%d\n",host,port);
+      close(socket_fd);
+      return GXID_RETURN_ERROR;
+    }
+
+  count = write(socket_fd,(char *)msg,ntohl(msg->any.length));
+  if (count != ntohl(msg->any.length))
+    {
+      fprintf(stderr,"gxid_lib: error writing");
+      close(socket_fd);
+      return GXID_RETURN_ERROR;
+    }
+
+  /* now read the return code */
+  count = read(socket_fd,(char *)&retval,sizeof(GxidI32));
+  if (count != sizeof(GxidI32))
+    {
+      fprintf(stderr,"gxid_lib: error reading return code");
+      close(socket_fd);
+      return GXID_RETURN_ERROR;
+    }
+
+  close (socket_fd);
+  return ntohl(retval);
+}
+
+/* claim a device. If exclusive, device is claimed exclusively */
+int 
+gxid_claim_device(char *host, int port, GxidU32 device, GxidU32 window,
+                 int exclusive)
+{
+  GxidClaimDevice msg;
+  msg.type = htonl(GXID_CLAIM_DEVICE);
+  msg.length = htonl(sizeof(GxidClaimDevice));
+  msg.device = htonl(device);
+  msg.window = htonl(window);
+  msg.exclusive = htonl(exclusive);
+
+  return gxid_send_message(host,port,(GxidMessage *)&msg);
+}
+
+/* release a device/window pair */
+int 
+gxid_release_device(char *host, int port, GxidU32 device, GxidU32 window)
+{
+  GxidReleaseDevice msg;
+  msg.type = htonl(GXID_RELEASE_DEVICE);
+  msg.length = htonl(sizeof(GxidReleaseDevice));
+  msg.device = htonl(device);
+  msg.window = htonl(window);
+
+  return gxid_send_message(host,port,(GxidMessage *)&msg);
+}
+
+#endif /* XINPUT_GXI */
+
diff --git a/gdk/x11/gxid_lib.h b/gdk/x11/gxid_lib.h
new file mode 100644 (file)
index 0000000..6a7103b
--- /dev/null
@@ -0,0 +1,6 @@
+#include "gxid_proto.h"
+
+int gxid_claim_device(char *host, int port, 
+                     GxidU32 device, GxidU32 window, int exclusive);
+int gxid_release_device(char *host, int port, GxidU32 device, 
+                       GxidU32 window);
diff --git a/gdk/x11/gxid_proto.h b/gdk/x11/gxid_proto.h
new file mode 100644 (file)
index 0000000..24959b8
--- /dev/null
@@ -0,0 +1,39 @@
+#define GXID_CLAIM_DEVICE       1
+#define GXID_RELEASE_DEVICE     2
+
+#define GXID_RETURN_OK          0
+#define GXID_RETURN_ERROR       -1
+
+typedef struct GxidClaimDevice_ GxidClaimDevice;
+typedef struct GxidReleaseDevice_ GxidReleaseDevice;
+typedef struct GxidMessageAny_ GxidMessageAny;
+typedef union GxidMessage_ GxidMessage;
+
+typedef unsigned long GxidU32;
+typedef long GxidI32;
+
+struct GxidClaimDevice_ {
+  GxidU32 type;
+  GxidU32 length;
+  GxidU32 device;
+  GxidU32 window;
+  GxidU32 exclusive;
+};
+
+struct GxidReleaseDevice_ {
+  GxidU32 type;
+  GxidU32 length;
+  GxidU32 device;
+  GxidU32 window;
+};
+
+struct GxidMessageAny_ {
+  GxidU32 type;
+  GxidU32 length;
+};
+
+union GxidMessage_ {
+  GxidMessageAny any;
+  GxidClaimDevice claim;
+  GxidReleaseDevice release;
+};
diff --git a/glib/.cvsignore b/glib/.cvsignore
new file mode 100644 (file)
index 0000000..e0d0bd2
--- /dev/null
@@ -0,0 +1,11 @@
+*.lo
+config.log
+libtool
+config.status
+stamp-h
+Makefile
+.deps
+_libs
+libglib.la
+testglib
+glibconfig.h
diff --git a/glib/AUTHORS b/glib/AUTHORS
new file mode 100644 (file)
index 0000000..67f4e56
--- /dev/null
@@ -0,0 +1 @@
+Peter Mattis (petm@xcf.berkeley.edu)
diff --git a/glib/COPYING b/glib/COPYING
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/glib/ChangeLog b/glib/ChangeLog
new file mode 100644 (file)
index 0000000..b119426
--- /dev/null
@@ -0,0 +1,10 @@
+Tue Dec 17 13:14:07 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * glib.h: Changed 'g_return_if_fail' and 'g_return_val_if_fail' to
+       not call 'g_string' but to simply stringify the
+       expression. Calling 'g_string' causes the expression to be
+       expanded which is undesired.
+
+Sun Dec  1 01:30:48 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * Started ChangeLog
diff --git a/glib/INSTALL b/glib/INSTALL
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/glib/Makefile.am b/glib/Makefile.am
new file mode 100644 (file)
index 0000000..18afb93
--- /dev/null
@@ -0,0 +1,38 @@
+## Process this file with automake to produce Makefile.in
+
+lib_LTLIBRARIES = libglib.la
+
+libglib_la_SOURCES = \
+               garray.c        \
+               gcache.c        \
+               gerror.c        \
+               ghash.c         \
+               glist.c         \
+               gmem.c          \
+               gprimes.c       \
+               gslist.c        \
+               gtimer.c        \
+               gtree.c         \
+               gutils.c        \
+               gstring.c
+
+include_HEADERS = \
+               glib.h \
+               glibconfig.h
+
+libglib_la_LDFLAGS = -version-info 1:0:0
+
+INCLUDES =
+
+noinst_PROGRAMS = testglib
+testglib_LDADD = $(top_builddir)/libglib.la
+
+.PHONY: files release
+
+files:
+       @files=`ls $(DISTFILES) 2> /dev/null `; for p in $$files; do \
+         echo $$p; \
+       done
+
+release:
+       $(MAKE) dist distdir=$(PACKAGE)`date +"%y%m%d"`
diff --git a/glib/NEWS b/glib/NEWS
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/glib/README b/glib/README
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/glib/acconfig.h b/glib/acconfig.h
new file mode 100644 (file)
index 0000000..48ca75f
--- /dev/null
@@ -0,0 +1,62 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/* acconfig.h
+   This file is in the public domain.
+
+   Descriptive text for the C preprocessor macros that
+   the distributed Autoconf macros can define.
+   No software package will use all of them; autoheader copies the ones
+   your configure.in uses into your configuration header file templates.
+
+   The entries are in sort -df order: alphabetical, case insensitive,
+   ignoring punctuation (such as underscores).  Although this order
+   can split up related entries, it makes it easier to check whether
+   a given entry is in the file.
+
+   Leave the following blank line there!!  Autoheader needs it.  */
+\f
+
+/* Other stuff */
+#undef HAVE_DOPRNT
+#undef HAVE_FLOAT_H
+#undef HAVE_LIMITS_H
+#undef HAVE_LONG_DOUBLE
+#undef HAVE_SYS_SELECT_H
+#undef HAVE_STRERROR
+#undef HAVE_STRSIGNAL
+#undef HAVE_VALUES_H
+#undef HAVE_VPRINTF
+
+#undef NO_FD_SET
+#undef NO_SYS_ERRLIST
+#undef NO_SYS_SIGLIST
+
+#undef SIZEOF_CHAR
+#undef SIZEOF_SHORT
+#undef SIZEOF_LONG
+#undef SIZEOF_INT
+#undef SIZEOF_VOID_P
+
+/* #undef PACKAGE */
+/* #undef VERSION */
+
+\f
+/* Leave that blank line there!!  Autoheader needs it.
+   If you're adding to this file, keep in mind:
+   The entries are in sort -df order: alphabetical, case insensitive,
+   ignoring punctuation (such as underscores).  */
diff --git a/glib/aclocal.m4 b/glib/aclocal.m4
new file mode 100644 (file)
index 0000000..9f99ab8
--- /dev/null
@@ -0,0 +1,395 @@
+dnl aclocal.m4 generated automatically by aclocal 1.2
+
+# Do all the work for Automake.  This macro actually does too much --
+# some checks are only needed if your package does certain things.
+# But this isn't really a big deal.
+
+# serial 1
+
+dnl Usage:
+dnl AM_INIT_AUTOMAKE(package,version, [no-define])
+
+AC_DEFUN(AM_INIT_AUTOMAKE,
+[AC_REQUIRE([AM_PROG_INSTALL])
+PACKAGE=[$1]
+AC_SUBST(PACKAGE)
+VERSION=[$2]
+AC_SUBST(VERSION)
+dnl test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+  AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+ifelse([$3],,
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE")
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION"))
+AM_SANITY_CHECK
+AC_ARG_PROGRAM
+dnl FIXME This is truly gross.
+missing_dir=`cd $ac_aux_dir && pwd`
+AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
+AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
+AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
+AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
+AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
+AC_PROG_MAKE_SET])
+
+
+# serial 1
+
+AC_DEFUN(AM_PROG_INSTALL,
+[AC_REQUIRE([AC_PROG_INSTALL])
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+AC_SUBST(INSTALL_SCRIPT)dnl
+])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+AC_DEFUN(AM_SANITY_CHECK,
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+   if test "$@" = "X"; then
+      # -L didn't work.
+      set X `ls -t $srcdir/configure conftestfile`
+   fi
+   test "[$]2" = conftestfile
+   )
+then
+   # Ok.
+   :
+else
+   AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+rm -f conftest*
+AC_MSG_RESULT(yes)])
+
+dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
+dnl The program must properly implement --version.
+AC_DEFUN(AM_MISSING_PROG,
+[AC_MSG_CHECKING(for working $2)
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if ($2 --version) < /dev/null > /dev/null 2>&1; then
+   $1=$2
+   AC_MSG_RESULT(found)
+else
+   $1="$3/missing $2"
+   AC_MSG_RESULT(missing)
+fi
+AC_SUBST($1)])
+
+# Like AC_CONFIG_HEADER, but automatically create stamp file.
+
+AC_DEFUN(AM_CONFIG_HEADER,
+[AC_PREREQ([2.12])
+AC_CONFIG_HEADER([$1])
+dnl When config.status generates a header, we must update the stamp-h file.
+dnl This file resides in the same directory as the config header
+dnl that is generated.  We must strip everything past the first ":",
+dnl and everything past the last "/".
+AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl
+ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>,
+<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>,
+<<am_indx=1
+for am_file in <<$1>>; do
+  case " <<$>>CONFIG_HEADERS " in
+  *" <<$>>am_file "*<<)>>
+    echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx
+    ;;
+  esac
+  am_indx=`expr "<<$>>am_indx" + 1`
+done<<>>dnl>>)
+changequote([,]))])
+
+
+# serial 17 AM_PROG_LIBTOOL
+AC_DEFUN(AM_PROG_LIBTOOL,
+[AC_REQUIRE([AC_CANONICAL_HOST])
+AC_REQUIRE([AC_PROG_RANLIB])
+AC_REQUIRE([AC_PROG_CC])
+AC_REQUIRE([AM_PROG_LD])
+AC_REQUIRE([AM_PROG_NM])
+AC_REQUIRE([AC_PROG_LN_S])
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)
+
+dnl Allow the --disable-shared flag to stop us from building shared libs.
+AC_ARG_ENABLE(shared,
+[  --enable-shared         build shared libraries [default=yes]],
+[if test "$enableval" = no; then
+  libtool_enable_shared=no
+else
+  libtool_enable_shared=yes
+fi])
+test -n "$libtool_enable_shared" && enable_shared="$libtool_enable_shared"
+libtool_shared=
+test "$enable_shared" = no && libtool_shared=" --disable-shared"
+
+dnl Allow the --disable-static flag to stop us from building static libs.
+AC_ARG_ENABLE(static,
+[  --enable-static         build static libraries [default=yes]],
+[if test "$enableval" = no; then
+  libtool_enable_static=no
+else
+  libtool_enable_static=yes
+fi])
+test -n "$libtool_enable_static" && enable_static="$libtool_enable_static"
+libtool_static=
+test "$enable_static" = no && libtool_static=" --disable-static"
+
+libtool_flags="$libtool_shared$libtool_static"
+test "$silent" = yes && libtool_flags="$libtool_flags --silent"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+[case "$host" in
+*-*-irix6*)
+  ac_save_CFLAGS="$CFLAGS"
+  flag_passed=no
+  for f in -32 -64 -n32 ABI -cckr -mips1 -mips2 -mips3 -mips4; do
+    case "$f" in
+    ABI)
+      test -n "$SGI_ABI" && flag_passed=yes
+      if test "$flag_passed" = no && test "$ac_cv_prog_gcc" = yes; then
+       # Choose the ABI flag according to GCC's specs.
+       if $CC -dumpspecs 2>&1 | sed '/^\*link:$/,/^$/!d' | egrep -e '[         ]-32' >/dev/null; then
+         LD="${LD-ld} -32"
+       else
+         LD="${LD-ld} -n32"
+       fi
+      fi
+      ;;
+
+    *)
+      if echo " $CC $CFLAGS " | egrep -e "[    ]$f[     ]" > /dev/null; then
+       flag_passed=yes
+       LD="${LD-ld} $f"
+      fi
+      ;;
+    esac
+  done
+  CFLAGS="$ac_save_CFLAGS"
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  CFLAGS="$CFLAGS -belf"
+  ;;
+esac]
+
+# Actually configure libtool.  ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" NM="$NM" RANLIB="$RANLIB" LN_S="$LN_S" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+|| AC_MSG_ERROR([libtool configure failed])
+])
+
+# AM_PROG_LD - find the path to the GNU or non-GNU linker
+AC_DEFUN(AM_PROG_LD,
+[AC_ARG_WITH(gnu-ld,
+[  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  AC_MSG_CHECKING([for ld used by GCC])
+  ac_prog=`($CC -print-prog-name=ld) 2>&5`
+  case "$ac_prog" in
+  # Accept absolute paths.
+  /*)
+    test -z "$LD" && LD="$ac_prog"
+    ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  AC_MSG_CHECKING([for GNU ld])
+else
+  AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(ac_cv_path_LD,
+[if test -z "$LD"; then
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog"; then
+      ac_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some GNU ld's only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+       test "$with_gnu_ld" != no && break
+      else
+        test "$with_gnu_ld" != yes && break
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+else
+  ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+  AC_MSG_RESULT($LD)
+else
+  AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_SUBST(LD)
+AM_PROG_LD_GNU
+])
+
+AC_DEFUN(AM_PROG_LD_GNU,
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  ac_cv_prog_gnu_ld=yes
+else
+  ac_cv_prog_gnu_ld=no
+fi])
+])
+
+# AM_PROG_NM - find the path to a BSD-compatible name lister
+AC_DEFUN(AM_PROG_NM,
+[AC_MSG_CHECKING([for BSD-compatible nm])
+AC_CACHE_VAL(ac_cv_path_NM,
+[case "$NM" in
+/*)
+  ac_cv_path_NM="$NM" # Let the user override the test with a path.
+  ;;
+*)
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in /usr/ucb $PATH /bin; do
+    test -z "$ac_dir" && dir=.
+    if test -f $ac_dir/nm; then
+      # Check to see if the nm accepts a BSD-compat flag.
+      if ($ac_dir/nm -B /dev/null 2>&1; exit 0) | grep /dev/null >/dev/null; then
+        ac_cv_path_NM="$ac_dir/nm -B"
+      elif ($ac_dir/nm -p /dev/null 2>&1; exit 0) | grep /dev/null >/dev/null; then
+        ac_cv_path_NM="$ac_dir/nm -p"
+      else
+        ac_cv_path_NM="$ac_dir/nm"
+      fi
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+  ;;
+esac])
+NM="$ac_cv_path_NM"
+AC_MSG_RESULT([$NM])
+AC_SUBST(NM)
+])
+
+# Add --enable-maintainer-mode option to configure.
+# From Jim Meyering
+
+# serial 1
+
+AC_DEFUN(AM_MAINTAINER_MODE,
+[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+  dnl maintainer-mode is disabled by default
+  AC_ARG_ENABLE(maintainer-mode,
+[  --enable-maintainer-mode enable make rules and dependencies not useful
+                          (and sometimes confusing) to the casual installer],
+      USE_MAINTAINER_MODE=$enableval,
+      USE_MAINTAINER_MODE=no)
+  AC_MSG_RESULT($USE_MAINTAINER_MODE)
+  if test $USE_MAINTAINER_MODE = yes; then
+    MAINT=
+  else
+    MAINT='#M#'
+  fi
+  AC_SUBST(MAINT)dnl
+]
+)
+
+
+# serial 1
+
+# @defmac AC_PROG_CC_STDC
+# @maindex PROG_CC_STDC
+# @ovindex CC
+# If the C compiler in not in ANSI C mode by default, try to add an option
+# to output variable @code{CC} to make it so.  This macro tries various
+# options that select ANSI C on some system or another.  It considers the
+# compiler to be in ANSI C mode if it defines @code{__STDC__} to 1 and
+# handles function prototypes correctly.
+#
+# If you use this macro, you should check after calling it whether the C
+# compiler has been set to accept ANSI C; if not, the shell variable
+# @code{am_cv_prog_cc_stdc} is set to @samp{no}.  If you wrote your source
+# code in ANSI C, you can make an un-ANSIfied copy of it by using the
+# program @code{ansi2knr}, which comes with Ghostscript.
+# @end defmac
+
+AC_DEFUN(AM_PROG_CC_STDC,
+[AC_REQUIRE([AC_PROG_CC])
+AC_BEFORE([$0], [AC_C_INLINE])
+AC_BEFORE([$0], [AC_C_CONST])
+AC_MSG_CHECKING(for ${CC-cc} option to accept ANSI C)
+AC_CACHE_VAL(am_cv_prog_cc_stdc,
+[am_cv_prog_cc_stdc=no
+ac_save_CC="$CC"
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX                  -qlanglvl=ansi
+# Ultrix and OSF/1     -std1
+# HP-UX                        -Aa -D_HPUX_SOURCE
+# SVR4                 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  AC_TRY_COMPILE(
+[#if !defined(__STDC__) || __STDC__ != 1
+choke me
+#endif
+/* DYNIX/ptx V4.1.3 can't compile sys/stat.h with -Xc -D__EXTENSIONS__. */
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/stat.h>
+#endif
+], [
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};],
+[am_cv_prog_cc_stdc="$ac_arg"; break])
+done
+CC="$ac_save_CC"
+])
+if test -z "$am_cv_prog_cc_stdc"; then
+  AC_MSG_RESULT([none needed])
+else
+  AC_MSG_RESULT($am_cv_prog_cc_stdc)
+fi
+case "x$am_cv_prog_cc_stdc" in
+  x|xno) ;;
+  *) CC="$CC $am_cv_prog_cc_stdc" ;;
+esac
+])
+
diff --git a/glib/config.guess b/glib/config.guess
new file mode 100755 (executable)
index 0000000..413ed41
--- /dev/null
@@ -0,0 +1,883 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Written by Per Bothner <bothner@cygnus.com>.
+# The master version of this file is at the FSF in /home/gd/gnu/lib.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit system type (host/target name).
+#
+# Only a few systems have been added to this list; please add others
+# (but try to keep the structure clean).
+#
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 8/24/94.)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+       PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    alpha:OSF1:*:*)
+       if test $UNAME_RELEASE = "V4.0"; then
+               UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+       fi
+       # A Vn.n version is a released version.
+       # A Tn.n version is a released field test version.
+       # A Xn.n version is an unreleased experimental baselevel.
+       # 1.2 uses "1.2" for uname -r.
+       cat <<EOF >dummy.s
+       .globl main
+       .ent main
+main:
+       .frame \$30,0,\$26,0
+       .prologue 0
+       .long 0x47e03d80 # implver $0
+       lda \$2,259
+       .long 0x47e20c21 # amask $2,$1
+       srl \$1,8,\$2
+       sll \$2,2,\$2
+       sll \$0,3,\$0
+       addl \$1,\$0,\$0
+       addl \$2,\$0,\$0
+       ret \$31,(\$26),1
+       .end main
+EOF
+       ${CC-cc} dummy.s -o dummy 2>/dev/null
+       if test "$?" = 0 ; then
+               ./dummy
+               case "$?" in
+                       7)
+                               UNAME_MACHINE="alpha"
+                               ;;
+                       15)
+                               UNAME_MACHINE="alphaev5"
+                               ;;
+                       14)
+                               UNAME_MACHINE="alphaev56"
+                               ;;
+                       10)
+                               UNAME_MACHINE="alphapca56"
+                               ;;
+                       16)
+                               UNAME_MACHINE="alphaev6"
+                               ;;
+               esac
+       fi
+       rm -f dummy.s dummy
+       echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr [[A-Z]] [[a-z]]`
+       exit 0 ;;
+    21064:Windows_NT:50:3)
+       echo alpha-dec-winnt3.5
+       exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+       echo m68k-cbm-sysv4
+       exit 0;;
+    amiga:NetBSD:*:*)
+      echo m68k-cbm-netbsd${UNAME_RELEASE}
+      exit 0 ;;
+    amiga:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    arc64:OpenBSD:*:*)
+       echo mips64el-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    arc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    hkmips:OpenBSD:*:*)
+       echo mips-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    pmax:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    sgi:OpenBSD:*:*)
+       echo mips-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    wgrisc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+       echo arm-acorn-riscix${UNAME_RELEASE}
+       exit 0;;
+    arm32:NetBSD:*:*)
+       echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+       exit 0 ;;
+    SR2?01:HI-UX/MPP:*:*)
+       echo hppa1.1-hitachi-hiuxmpp
+       exit 0;;
+    Pyramid*:OSx*:*:*|MIS*:OSx*:*:*)
+       # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+       if test "`(/bin/universe) 2>/dev/null`" = att ; then
+               echo pyramid-pyramid-sysv3
+       else
+               echo pyramid-pyramid-bsd
+       fi
+       exit 0 ;;
+    NILE:*:*:dcosx)
+       echo pyramid-pyramid-svr4
+       exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+       echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    i86pc:SunOS:5.*:*)
+       echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:6*:*)
+       # According to config.sub, this is the proper way to canonicalize
+       # SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+       # it's likely to be more like Solaris than SunOS4.
+       echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:*:*)
+       case "`/usr/bin/arch -k`" in
+           Series*|S4*)
+               UNAME_RELEASE=`uname -v`
+               ;;
+       esac
+       # Japanese Language versions have a version number like `4.1.3-JL'.
+       echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+       exit 0 ;;
+    sun3*:SunOS:*:*)
+       echo m68k-sun-sunos${UNAME_RELEASE}
+       exit 0 ;;
+    sun*:*:4.2BSD:*)
+       UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+       test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+       case "`/bin/arch`" in
+           sun3)
+               echo m68k-sun-sunos${UNAME_RELEASE}
+               ;;
+           sun4)
+               echo sparc-sun-sunos${UNAME_RELEASE}
+               ;;
+       esac
+       exit 0 ;;
+    aushp:SunOS:*:*)
+       echo sparc-auspex-sunos${UNAME_RELEASE}
+       exit 0 ;;
+    atari*:NetBSD:*:*)
+       echo m68k-atari-netbsd${UNAME_RELEASE}
+       exit 0 ;;
+    atari*:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    sun3*:NetBSD:*:*)
+       echo m68k-sun-netbsd${UNAME_RELEASE}
+       exit 0 ;;
+    sun3*:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mac68k:NetBSD:*:*)
+       echo m68k-apple-netbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mac68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+       echo m88k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    powerpc:machten:*:*)
+       echo powerpc-apple-machten${UNAME_RELEASE}
+       exit 0 ;;
+    RISC*:Mach:*:*)
+       echo mips-dec-mach_bsd4.3
+       exit 0 ;;
+    RISC*:ULTRIX:*:*)
+       echo mips-dec-ultrix${UNAME_RELEASE}
+       exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+       echo vax-dec-ultrix${UNAME_RELEASE}
+       exit 0 ;;
+    2020:CLIX:*:*)
+       echo clipper-intergraph-clix${UNAME_RELEASE}
+       exit 0 ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+       sed 's/^        //' << EOF >dummy.c
+       int main (argc, argv) int argc; char **argv; {
+       #if defined (host_mips) && defined (MIPSEB)
+       #if defined (SYSTYPE_SYSV)
+         printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_SVR4)
+         printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+         printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+       #endif
+       #endif
+         exit (-1);
+       }
+EOF
+       ${CC-cc} dummy.c -o dummy \
+         && ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+         && rm dummy.c dummy && exit 0
+       rm -f dummy.c dummy
+       echo mips-mips-riscos${UNAME_RELEASE}
+       exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+       echo powerpc-harris-powerunix
+       exit 0 ;;
+    m88k:CX/UX:7*:*)
+       echo m88k-harris-cxux7
+       exit 0 ;;
+    m88k:*:4*:R4*)
+       echo m88k-motorola-sysv4
+       exit 0 ;;
+    m88k:*:3*:R3*)
+       echo m88k-motorola-sysv3
+       exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+        if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then
+       if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
+            -o ${TARGET_BINARY_INTERFACE}x = x ] ; then
+               echo m88k-dg-dgux${UNAME_RELEASE}
+       else
+               echo m88k-dg-dguxbcs${UNAME_RELEASE}
+       fi
+        else echo i586-dg-dgux${UNAME_RELEASE}
+        fi
+       exit 0 ;;
+    M88*:DolphinOS:*:*)        # DolphinOS (SVR3)
+       echo m88k-dolphin-sysv3
+       exit 0 ;;
+    M88*:*:R3*:*)
+       # Delta 88k system running SVR3
+       echo m88k-motorola-sysv3
+       exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+       echo m88k-tektronix-sysv3
+       exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+       echo m68k-tektronix-bsd
+       exit 0 ;;
+    *:IRIX*:*:*)
+       echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+       exit 0 ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+       echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+       exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i?86:AIX:*:*)
+       echo i386-ibm-aix
+       exit 0 ;;
+    *:AIX:2:3)
+       if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+               sed 's/^                //' << EOF >dummy.c
+               #include <sys/systemcfg.h>
+
+               main()
+                       {
+                       if (!__power_pc())
+                               exit(1);
+                       puts("powerpc-ibm-aix3.2.5");
+                       exit(0);
+                       }
+EOF
+               ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
+               rm -f dummy.c dummy
+               echo rs6000-ibm-aix3.2.5
+       elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+               echo rs6000-ibm-aix3.2.4
+       else
+               echo rs6000-ibm-aix3.2
+       fi
+       exit 0 ;;
+    *:AIX:*:4)
+       if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then
+               IBM_ARCH=rs6000
+       else
+               IBM_ARCH=powerpc
+       fi
+       if [ -x /usr/bin/oslevel ] ; then
+               IBM_REV=`/usr/bin/oslevel`
+       else
+               IBM_REV=4.${UNAME_RELEASE}
+       fi
+       echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+       exit 0 ;;
+    *:AIX:*:*)
+       echo rs6000-ibm-aix
+       exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+       echo romp-ibm-bsd4.4
+       exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC NetBSD and
+       echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+       exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+       echo rs6000-bull-bosx
+       exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+       echo m68k-bull-sysv3
+       exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+       echo m68k-hp-bsd
+       exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+       echo m68k-hp-bsd4.4
+       exit 0 ;;
+    9000/[3478]??:HP-UX:*:*)
+       case "${UNAME_MACHINE}" in
+           9000/31? )            HP_ARCH=m68000 ;;
+           9000/[34]?? )         HP_ARCH=m68k ;;
+           9000/7?? | 9000/8?[1679] ) HP_ARCH=hppa1.1 ;;
+           9000/8?? )            HP_ARCH=hppa1.0 ;;
+       esac
+       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+       echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+       exit 0 ;;
+    3050*:HI-UX:*:*)
+       sed 's/^        //' << EOF >dummy.c
+       #include <unistd.h>
+       int
+       main ()
+       {
+         long cpu = sysconf (_SC_CPU_VERSION);
+         /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+            true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+            results, however.  */
+         if (CPU_IS_PA_RISC (cpu))
+           {
+             switch (cpu)
+               {
+                 case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+                 default: puts ("hppa-hitachi-hiuxwe2"); break;
+               }
+           }
+         else if (CPU_IS_HP_MC68K (cpu))
+           puts ("m68k-hitachi-hiuxwe2");
+         else puts ("unknown-hitachi-hiuxwe2");
+         exit (0);
+       }
+EOF
+       ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
+       rm -f dummy.c dummy
+       echo unknown-hitachi-hiuxwe2
+       exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+       echo hppa1.1-hp-bsd
+       exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+       echo hppa1.0-hp-bsd
+       exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+       echo hppa1.1-hp-osf
+       exit 0 ;;
+    hp8??:OSF1:*:*)
+       echo hppa1.0-hp-osf
+       exit 0 ;;
+    i?86:OSF1:*:*)
+       if [ -x /usr/sbin/sysversion ] ; then
+           echo ${UNAME_MACHINE}-unknown-osf1mk
+       else
+           echo ${UNAME_MACHINE}-unknown-osf1
+       fi
+       exit 0 ;;
+    parisc*:Lites*:*:*)
+       echo hppa1.1-hp-lites
+       exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+       echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+       echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+       echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+       echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*X-MP:*:*:*)
+       echo xmp-cray-unicos
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+       echo ymp-cray-unicos${UNAME_RELEASE}
+       exit 0 ;;
+    CRAY*[A-Z]90:*:*:*)
+       echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+       | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+             -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
+       exit 0 ;;
+    CRAY*TS:*:*:*)
+       echo t90-cray-unicos${UNAME_RELEASE}
+       exit 0 ;;
+    CRAY-2:*:*:*)
+       echo cray2-cray-unicos
+        exit 0 ;;
+    F300:UNIX_System_V:*:*)
+        FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit 0 ;;
+    F301:UNIX_System_V:*:*)
+       echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
+       exit 0 ;;
+    hp3[0-9][05]:NetBSD:*:*)
+       echo m68k-hp-netbsd${UNAME_RELEASE}
+       exit 0 ;;
+    hp300:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    i?86:BSD/386:*:* | *:BSD/OS:*:*)
+       echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    *:FreeBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+       exit 0 ;;
+    *:NetBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+       exit 0 ;;
+    *:OpenBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+       exit 0 ;;
+    i*:CYGWIN*:*)
+       echo i386-pc-cygwin32
+       exit 0 ;;
+    i*:MINGW*:*)
+       echo i386-pc-mingw32
+       exit 0 ;;
+    p*:CYGWIN*:*)
+       echo powerpcle-unknown-cygwin32
+       exit 0 ;;
+    prep*:SunOS:5.*:*)
+       echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    *:GNU:*:*)
+       echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+       exit 0 ;;
+    *:Linux:*:*)
+       # The BFD linker knows what the default object file format is, so
+       # first see if it will tell us.
+       ld_help_string=`ld --help 2>&1`
+       ld_supported_emulations=`echo $ld_help_string \
+                        | sed -ne '/supported emulations:/!d
+                                   s/[         ][      ]*/ /g
+                                   s/.*supported emulations: *//
+                                   s/ .*//
+                                   p'`
+        case "$ld_supported_emulations" in
+         i?86linux)  echo "${UNAME_MACHINE}-pc-linux-gnuaout"      ; exit 0 ;;
+         i?86coff)   echo "${UNAME_MACHINE}-pc-linux-gnucoff"      ; exit 0 ;;
+         sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+         m68klinux)  echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+         elf32ppc)   echo "powerpc-unknown-linux-gnu"              ; exit 0 ;;
+       esac
+
+       if test "${UNAME_MACHINE}" = "alpha" ; then
+               sed 's/^        //'  <<EOF >dummy.s
+               .globl main
+               .ent main
+       main:
+               .frame \$30,0,\$26,0
+               .prologue 0
+               .long 0x47e03d80 # implver $0
+               lda \$2,259
+               .long 0x47e20c21 # amask $2,$1
+               srl \$1,8,\$2
+               sll \$2,2,\$2
+               sll \$0,3,\$0
+               addl \$1,\$0,\$0
+               addl \$2,\$0,\$0
+               ret \$31,(\$26),1
+               .end main
+EOF
+               LIBC=""
+               ${CC-cc} dummy.s -o dummy 2>/dev/null
+               if test "$?" = 0 ; then
+                       ./dummy
+                       case "$?" in
+                       7)
+                               UNAME_MACHINE="alpha"
+                               ;;
+                       15)
+                               UNAME_MACHINE="alphaev5"
+                               ;;
+                       14)
+                               UNAME_MACHINE="alphaev56"
+                               ;;
+                       10)
+                               UNAME_MACHINE="alphapca56"
+                               ;;
+                       16)
+                               UNAME_MACHINE="alphaev6"
+                               ;;
+                       esac    
+
+                       objdump --private-headers dummy | \
+                         grep ld.so.1 > /dev/null
+                       if test "$?" = 0 ; then
+                               LIBC="libc1"
+                       fi
+               fi      
+               rm -f dummy.s dummy
+               echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0
+       elif test "${UNAME_MACHINE}" = "mips" ; then
+         cat >dummy.c <<EOF
+main(argc, argv)
+     int argc;
+     char *argv[];
+{
+#ifdef __MIPSEB__
+  printf ("%s-unknown-linux-gnu\n", argv[1]);
+#endif
+#ifdef __MIPSEL__
+  printf ("%sel-unknown-linux-gnu\n", argv[1]);
+#endif
+  return 0;
+}
+EOF
+         ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
+         rm -f dummy.c dummy
+       else
+         # Either a pre-BFD a.out linker (linux-gnuoldld)
+         # or one that does not give us useful --help.
+         # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout.
+         # If ld does not provide *any* "supported emulations:"
+         # that means it is gnuoldld.
+         echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:"
+         test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
+
+         case "${UNAME_MACHINE}" in
+         i?86)
+           VENDOR=pc;
+           ;;
+         *)
+           VENDOR=unknown;
+           ;;
+         esac
+         # Determine whether the default compiler is a.out or elf
+         cat >dummy.c <<EOF
+#include <features.h>
+main(argc, argv)
+     int argc;
+     char *argv[];
+{
+#ifdef __ELF__
+# ifdef __GLIBC__
+#  if __GLIBC__ >= 2
+    printf ("%s-${VENDOR}-linux-gnu\n", argv[1]);
+#  else
+    printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+#  endif
+# else
+   printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
+#else
+  printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]);
+#endif
+  return 0;
+}
+EOF
+         ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
+         rm -f dummy.c dummy
+       fi ;;
+# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.  earlier versions
+# are messed up and put the nodename in both sysname and nodename.
+    i?86:DYNIX/ptx:4*:*)
+       echo i386-sequent-sysv4
+       exit 0 ;;
+    i?86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+       # I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+       echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+       exit 0 ;;
+    i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
+       if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+               echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
+       else
+               echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
+       fi
+       exit 0 ;;
+    i?86:*:3.2:*)
+       if test -f /usr/options/cb.name; then
+               UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+               echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+       elif /bin/uname -X 2>/dev/null >/dev/null ; then
+               UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+               (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+               (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+                       && UNAME_MACHINE=i586
+               echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+       else
+               echo ${UNAME_MACHINE}-pc-sysv32
+       fi
+       exit 0 ;;
+    pc:*:*:*)
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+       echo i386-pc-msdosdjgpp
+        exit 0 ;;
+    Intel:Mach:3*:*)
+       echo i386-pc-mach3
+       exit 0 ;;
+    paragon:*:*:*)
+       echo i860-intel-osf1
+       exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+       if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+         echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+       else # Add other i860-SVR4 vendors below as they are discovered.
+         echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+       fi
+       exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+       # "miniframe"
+       echo m68010-convergent-sysv
+       exit 0 ;;
+    M68*:*:R3V[567]*:*)
+       test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+       OS_REL=''
+       test -r /etc/.relid \
+       && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+       /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+         && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+       /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+         && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:*)
+       echo m68k-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+       echo m68k-atari-sysv4
+       exit 0 ;;
+    i?86:LynxOS:2.*:*)
+       echo i386-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+       echo sparc-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*)
+       echo rs6000-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+       echo mips-dde-sysv${UNAME_RELEASE}
+       exit 0 ;;
+    RM*:SINIX-*:*:*)
+       echo mips-sni-sysv4
+       exit 0 ;;
+    *:SINIX-*:*:*)
+       if uname -p 2>/dev/null >/dev/null ; then
+               UNAME_MACHINE=`(uname -p) 2>/dev/null`
+               echo ${UNAME_MACHINE}-sni-sysv4
+       else
+               echo ns32k-sni-sysv
+       fi
+       exit 0 ;;
+    PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                           # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+       # From Gerald Hewes <hewes@openmarket.com>.
+       # How about differentiating between stratus architectures? -djm
+       echo hppa1.1-stratus-sysv4
+       exit 0 ;;
+    *:*:*:FTX*)
+       # From seanf@swdc.stratus.com.
+       echo i860-stratus-sysv4
+       exit 0 ;;
+    mc68*:A/UX:*:*)
+       echo m68k-apple-aux${UNAME_RELEASE}
+       exit 0 ;;
+    news*:NEWS-OS:*:6*)
+       echo mips-sony-newsos6
+       exit 0 ;;
+    R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:*)
+       if [ -d /usr/nec ]; then
+               echo mips-nec-sysv${UNAME_RELEASE}
+       else
+               echo mips-unknown-sysv${UNAME_RELEASE}
+       fi
+        exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+cat >dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+         ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+       printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+       printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+#if !defined (ultrix)
+  printf ("vax-dec-bsd\n"); exit (0);
+#else
+  printf ("vax-dec-ultrix\n"); exit (0);
+#endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0
+rm -f dummy.c dummy
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+       echo c1-convex-bsd
+       exit 0 ;;
+    c2*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+       exit 0 ;;
+    c34*)
+       echo c34-convex-bsd
+       exit 0 ;;
+    c38*)
+       echo c38-convex-bsd
+       exit 0 ;;
+    c4*)
+       echo c4-convex-bsd
+       exit 0 ;;
+    esac
+fi
+
+#echo '(Unable to guess system type)' 1>&2
+
+exit 1
diff --git a/glib/config.sub b/glib/config.sub
new file mode 100755 (executable)
index 0000000..213a6d4
--- /dev/null
@@ -0,0 +1,954 @@
+#! /bin/sh
+# Configuration validation subroutine script, version 1.1.
+#   Copyright (C) 1991, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#      CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#      CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+if [ x$1 = x ]
+then
+       echo Configuration name missing. 1>&2
+       echo "Usage: $0 CPU-MFR-OPSYS" 1>&2
+       echo "or     $0 ALIAS" 1>&2
+       echo where ALIAS is a recognized configuration type. 1>&2
+       exit 1
+fi
+
+# First pass through any local machine types.
+case $1 in
+       *local*)
+               echo $1
+               exit 0
+               ;;
+       *)
+       ;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  linux-gnu*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+       -sun*os*)
+               # Prevent following clause from handling this invalid input.
+               ;;
+       -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+       -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+       -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+       -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+       -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+       -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+       -apple)
+               os=
+               basic_machine=$1
+               ;;
+       -hiux*)
+               os=-hiuxwe2
+               ;;
+       -sco5)
+               os=sco3.2v5
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco4)
+               os=-sco3.2v4
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2.[4-9]*)
+               os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2v[4-9]*)
+               # Don't forget version if it is 3.2v4 or newer.
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco*)
+               os=-sco3.2v2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -isc)
+               os=-isc2.2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -clix*)
+               basic_machine=clipper-intergraph
+               ;;
+       -isc*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -lynx*)
+               os=-lynxos
+               ;;
+       -ptx*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+               ;;
+       -windowsnt*)
+               os=`echo $os | sed -e 's/windowsnt/winnt/'`
+               ;;
+       -psos*)
+               os=-psos
+               ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+       # Recognize the basic CPU types without company name.
+       # Some are omitted here because they have special meanings below.
+       tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
+               | arme[lb] | pyramid | mn10200 | mn10300 \
+               | tron | a29k | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 \
+               | alpha | alphaev5 | alphaev56 | we32k | ns16k | clipper \
+               | i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \
+               | mips64 | mipsel | mips64el | mips64orion | mips64orionel \
+               | mipstx39 | mipstx39el \
+               | sparc | sparclet | sparclite | sparc64 | v850)
+               basic_machine=$basic_machine-unknown
+               ;;
+       # We use `pc' rather than `unknown'
+       # because (1) that's what they normally are, and
+       # (2) the word "unknown" tends to confuse beginning users.
+       i[3456]86)
+         basic_machine=$basic_machine-pc
+         ;;
+       # Object if more than one company name word.
+       *-*-*)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+       # Recognize the basic CPU types with company name.
+       vax-* | tahoe-* | i[3456]86-* | i860-* | m32r-* | m68k-* | m68000-* \
+             | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
+             | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
+             | power-* | none-* | 580-* | cray2-* | h8300-* | i960-* \
+             | xmp-* | ymp-* | hppa-* | hppa1.0-* | hppa1.1-* \
+             | alpha-* | alphaev5-* | alphaev56-* | we32k-* | cydra-* \
+             | ns16k-* | pn-* | np1-* | xps100-* | clipper-* | orion-* \
+             | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
+             | sparc64-* | mips64-* | mipsel-* \
+             | mips64el-* | mips64orion-* | mips64orionel-*  \
+             | mipstx39-* | mipstx39el-* \
+             | f301-*)
+               ;;
+       # Recognize the various machine names and aliases which stand
+       # for a CPU type and a company and sometimes even an OS.
+       3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+               basic_machine=m68000-att
+               ;;
+       3b*)
+               basic_machine=we32k-att
+               ;;
+       alliant | fx80)
+               basic_machine=fx80-alliant
+               ;;
+       altos | altos3068)
+               basic_machine=m68k-altos
+               ;;
+       am29k)
+               basic_machine=a29k-none
+               os=-bsd
+               ;;
+       amdahl)
+               basic_machine=580-amdahl
+               os=-sysv
+               ;;
+       amiga | amiga-*)
+               basic_machine=m68k-cbm
+               ;;
+       amigaos | amigados)
+               basic_machine=m68k-cbm
+               os=-amigaos
+               ;;
+       amigaunix | amix)
+               basic_machine=m68k-cbm
+               os=-sysv4
+               ;;
+       apollo68)
+               basic_machine=m68k-apollo
+               os=-sysv
+               ;;
+       aux)
+               basic_machine=m68k-apple
+               os=-aux
+               ;;
+       balance)
+               basic_machine=ns32k-sequent
+               os=-dynix
+               ;;
+       convex-c1)
+               basic_machine=c1-convex
+               os=-bsd
+               ;;
+       convex-c2)
+               basic_machine=c2-convex
+               os=-bsd
+               ;;
+       convex-c32)
+               basic_machine=c32-convex
+               os=-bsd
+               ;;
+       convex-c34)
+               basic_machine=c34-convex
+               os=-bsd
+               ;;
+       convex-c38)
+               basic_machine=c38-convex
+               os=-bsd
+               ;;
+       cray | ymp)
+               basic_machine=ymp-cray
+               os=-unicos
+               ;;
+       cray2)
+               basic_machine=cray2-cray
+               os=-unicos
+               ;;
+       [ctj]90-cray)
+               basic_machine=c90-cray
+               os=-unicos
+               ;;
+       crds | unos)
+               basic_machine=m68k-crds
+               ;;
+       da30 | da30-*)
+               basic_machine=m68k-da30
+               ;;
+       decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+               basic_machine=mips-dec
+               ;;
+       delta | 3300 | motorola-3300 | motorola-delta \
+             | 3300-motorola | delta-motorola)
+               basic_machine=m68k-motorola
+               ;;
+       delta88)
+               basic_machine=m88k-motorola
+               os=-sysv3
+               ;;
+       dpx20 | dpx20-*)
+               basic_machine=rs6000-bull
+               os=-bosx
+               ;;
+       dpx2* | dpx2*-bull)
+               basic_machine=m68k-bull
+               os=-sysv3
+               ;;
+       ebmon29k)
+               basic_machine=a29k-amd
+               os=-ebmon
+               ;;
+       elxsi)
+               basic_machine=elxsi-elxsi
+               os=-bsd
+               ;;
+       encore | umax | mmax)
+               basic_machine=ns32k-encore
+               ;;
+       fx2800)
+               basic_machine=i860-alliant
+               ;;
+       genix)
+               basic_machine=ns32k-ns
+               ;;
+       gmicro)
+               basic_machine=tron-gmicro
+               os=-sysv
+               ;;
+       h3050r* | hiux*)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       h8300hms)
+               basic_machine=h8300-hitachi
+               os=-hms
+               ;;
+       harris)
+               basic_machine=m88k-harris
+               os=-sysv3
+               ;;
+       hp300-*)
+               basic_machine=m68k-hp
+               ;;
+       hp300bsd)
+               basic_machine=m68k-hp
+               os=-bsd
+               ;;
+       hp300hpux)
+               basic_machine=m68k-hp
+               os=-hpux
+               ;;
+       hp9k2[0-9][0-9] | hp9k31[0-9])
+               basic_machine=m68000-hp
+               ;;
+       hp9k3[2-9][0-9])
+               basic_machine=m68k-hp
+               ;;
+       hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7)
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[0-9][0-9] | hp8[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hppa-next)
+               os=-nextstep3
+               ;;
+       i370-ibm* | ibm*)
+               basic_machine=i370-ibm
+               os=-mvs
+               ;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+       i[3456]86v32)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv32
+               ;;
+       i[3456]86v4*)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv4
+               ;;
+       i[3456]86v)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv
+               ;;
+       i[3456]86sol2)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-solaris2
+               ;;
+       iris | iris4d)
+               basic_machine=mips-sgi
+               case $os in
+                   -irix*)
+                       ;;
+                   *)
+                       os=-irix4
+                       ;;
+               esac
+               ;;
+       isi68 | isi)
+               basic_machine=m68k-isi
+               os=-sysv
+               ;;
+       m88k-omron*)
+               basic_machine=m88k-omron
+               ;;
+       magnum | m3230)
+               basic_machine=mips-mips
+               os=-sysv
+               ;;
+       merlin)
+               basic_machine=ns32k-utek
+               os=-sysv
+               ;;
+       miniframe)
+               basic_machine=m68000-convergent
+               ;;
+       mipsel*-linux*)
+               basic_machine=mipsel-unknown
+               os=-linux-gnu
+               ;;
+       mips*-linux*)
+               basic_machine=mips-unknown
+               os=-linux-gnu
+               ;;
+       mips3*-*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+               ;;
+       mips3*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+               ;;
+       ncr3000)
+               basic_machine=i486-ncr
+               os=-sysv4
+               ;;
+       news | news700 | news800 | news900)
+               basic_machine=m68k-sony
+               os=-newsos
+               ;;
+       news1000)
+               basic_machine=m68030-sony
+               os=-newsos
+               ;;
+       news-3600 | risc-news)
+               basic_machine=mips-sony
+               os=-newsos
+               ;;
+       next | m*-next )
+               basic_machine=m68k-next
+               case $os in
+                   -nextstep* )
+                       ;;
+                   -ns2*)
+                     os=-nextstep2
+                       ;;
+                   *)
+                     os=-nextstep3
+                       ;;
+               esac
+               ;;
+       nh3000)
+               basic_machine=m68k-harris
+               os=-cxux
+               ;;
+       nh[45]000)
+               basic_machine=m88k-harris
+               os=-cxux
+               ;;
+       nindy960)
+               basic_machine=i960-intel
+               os=-nindy
+               ;;
+       np1)
+               basic_machine=np1-gould
+               ;;
+       pa-hitachi)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       paragon)
+               basic_machine=i860-intel
+               os=-osf
+               ;;
+       pbd)
+               basic_machine=sparc-tti
+               ;;
+       pbb)
+               basic_machine=m68k-tti
+               ;;
+        pc532 | pc532-*)
+               basic_machine=ns32k-pc532
+               ;;
+       pentium | p5)
+               basic_machine=i586-intel
+               ;;
+       pentiumpro | p6)
+               basic_machine=i686-intel
+               ;;
+       pentium-* | p5-*)
+               basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentiumpro-* | p6-*)
+               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       k5)
+               # We don't have specific support for AMD's K5 yet, so just call it a Pentium
+               basic_machine=i586-amd
+               ;;
+       nexen)
+               # We don't have specific support for Nexgen yet, so just call it a Pentium
+               basic_machine=i586-nexgen
+               ;;
+       pn)
+               basic_machine=pn-gould
+               ;;
+       power)  basic_machine=rs6000-ibm
+               ;;
+       ppc)    basic_machine=powerpc-unknown
+               ;;
+       ppc-*)  basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppcle | powerpclittle | ppc-le | powerpc-little)
+               basic_machine=powerpcle-unknown
+               ;;
+       ppcle-* | powerpclittle-*)
+               basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ps2)
+               basic_machine=i386-ibm
+               ;;
+       rm[46]00)
+               basic_machine=mips-siemens
+               ;;
+       rtpc | rtpc-*)
+               basic_machine=romp-ibm
+               ;;
+       sequent)
+               basic_machine=i386-sequent
+               ;;
+       sh)
+               basic_machine=sh-hitachi
+               os=-hms
+               ;;
+       sps7)
+               basic_machine=m68k-bull
+               os=-sysv2
+               ;;
+       spur)
+               basic_machine=spur-unknown
+               ;;
+       sun2)
+               basic_machine=m68000-sun
+               ;;
+       sun2os3)
+               basic_machine=m68000-sun
+               os=-sunos3
+               ;;
+       sun2os4)
+               basic_machine=m68000-sun
+               os=-sunos4
+               ;;
+       sun3os3)
+               basic_machine=m68k-sun
+               os=-sunos3
+               ;;
+       sun3os4)
+               basic_machine=m68k-sun
+               os=-sunos4
+               ;;
+       sun4os3)
+               basic_machine=sparc-sun
+               os=-sunos3
+               ;;
+       sun4os4)
+               basic_machine=sparc-sun
+               os=-sunos4
+               ;;
+       sun4sol2)
+               basic_machine=sparc-sun
+               os=-solaris2
+               ;;
+       sun3 | sun3-*)
+               basic_machine=m68k-sun
+               ;;
+       sun4)
+               basic_machine=sparc-sun
+               ;;
+       sun386 | sun386i | roadrunner)
+               basic_machine=i386-sun
+               ;;
+       symmetry)
+               basic_machine=i386-sequent
+               os=-dynix
+               ;;
+       tx39)
+               basic_machine=mipstx39-unknown
+               ;;
+       tx39el)
+               basic_machine=mipstx39el-unknown
+               ;;
+       tower | tower-32)
+               basic_machine=m68k-ncr
+               ;;
+       udi29k)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       ultra3)
+               basic_machine=a29k-nyu
+               os=-sym1
+               ;;
+       vaxv)
+               basic_machine=vax-dec
+               os=-sysv
+               ;;
+       vms)
+               basic_machine=vax-dec
+               os=-vms
+               ;;
+       vpp*|vx|vx-*)
+               basic_machine=f301-fujitsu
+               ;;
+       vxworks960)
+               basic_machine=i960-wrs
+               os=-vxworks
+               ;;
+       vxworks68)
+               basic_machine=m68k-wrs
+               os=-vxworks
+               ;;
+       vxworks29k)
+               basic_machine=a29k-wrs
+               os=-vxworks
+               ;;
+       xmp)
+               basic_machine=xmp-cray
+               os=-unicos
+               ;;
+        xps | xps100)
+               basic_machine=xps100-honeywell
+               ;;
+       none)
+               basic_machine=none-none
+               os=-none
+               ;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+       mips)
+               if [ x$os = x-linux-gnu ]; then
+                       basic_machine=mips-unknown
+               else
+                       basic_machine=mips-mips
+               fi
+               ;;
+       romp)
+               basic_machine=romp-ibm
+               ;;
+       rs6000)
+               basic_machine=rs6000-ibm
+               ;;
+       vax)
+               basic_machine=vax-dec
+               ;;
+       pdp11)
+               basic_machine=pdp11-dec
+               ;;
+       we32k)
+               basic_machine=we32k-att
+               ;;
+       sparc)
+               basic_machine=sparc-sun
+               ;;
+        cydra)
+               basic_machine=cydra-cydrome
+               ;;
+       orion)
+               basic_machine=orion-highlevel
+               ;;
+       orion105)
+               basic_machine=clipper-highlevel
+               ;;
+       *)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+       *-digital*)
+               basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+               ;;
+       *-commodore*)
+               basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+               ;;
+       *)
+               ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+       # -solaris* is a basic system type, with this one exception.
+       -solaris1 | -solaris1.*)
+               os=`echo $os | sed -e 's|solaris1|sunos4|'`
+               ;;
+       -solaris)
+               os=-solaris2
+               ;;
+       -svr4*)
+               os=-sysv4
+               ;;
+       -unixware*)
+               os=-sysv4.2uw
+               ;;
+       -gnu/linux*)
+               os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+               ;;
+       # First accept the basic system types.
+       # The portable systems comes first.
+       # Each alternative MUST END IN A *, to match a version number.
+       # -sysv* is not here because it comes later, after sysvr4.
+       -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+             | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+             | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+             | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+             | -aos* \
+             | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+             | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+             | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+             | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \
+             | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+             | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+             | -cygwin32* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+             | -mingw32* | -linux-gnu* | -uxpv*)
+       # Remember, each alternative MUST END IN *, to match a version number.
+               ;;
+       -linux*)
+               os=`echo $os | sed -e 's|linux|linux-gnu|'`
+               ;;
+       -sunos5*)
+               os=`echo $os | sed -e 's|sunos5|solaris2|'`
+               ;;
+       -sunos6*)
+               os=`echo $os | sed -e 's|sunos6|solaris3|'`
+               ;;
+       -osfrose*)
+               os=-osfrose
+               ;;
+       -osf*)
+               os=-osf
+               ;;
+       -utek*)
+               os=-bsd
+               ;;
+       -dynix*)
+               os=-bsd
+               ;;
+       -acis*)
+               os=-aos
+               ;;
+       -ctix* | -uts*)
+               os=-sysv
+               ;;
+       -ns2 )
+               os=-nextstep2
+               ;;
+       # Preserve the version number of sinix5.
+       -sinix5.*)
+               os=`echo $os | sed -e 's|sinix|sysv|'`
+               ;;
+       -sinix*)
+               os=-sysv4
+               ;;
+       -triton*)
+               os=-sysv3
+               ;;
+       -oss*)
+               os=-sysv3
+               ;;
+       -svr4)
+               os=-sysv4
+               ;;
+       -svr3)
+               os=-sysv3
+               ;;
+       -sysvr4)
+               os=-sysv4
+               ;;
+       # This must come after -sysvr4.
+       -sysv*)
+               ;;
+       -xenix)
+               os=-xenix
+               ;;
+       -none)
+               ;;
+       *)
+               # Get rid of the `-' at the beginning of $os.
+               os=`echo $os | sed 's/[^-]*-//'`
+               echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+       *-acorn)
+               os=-riscix1.2
+               ;;
+       arm*-semi)
+               os=-aout
+               ;;
+        pdp11-*)
+               os=-none
+               ;;
+       *-dec | vax-*)
+               os=-ultrix4.2
+               ;;
+       m68*-apollo)
+               os=-domain
+               ;;
+       i386-sun)
+               os=-sunos4.0.2
+               ;;
+       m68000-sun)
+               os=-sunos3
+               # This also exists in the configure program, but was not the
+               # default.
+               # os=-sunos4
+               ;;
+       *-tti)  # must be before sparc entry or we get the wrong os.
+               os=-sysv3
+               ;;
+       sparc-* | *-sun)
+               os=-sunos4.1.1
+               ;;
+       *-ibm)
+               os=-aix
+               ;;
+       *-hp)
+               os=-hpux
+               ;;
+       *-hitachi)
+               os=-hiux
+               ;;
+       i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+               os=-sysv
+               ;;
+       *-cbm)
+               os=-amigaos
+               ;;
+       *-dg)
+               os=-dgux
+               ;;
+       *-dolphin)
+               os=-sysv3
+               ;;
+       m68k-ccur)
+               os=-rtu
+               ;;
+       m88k-omron*)
+               os=-luna
+               ;;
+       *-next )
+               os=-nextstep
+               ;;
+       *-sequent)
+               os=-ptx
+               ;;
+       *-crds)
+               os=-unos
+               ;;
+       *-ns)
+               os=-genix
+               ;;
+       i370-*)
+               os=-mvs
+               ;;
+       *-next)
+               os=-nextstep3
+               ;;
+        *-gould)
+               os=-sysv
+               ;;
+        *-highlevel)
+               os=-bsd
+               ;;
+       *-encore)
+               os=-bsd
+               ;;
+        *-sgi)
+               os=-irix
+               ;;
+        *-siemens)
+               os=-sysv4
+               ;;
+       *-masscomp)
+               os=-rtu
+               ;;
+       f301-fujitsu)
+               os=-uxpv
+               ;;
+       *)
+               os=-none
+               ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+       *-unknown)
+               case $os in
+                       -riscix*)
+                               vendor=acorn
+                               ;;
+                       -sunos*)
+                               vendor=sun
+                               ;;
+                       -aix*)
+                               vendor=ibm
+                               ;;
+                       -hpux*)
+                               vendor=hp
+                               ;;
+                       -hiux*)
+                               vendor=hitachi
+                               ;;
+                       -unos*)
+                               vendor=crds
+                               ;;
+                       -dgux*)
+                               vendor=dg
+                               ;;
+                       -luna*)
+                               vendor=omron
+                               ;;
+                       -genix*)
+                               vendor=ns
+                               ;;
+                       -mvs*)
+                               vendor=ibm
+                               ;;
+                       -ptx*)
+                               vendor=sequent
+                               ;;
+                       -vxsim* | -vxworks*)
+                               vendor=wrs
+                               ;;
+                       -aux*)
+                               vendor=apple
+                               ;;
+               esac
+               basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+               ;;
+esac
+
+echo $basic_machine$os
diff --git a/glib/configure b/glib/configure
new file mode 100755 (executable)
index 0000000..becb1c7
--- /dev/null
@@ -0,0 +1,2921 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.12 
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]"
+ac_help="$ac_help
+  --enable-shared         build shared libraries [default=yes]"
+ac_help="$ac_help
+  --enable-static         build static libraries [default=yes]"
+ac_help="$ac_help
+  --enable-maintainer-mode enable make rules and dependencies not useful
+                          (and sometimes confusing) to the casual installer"
+ac_help="$ac_help
+  --enable-debug          turn on debugging [default=no]"
+ac_help="$ac_help
+  --enable-ansi           turn on strict ansi [default=no]"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  case "$ac_option" in
+  -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) ac_optarg= ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case "$ac_option" in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir="$ac_optarg" ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build="$ac_optarg" ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file="$ac_optarg" ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir="$ac_optarg" ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    eval "enable_${ac_feature}=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix="$ac_optarg" ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he)
+    # Omit some internal or obsolete options to make the list less imposing.
+    # This message is too long to be a string in the A/UX 3.1 sh.
+    cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+  --cache-file=FILE       cache test results in FILE
+  --help                  print this message
+  --no-create             do not create output files
+  --quiet, --silent       do not print \`checking...' messages
+  --version               print the version of autoconf that created configure
+Directory and file names:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [same as prefix]
+  --bindir=DIR            user executables in DIR [EPREFIX/bin]
+  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
+  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
+  --datadir=DIR           read-only architecture-independent data in DIR
+                          [PREFIX/share]
+  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
+                          [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
+  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
+  --includedir=DIR        C header files in DIR [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
+  --infodir=DIR           info documentation in DIR [PREFIX/info]
+  --mandir=DIR            man documentation in DIR [PREFIX/man]
+  --srcdir=DIR            find the sources in DIR [configure dir or ..]
+  --program-prefix=PREFIX prepend PREFIX to installed program names
+  --program-suffix=SUFFIX append SUFFIX to installed program names
+  --program-transform-name=PROGRAM
+                          run sed PROGRAM on installed program names
+EOF
+    cat << EOF
+Host type:
+  --build=BUILD           configure for building on BUILD [BUILD=HOST]
+  --host=HOST             configure for HOST [guessed]
+  --target=TARGET         configure for TARGET [TARGET=HOST]
+Features and packages:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --x-includes=DIR        X include files are in DIR
+  --x-libraries=DIR       X library files are in DIR
+EOF
+    if test -n "$ac_help"; then
+      echo "--enable and --with options recognized:$ac_help"
+    fi
+    exit 0 ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host="$ac_optarg" ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir="$ac_optarg" ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir="$ac_optarg" ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir="$ac_optarg" ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir="$ac_optarg" ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir="$ac_optarg" ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir="$ac_optarg" ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir="$ac_optarg" ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix="$ac_optarg" ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix="$ac_optarg" ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix="$ac_optarg" ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name="$ac_optarg" ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir="$ac_optarg" ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir="$ac_optarg" ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site="$ac_optarg" ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir="$ac_optarg" ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir="$ac_optarg" ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target="$ac_optarg" ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers)
+    echo "configure generated by autoconf version 2.12"
+    exit 0 ;;
+
+  -with-* | --with-*)
+    ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_${ac_package}='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    eval "with_${ac_package}=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes="$ac_optarg" ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries="$ac_optarg" ;;
+
+  -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+    ;;
+
+  *)
+    if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+      echo "configure: warning: $ac_option: invalid host type" 1>&2
+    fi
+    if test "x$nonopt" != xNONE; then
+      { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+    fi
+    nonopt="$ac_option"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+  exec 6>/dev/null
+else
+  exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+  case "$ac_arg" in
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c) ;;
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+  *" "*|*"     "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+  ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+  *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+  esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set.  These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=glib.h
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_prog=$0
+  ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+  test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+  else
+    { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+  fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    echo "loading site script $ac_site_file"
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  echo "loading cache $cache_file"
+  . $cache_file
+else
+  echo "creating cache $cache_file"
+  > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+    ac_n= ac_c='
+' ac_t='       '
+  else
+    ac_n=-n ac_c= ac_t=
+  fi
+else
+  ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:566: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    IFS="${IFS=        }"; ac_save_IFS="$IFS"; IFS="${IFS}:"
+  for ac_dir in $PATH; do
+    # Account for people who put trailing slashes in PATH elements.
+    case "$ac_dir/" in
+    /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+    *)
+      # OSF1 and SCO ODT 3.0 have their own names for install.
+      for ac_prog in ginstall installbsd scoinst install; do
+        if test -f $ac_dir/$ac_prog; then
+         if test $ac_prog = install &&
+            grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+           # AIX install.  It has an incompatible calling convention.
+           # OSF/1 installbsd also uses dspmsg, but is usable.
+           :
+         else
+           ac_cv_path_install="$ac_dir/$ac_prog -c"
+           break 2
+         fi
+       fi
+      done
+      ;;
+    esac
+  done
+  IFS="$ac_save_IFS"
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL="$ac_cv_path_install"
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL="$ac_install_sh"
+  fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+
+PACKAGE=glib
+
+VERSION=971109
+
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+  { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
+fi
+cat >> confdefs.h <<EOF
+#define PACKAGE "$PACKAGE"
+EOF
+
+cat >> confdefs.h <<EOF
+#define VERSION "$VERSION"
+EOF
+
+echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
+echo "configure:635: checking whether build environment is sane" >&5
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+   if test "" = "X"; then
+      # -L didn't work.
+      set X `ls -t $srcdir/configure conftestfile`
+   fi
+   test "$2" = conftestfile
+   )
+then
+   # Ok.
+   :
+else
+   { echo "configure: error: newly created file is older than distributed files!
+Check your system clock" 1>&2; exit 1; }
+fi
+rm -f conftest*
+echo "$ac_t""yes" 1>&6
+if test "$program_transform_name" = s,x,x,; then
+  program_transform_name=
+else
+  # Double any \ or $.  echo might interpret backslashes.
+  cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+  program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+  rm -f conftestsed
+fi
+test "$program_prefix" != NONE &&
+  program_transform_name="s,^,${program_prefix},; $program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+  program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+missing_dir=`cd $ac_aux_dir && pwd`
+echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
+echo "configure:682: checking for working aclocal" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if (aclocal --version) < /dev/null > /dev/null 2>&1; then
+   ACLOCAL=aclocal
+   echo "$ac_t""found" 1>&6
+else
+   ACLOCAL="$missing_dir/missing aclocal"
+   echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
+echo "configure:695: checking for working autoconf" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if (autoconf --version) < /dev/null > /dev/null 2>&1; then
+   AUTOCONF=autoconf
+   echo "$ac_t""found" 1>&6
+else
+   AUTOCONF="$missing_dir/missing autoconf"
+   echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working automake""... $ac_c" 1>&6
+echo "configure:708: checking for working automake" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if (automake --version) < /dev/null > /dev/null 2>&1; then
+   AUTOMAKE=automake
+   echo "$ac_t""found" 1>&6
+else
+   AUTOMAKE="$missing_dir/missing automake"
+   echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
+echo "configure:721: checking for working autoheader" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if (autoheader --version) < /dev/null > /dev/null 2>&1; then
+   AUTOHEADER=autoheader
+   echo "$ac_t""found" 1>&6
+else
+   AUTOHEADER="$missing_dir/missing autoheader"
+   echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
+echo "configure:734: checking for working makeinfo" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if (makeinfo --version) < /dev/null > /dev/null 2>&1; then
+   MAKEINFO=makeinfo
+   echo "$ac_t""found" 1>&6
+else
+   MAKEINFO="$missing_dir/missing makeinfo"
+   echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:747: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftestmake <<\EOF
+all:
+       @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+  eval ac_cv_prog_make_${ac_make}_set=yes
+else
+  eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  SET_MAKE=
+else
+  echo "$ac_t""no" 1>&6
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+# Specify a configuration file
+
+
+
+
+
+# Make sure we can run config.sub.
+if $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:786: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+  case $nonopt in
+  NONE)
+    if host_alias=`$ac_config_guess`; then :
+    else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+    fi ;;
+  *) host_alias=$nonopt ;;
+  esac ;;
+esac
+
+host=`$ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:809: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_RANLIB="ranlib"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+  echo "$ac_t""$RANLIB" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:838: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="gcc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:867: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  ac_prog_rejected=no
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+        ac_prog_rejected=yes
+       continue
+      fi
+      ac_cv_prog_CC="cc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# -gt 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    set dummy "$ac_dir/$ac_word" "$@"
+    shift
+    ac_cv_prog_CC="$@"
+  fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:915: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext <<EOF
+#line 925 "configure"
+#include "confdefs.h"
+main(){return(0);}
+EOF
+if { (eval echo configure:929: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  ac_cv_prog_cc_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cc_cross=no
+  else
+    ac_cv_prog_cc_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+  { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:949: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:954: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:963: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gcc=yes
+else
+  ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+  GCC=yes
+  ac_test_CFLAGS="${CFLAGS+set}"
+  ac_save_CFLAGS="$CFLAGS"
+  CFLAGS=
+  echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:978: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+  ac_cv_prog_cc_g=yes
+else
+  ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+  if test "$ac_test_CFLAGS" = set; then
+    CFLAGS="$ac_save_CFLAGS"
+  elif test $ac_cv_prog_cc_g = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-O2"
+  fi
+else
+  GCC=
+  test "${CFLAGS+set}" = set || CFLAGS="-g"
+fi
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+  withval="$with_gnu_ld"
+  test "$withval" = no || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+
+
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6
+echo "configure:1018: checking for ld used by GCC" >&5
+  ac_prog=`($CC -print-prog-name=ld) 2>&5`
+  case "$ac_prog" in
+  # Accept absolute paths.
+  /*)
+    test -z "$LD" && LD="$ac_prog"
+    ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  echo $ac_n "checking for GNU ld""... $ac_c" 1>&6
+echo "configure:1036: checking for GNU ld" >&5
+else
+  echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+echo "configure:1039: checking for non-GNU ld" >&5
+fi
+if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -z "$LD"; then
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog"; then
+      ac_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some GNU ld's only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+       test "$with_gnu_ld" != no && break
+      else
+        test "$with_gnu_ld" != yes && break
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+else
+  ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+  echo "$ac_t""$LD" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; }
+
+echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6
+echo "configure:1075: checking if the linker ($LD) is GNU ld" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gnu_ld'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  ac_cv_prog_gnu_ld=yes
+else
+  ac_cv_prog_gnu_ld=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gnu_ld" 1>&6
+
+
+echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6
+echo "configure:1091: checking for BSD-compatible nm" >&5
+if eval "test \"`echo '$''{'ac_cv_path_NM'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$NM" in
+/*)
+  ac_cv_path_NM="$NM" # Let the user override the test with a path.
+  ;;
+*)
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in /usr/ucb $PATH /bin; do
+    test -z "$ac_dir" && dir=.
+    if test -f $ac_dir/nm; then
+      # Check to see if the nm accepts a BSD-compat flag.
+      if ($ac_dir/nm -B /dev/null 2>&1; exit 0) | grep /dev/null >/dev/null; then
+        ac_cv_path_NM="$ac_dir/nm -B"
+      elif ($ac_dir/nm -p /dev/null 2>&1; exit 0) | grep /dev/null >/dev/null; then
+        ac_cv_path_NM="$ac_dir/nm -p"
+      else
+        ac_cv_path_NM="$ac_dir/nm"
+      fi
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+  ;;
+esac
+fi
+
+NM="$ac_cv_path_NM"
+echo "$ac_t""$NM" 1>&6
+
+
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+echo "configure:1126: checking whether ln -s works" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+  rm -f conftestdata
+  ac_cv_prog_LN_S="ln -s"
+else
+  ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+
+
+
+
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+  enableval="$enable_shared"
+  if test "$enableval" = no; then
+  libtool_enable_shared=no
+else
+  libtool_enable_shared=yes
+fi
+fi
+
+test -n "$libtool_enable_shared" && enable_shared="$libtool_enable_shared"
+libtool_shared=
+test "$enable_shared" = no && libtool_shared=" --disable-shared"
+
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+  enableval="$enable_static"
+  if test "$enableval" = no; then
+  libtool_enable_static=no
+else
+  libtool_enable_static=yes
+fi
+fi
+
+test -n "$libtool_enable_static" && enable_static="$libtool_enable_static"
+libtool_static=
+test "$enable_static" = no && libtool_static=" --disable-static"
+
+libtool_flags="$libtool_shared$libtool_static"
+test "$silent" = yes && libtool_flags="$libtool_flags --silent"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$host" in
+*-*-irix6*)
+  ac_save_CFLAGS="$CFLAGS"
+  flag_passed=no
+  for f in -32 -64 -n32 ABI -cckr -mips1 -mips2 -mips3 -mips4; do
+    case "$f" in
+    ABI)
+      test -n "$SGI_ABI" && flag_passed=yes
+      if test "$flag_passed" = no && test "$ac_cv_prog_gcc" = yes; then
+       # Choose the ABI flag according to GCC's specs.
+       if $CC -dumpspecs 2>&1 | sed '/^\*link:$/,/^$/!d' | egrep -e '[         ]-32' >/dev/null; then
+         LD="${LD-ld} -32"
+       else
+         LD="${LD-ld} -n32"
+       fi
+      fi
+      ;;
+
+    *)
+      if echo " $CC $CFLAGS " | egrep -e "[    ]$f[     ]" > /dev/null; then
+       flag_passed=yes
+       LD="${LD-ld} $f"
+      fi
+      ;;
+    esac
+  done
+  CFLAGS="$ac_save_CFLAGS"
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  CFLAGS="$CFLAGS -belf"
+  ;;
+esac
+
+# Actually configure libtool.  ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" NM="$NM" RANLIB="$RANLIB" LN_S="$LN_S" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+|| { echo "configure: error: libtool configure failed" 1>&2; exit 1; }
+
+
+echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
+echo "configure:1236: checking whether to enable maintainer-specific portions of Makefiles" >&5
+    # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then
+  enableval="$enable_maintainer_mode"
+  USE_MAINTAINER_MODE=$enableval
+else
+  USE_MAINTAINER_MODE=no
+fi
+
+  echo "$ac_t""$USE_MAINTAINER_MODE" 1>&6
+  if test $USE_MAINTAINER_MODE = yes; then
+    MAINT=
+  else
+    MAINT='#M#'
+  fi
+  
+
+
+
+# Make sure we can run config.sub.
+if $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:1261: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+  case $nonopt in
+  NONE)
+    if host_alias=`$ac_config_guess`; then :
+    else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+    fi ;;
+  *) host_alias=$nonopt ;;
+  esac ;;
+esac
+
+host=`$ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+
+# Check whether --enable-debug or --disable-debug was given.
+if test "${enable_debug+set}" = set; then
+  enableval="$enable_debug"
+  if eval "test x$enable_debug = xyes"; then
+  DEBUGFLAG="-g"
+fi
+fi
+
+
+# Check whether --enable-ansi or --disable-ansi was given.
+if test "${enable_ansi+set}" = set; then
+  enableval="$enable_ansi"
+  :
+else
+  enable_ansi=no
+fi
+
+
+if test -n "$DEBUGFLAG"; then
+  CFLAGS="$DEBUGFLAG"
+fi
+
+# Checks for programs.
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1308: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="gcc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1337: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  ac_prog_rejected=no
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+        ac_prog_rejected=yes
+       continue
+      fi
+      ac_cv_prog_CC="cc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# -gt 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    set dummy "$ac_dir/$ac_word" "$@"
+    shift
+    ac_cv_prog_CC="$@"
+  fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1385: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext <<EOF
+#line 1395 "configure"
+#include "confdefs.h"
+main(){return(0);}
+EOF
+if { (eval echo configure:1399: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  ac_cv_prog_cc_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cc_cross=no
+  else
+    ac_cv_prog_cc_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+  { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:1419: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:1424: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1433: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gcc=yes
+else
+  ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+  GCC=yes
+  ac_test_CFLAGS="${CFLAGS+set}"
+  ac_save_CFLAGS="$CFLAGS"
+  CFLAGS=
+  echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:1448: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+  ac_cv_prog_cc_g=yes
+else
+  ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+  if test "$ac_test_CFLAGS" = set; then
+    CFLAGS="$ac_save_CFLAGS"
+  elif test $ac_cv_prog_cc_g = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-O2"
+  fi
+else
+  GCC=
+  test "${CFLAGS+set}" = set || CFLAGS="-g"
+fi
+
+
+
+
+echo $ac_n "checking for ${CC-cc} option to accept ANSI C""... $ac_c" 1>&6
+echo "configure:1479: checking for ${CC-cc} option to accept ANSI C" >&5
+if eval "test \"`echo '$''{'am_cv_prog_cc_stdc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  am_cv_prog_cc_stdc=no
+ac_save_CC="$CC"
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX                  -qlanglvl=ansi
+# Ultrix and OSF/1     -std1
+# HP-UX                        -Aa -D_HPUX_SOURCE
+# SVR4                 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  cat > conftest.$ac_ext <<EOF
+#line 1495 "configure"
+#include "confdefs.h"
+#if !defined(__STDC__) || __STDC__ != 1
+choke me
+#endif
+/* DYNIX/ptx V4.1.3 can't compile sys/stat.h with -Xc -D__EXTENSIONS__. */
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/stat.h>
+#endif
+
+int main() {
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+; return 0; }
+EOF
+if { (eval echo configure:1513: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  am_cv_prog_cc_stdc="$ac_arg"; break
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+CC="$ac_save_CC"
+
+fi
+
+if test -z "$am_cv_prog_cc_stdc"; then
+  echo "$ac_t""none needed" 1>&6
+else
+  echo "$ac_t""$am_cv_prog_cc_stdc" 1>&6
+fi
+case "x$am_cv_prog_cc_stdc" in
+  x|xno) ;;
+  *) CC="$CC $am_cv_prog_cc_stdc" ;;
+esac
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:1547: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    IFS="${IFS=        }"; ac_save_IFS="$IFS"; IFS="${IFS}:"
+  for ac_dir in $PATH; do
+    # Account for people who put trailing slashes in PATH elements.
+    case "$ac_dir/" in
+    /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+    *)
+      # OSF1 and SCO ODT 3.0 have their own names for install.
+      for ac_prog in ginstall installbsd scoinst install; do
+        if test -f $ac_dir/$ac_prog; then
+         if test $ac_prog = install &&
+            grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+           # AIX install.  It has an incompatible calling convention.
+           # OSF/1 installbsd also uses dspmsg, but is usable.
+           :
+         else
+           ac_cv_path_install="$ac_dir/$ac_prog -c"
+           break 2
+         fi
+       fi
+      done
+      ;;
+    esac
+  done
+  IFS="$ac_save_IFS"
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL="$ac_cv_path_install"
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL="$ac_install_sh"
+  fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+if eval "test x$GCC = xyes"; then
+  test `echo "$CFLAGS" | grep "\-Wall" > /dev/null 2> /dev/null`
+  if test ! $?; then
+    CFLAGS="$CFLAGS -Wall"
+  fi
+
+  if eval "test x$enable_ansi = xyes"; then
+    test `echo "$CFLAGS" | grep "\-ansi" > /dev/null 2> /dev/null`
+    if test ! $?; then
+      CFLAGS="$CFLAGS -ansi"
+    fi
+
+    test `echo "$CFLAGS" | grep "\-pedantic" > /dev/null 2> /dev/null`
+    if test ! $?; then
+      CFLAGS="$CFLAGS -pedantic"
+    fi
+  fi
+fi
+
+# Checks for header files.
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:1618: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    # This must be in double quotes, not single quotes, because CPP may get
+  # substituted into the Makefile and "${CC-cc}" will confuse make.
+  CPP="${CC-cc} -E"
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp.
+  cat > conftest.$ac_ext <<EOF
+#line 1633 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1639: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP="${CC-cc} -E -traditional-cpp"
+  cat > conftest.$ac_ext <<EOF
+#line 1650 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1656: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+  ac_cv_prog_CPP="$CPP"
+fi
+  CPP="$ac_cv_prog_CPP"
+else
+  ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:1679: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1684 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1692: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  ac_cv_header_stdc=yes
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1709 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "memchr" >/dev/null 2>&1; then
+  :
+else
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1727 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "free" >/dev/null 2>&1; then
+  :
+else
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+  :
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1748 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:1759: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  :
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+  cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+
+# Checks for library functions.
+echo $ac_n "checking for vprintf""... $ac_c" 1>&6
+echo "configure:1785: checking for vprintf" >&5
+if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1790 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char vprintf(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char vprintf();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_vprintf) || defined (__stub___vprintf)
+choke me
+#else
+vprintf();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1813: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  eval "ac_cv_func_vprintf=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_vprintf=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'vprintf`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  cat >> confdefs.h <<\EOF
+#define HAVE_VPRINTF 1
+EOF
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+if test "$ac_cv_func_vprintf" != yes; then
+echo $ac_n "checking for _doprnt""... $ac_c" 1>&6
+echo "configure:1837: checking for _doprnt" >&5
+if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1842 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char _doprnt(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char _doprnt();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub__doprnt) || defined (__stub____doprnt)
+choke me
+#else
+_doprnt();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1865: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  eval "ac_cv_func__doprnt=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func__doprnt=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'_doprnt`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  cat >> confdefs.h <<\EOF
+#define HAVE_DOPRNT 1
+EOF
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+
+echo $ac_n "checking size of char""... $ac_c" 1>&6
+echo "configure:1891: checking size of char" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_char'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1899 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(char));
+  exit(0);
+}
+EOF
+if { (eval echo configure:1910: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_char=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_char=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_char" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_CHAR $ac_cv_sizeof_char
+EOF
+
+
+echo $ac_n "checking size of short""... $ac_c" 1>&6
+echo "configure:1930: checking size of short" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1938 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(short));
+  exit(0);
+}
+EOF
+if { (eval echo configure:1949: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_short=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_short=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_short" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_SHORT $ac_cv_sizeof_short
+EOF
+
+
+echo $ac_n "checking size of long""... $ac_c" 1>&6
+echo "configure:1969: checking size of long" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1977 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(long));
+  exit(0);
+}
+EOF
+if { (eval echo configure:1988: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_long=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_long=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_long" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+EOF
+
+
+echo $ac_n "checking size of int""... $ac_c" 1>&6
+echo "configure:2008: checking size of int" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2016 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(int));
+  exit(0);
+}
+EOF
+if { (eval echo configure:2027: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_int=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_int=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_int" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_INT $ac_cv_sizeof_int
+EOF
+
+
+echo $ac_n "checking size of void *""... $ac_c" 1>&6
+echo "configure:2047: checking size of void *" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_void_p'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2055 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(void *));
+  exit(0);
+}
+EOF
+if { (eval echo configure:2066: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_void_p=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_void_p=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_void_p" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_VOID_P $ac_cv_sizeof_void_p
+EOF
+
+
+
+echo $ac_n "checking for long double""... $ac_c" 1>&6
+echo "configure:2087: checking for long double" >&5
+if eval "test \"`echo '$''{'ac_cv_c_long_double'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$GCC" = yes; then
+  ac_cv_c_long_double=yes
+else
+if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2098 "configure"
+#include "confdefs.h"
+int main() {
+/* The Stardent Vistra knows sizeof(long double), but does not support it.  */
+long double foo = 0.0;
+/* On Ultrix 4.3 cc, long double is 4 and double is 8.  */
+exit(sizeof(long double) < sizeof(double)); }
+EOF
+if { (eval echo configure:2106: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_c_long_double=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_c_long_double=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_c_long_double" 1>&6
+if test $ac_cv_c_long_double = yes; then
+  cat >> confdefs.h <<\EOF
+#define HAVE_LONG_DOUBLE 1
+EOF
+
+fi
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:2130: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2135 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this.  */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this.  */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this.  */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+   It does not let you subtract one const X* pointer from another in an arm
+   of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this.  */
+  char *t;
+  char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+  *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+  int x[] = {25, 17};
+  const int *foo = &x[0];
+  ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+  typedef const int *iptr;
+  iptr p = 0;
+  ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+     "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+  struct s { int j; const int *ap[3]; };
+  struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+  const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:2184: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_c_const=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+  cat >> confdefs.h <<\EOF
+#define const 
+EOF
+
+fi
+
+echo $ac_n "checking for inline""... $ac_c" 1>&6
+echo "configure:2205: checking for inline" >&5
+if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+  cat > conftest.$ac_ext <<EOF
+#line 2212 "configure"
+#include "confdefs.h"
+
+int main() {
+} $ac_kw foo() {
+; return 0; }
+EOF
+if { (eval echo configure:2219: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_c_inline=$ac_kw; break
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+
+fi
+
+echo "$ac_t""$ac_cv_c_inline" 1>&6
+case "$ac_cv_c_inline" in
+  inline | yes) ;;
+  no) cat >> confdefs.h <<\EOF
+#define inline 
+EOF
+ ;;
+  *)  cat >> confdefs.h <<EOF
+#define inline $ac_cv_c_inline
+EOF
+ ;;
+esac
+
+
+for ac_hdr in float.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2249: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2254 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2259: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ cat >> confdefs.h <<\EOF
+#define HAVE_FLOAT_H 1
+EOF
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_hdr in limits.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2292: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2297 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2302: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ cat >> confdefs.h <<\EOF
+#define HAVE_LIMITS_H 1
+EOF
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_hdr in values.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2335: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2340 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2345: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ cat >> confdefs.h <<\EOF
+#define HAVE_VALUES_H 1
+EOF
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+
+# Check for strerror and strsignal functions
+for ac_func in strerror strsignal
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2379: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2384 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2407: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+
+# Check for sys_errlist
+echo $ac_n "checking sys_errlist""... $ac_c" 1>&6
+echo "configure:2434: checking sys_errlist" >&5
+cat > conftest.$ac_ext <<EOF
+#line 2436 "configure"
+#include "confdefs.h"
+
+int main() {
+
+extern char *sys_errlist[];
+extern int sys_nerr;
+sys_errlist[sys_nerr-1][0] = 0;
+
+; return 0; }
+EOF
+if { (eval echo configure:2447: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  glib_ok=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  glib_ok=no
+fi
+rm -f conftest*
+echo "$ac_t""$glib_ok" 1>&6
+if test $glib_ok = no; then
+    cat >> confdefs.h <<\EOF
+#define NO_SYS_ERRLIST 1
+EOF
+
+fi
+
+# Check for sys_siglist
+echo $ac_n "checking sys_siglist""... $ac_c" 1>&6
+echo "configure:2467: checking sys_siglist" >&5
+cat > conftest.$ac_ext <<EOF
+#line 2469 "configure"
+#include "confdefs.h"
+
+int main() {
+
+extern char *sys_siglist[];
+sys_siglist[1][0] = 0;
+
+; return 0; }
+EOF
+if { (eval echo configure:2479: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  glib_ok=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  glib_ok=no
+fi
+rm -f conftest*
+echo "$ac_t""$glib_ok" 1>&6
+if test $glib_ok = no; then
+    cat >> confdefs.h <<\EOF
+#define NO_SYS_SIGLIST 1
+EOF
+
+fi
+
+# Check for sys/select.h
+
+echo $ac_n "checking fd_set and sys/select""... $ac_c" 1>&6
+echo "configure:2500: checking fd_set and sys/select" >&5
+cat > conftest.$ac_ext <<EOF
+#line 2502 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+int main() {
+fd_set readMask, writeMask;
+; return 0; }
+EOF
+if { (eval echo configure:2509: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  gtk_ok=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  gtk_ok=no
+fi
+rm -f conftest*
+if test $gtk_ok = no; then
+    cat > conftest.$ac_ext <<EOF
+#line 2521 "configure"
+#include "confdefs.h"
+#include <sys/select.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "fd_mask" >/dev/null 2>&1; then
+  rm -rf conftest*
+  gtk_ok=yes
+fi
+rm -f conftest*
+
+    if test $gtk_ok = yes; then
+        cat >> confdefs.h <<\EOF
+#define HAVE_SYS_SELECT_H 1
+EOF
+
+    fi
+fi
+echo "$ac_t""$gtk_ok" 1>&6
+if test $gtk_ok = no; then
+    cat >> confdefs.h <<\EOF
+#define NO_FD_SET 1
+EOF
+
+fi
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+  case `(ac_space=' '; set) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[        ]*VPATH[        ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+  case "\$ac_option" in
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+    exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+    echo "$CONFIG_STATUS generated by autoconf version 2.12"
+    exit 0 ;;
+  -help | --help | --hel | --he | --h)
+    echo "\$ac_cs_usage"; exit 0 ;;
+  *) echo "\$ac_cs_usage"; exit 1 ;;
+  esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile glibconfig.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@PACKAGE@%$PACKAGE%g
+s%@VERSION@%$VERSION%g
+s%@ACLOCAL@%$ACLOCAL%g
+s%@AUTOCONF@%$AUTOCONF%g
+s%@AUTOMAKE@%$AUTOMAKE%g
+s%@AUTOHEADER@%$AUTOHEADER%g
+s%@MAKEINFO@%$MAKEINFO%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@RANLIB@%$RANLIB%g
+s%@CC@%$CC%g
+s%@LD@%$LD%g
+s%@NM@%$NM%g
+s%@LN_S@%$LN_S%g
+s%@LIBTOOL@%$LIBTOOL%g
+s%@MAINT@%$MAINT%g
+s%@CPP@%$CPP%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+  if test $ac_beg -gt 1; then
+    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+  else
+    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+  fi
+  if test ! -s conftest.s$ac_file; then
+    ac_more_lines=false
+    rm -f conftest.s$ac_file
+  else
+    if test -z "$ac_sed_cmds"; then
+      ac_sed_cmds="sed -f conftest.s$ac_file"
+    else
+      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+    fi
+    ac_file=`expr $ac_file + 1`
+    ac_beg=$ac_end
+    ac_end=`expr $ac_end + $ac_max_sed_cmds`
+  fi
+done
+if test -z "$ac_sed_cmds"; then
+  ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+  # Remove last slash and all that follows it.  Not all systems have dirname.
+  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+    # The file is in a subdirectory.
+    test ! -d "$ac_dir" && mkdir "$ac_dir"
+    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+    # A "../" for each directory in $ac_dir_suffix.
+    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+  else
+    ac_dir_suffix= ac_dots=
+  fi
+
+  case "$ac_given_srcdir" in
+  .)  srcdir=.
+      if test -z "$ac_dots"; then top_srcdir=.
+      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+  *) # Relative path.
+    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+    top_srcdir="$ac_dots$ac_given_srcdir" ;;
+  esac
+
+  case "$ac_given_INSTALL" in
+  [/$]*) INSTALL="$ac_given_INSTALL" ;;
+  *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+  esac
+
+  echo creating "$ac_file"
+  rm -f "$ac_file"
+  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+  case "$ac_file" in
+  *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+  *) ac_comsub= ;;
+  esac
+
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([  ]*\)#\([        ]*define[       ][      ]*\)'
+ac_dB='\([     ][      ]*\)[^  ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([  ]*\)#\([        ]*\)undef\([    ][      ]*\)'
+ac_uB='\([     ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([  ]*\)#\([        ]*\)undef\([    ][      ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+  CONFIG_HEADERS="glibconfig.h"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  echo creating $ac_file
+
+  rm -f conftest.frag conftest.in conftest.out
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h.  And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[   ]*#[    ]*undef[        ][      ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+  ac_lines=`grep -c . conftest.vals`
+  # grep -c gives empty output for an empty file on some AIX systems.
+  if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+  # Write a limited-size here document to conftest.frag.
+  echo '  cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+  echo 'CEOF
+  sed -f conftest.frag conftest.in > conftest.out
+  rm -f conftest.in
+  mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+  rm -f conftest.vals
+  mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+  rm -f conftest.frag conftest.h
+  echo "/* $ac_file.  Generated automatically by configure.  */" > conftest.h
+  cat conftest.in >> conftest.h
+  rm -f conftest.in
+  if cmp -s $ac_file conftest.h 2>/dev/null; then
+    echo "$ac_file is unchanged"
+    rm -f conftest.h
+  else
+    # Remove last slash and all that follows it.  Not all systems have dirname.
+      ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+      if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+      # The file is in a subdirectory.
+      test ! -d "$ac_dir" && mkdir "$ac_dir"
+    fi
+    rm -f $ac_file
+    mv conftest.h $ac_file
+  fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/glib/configure.in b/glib/configure.in
new file mode 100644 (file)
index 0000000..d97b441
--- /dev/null
@@ -0,0 +1,116 @@
+# Process this file with autoconf to produce a configure script.
+AC_INIT(glib.h)
+
+dnl Initialize automake stuff
+AM_INIT_AUTOMAKE(glib, 971109)
+
+# Specify a configuration file
+AM_CONFIG_HEADER(glibconfig.h)
+
+dnl Initialize libtool
+AM_PROG_LIBTOOL
+
+dnl Initialize maintainer mode
+AM_MAINTAINER_MODE
+
+AC_CANONICAL_HOST
+
+AC_ARG_ENABLE(debug, [  --enable-debug          turn on debugging [default=no]],
+if eval "test x$enable_debug = xyes"; then
+  DEBUGFLAG="-g"
+fi)
+
+AC_ARG_ENABLE(ansi, [  --enable-ansi           turn on strict ansi [default=no]],
+                   , enable_ansi=no)
+
+if test -n "$DEBUGFLAG"; then
+  CFLAGS="$DEBUGFLAG"
+fi
+
+# Checks for programs.
+AC_PROG_CC
+AM_PROG_CC_STDC
+AC_PROG_INSTALL
+
+if eval "test x$GCC = xyes"; then
+  test `echo "$CFLAGS" | grep "\-Wall" > /dev/null 2> /dev/null`
+  if test ! $?; then
+    CFLAGS="$CFLAGS -Wall"
+  fi
+
+  if eval "test x$enable_ansi = xyes"; then
+    test `echo "$CFLAGS" | grep "\-ansi" > /dev/null 2> /dev/null`
+    if test ! $?; then
+      CFLAGS="$CFLAGS -ansi"
+    fi
+
+    test `echo "$CFLAGS" | grep "\-pedantic" > /dev/null 2> /dev/null`
+    if test ! $?; then
+      CFLAGS="$CFLAGS -pedantic"
+    fi
+  fi
+fi
+
+# Checks for header files.
+AC_HEADER_STDC
+
+# Checks for library functions.
+AC_FUNC_VPRINTF
+
+AC_CHECK_SIZEOF(char)
+AC_CHECK_SIZEOF(short)
+AC_CHECK_SIZEOF(long)
+AC_CHECK_SIZEOF(int)
+AC_CHECK_SIZEOF(void *)
+
+AC_C_LONG_DOUBLE
+AC_C_CONST
+AC_C_INLINE
+
+AC_CHECK_HEADERS(float.h, AC_DEFINE(HAVE_FLOAT_H))
+AC_CHECK_HEADERS(limits.h, AC_DEFINE(HAVE_LIMITS_H))
+AC_CHECK_HEADERS(values.h, AC_DEFINE(HAVE_VALUES_H))
+
+# Check for strerror and strsignal functions
+AC_CHECK_FUNCS(strerror strsignal)
+
+# Check for sys_errlist
+AC_MSG_CHECKING(sys_errlist)
+AC_TRY_LINK(, [
+extern char *sys_errlist[];
+extern int sys_nerr;
+sys_errlist[sys_nerr-1][0] = 0;
+], glib_ok=yes, glib_ok=no)
+AC_MSG_RESULT($glib_ok)
+if test $glib_ok = no; then
+    AC_DEFINE(NO_SYS_ERRLIST)
+fi
+
+# Check for sys_siglist
+AC_MSG_CHECKING(sys_siglist)
+AC_TRY_LINK(, [
+extern char *sys_siglist[];
+sys_siglist[1][0] = 0;
+], glib_ok=yes, glib_ok=no)
+AC_MSG_RESULT($glib_ok)
+if test $glib_ok = no; then
+    AC_DEFINE(NO_SYS_SIGLIST)
+fi
+
+# Check for sys/select.h
+
+AC_MSG_CHECKING([fd_set and sys/select])
+AC_TRY_COMPILE([#include <sys/types.h>],
+        [fd_set readMask, writeMask;], gtk_ok=yes, gtk_ok=no)
+if test $gtk_ok = no; then
+    AC_HEADER_EGREP(fd_mask, sys/select.h, gtk_ok=yes)
+    if test $gtk_ok = yes; then
+        AC_DEFINE(HAVE_SYS_SELECT_H)
+    fi
+fi
+AC_MSG_RESULT($gtk_ok)
+if test $gtk_ok = no; then
+    AC_DEFINE(NO_FD_SET)
+fi
+
+AC_OUTPUT(Makefile)
diff --git a/glib/garray.c b/glib/garray.c
new file mode 100644 (file)
index 0000000..3700848
--- /dev/null
@@ -0,0 +1,142 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <string.h>
+#include "glib.h"
+
+
+#define MIN_ARRAY_SIZE  16
+
+
+typedef struct _GRealArray  GRealArray;
+
+struct _GRealArray
+{
+  guint8 *data;
+  guint   len;
+  guint   alloc;
+  guint   zero_terminated;
+};
+
+
+static gint g_nearest_pow        (gint        num);
+static void g_array_maybe_expand (GRealArray *array,
+                                 gint        len);
+
+
+static GMemChunk *array_mem_chunk = NULL;
+
+
+GArray*
+g_array_new (zero_terminated)
+{
+  GRealArray *array;
+
+  if (!array_mem_chunk)
+    array_mem_chunk = g_mem_chunk_new ("array mem chunk",
+                                      sizeof (GRealArray),
+                                      1024, G_ALLOC_AND_FREE);
+
+  array = g_chunk_new (GRealArray, array_mem_chunk);
+
+  array->data = NULL;
+  array->len = 0;
+  array->alloc = 0;
+  array->zero_terminated = (zero_terminated ? 1 : 0);
+
+  return (GArray*) array;
+}
+
+void
+g_array_free (GArray *array,
+             gint    free_segment)
+{
+  if (free_segment)
+    g_free (array->data);
+
+  g_mem_chunk_free (array_mem_chunk, array);
+}
+
+GArray*
+g_rarray_append (GArray   *array,
+                gpointer  data,
+                gint      size)
+{
+  g_array_maybe_expand ((GRealArray*) array, size);
+
+  memcpy (array->data + array->len, data, size);
+
+  array->len += size;
+
+  return array;
+}
+
+GArray*
+g_rarray_prepend (GArray   *array,
+                 gpointer  data,
+                 gint      size)
+{
+  g_array_maybe_expand ((GRealArray*) array, size);
+
+  memmove (array->data + size, array->data, array->len);
+  memcpy (array->data, data, size);
+
+  array->len += size;
+
+  return array;
+}
+
+GArray*
+g_rarray_truncate (GArray *array,
+                  gint    length,
+                  gint    size)
+{
+  if (array->data)
+    memset (array->data + length * size, 0, size);
+  array->len = length;
+  return array;
+}
+
+
+static gint
+g_nearest_pow (gint num)
+{
+  gint n = 1;
+
+  while (n < num)
+    n <<= 1;
+
+  return n;
+}
+
+static void
+g_array_maybe_expand (GRealArray *array,
+                     gint        len)
+{
+  guint old_alloc;
+
+  if ((array->len + len) > array->alloc)
+    {
+      old_alloc = array->alloc;
+
+      array->alloc = g_nearest_pow (array->len + array->zero_terminated + len);
+      array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE);
+      array->data = g_realloc (array->data, array->alloc);
+
+      memset (array->data + old_alloc, 0, array->alloc - old_alloc);
+    }
+}
diff --git a/glib/gcache.c b/glib/gcache.c
new file mode 100644 (file)
index 0000000..b121219
--- /dev/null
@@ -0,0 +1,211 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "glib.h"
+
+
+typedef struct _GCacheNode  GCacheNode;
+typedef struct _GRealCache  GRealCache;
+
+struct _GCacheNode
+{
+  /* A reference counted node */
+  gpointer value;
+  gint ref_count;
+};
+
+struct _GRealCache
+{
+  /* Called to create a value from a key */
+  GCacheNewFunc value_new_func;
+
+  /* Called to destroy a value */
+  GCacheDestroyFunc value_destroy_func;
+
+  /* Called to duplicate a key */
+  GCacheDupFunc key_dup_func;
+
+  /* Called to destroy a key */
+  GCacheDestroyFunc key_destroy_func;
+
+  /* Associates keys with nodes */
+  GHashTable *key_table;
+
+  /* Associates nodes with keys */
+  GHashTable *value_table;
+};
+
+
+static GCacheNode* g_cache_node_new     (gpointer value);
+static void        g_cache_node_destroy (GCacheNode *node);
+
+
+static GMemChunk *node_mem_chunk = NULL;
+
+
+GCache*
+g_cache_new (GCacheNewFunc      value_new_func,
+            GCacheDestroyFunc  value_destroy_func,
+            GCacheDupFunc      key_dup_func,
+            GCacheDestroyFunc  key_destroy_func,
+            GHashFunc          hash_key_func,
+            GHashFunc          hash_value_func,
+            GCompareFunc       key_compare_func)
+{
+  GRealCache *cache;
+
+  g_return_val_if_fail (value_new_func != NULL, NULL);
+  g_return_val_if_fail (value_destroy_func != NULL, NULL);
+  g_return_val_if_fail (key_dup_func != NULL, NULL);
+  g_return_val_if_fail (key_destroy_func != NULL, NULL);
+  g_return_val_if_fail (hash_key_func != NULL, NULL);
+  g_return_val_if_fail (hash_value_func != NULL, NULL);
+  g_return_val_if_fail (key_compare_func != NULL, NULL);
+
+  cache = g_new (GRealCache, 1);
+  cache->value_new_func = value_new_func;
+  cache->value_destroy_func = value_destroy_func;
+  cache->key_dup_func = key_dup_func;
+  cache->key_destroy_func = key_destroy_func;
+  cache->key_table = g_hash_table_new (hash_key_func, key_compare_func);
+  cache->value_table = g_hash_table_new (hash_value_func, NULL);
+
+  return (GCache*) cache;
+}
+
+void
+g_cache_destroy (GCache *cache)
+{
+  GRealCache *rcache;
+
+  g_return_if_fail (cache != NULL);
+
+  rcache = (GRealCache*) cache;
+  g_hash_table_destroy (rcache->key_table);
+  g_hash_table_destroy (rcache->value_table);
+  g_free (rcache);
+}
+
+gpointer
+g_cache_insert (GCache   *cache,
+               gpointer  key)
+{
+  GRealCache *rcache;
+  GCacheNode *node;
+  gpointer value;
+
+  g_return_val_if_fail (cache != NULL, NULL);
+
+  rcache = (GRealCache*) cache;
+
+  node = g_hash_table_lookup (rcache->key_table, key);
+  if (node)
+    {
+      node->ref_count += 1;
+      return node->value;
+    }
+
+  key = (* rcache->key_dup_func) (key);
+  value = (* rcache->value_new_func) (key);
+  node = g_cache_node_new (value);
+
+  g_hash_table_insert (rcache->key_table, key, node);
+  g_hash_table_insert (rcache->value_table, value, key);
+
+  return node->value;
+}
+
+void
+g_cache_remove (GCache   *cache,
+               gpointer  value)
+{
+  GRealCache *rcache;
+  GCacheNode *node;
+  gpointer key;
+
+  g_return_if_fail (cache != NULL);
+
+  rcache = (GRealCache*) cache;
+
+  key = g_hash_table_lookup (rcache->value_table, value);
+  node = g_hash_table_lookup (rcache->key_table, key);
+
+  node->ref_count -= 1;
+  if (node->ref_count == 0)
+    {
+      g_hash_table_remove (rcache->value_table, value);
+      g_hash_table_remove (rcache->key_table, key);
+
+      (* rcache->key_destroy_func) (key);
+      (* rcache->value_destroy_func) (node->value);
+      g_cache_node_destroy (node);
+    }
+}
+
+void
+g_cache_key_foreach (GCache   *cache,
+                    GHFunc    func,
+                    gpointer  user_data)
+{
+  GRealCache *rcache;
+
+  g_return_if_fail (cache != NULL);
+  g_return_if_fail (func != NULL);
+
+  rcache = (GRealCache*) cache;
+
+  g_hash_table_foreach (rcache->value_table, func, user_data);
+}
+
+void
+g_cache_value_foreach (GCache   *cache,
+                      GHFunc    func,
+                      gpointer  user_data)
+{
+  GRealCache *rcache;
+
+  g_return_if_fail (cache != NULL);
+  g_return_if_fail (func != NULL);
+
+  rcache = (GRealCache*) cache;
+
+  g_hash_table_foreach (rcache->key_table, func, user_data);
+}
+
+
+static GCacheNode*
+g_cache_node_new (gpointer value)
+{
+  GCacheNode *node;
+
+  if (!node_mem_chunk)
+    node_mem_chunk = g_mem_chunk_new ("cache node mem chunk", sizeof (GCacheNode),
+                                     1024, G_ALLOC_AND_FREE);
+
+  node = g_chunk_new (GCacheNode, node_mem_chunk);
+
+  node->value = value;
+  node->ref_count = 1;
+
+  return node;
+}
+
+static void
+g_cache_node_destroy (GCacheNode *node)
+{
+  g_mem_chunk_free (node_mem_chunk, node);
+}
diff --git a/glib/gerror.c b/glib/gerror.c
new file mode 100644 (file)
index 0000000..96e1013
--- /dev/null
@@ -0,0 +1,256 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include <sys/times.h>
+#include <sys/types.h>
+
+#include <time.h>
+#include <unistd.h>
+#include "glib.h"
+
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif /* HAVE_SYS_SELECT_H */
+
+#ifdef STDC_HEADERS
+#include <string.h> /* for bzero on BSD systems */
+#endif
+
+#define INTERACTIVE 0
+#define STACK_TRACE 1
+
+
+#ifndef NO_FD_SET
+#  define SELECT_MASK fd_set
+#else
+#  ifndef _AIX
+     typedef long fd_mask;
+#  endif
+#  if defined(_IBMR2)
+#    define SELECT_MASK void
+#  else
+#    define SELECT_MASK int
+#  endif
+#endif
+
+
+static int  do_query (char *prompt);
+static void debug (char *progname, int method);
+static void stack_trace (char **);
+static void stack_trace_sigchld (int);
+
+
+static int stack_trace_done;
+
+void
+g_debug (char *progname)
+{
+  char buf[32];
+
+  fprintf (stdout, "[n]othing, [e]xit, [s]tack trace, [a]ttach to process: ");
+  fflush (stdout);
+
+  fgets (buf, 32, stdin);
+  if (strcmp (buf, "n\n") == 0)
+    return;
+  else if (strcmp (buf, "s\n") == 0)
+    debug (progname, STACK_TRACE);
+  else if (strcmp (buf, "a\n") == 0)
+    debug (progname, INTERACTIVE);
+  else
+    exit (0);
+}
+
+void
+g_attach_process (char *progname, int query)
+{
+  if (!query || do_query ("attach to process"))
+    debug (progname, INTERACTIVE);
+}
+
+void
+g_stack_trace (char *progname, int query)
+{
+  if (!query || do_query ("print stack trace"))
+    debug (progname, STACK_TRACE);
+}
+
+static int
+do_query (char *prompt)
+{
+  char buf[32];
+
+  fprintf (stdout, "%s (y/n) ", prompt);
+  fflush (stdout);
+
+  fgets (buf, 32, stdin);
+  if ((strcmp (buf, "yes\n") == 0) ||
+      (strcmp (buf, "y\n") == 0) ||
+      (strcmp (buf, "YES\n") == 0) ||
+      (strcmp (buf, "Y\n") == 0))
+    return TRUE;
+
+  return FALSE;
+}
+
+static void
+debug (char *progname,
+       int   method)
+{
+  pid_t pid;
+  char buf[16];
+  char *args[4] = { "gdb", NULL, NULL, NULL };
+  volatile int x;
+
+  sprintf (buf, "%d", (int) getpid ());
+
+  args[1] = progname;
+  args[2] = buf;
+
+  switch (method)
+    {
+    case INTERACTIVE:
+      fprintf (stdout, "pid: %s\n", buf);
+      break;
+    case STACK_TRACE:
+      pid = fork ();
+      if (pid == 0)
+       {
+         stack_trace (args);
+         _exit (0);
+       }
+      else if (pid == (pid_t) -1)
+       {
+         perror ("could not fork");
+         return;
+       }
+      break;
+    }
+
+  x = 1;
+  while (x)
+    ;
+}
+
+static void
+stack_trace (char **args)
+{
+  pid_t pid;
+  int in_fd[2];
+  int out_fd[2];
+  SELECT_MASK fdset;
+  SELECT_MASK readset;
+  struct timeval tv;
+  int sel, index, state;
+  char buffer[256];
+  char c;
+
+  stack_trace_done = 0;
+  signal (SIGCHLD, stack_trace_sigchld);
+
+  if ((pipe (in_fd) == -1) || (pipe (out_fd) == -1))
+    {
+      perror ("could open pipe");
+      _exit (0);
+    }
+
+  pid = fork ();
+  if (pid == 0)
+    {
+      close (0); dup (in_fd[0]);   /* set the stdin to the in pipe */
+      close (1); dup (out_fd[1]);  /* set the stdout to the out pipe */
+      close (2); dup (out_fd[1]);  /* set the stderr to the out pipe */
+
+      execvp (args[0], args);      /* exec gdb */
+      perror ("exec failed");
+      _exit (0);
+    }
+  else if (pid == (pid_t) -1)
+    {
+      perror ("could not fork");
+      _exit (0);
+    }
+
+  FD_ZERO (&fdset);
+  FD_SET (out_fd[0], &fdset);
+
+  write (in_fd[1], "backtrace\n", 10);
+  write (in_fd[1], "p x = 0\n", 8);
+  write (in_fd[1], "quit\n", 5);
+
+  index = 0;
+  state = 0;
+
+  while (1)
+    {
+      readset = fdset;
+      tv.tv_sec = 1;
+      tv.tv_usec = 0;
+
+      sel = select (FD_SETSIZE, &readset, NULL, NULL, &tv);
+      if (sel == -1)
+        break;
+
+      if ((sel > 0) && (FD_ISSET (out_fd[0], &readset)))
+        {
+          if (read (out_fd[0], &c, 1))
+            {
+              switch (state)
+                {
+                case 0:
+                  if (c == '#')
+                    {
+                      state = 1;
+                      index = 0;
+                      buffer[index++] = c;
+                    }
+                  break;
+                case 1:
+                  buffer[index++] = c;
+                  if ((c == '\n') || (c == '\r'))
+                    {
+                      buffer[index] = 0;
+                      fprintf (stdout, "%s", buffer);
+                      state = 0;
+                      index = 0;
+                    }
+                  break;
+                default:
+                  break;
+                }
+            }
+        }
+      else if (stack_trace_done)
+        break;
+    }
+
+  close (in_fd[0]);
+  close (in_fd[1]);
+  close (out_fd[0]);
+  close (out_fd[1]);
+  _exit (0);
+}
+
+static void
+stack_trace_sigchld (int signum)
+{
+  stack_trace_done = 1;
+}
diff --git a/glib/ghash.c b/glib/ghash.c
new file mode 100644 (file)
index 0000000..ed736d4
--- /dev/null
@@ -0,0 +1,418 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "glib.h"
+
+
+#define HASH_TABLE_MIN_SIZE 11
+#define HASH_TABLE_MAX_SIZE 13845163
+
+
+typedef struct _GHashNode      GHashNode;
+typedef struct _GRealHashTable GRealHashTable;
+
+struct _GHashNode
+{
+  gpointer key;
+  gpointer value;
+  GHashNode *next;
+};
+
+struct _GRealHashTable
+{
+  gint size;
+  gint nnodes;
+  gint frozen;
+  GHashNode **nodes;
+  GHashFunc hash_func;
+  GCompareFunc key_compare_func;
+};
+
+
+static void       g_hash_table_resize  (GHashTable *hash_table);
+static gint       g_hash_closest_prime (gint        num);
+static GHashNode* g_hash_node_new      (gpointer    key,
+                                       gpointer    value);
+static void       g_hash_node_destroy  (GHashNode  *hash_node);
+static void       g_hash_nodes_destroy (GHashNode  *hash_node);
+
+
+extern gint g_primes[];
+extern gint g_nprimes;
+
+static GMemChunk *node_mem_chunk = NULL;
+static GHashNode *node_free_list = NULL;
+
+
+GHashTable*
+g_hash_table_new (GHashFunc    hash_func,
+                 GCompareFunc key_compare_func)
+{
+  GRealHashTable *hash_table;
+
+  g_return_val_if_fail (hash_func != NULL, NULL);
+
+  hash_table = g_new (GRealHashTable, 1);
+  hash_table->size = 0;
+  hash_table->nnodes = 0;
+  hash_table->frozen = FALSE;
+  hash_table->nodes = NULL;
+  hash_table->hash_func = hash_func;
+  hash_table->key_compare_func = key_compare_func;
+
+  return ((GHashTable*) hash_table);
+}
+
+void
+g_hash_table_destroy (GHashTable *hash_table)
+{
+  GRealHashTable *rhash_table;
+  gint i;
+
+  if (hash_table)
+    {
+      rhash_table = (GRealHashTable*) hash_table;
+
+      for (i = 0; i < rhash_table->size; i++)
+       g_hash_nodes_destroy (rhash_table->nodes[i]);
+
+      if (rhash_table->nodes)
+       g_free (rhash_table->nodes);
+      g_free (rhash_table);
+    }
+}
+
+void
+g_hash_table_insert (GHashTable *hash_table,
+                    gpointer    key,
+                    gpointer    value)
+{
+  GRealHashTable *rhash_table;
+  GHashNode *node;
+  guint hash_val;
+
+  if (hash_table)
+    {
+      rhash_table = (GRealHashTable*) hash_table;
+
+      if (rhash_table->size == 0)
+       g_hash_table_resize (hash_table);
+
+      hash_val = (* rhash_table->hash_func) (key) % rhash_table->size;
+
+      node = rhash_table->nodes[hash_val];
+      while (node)
+       {
+         if ((rhash_table->key_compare_func &&
+              (* rhash_table->key_compare_func) (node->key, key)) ||
+             (node->key == key))
+           {
+             node->value = value;
+             return;
+           }
+         node = node->next;
+       }
+
+      node = g_hash_node_new (key, value);
+      node->next = rhash_table->nodes[hash_val];
+      rhash_table->nodes[hash_val] = node;
+
+      rhash_table->nnodes += 1;
+      g_hash_table_resize (hash_table);
+    }
+}
+
+void
+g_hash_table_remove (GHashTable *hash_table,
+                    gpointer    key)
+{
+  GRealHashTable *rhash_table;
+  GHashNode *node;
+  GHashNode *prev;
+  guint hash_val;
+
+  rhash_table = (GRealHashTable*) hash_table;
+  if (hash_table && rhash_table->size)
+    {
+      hash_val = (* rhash_table->hash_func) (key) % rhash_table->size;
+
+      prev = NULL;
+      node = rhash_table->nodes[hash_val];
+
+      while (node)
+       {
+         if ((rhash_table->key_compare_func &&
+              (* rhash_table->key_compare_func) (node->key, key)) ||
+             (node->key == key))
+           {
+             if (prev)
+               prev->next = node->next;
+             if (node == rhash_table->nodes[hash_val])
+               rhash_table->nodes[hash_val] = node->next;
+
+             g_hash_node_destroy (node);
+
+             rhash_table->nnodes -= 1;
+             g_hash_table_resize (hash_table);
+             break;
+           }
+
+         prev = node;
+         node = node->next;
+       }
+    }
+}
+
+gpointer
+g_hash_table_lookup (GHashTable     *hash_table,
+                    const gpointer  key)
+{
+  GRealHashTable *rhash_table;
+  GHashNode *node;
+  guint hash_val;
+
+  rhash_table = (GRealHashTable*) hash_table;
+  if (hash_table && rhash_table->size)
+    {
+      hash_val = (* rhash_table->hash_func) (key) % rhash_table->size;
+
+      node = rhash_table->nodes[hash_val];
+
+      /* Hash table lookup needs to be fast.
+       *  We therefore remove the extra conditional of testing
+       *  whether to call the key_compare_func or not from
+       *  the inner loop.
+       */
+      if (rhash_table->key_compare_func)
+       {
+         while (node)
+           {
+             if ((* rhash_table->key_compare_func) (node->key, key))
+               return node->value;
+             node = node->next;
+           }
+       }
+      else
+       {
+         while (node)
+           {
+             if (node->key == key)
+               return node->value;
+             node = node->next;
+           }
+       }
+    }
+
+  return NULL;
+}
+
+void
+g_hash_table_freeze (GHashTable *hash_table)
+{
+  GRealHashTable *rhash_table;
+
+  if (hash_table)
+    {
+      rhash_table = (GRealHashTable*) hash_table;
+      rhash_table->frozen = TRUE;
+    }
+}
+
+void
+g_hash_table_thaw (GHashTable *hash_table)
+{
+  GRealHashTable *rhash_table;
+
+  if (hash_table)
+    {
+      rhash_table = (GRealHashTable*) hash_table;
+      rhash_table->frozen = FALSE;
+
+      g_hash_table_resize (hash_table);
+    }
+}
+
+void
+g_hash_table_foreach (GHashTable *hash_table,
+                     GHFunc      func,
+                     gpointer    user_data)
+{
+  GRealHashTable *rhash_table;
+  GHashNode *node;
+  gint i;
+
+  if (hash_table)
+    {
+      rhash_table = (GRealHashTable*) hash_table;
+
+      for (i = 0; i < rhash_table->size; i++)
+       {
+         node = rhash_table->nodes[i];
+
+         while (node)
+           {
+             (* func) (node->key, node->value, user_data);
+             node = node->next;
+           }
+       }
+    }
+}
+
+
+static void
+g_hash_table_resize (GHashTable *hash_table)
+{
+  GRealHashTable *rhash_table;
+  GHashNode **new_nodes;
+  GHashNode *node;
+  GHashNode *next;
+  gfloat nodes_per_list;
+  guint hash_val;
+  gint new_size;
+  gint need_resize;
+  gint i;
+
+  if (hash_table)
+    {
+      rhash_table = (GRealHashTable*) hash_table;
+
+      if (rhash_table->size == 0)
+       {
+         rhash_table->size = HASH_TABLE_MIN_SIZE;
+         rhash_table->nodes = g_new (GHashNode*, rhash_table->size);
+
+         for (i = 0; i < rhash_table->size; i++)
+           rhash_table->nodes[i] = NULL;
+       }
+      else if (!rhash_table->frozen)
+       {
+         need_resize = FALSE;
+         nodes_per_list = (gfloat) rhash_table->nnodes / (gfloat) rhash_table->size;
+
+         if (nodes_per_list < 0.3)
+           {
+             if (rhash_table->size > HASH_TABLE_MIN_SIZE)
+               need_resize = TRUE;
+           }
+         else if (nodes_per_list > 3.0)
+           {
+             if (rhash_table->size < HASH_TABLE_MAX_SIZE)
+               need_resize = TRUE;
+           }
+
+         if (need_resize)
+           {
+             new_size = g_hash_closest_prime (rhash_table->nnodes);
+             if (new_size < HASH_TABLE_MIN_SIZE)
+               new_size = HASH_TABLE_MIN_SIZE;
+             else if (new_size > HASH_TABLE_MAX_SIZE)
+               new_size = HASH_TABLE_MAX_SIZE;
+
+             new_nodes = g_new (GHashNode*, new_size);
+
+             for (i = 0; i < new_size; i++)
+               new_nodes[i] = NULL;
+
+             for (i = 0; i < rhash_table->size; i++)
+               {
+                 node = rhash_table->nodes[i];
+
+                 while (node)
+                   {
+                     next = node->next;
+
+                     hash_val = (* rhash_table->hash_func) (node->key) % new_size;
+                     node->next = new_nodes[hash_val];
+                     new_nodes[hash_val] = node;
+
+                     node = next;
+                   }
+               }
+
+             g_free (rhash_table->nodes);
+
+             rhash_table->nodes = new_nodes;
+             rhash_table->size = new_size;
+           }
+       }
+    }
+}
+
+static gint
+g_hash_closest_prime (gint num)
+{
+  gint i;
+
+  for (i = 0; i < g_nprimes; i++)
+    if ((g_primes[i] - num) > 0)
+      return g_primes[i];
+
+  return g_primes[g_nprimes - 1];
+}
+
+static GHashNode*
+g_hash_node_new (gpointer key,
+                gpointer value)
+{
+  GHashNode *hash_node;
+
+  if (node_free_list)
+    {
+      hash_node = node_free_list;
+      node_free_list = node_free_list->next;
+    }
+  else
+    {
+      if (!node_mem_chunk)
+       node_mem_chunk = g_mem_chunk_new ("hash node mem chunk",
+                                         sizeof (GHashNode),
+                                         1024, G_ALLOC_ONLY);
+
+      hash_node = g_chunk_new (GHashNode, node_mem_chunk);
+    }
+
+  hash_node->key = key;
+  hash_node->value = value;
+  hash_node->next = NULL;
+
+  return hash_node;
+}
+
+static void
+g_hash_node_destroy (GHashNode *hash_node)
+{
+  if (hash_node)
+    {
+      hash_node->next = node_free_list;
+      node_free_list = hash_node;
+    }
+}
+
+static void
+g_hash_nodes_destroy (GHashNode *hash_node)
+{
+  GHashNode *node;
+
+  if (hash_node)
+    {
+      node = hash_node;
+      while (node->next)
+       node = node->next;
+      node->next = node_free_list;
+      node_free_list = hash_node;
+    }
+}
diff --git a/glib/glib.h b/glib/glib.h
new file mode 100644 (file)
index 0000000..9af5fa1
--- /dev/null
@@ -0,0 +1,674 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __G_LIB_H__
+#define __G_LIB_H__
+
+
+#include <glibconfig.h>
+
+#ifdef USE_DMALLOC
+#include "dmalloc.h"
+#endif
+
+
+/* glib provides definitions for the extrema of many
+ *  of the standard types. These are:
+ * G_MINFLOAT
+ * G_MAXFLOAT
+ * G_MINDOUBLE
+ * G_MAXDOUBLE
+ * G_MINSHORT
+ * G_MAXSHORT
+ * G_MININT
+ * G_MAXINT
+ * G_MINLONG
+ * G_MAXLONG
+ */
+
+#ifdef HAVE_FLOAT_H
+
+#include <float.h>
+
+#define G_MINFLOAT   FLT_MIN
+#define G_MAXFLOAT   FLT_MAX
+#define G_MINDOUBLE  DBL_MIN
+#define G_MAXDOUBLE  DBL_MAX
+
+#elif HAVE_VALUES_H
+
+#include <values.h>
+
+#define G_MINFLOAT  MINFLOAT
+#define G_MAXFLOAT  MAXFLOAT
+#define G_MINDOUBLE MINDOUBLE
+#define G_MAXDOUBLE MAXDOUBLE
+
+#endif /* HAVE_VALUES_H */
+
+
+#ifdef HAVE_LIMITS_H
+
+#include <limits.h>
+
+#define G_MINSHORT  SHRT_MIN
+#define G_MAXSHORT  SHRT_MAX
+#define G_MININT    INT_MIN
+#define G_MAXINT    INT_MAX
+#define G_MINLONG   LONG_MIN
+#define G_MAXLONG   LONG_MAX
+
+#elif HAVE_VALUES_H
+
+#ifdef HAVE_FLOAT_H
+#include <values.h>
+#endif /* HAVE_FLOAT_H */
+
+#define G_MINSHORT  MINSHORT
+#define G_MAXSHORT  MAXSHORT
+#define G_MININT    MININT
+#define G_MAXINT    MAXINT
+#define G_MINLONG   MINLONG
+#define G_MAXLONG   MAXLONG
+
+#endif /* HAVE_VALUES_H */
+
+
+/* Provide definitions for some commonly used macros.
+ *  These are only provided if they haven't already
+ *  been defined. It is assumed that if they are already
+ *  defined then the current definition is correct.
+ */
+
+#ifndef FALSE
+#define FALSE 0
+#endif /* FALSE */
+
+#ifndef TRUE
+#define TRUE 1
+#endif /* TRUE */
+
+#ifndef NULL
+#define NULL ((void*) 0)
+#endif /* NULL */
+
+#ifndef MAX
+#define MAX(a, b)  (((a) > (b)) ? (a) : (b))
+#endif /* MAX */
+
+#ifndef MIN
+#define MIN(a, b)  (((a) < (b)) ? (a) : (b))
+#endif /* MIN */
+
+#ifndef ABS
+#define ABS(a)     (((a) < 0) ? -(a) : (a))
+#endif /* ABS */
+
+#ifndef CLAMP
+#define CLAMP(x, low, high)  (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
+#endif /* CLAMP */
+
+#ifndef ATEXIT
+#define ATEXIT(proc)   (atexit (proc))
+#endif /* ATEXIT */
+
+
+/* Provide macros for easily allocating memory. The macros
+ *  will cast the allocated memory to the specified type
+ *  in order to avoid compiler warnings. (Makes the code neater).
+ */
+
+#ifdef __DMALLOC_H__
+
+#define g_new(type,count)        ALLOC(type,count)
+#define g_new0(type,count)       CALLOC(type,count)
+
+#else /* __DMALLOC_H__ */
+
+#define g_new(type, count)        \
+    ((type *) g_malloc ((unsigned) sizeof (type) * (count)))
+#define g_new0(type, count)       \
+    ((type *) g_malloc0 ((unsigned) sizeof (type) * (count)))
+#endif /* __DMALLOC_H__ */
+
+#define g_chunk_new(type, chunk)  \
+    ((type *) g_mem_chunk_alloc (chunk))
+
+
+/* Provide macros for error handling. The "assert" macros will
+ *  exit on failur. The "return" macros will exit the current
+ *  function. Two different definitions are given for the macros
+ *  in order to support gcc's __PRETTY_FUNCTION__ capability.
+ */
+
+#define g_string(x) #x
+
+#ifdef __GNUC__
+
+#define g_assert(expr) \
+     if (!(expr))                                    \
+       g_error ("file %s: line %d (%s): \"%s\"",     \
+               __FILE__,                            \
+               __LINE__,                            \
+               __PRETTY_FUNCTION__,                 \
+               #expr)
+
+#define g_assert_not_reached() \
+     g_error ("file %s: line %d (%s): \"should not be reached\"",     \
+             __FILE__,                                               \
+             __LINE__,                                               \
+             __PRETTY_FUNCTION__)
+
+#define g_return_if_fail(expr) \
+     if (!(expr))                                              \
+       {                                                       \
+         g_warning ("file %s: line %d (%s): \"%s\"",           \
+                   __FILE__,                                  \
+                   __LINE__,                                  \
+                   __PRETTY_FUNCTION__,                       \
+                   #expr);                                    \
+         return;                                               \
+       }
+
+#define g_return_val_if_fail(expr,val) \
+     if (!(expr))                                              \
+       {                                                       \
+         g_warning ("file %s: line %d (%s): \"%s\"",           \
+                   __FILE__,                                  \
+                   __LINE__,                                  \
+                   __PRETTY_FUNCTION__,                       \
+                   #expr);                                    \
+         return val;                                           \
+       }
+
+#else /* __GNUC__ */
+
+#define g_assert(expr) \
+     if (!(expr))                                    \
+       g_error ("file %s: line %d: \"%s\"",          \
+               __FILE__,                            \
+               __LINE__,                            \
+               #expr)
+
+#define g_assert_not_reached() \
+     g_error ("file %s: line %d: \"should not be reached\"",          \
+             __FILE__,                                               \
+             __LINE__)
+
+#define g_return_if_fail(expr) \
+     if (!(expr))                                        \
+       {                                                 \
+         g_warning ("file %s: line %d: \"%s\"",          \
+                   __FILE__,                            \
+                   __LINE__,                            \
+                   #expr);                              \
+        return;                                         \
+       }
+
+#define g_return_val_if_fail(expr, val) \
+     if (!(expr))                                        \
+       {                                                 \
+         g_warning ("file %s: line %d: \"%s\"",          \
+                   __FILE__,                            \
+                   __LINE__,                            \
+                   #expr);                              \
+        return val;                                     \
+       }
+
+#endif /* __GNUC__ */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Provide type definitions for commonly used types.
+ *  These are useful because a "gint8" can be adjusted
+ *  to be 1 byte (8 bits) on all platforms. Similarly and
+ *  more importantly, "gint32" can be adjusted to be
+ *  4 bytes (32 bits) on all platforms.
+ */
+
+typedef char   gchar;
+typedef short  gshort;
+typedef long   glong;
+typedef int    gint;
+typedef char   gboolean;
+
+typedef unsigned char   guchar;
+typedef unsigned short  gushort;
+typedef unsigned long   gulong;
+typedef unsigned int    guint;
+
+typedef float   gfloat;
+typedef double  gdouble;
+
+#ifdef HAVE_LONG_DOUBLE
+typedef long double gldouble;
+#else /* HAVE_LONG_DOUBLE */
+typedef double gldouble;
+#endif /* HAVE_LONG_DOUBLE */
+
+typedef void* gpointer;
+
+#if (SIZEOF_CHAR == 1)
+typedef signed char     gint8;
+typedef unsigned char   guint8;
+#endif /* SIZEOF_CHAR */
+
+
+#if (SIZEOF_SHORT == 2)
+typedef signed short    gint16;
+typedef unsigned short  guint16;
+#endif /* SIZEOF_SHORT */
+
+
+#if (SIZEOF_INT == 4)
+typedef signed int      gint32;
+typedef unsigned int    guint32;
+#elif (SIZEOF_LONG == 4)
+typedef signed long     gint32;
+typedef unsigned long   guint32;
+#endif /* SIZEOF_INT */
+
+
+typedef struct _GList          GList;
+typedef struct _GSList         GSList;
+typedef struct _GHashTable     GHashTable;
+typedef struct _GCache         GCache;
+typedef struct _GTree          GTree;
+typedef struct _GTimer         GTimer;
+typedef struct _GMemChunk      GMemChunk;
+typedef struct _GListAllocator GListAllocator;
+typedef struct _GStringChunk   GStringChunk;
+typedef struct _GString        GString;
+typedef struct _GArray         GArray;
+
+typedef void (*GFunc) (gpointer data, gpointer user_data);
+typedef void (*GHFunc) (gpointer key, gpointer value, gpointer user_data);
+typedef guint (*GHashFunc) (gpointer key);
+typedef gint (*GCompareFunc) (gpointer a, gpointer b);
+typedef gpointer (*GCacheNewFunc) (gpointer key);
+typedef gpointer (*GCacheDupFunc) (gpointer value);
+typedef void (*GCacheDestroyFunc) (gpointer value);
+typedef gint (*GTraverseFunc) (gpointer key,
+                              gpointer value,
+                              gpointer data);
+typedef gint (*GSearchFunc) (gpointer key,
+                            gpointer data);
+typedef void (*GErrorFunc) (gchar *str);
+typedef void (*GWarningFunc) (gchar *str);
+typedef void (*GPrintFunc) (gchar *str);
+
+
+struct _GList
+{
+  gpointer data;
+  GList *next;
+  GList *prev;
+};
+
+struct _GSList
+{
+  gpointer data;
+  GSList *next;
+};
+
+struct _GString
+{
+  gchar *str;
+  gint len;
+};
+
+struct _GArray
+{
+  gchar *data;
+  guint len;
+};
+
+struct _GHashTable { gint dummy; };
+struct _GCache { gint dummy; };
+struct _GTree { gint dummy; };
+struct _GTimer { gint dummy; };
+struct _GMemChunk { gint dummy; };
+struct _GListAllocator { gint dummy; };
+struct _GStringChunk { gint dummy; };
+
+typedef enum
+{
+  G_IN_ORDER,
+  G_PRE_ORDER,
+  G_POST_ORDER
+} GTraverseType;
+
+/* Doubly linked lists
+ */
+GList* g_list_alloc       (void);
+void   g_list_free        (GList     *list);
+void   g_list_free_1      (GList     *list);
+GList* g_list_append      (GList     *list,
+                          gpointer   data);
+GList* g_list_prepend     (GList     *list,
+                          gpointer   data);
+GList* g_list_insert      (GList     *list,
+                          gpointer   data,
+                          gint       position);
+GList* g_list_remove      (GList     *list,
+                          gpointer   data);
+GList* g_list_remove_link (GList     *list,
+                          GList     *link);
+GList* g_list_reverse     (GList     *list);
+GList* g_list_nth         (GList     *list,
+                          gint       n);
+GList* g_list_find        (GList     *list,
+                          gpointer   data);
+GList* g_list_last        (GList     *list);
+GList* g_list_first       (GList     *list);
+gint   g_list_length      (GList     *list);
+void   g_list_foreach     (GList     *list,
+                          GFunc      func,
+                          gpointer   user_data);
+
+
+/* Singly linked lists
+ */
+GSList* g_slist_alloc       (void);
+void    g_slist_free        (GSList   *list);
+void    g_slist_free_1      (GSList   *list);
+GSList* g_slist_append      (GSList   *list,
+                            gpointer  data);
+GSList* g_slist_prepend     (GSList   *list,
+                            gpointer  data);
+GSList* g_slist_insert      (GSList   *list,
+                            gpointer  data,
+                            gint      position);
+GSList* g_slist_remove      (GSList   *list,
+                            gpointer  data);
+GSList* g_slist_remove_link (GSList   *list,
+                            GSList   *link);
+GSList* g_slist_reverse     (GSList   *list);
+GSList* g_slist_nth         (GSList   *list,
+                            gint      n);
+GSList* g_slist_find        (GSList   *list,
+                            gpointer  data);
+GSList* g_slist_last        (GSList   *list);
+gint    g_slist_length      (GSList   *list);
+void    g_slist_foreach     (GSList   *list,
+                            GFunc     func,
+                            gpointer  user_data);
+
+
+/* List Allocators
+ */
+GListAllocator* g_list_allocator_new  (void);
+void            g_list_allocator_free (GListAllocator* allocator);
+GListAllocator* g_slist_set_allocator (GListAllocator* allocator);
+GListAllocator* g_list_set_allocator  (GListAllocator* allocator);
+
+
+/* Hash tables
+ */
+GHashTable* g_hash_table_new     (GHashFunc       hash_func,
+                                 GCompareFunc    key_compare_func);
+void        g_hash_table_destroy (GHashTable     *hash_table);
+void        g_hash_table_insert  (GHashTable     *hash_table,
+                                 gpointer        key,
+                                 gpointer        value);
+void        g_hash_table_remove  (GHashTable     *hash_table,
+                                 gpointer        key);
+gpointer    g_hash_table_lookup  (GHashTable     *hash_table,
+                                 const gpointer  key);
+void        g_hash_table_freeze  (GHashTable     *hash_table);
+void        g_hash_table_thaw    (GHashTable     *hash_table);
+void        g_hash_table_foreach (GHashTable     *hash_table,
+                                 GHFunc          func,
+                                 gpointer        user_data);
+
+
+/* Caches
+ */
+GCache*  g_cache_new           (GCacheNewFunc      value_new_func,
+                               GCacheDestroyFunc  value_destroy_func,
+                               GCacheDupFunc      key_dup_func,
+                               GCacheDestroyFunc  key_destroy_func,
+                               GHashFunc          hash_key_func,
+                               GHashFunc          hash_value_func,
+                               GCompareFunc       key_compare_func);
+void     g_cache_destroy       (GCache            *cache);
+gpointer g_cache_insert        (GCache            *cache,
+                               gpointer           key);
+void     g_cache_remove        (GCache            *cache,
+                               gpointer           value);
+void     g_cache_key_foreach   (GCache            *cache,
+                               GHFunc             func,
+                               gpointer           user_data);
+void     g_cache_value_foreach (GCache            *cache,
+                               GHFunc             func,
+                               gpointer           user_data);
+
+
+/* Trees
+ */
+GTree*   g_tree_new      (GCompareFunc   key_compare_func);
+void     g_tree_destroy  (GTree         *tree);
+void     g_tree_insert   (GTree         *tree,
+                         gpointer       key,
+                         gpointer       value);
+void     g_tree_remove   (GTree         *tree,
+                         gpointer       key);
+gpointer g_tree_lookup   (GTree         *tree,
+                         gpointer       key);
+void     g_tree_traverse (GTree         *tree,
+                         GTraverseFunc  traverse_func,
+                         GTraverseType  traverse_type,
+                         gpointer       data);
+gpointer g_tree_search   (GTree         *tree,
+                         GSearchFunc    search_func,
+                         gpointer       data);
+gint     g_tree_height   (GTree         *tree);
+gint     g_tree_nnodes   (GTree         *tree);
+
+
+/* Memory
+ */
+
+#ifdef USE_DMALLOC
+
+#define g_malloc(size)       (gpointer) MALLOC(size)
+#define g_malloc0(size)      (gpointer) CALLOC(char,size)
+#define g_realloc(mem,size)  (gpointer) REALLOC(mem,char,size)
+#define g_free(mem)          FREE(mem)
+
+#else /* USE_DMALLOC */
+
+gpointer g_malloc      (gulong    size);
+gpointer g_malloc0     (gulong    size);
+gpointer g_realloc     (gpointer  mem,
+                       gulong    size);
+void     g_free        (gpointer  mem);
+
+#endif /* USE_DMALLOC */
+
+void     g_mem_profile (void);
+void     g_mem_check   (gpointer  mem);
+
+
+/* "g_mem_chunk_new" creates a new memory chunk.
+ * Memory chunks are used to allocate pieces of memory which are
+ *  always the same size. Lists are a good example of such a data type.
+ * The memory chunk allocates and frees blocks of memory as needed.
+ *  Just be sure to call "g_mem_chunk_free" and not "g_free" on data
+ *  allocated in a mem chunk. ("g_free" will most likely cause a seg
+ *  fault...somewhere).
+ *
+ * Oh yeah, GMemChunk is an opaque data type. (You don't really
+ *  want to know what's going on inside do you?)
+ */
+
+/* ALLOC_ONLY MemChunk's can only allocate memory. The free operation
+ *  is interpreted as a no op. ALLOC_ONLY MemChunk's save 4 bytes per
+ *  atom. (They are also useful for lists which use MemChunk to allocate
+ *  memory but are also part of the MemChunk implementation).
+ * ALLOC_AND_FREE MemChunk's can allocate and free memory.
+ */
+
+#define G_ALLOC_ONLY      1
+#define G_ALLOC_AND_FREE  2
+
+GMemChunk* g_mem_chunk_new     (gchar     *name,
+                               gint       atom_size,
+                               gulong     area_size,
+                               gint       type);
+void       g_mem_chunk_destroy (GMemChunk *mem_chunk);
+gpointer   g_mem_chunk_alloc   (GMemChunk *mem_chunk);
+void       g_mem_chunk_free    (GMemChunk *mem_chunk,
+                               gpointer   mem);
+void       g_mem_chunk_clean   (GMemChunk *mem_chunk);
+void       g_mem_chunk_reset   (GMemChunk *mem_chunk);
+void       g_mem_chunk_print   (GMemChunk *mem_chunk);
+void       g_mem_chunk_info    (void);
+
+/* Ah yes...we have a "g_blow_chunks" function.
+ * "g_blow_chunks" simply compresses all the chunks. This operation
+ *  consists of freeing every memory area that should be freed (but
+ *  which we haven't gotten around to doing yet). And, no,
+ *  "g_blow_chunks" doesn't follow the naming scheme, but it is a
+ *  much better name than "g_mem_chunk_clean_all" or something
+ *  similar.
+ */
+void g_blow_chunks (void);
+
+
+/* Timer
+ */
+GTimer* g_timer_new     (void);
+void    g_timer_destroy (GTimer  *timer);
+void    g_timer_start   (GTimer  *timer);
+void    g_timer_stop    (GTimer  *timer);
+void    g_timer_reset   (GTimer  *timer);
+gdouble g_timer_elapsed (GTimer  *timer,
+                        gulong  *microseconds);
+
+
+/* Output
+ */
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
+void g_error   (gchar *format, ...) __attribute__ ((format (printf, 1, 2)));
+void g_warning (gchar *format, ...) __attribute__ ((format (printf, 1, 2)));
+void g_message (gchar *format, ...) __attribute__ ((format (printf, 1, 2)));
+void g_print   (gchar *format, ...) __attribute__ ((format (printf, 1, 2)));
+#else
+void g_error   (gchar *format, ...);
+void g_warning (gchar *format, ...);
+void g_message (gchar *format, ...);
+void g_print   (gchar *format, ...);
+#endif
+
+/* Utility functions
+ */
+gchar* g_strdup    (const gchar *str);
+gchar* g_strerror  (gint errnum);
+gchar* g_strsignal (gint signum);
+
+
+/* Errors
+ */
+GErrorFunc   g_set_error_handler   (GErrorFunc   func);
+GWarningFunc g_set_warning_handler (GWarningFunc func);
+GPrintFunc   g_set_message_handler (GPrintFunc func);
+GPrintFunc   g_set_print_handler   (GPrintFunc func);
+
+void g_debug          (char *progname);
+void g_attach_process (char *progname, int query);
+void g_stack_trace    (char *progname, int query);
+
+
+/* String Chunks
+ */
+GStringChunk* g_string_chunk_new           (gint size);
+void          g_string_chunk_free          (GStringChunk *chunk);
+gchar*        g_string_chunk_insert        (GStringChunk *chunk,
+                                           gchar*        string);
+gchar*        g_string_chunk_insert_const  (GStringChunk *chunk,
+                                           gchar*        string);
+
+/* Strings
+ */
+GString* g_string_new       (gchar   *init);
+void     g_string_free      (GString *string,
+                            gint     free_segment);
+GString* g_string_assign    (GString *lval,
+                            gchar   *rval);
+GString* g_string_truncate  (GString *string,
+                            gint     len);
+GString* g_string_append    (GString *string,
+                            gchar   *val);
+GString* g_string_append_c  (GString *string,
+                            gchar    c);
+GString* g_string_prepend   (GString *string,
+                            gchar   *val);
+GString* g_string_prepend_c (GString *string,
+                            gchar    c);
+void     g_string_sprintf   (GString *string,
+                            gchar   *fmt,
+                            ...);
+void     g_string_sprintfa  (GString *string,
+                            gchar   *fmt,
+                            ...);
+
+/* Resizable arrays
+ */
+#define g_array_append_val(array,type,val) \
+     g_rarray_append (array, (gpointer) &val, sizeof (type))
+#define g_array_append_vals(array,type,vals,nvals) \
+     g_rarray_append (array, (gpointer) vals, sizeof (type) * nvals)
+#define g_array_prepend_val(array,type,val) \
+     g_rarray_prepend (array, (gpointer) &val, sizeof (type))
+#define g_array_prepend_vals(array,type,vals,nvals) \
+     g_rarray_prepend (array, (gpointer) vals, sizeof (type) * nvals)
+#define g_array_truncate(array,type,length) \
+     g_rarray_truncate (array, length, sizeof (type))
+#define g_array_index(array,type,index) \
+     ((type*) array->data)[index]
+
+GArray* g_array_new       (gint      zero_terminated);
+void    g_array_free      (GArray   *array,
+                          gint      free_segment);
+GArray* g_rarray_append   (GArray   *array,
+                          gpointer  data,
+                          gint      size);
+GArray* g_rarray_prepend  (GArray   *array,
+                          gpointer  data,
+                          gint      size);
+GArray* g_rarray_truncate (GArray   *array,
+                          gint      length,
+                          gint      size);
+
+
+/* Hash Functions
+ */
+gint  g_string_equal (gpointer v,
+                     gpointer v2);
+guint g_string_hash  (gpointer v);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __G_LIB_H__ */
diff --git a/glib/glibconfig.h.in b/glib/glibconfig.h.in
new file mode 100644 (file)
index 0000000..7a76559
--- /dev/null
@@ -0,0 +1,67 @@
+/* glibconfig.h.in.  Generated automatically from configure.in by autoheader.  */
+
+/* Define to empty if the keyword does not work.  */
+#undef const
+
+/* Define if you don't have vprintf but do have _doprnt.  */
+#undef HAVE_DOPRNT
+
+/* Define if the `long double' type works.  */
+#undef HAVE_LONG_DOUBLE
+
+/* Define if you have the vprintf function.  */
+#undef HAVE_VPRINTF
+
+/* Define as __inline if that's what the C compiler calls it.  */
+#undef inline
+
+/* Define if you have the ANSI C header files.  */
+#undef STDC_HEADERS
+
+/* Other stuff */
+#undef HAVE_DOPRNT
+#undef HAVE_FLOAT_H
+#undef HAVE_LIMITS_H
+#undef HAVE_LONG_DOUBLE
+#undef HAVE_SYS_SELECT_H
+#undef HAVE_STRERROR
+#undef HAVE_STRSIGNAL
+#undef HAVE_VALUES_H
+#undef HAVE_VPRINTF
+
+#undef NO_FD_SET
+#undef NO_SYS_ERRLIST
+#undef NO_SYS_SIGLIST
+
+/* #undef PACKAGE */
+/* #undef VERSION */
+
+/* The number of bytes in a char.  */
+#undef SIZEOF_CHAR
+
+/* The number of bytes in a int.  */
+#undef SIZEOF_INT
+
+/* The number of bytes in a long.  */
+#undef SIZEOF_LONG
+
+/* The number of bytes in a short.  */
+#undef SIZEOF_SHORT
+
+/* The number of bytes in a void *.  */
+#undef SIZEOF_VOID_P
+
+/* Define if you have the strerror function.  */
+#undef HAVE_STRERROR
+
+/* Define if you have the strsignal function.  */
+#undef HAVE_STRSIGNAL
+
+/* Define if you have the <float.h> header file.  */
+#undef HAVE_FLOAT_H
+
+/* Define if you have the <limits.h> header file.  */
+#undef HAVE_LIMITS_H
+
+/* Define if you have the <values.h> header file.  */
+#undef HAVE_VALUES_H
diff --git a/glib/glist.c b/glib/glist.c
new file mode 100644 (file)
index 0000000..f5a31d7
--- /dev/null
@@ -0,0 +1,349 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "glib.h"
+
+
+typedef struct _GRealListAllocator GRealListAllocator;
+
+struct _GRealListAllocator
+{
+  GMemChunk *list_mem_chunk;
+  GList     *free_list;
+};
+
+
+static GRealListAllocator *default_allocator = NULL;
+static GRealListAllocator *current_allocator = NULL;
+
+
+GListAllocator*
+g_list_allocator_new ()
+{
+  GRealListAllocator* allocator = g_new (GRealListAllocator, 1);
+
+  allocator->list_mem_chunk = NULL;
+  allocator->free_list = NULL;
+
+  return (GListAllocator*) allocator;
+}
+
+void
+g_list_allocator_free (GListAllocator* fallocator)
+{
+  GRealListAllocator* allocator = (GRealListAllocator *) fallocator;
+
+  if (allocator && allocator->list_mem_chunk)
+    g_mem_chunk_destroy (allocator->list_mem_chunk);
+  if (allocator)
+    g_free (allocator);
+}
+
+GListAllocator*
+g_list_set_allocator (GListAllocator* fallocator)
+{
+  GRealListAllocator* allocator = (GRealListAllocator *) fallocator;
+  GRealListAllocator* old_allocator = current_allocator;
+
+  if (allocator)
+    current_allocator = allocator;
+  else
+    {
+      if (!default_allocator)
+       default_allocator = (GRealListAllocator*) g_list_allocator_new ();
+      current_allocator = default_allocator;
+    }
+
+  if (!current_allocator->list_mem_chunk)
+    current_allocator->list_mem_chunk = g_mem_chunk_new ("list mem chunk",
+                                                        sizeof (GList),
+                                                        1024,
+                                                        G_ALLOC_ONLY);
+
+  return (GListAllocator*) (old_allocator == default_allocator ? NULL : old_allocator);
+}
+
+
+GList*
+g_list_alloc ()
+{
+  GList *new_list;
+
+  g_list_set_allocator (NULL);
+  if (current_allocator->free_list)
+    {
+      new_list = current_allocator->free_list;
+      current_allocator->free_list = current_allocator->free_list->next;
+    }
+  else
+    {
+      new_list = g_chunk_new (GList, current_allocator->list_mem_chunk);
+    }
+
+  new_list->data = NULL;
+  new_list->next = NULL;
+  new_list->prev = NULL;
+
+  return new_list;
+}
+
+void
+g_list_free (GList *list)
+{
+  GList *last;
+
+  if (list)
+    {
+      last = g_list_last (list);
+      last->next = current_allocator->free_list;
+      current_allocator->free_list = list;
+    }
+}
+
+void
+g_list_free_1 (GList *list)
+{
+  if (list)
+    {
+      list->next = current_allocator->free_list;
+      current_allocator->free_list = list;
+    }
+}
+
+GList*
+g_list_append (GList    *list,
+              gpointer  data)
+{
+  GList *new_list;
+  GList *last;
+
+  new_list = g_list_alloc ();
+  new_list->data = data;
+
+  if (!list)
+    {
+      list = new_list;
+    }
+  else
+    {
+      last = g_list_last (list);
+      g_assert (last != NULL);
+      last->next = new_list;
+      new_list->prev = last;
+    }
+
+  return list;
+}
+
+GList*
+g_list_prepend (GList    *list,
+               gpointer  data)
+{
+  GList *new_list;
+
+  new_list = g_list_alloc ();
+  new_list->data = data;
+
+  if (list)
+    {
+      if (list->prev)
+       list->prev->next = new_list;
+      new_list->prev = list->prev;
+      list->prev = new_list;
+    }
+  new_list->next = list;
+
+  return new_list;
+}
+
+GList*
+g_list_insert (GList    *list,
+              gpointer  data,
+              gint      position)
+{
+  GList *new_list;
+  GList *tmp_list;
+
+  if (position < 0)
+    return g_list_append (list, data);
+  else if (position == 0)
+    return g_list_prepend (list, data);
+
+  tmp_list = g_list_nth (list, position);
+  if (!tmp_list)
+    return g_list_append (list, data);
+
+  new_list = g_list_alloc ();
+  new_list->data = data;
+
+  if (tmp_list->prev)
+    tmp_list->prev->next = new_list;
+  new_list->next = tmp_list;
+  new_list->prev = tmp_list->prev;
+  tmp_list->prev = new_list;
+
+  if (tmp_list == list)
+    list = new_list;
+
+  return list;
+}
+
+GList*
+g_list_remove (GList    *list,
+              gpointer  data)
+{
+  GList *tmp;
+
+  tmp = list;
+  while (tmp)
+    {
+      if (tmp->data == data)
+       {
+         if (tmp->prev)
+           tmp->prev->next = tmp->next;
+         if (tmp->next)
+           tmp->next->prev = tmp->prev;
+
+         if (list == tmp)
+           list = list->next;
+
+         tmp->next = NULL;
+         tmp->prev = NULL;
+         g_list_free (tmp);
+
+         break;
+       }
+
+      tmp = tmp->next;
+    }
+  return list;
+}
+
+GList*
+g_list_remove_link (GList *list,
+                   GList *link)
+{
+  if (link)
+    {
+      if (link->prev)
+       link->prev->next = link->next;
+      if (link->next)
+       link->next->prev = link->prev;
+
+      if (link == list)
+       list = list->next;
+
+      link->next = NULL;
+      link->prev = NULL;
+    }
+
+  return list;
+}
+
+GList*
+g_list_reverse (GList *list)
+{
+  GList *tmp;
+  GList *last;
+
+  last = NULL;
+  while (list)
+    {
+      last = list;
+      tmp = list->next;
+      list->next = list->prev;
+      list->prev = tmp;
+      list = tmp;
+    }
+
+  return last;
+}
+
+GList*
+g_list_nth (GList *list,
+           gint   n)
+{
+  while ((n-- > 0) && list)
+    list = list->next;
+
+  return list;
+}
+
+GList*
+g_list_find (GList    *list,
+            gpointer  data)
+{
+  while (list)
+    {
+      if (list->data == data)
+       break;
+      list = list->next;
+    }
+
+  return list;
+}
+
+GList*
+g_list_last (GList *list)
+{
+  if (list)
+    {
+      while (list->next)
+       list = list->next;
+    }
+
+  return list;
+}
+
+GList*
+g_list_first (GList *list)
+{
+  if (list)
+    {
+      while (list->prev)
+        list = list->prev;
+    }
+
+  return list;
+}
+
+gint
+g_list_length (GList *list)
+{
+  gint length;
+
+  length = 0;
+  while (list)
+    {
+      length++;
+      list = list->next;
+    }
+
+  return length;
+}
+
+void
+g_list_foreach (GList    *list,
+                GFunc     func,
+               gpointer  user_data)
+{
+  while (list)
+    {
+      (*func) (list->data, user_data);
+      list = list->next;
+    }
+}
diff --git a/glib/gmem.c b/glib/gmem.c
new file mode 100644 (file)
index 0000000..35dfdab
--- /dev/null
@@ -0,0 +1,824 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdlib.h>
+#include <string.h>
+#include "glib.h"
+
+
+/* #define MEM_PROFILE */
+/* #define MEM_CHECK */
+
+
+#define MAX_MEM_AREA  65536L
+#define MEM_AREA_SIZE 4L
+
+#if SIZEOF_VOID_P > SIZEOF_LONG
+#define MEM_ALIGN     SIZEOF_VOID_P
+#else
+#define MEM_ALIGN     SIZEOF_LONG
+#endif
+
+
+typedef struct _GFreeAtom      GFreeAtom;
+typedef struct _GMemArea       GMemArea;
+typedef struct _GRealMemChunk  GRealMemChunk;
+
+struct _GFreeAtom
+{
+  GFreeAtom *next;
+};
+
+struct _GMemArea
+{
+  GMemArea *next;            /* the next mem area */
+  GMemArea *prev;            /* the previous mem area */
+  gulong index;              /* the current index into the "mem" array */
+  gulong free;               /* the number of free bytes in this mem area */
+  gulong allocated;          /* the number of atoms allocated from this area */
+  gulong mark;               /* is this mem area marked for deletion */
+  gchar mem[MEM_AREA_SIZE];  /* the mem array from which atoms get allocated
+                             * the actual size of this array is determined by
+                             *  the mem chunk "area_size". ANSI says that it
+                             *  must be declared to be the maximum size it
+                             *  can possibly be (even though the actual size
+                             *  may be less).
+                             */
+};
+
+struct _GRealMemChunk
+{
+  gchar *name;               /* name of this MemChunk...used for debugging output */
+  gint type;                 /* the type of MemChunk: ALLOC_ONLY or ALLOC_AND_FREE */
+  gint num_mem_areas;        /* the number of memory areas */
+  gint num_marked_areas;     /* the number of areas marked for deletion */
+  guint atom_size;           /* the size of an atom */
+  gulong area_size;          /* the size of a memory area */
+  GMemArea *mem_area;        /* the current memory area */
+  GMemArea *mem_areas;       /* a list of all the mem areas owned by this chunk */
+  GMemArea *free_mem_area;   /* the free area...which is about to be destroyed */
+  GFreeAtom *free_atoms;     /* the free atoms list */
+  GTree *mem_tree;           /* tree of mem areas sorted by memory address */
+  GRealMemChunk *next;       /* pointer to the next chunk */
+  GRealMemChunk *prev;       /* pointer to the previous chunk */
+};
+
+
+static gulong g_mem_chunk_compute_size (gulong    size);
+static gint   g_mem_chunk_area_compare (GMemArea *a,
+                                       GMemArea *b);
+static gint   g_mem_chunk_area_search  (GMemArea *a,
+                                       gchar    *addr);
+
+
+static GRealMemChunk *mem_chunks = NULL;
+
+#ifdef MEM_PROFILE
+static gulong allocations[4096] = { 0 };
+static gulong allocated_mem = 0;
+static gulong freed_mem = 0;
+#endif /* MEM_PROFILE */
+
+
+#ifndef USE_DMALLOC
+
+gpointer
+g_malloc (gulong size)
+{
+  gpointer p;
+
+
+#if defined(MEM_PROFILE) || defined(MEM_CHECK)
+  gulong *t;
+#endif /* MEM_PROFILE || MEM_CHECK */
+
+
+  if (size == 0)
+    return NULL;
+
+
+#if defined(MEM_PROFILE) || defined(MEM_CHECK)
+  size += SIZEOF_LONG;
+#endif /* MEM_PROFILE || MEM_CHECK */
+
+#ifdef MEM_CHECK
+  size += SIZEOF_LONG;
+#endif /* MEM_CHECK */
+
+
+  p = (gpointer) malloc (size);
+  if (!p)
+    g_error ("could not allocate %ld bytes", size);
+
+
+#ifdef MEM_CHECK
+  size -= SIZEOF_LONG;
+
+  t = p;
+  p = ((guchar*) p + SIZEOF_LONG);
+  *t = 0;
+#endif /* MEM_CHECK */
+
+#if defined(MEM_PROFILE) || defined(MEM_CHECK)
+  size -= SIZEOF_LONG;
+
+  t = p;
+  p = ((guchar*) p + SIZEOF_LONG);
+  *t = size;
+
+#ifdef MEM_PROFILE
+  if (size <= 4095)
+    allocations[size-1] += 1;
+  else
+    allocations[4095] += 1;
+  allocated_mem += size;
+#endif /* MEM_PROFILE */
+#endif /* MEM_PROFILE || MEM_CHECK */
+
+
+  return p;
+}
+
+gpointer
+g_malloc0 (gulong size)
+{
+  gpointer p;
+
+
+#if defined(MEM_PROFILE) || defined(MEM_CHECK)
+  gulong *t;
+#endif /* MEM_PROFILE || MEM_CHECK */
+
+
+  if (size == 0)
+    return NULL;
+
+
+#ifdef MEM_PROFILE
+  size += SIZEOF_LONG;
+#endif /* MEM_PROFILE */
+
+#ifdef MEM_CHECK
+  size += SIZEOF_LONG;
+#endif /* MEM_CHECK */
+
+
+  p = (gpointer) calloc (size, 1);
+  if (!p)
+    g_error ("could not allocate %ld bytes", size);
+
+
+#ifdef MEM_CHECK
+  size -= SIZEOF_LONG;
+
+  t = p;
+  p = ((guchar*) p + SIZEOF_LONG);
+  *t = 0;
+#endif /* MEM_CHECK */
+
+#if defined(MEM_PROFILE) || defined(MEM_CHECK)
+  size -= SIZEOF_LONG;
+
+  t = p;
+  p = ((guchar*) p + SIZEOF_LONG);
+  *t = size;
+
+#ifdef MEM_PROFILE
+  if (size <= 4095)
+    allocations[size-1] += 1;
+  else
+    allocations[4095] += 1;
+  allocated_mem += size;
+#endif /* MEM_PROFILE */
+#endif /* MEM_PROFILE */
+
+
+  return p;
+}
+
+gpointer
+g_realloc (gpointer mem,
+          gulong   size)
+{
+  gpointer p;
+
+#if defined(MEM_PROFILE) || defined(MEM_CHECK)
+  gulong *t;
+#endif /* MEM_PROFILE || MEM_CHECK */
+
+
+  if (size == 0)
+    return NULL;
+
+
+#if defined(MEM_PROFILE) || defined(MEM_CHECK)
+  size += SIZEOF_LONG;
+#endif /* MEM_PROFILE || MEM_CHECK */
+
+#ifdef MEM_CHECK
+  size += SIZEOF_LONG;
+#endif /* MEM_CHECK */
+
+
+  if (!mem)
+    p = (gpointer) malloc (size);
+  else
+    {
+#if defined(MEM_PROFILE) || defined(MEM_CHECK)
+      t = (gulong*) ((guchar*) mem - SIZEOF_LONG);
+#ifdef MEM_PROFILE
+      freed_mem += *t;
+#endif /* MEM_PROFILE */
+      mem = t;
+#endif /* MEM_PROFILE || MEM_CHECK */
+
+#ifdef MEM_CHECK
+      t = (gulong*) ((guchar*) mem - SIZEOF_LONG);
+      if (*t >= 1)
+       g_warning ("trying to realloc freed memory\n");
+      mem = t;
+#endif /* MEM_CHECK */
+
+      p = (gpointer) realloc (mem, size);
+    }
+
+  if (!p)
+    g_error ("could not reallocate %ld bytes", size);
+
+
+#ifdef MEM_CHECK
+  size -= SIZEOF_LONG;
+
+  t = p;
+  p = ((guchar*) p + SIZEOF_LONG);
+  *t = 0;
+#endif /* MEM_CHECK */
+
+#if defined(MEM_PROFILE) || defined(MEM_CHECK)
+  size -= SIZEOF_LONG;
+
+  t = p;
+  p = ((guchar*) p + SIZEOF_LONG);
+  *t = size;
+
+#ifdef MEM_PROFILE
+  if (size <= 4095)
+    allocations[size-1] += 1;
+  else
+    allocations[4095] += 1;
+  allocated_mem += size;
+#endif /* MEM_PROFILE */
+#endif /* MEM_PROFILE || MEM_CHECK */
+
+
+  return p;
+}
+
+void
+g_free (gpointer mem)
+{
+  if (mem)
+    {
+#if defined(MEM_PROFILE) || defined(MEM_CHECK)
+      gulong *t;
+      gulong size;
+#endif /* MEM_PROFILE || MEM_CHECK */
+
+#if defined(MEM_PROFILE) || defined(MEM_CHECK)
+      t = (gulong*) ((guchar*) mem - SIZEOF_LONG);
+      size = *t;
+#ifdef MEM_PROFILE
+      freed_mem += size;
+#endif /* MEM_PROFILE */
+      mem = t;
+#endif /* MEM_PROFILE || MEM_CHECK */
+
+#ifdef MEM_CHECK
+      t = (gulong*) ((guchar*) mem - SIZEOF_LONG);
+      if (*t >= 1)
+       g_warning ("freeing previously freed memory\n");
+      *t += 1;
+      mem = t;
+
+      memset ((guchar*) mem + 8, 0, size);
+#else /* MEM_CHECK */
+      free (mem);
+#endif /* MEM_CHECK */
+    }
+}
+
+#endif /* ! USE_DMALLOC */
+
+
+void
+g_mem_profile ()
+{
+#ifdef MEM_PROFILE
+  gint i;
+
+  for (i = 0; i < 4095; i++)
+    if (allocations[i] > 0)
+      g_print ("%lu allocations of %d bytes\n", allocations[i], i + 1);
+
+  if (allocations[4095] > 0)
+    g_print ("%lu allocations of greater than 4095 bytes\n", allocations[4095]);
+  g_print ("%lu bytes allocated\n", allocated_mem);
+  g_print ("%lu bytes freed\n", freed_mem);
+  g_print ("%lu bytes in use\n", allocated_mem - freed_mem);
+#endif /* MEM_PROFILE */
+}
+
+void
+g_mem_check (gpointer mem)
+{
+#ifdef MEM_CHECK
+  gulong *t;
+
+  t = (gulong*) ((guchar*) mem - SIZEOF_LONG - SIZEOF_LONG);
+
+  if (*t >= 1)
+    g_warning ("mem: 0x%08x has been freed: %lu\n", (gulong) mem, *t);
+#endif /* MEM_CHECK */
+}
+
+GMemChunk*
+g_mem_chunk_new (gchar  *name,
+                gint    atom_size,
+                gulong  area_size,
+                gint    type)
+{
+  GRealMemChunk *mem_chunk;
+  gulong rarea_size;
+
+  mem_chunk = g_new (struct _GRealMemChunk, 1);
+  mem_chunk->name = name;
+  mem_chunk->type = type;
+  mem_chunk->num_mem_areas = 0;
+  mem_chunk->num_marked_areas = 0;
+  mem_chunk->mem_area = NULL;
+  mem_chunk->free_mem_area = NULL;
+  mem_chunk->free_atoms = NULL;
+  mem_chunk->mem_tree = NULL;
+  mem_chunk->mem_areas = NULL;
+  mem_chunk->atom_size = atom_size;
+
+  if (mem_chunk->type == G_ALLOC_AND_FREE)
+    mem_chunk->mem_tree = g_tree_new ((GCompareFunc) g_mem_chunk_area_compare);
+
+  if (mem_chunk->atom_size % MEM_ALIGN)
+    mem_chunk->atom_size += MEM_ALIGN - (mem_chunk->atom_size % MEM_ALIGN);
+
+  mem_chunk->area_size = area_size;
+  if (mem_chunk->area_size > MAX_MEM_AREA)
+    mem_chunk->area_size = MAX_MEM_AREA;
+  while (mem_chunk->area_size < mem_chunk->atom_size)
+    mem_chunk->area_size *= 2;
+
+  rarea_size = mem_chunk->area_size + sizeof (GMemArea) - MEM_AREA_SIZE;
+  rarea_size = g_mem_chunk_compute_size (rarea_size);
+  mem_chunk->area_size = rarea_size - (sizeof (GMemArea) - MEM_AREA_SIZE);
+
+  /*
+  mem_chunk->area_size -= (sizeof (GMemArea) - MEM_AREA_SIZE);
+  if (mem_chunk->area_size < mem_chunk->atom_size)
+    {
+      mem_chunk->area_size = (mem_chunk->area_size + sizeof (GMemArea) - MEM_AREA_SIZE) * 2;
+      mem_chunk->area_size -= (sizeof (GMemArea) - MEM_AREA_SIZE);
+    }
+
+  if (mem_chunk->area_size % mem_chunk->atom_size)
+    mem_chunk->area_size += mem_chunk->atom_size - (mem_chunk->area_size % mem_chunk->atom_size);
+    */
+
+  mem_chunk->next = mem_chunks;
+  mem_chunk->prev = NULL;
+  if (mem_chunks)
+    mem_chunks->prev = mem_chunk;
+  mem_chunks = mem_chunk;
+
+  return ((GMemChunk*) mem_chunk);
+}
+
+void
+g_mem_chunk_destroy (GMemChunk *mem_chunk)
+{
+  GRealMemChunk *rmem_chunk;
+  GMemArea *mem_areas;
+  GMemArea *temp_area;
+
+  g_assert (mem_chunk != NULL);
+
+  rmem_chunk = (GRealMemChunk*) mem_chunk;
+
+  mem_areas = rmem_chunk->mem_areas;
+  while (mem_areas)
+    {
+      temp_area = mem_areas;
+      mem_areas = mem_areas->next;
+      g_free (temp_area);
+    }
+
+  if (rmem_chunk->next)
+    rmem_chunk->next->prev = rmem_chunk->prev;
+  if (rmem_chunk->prev)
+    rmem_chunk->prev->next = rmem_chunk->next;
+
+  if (rmem_chunk == mem_chunks)
+    mem_chunks = mem_chunks->next;
+
+  if (rmem_chunk->type == G_ALLOC_AND_FREE)
+    g_tree_destroy (rmem_chunk->mem_tree);
+
+  g_free (rmem_chunk);
+}
+
+gpointer
+g_mem_chunk_alloc (GMemChunk *mem_chunk)
+{
+  GRealMemChunk *rmem_chunk;
+  GMemArea *temp_area;
+  gpointer mem;
+
+  g_assert (mem_chunk != NULL);
+
+  rmem_chunk = (GRealMemChunk*) mem_chunk;
+
+  while (rmem_chunk->free_atoms)
+    {
+      /* Get the first piece of memory on the "free_atoms" list.
+       * We can go ahead and destroy the list node we used to keep
+       *  track of it with and to update the "free_atoms" list to
+       *  point to its next element.
+       */
+      mem = rmem_chunk->free_atoms;
+      rmem_chunk->free_atoms = rmem_chunk->free_atoms->next;
+
+      /* Determine which area this piece of memory is allocated from */
+      temp_area = g_tree_search (rmem_chunk->mem_tree,
+                                (GSearchFunc) g_mem_chunk_area_search,
+                                mem);
+
+      /* If the area has been marked, then it is being destroyed.
+       *  (ie marked to be destroyed).
+       * We check to see if all of the segments on the free list that
+       *  reference this area have been removed. This occurs when
+       *  the ammount of free memory is less than the allocatable size.
+       * If the chunk should be freed, then we place it in the "free_mem_area".
+       * This is so we make sure not to free the mem area here and then
+       *  allocate it again a few lines down.
+       * If we don't allocate a chunk a few lines down then the "free_mem_area"
+       *  will be freed.
+       * If there is already a "free_mem_area" then we'll just free this mem area.
+       */
+      if (temp_area->mark)
+        {
+          /* Update the "free" memory available in that area */
+          temp_area->free += rmem_chunk->atom_size;
+
+          if (temp_area->free == rmem_chunk->area_size)
+            {
+              if (temp_area == rmem_chunk->mem_area)
+                rmem_chunk->mem_area = NULL;
+
+              if (rmem_chunk->free_mem_area)
+                {
+                  rmem_chunk->num_mem_areas -= 1;
+                  rmem_chunk->num_marked_areas -= 1;
+
+                  if (temp_area->next)
+                    temp_area->next->prev = temp_area->prev;
+                  if (temp_area->prev)
+                    temp_area->prev->next = temp_area->next;
+                  if (temp_area == rmem_chunk->mem_areas)
+                    rmem_chunk->mem_areas = rmem_chunk->mem_areas->next;
+                  if (temp_area == rmem_chunk->mem_area)
+                    rmem_chunk->mem_area = NULL;
+
+                  g_free (temp_area);
+                }
+              else
+                rmem_chunk->free_mem_area = temp_area;
+           }
+       }
+      else
+        {
+          /* Update the number of allocated atoms count.
+          */
+          temp_area->allocated += 1;
+
+          /* The area wasn't marked...return the memory
+          */
+         goto outa_here;
+        }
+    }
+
+  /* If there isn't a current mem area or the current mem area is out of space
+   *  then allocate a new mem area. We'll first check and see if we can use
+   *  the "free_mem_area". Otherwise we'll just malloc the mem area.
+   */
+  if ((!rmem_chunk->mem_area) ||
+      ((rmem_chunk->mem_area->index + rmem_chunk->atom_size) > rmem_chunk->area_size))
+    {
+      if (rmem_chunk->free_mem_area)
+        {
+          rmem_chunk->mem_area = rmem_chunk->free_mem_area;
+         rmem_chunk->free_mem_area = NULL;
+        }
+      else
+        {
+         rmem_chunk->mem_area = (GMemArea*) g_malloc (sizeof (GMemArea) -
+                                                      MEM_AREA_SIZE +
+                                                      rmem_chunk->area_size);
+
+         rmem_chunk->num_mem_areas += 1;
+         rmem_chunk->mem_area->next = rmem_chunk->mem_areas;
+         rmem_chunk->mem_area->prev = NULL;
+
+         if (rmem_chunk->mem_areas)
+           rmem_chunk->mem_areas->prev = rmem_chunk->mem_area;
+         rmem_chunk->mem_areas = rmem_chunk->mem_area;
+
+         if (rmem_chunk->type == G_ALLOC_AND_FREE)
+           g_tree_insert (rmem_chunk->mem_tree, rmem_chunk->mem_area, rmem_chunk->mem_area);
+        }
+
+      rmem_chunk->mem_area->index = 0;
+      rmem_chunk->mem_area->free = rmem_chunk->area_size;
+      rmem_chunk->mem_area->allocated = 0;
+      rmem_chunk->mem_area->mark = 0;
+    }
+  else if (rmem_chunk->free_mem_area)
+    {
+      rmem_chunk->num_mem_areas -= 1;
+
+      if (rmem_chunk->free_mem_area->next)
+       rmem_chunk->free_mem_area->next->prev = rmem_chunk->free_mem_area->prev;
+      if (rmem_chunk->free_mem_area->prev)
+       rmem_chunk->free_mem_area->prev->next = rmem_chunk->free_mem_area->next;
+      if (rmem_chunk->free_mem_area == rmem_chunk->mem_areas)
+       rmem_chunk->mem_areas = rmem_chunk->mem_areas->next;
+
+      if (rmem_chunk->type == G_ALLOC_AND_FREE)
+       g_tree_remove (rmem_chunk->mem_tree, rmem_chunk->free_mem_area);
+
+      g_free (rmem_chunk->free_mem_area);
+      rmem_chunk->free_mem_area = NULL;
+    }
+
+  /* Get the memory and modify the state variables appropriately.
+   */
+  mem = (gpointer) &rmem_chunk->mem_area->mem[rmem_chunk->mem_area->index];
+  rmem_chunk->mem_area->index += rmem_chunk->atom_size;
+  rmem_chunk->mem_area->free -= rmem_chunk->atom_size;
+  rmem_chunk->mem_area->allocated += 1;
+
+outa_here:
+  return mem;
+}
+
+void
+g_mem_chunk_free (GMemChunk *mem_chunk,
+                 gpointer   mem)
+{
+  GRealMemChunk *rmem_chunk;
+  GMemArea *temp_area;
+  GFreeAtom *free_atom;
+
+  g_assert (mem_chunk != NULL);
+  g_assert (mem != NULL);
+
+  rmem_chunk = (GRealMemChunk*) mem_chunk;
+
+  /* Don't do anything if this is an ALLOC_ONLY chunk
+   */
+  if (rmem_chunk->type == G_ALLOC_AND_FREE)
+    {
+      /* Place the memory on the "free_atoms" list
+       */
+      free_atom = (GFreeAtom*) mem;
+      free_atom->next = rmem_chunk->free_atoms;
+      rmem_chunk->free_atoms = free_atom;
+
+      temp_area = g_tree_search (rmem_chunk->mem_tree,
+                                (GSearchFunc) g_mem_chunk_area_search,
+                                mem);
+
+      temp_area->allocated -= 1;
+
+      if (temp_area->allocated == 0)
+       {
+         temp_area->mark = 1;
+         rmem_chunk->num_marked_areas += 1;
+
+         g_mem_chunk_clean (mem_chunk);
+       }
+    }
+}
+
+void
+g_mem_chunk_clean (GMemChunk *mem_chunk)
+{
+  GRealMemChunk *rmem_chunk;
+  GMemArea *mem_area;
+  GFreeAtom *prev_free_atom;
+  GFreeAtom *temp_free_atom;
+  gpointer mem;
+
+  g_assert (mem_chunk != NULL);
+
+  rmem_chunk = (GRealMemChunk*) mem_chunk;
+
+  if (rmem_chunk->type == G_ALLOC_AND_FREE)
+    {
+      prev_free_atom = NULL;
+      temp_free_atom = rmem_chunk->free_atoms;
+
+      while (temp_free_atom)
+       {
+         mem = (gpointer) temp_free_atom;
+
+         mem_area = g_tree_search (rmem_chunk->mem_tree,
+                                   (GSearchFunc) g_mem_chunk_area_search,
+                                   mem);
+
+          /* If this mem area is marked for destruction then delete the
+          *  area and list node and decrement the free mem.
+           */
+         if (mem_area->mark)
+           {
+             if (prev_free_atom)
+               prev_free_atom->next = temp_free_atom->next;
+             else
+               rmem_chunk->free_atoms = temp_free_atom->next;
+             temp_free_atom = temp_free_atom->next;
+
+             mem_area->free += rmem_chunk->atom_size;
+             if (mem_area->free == rmem_chunk->area_size)
+               {
+                 rmem_chunk->num_mem_areas -= 1;
+                 rmem_chunk->num_marked_areas -= 1;
+
+                 if (mem_area->next)
+                   mem_area->next->prev = mem_area->prev;
+                 if (mem_area->prev)
+                   mem_area->prev->next = mem_area->next;
+                 if (mem_area == rmem_chunk->mem_areas)
+                   rmem_chunk->mem_areas = rmem_chunk->mem_areas->next;
+                 if (mem_area == rmem_chunk->mem_area)
+                   rmem_chunk->mem_area = NULL;
+
+                 if (rmem_chunk->type == G_ALLOC_AND_FREE)
+                   g_tree_remove (rmem_chunk->mem_tree, mem_area);
+                 g_free (mem_area);
+               }
+           }
+         else
+           {
+             prev_free_atom = temp_free_atom;
+             temp_free_atom = temp_free_atom->next;
+           }
+       }
+    }
+}
+
+void
+g_mem_chunk_reset (GMemChunk *mem_chunk)
+{
+  GRealMemChunk *rmem_chunk;
+  GMemArea *mem_areas;
+  GMemArea *temp_area;
+
+  g_assert (mem_chunk != NULL);
+
+  rmem_chunk = (GRealMemChunk*) mem_chunk;
+
+  mem_areas = rmem_chunk->mem_areas;
+  rmem_chunk->num_mem_areas = 0;
+  rmem_chunk->mem_areas = NULL;
+  rmem_chunk->mem_area = NULL;
+
+  while (mem_areas)
+    {
+      temp_area = mem_areas;
+      mem_areas = mem_areas->next;
+      g_free (temp_area);
+    }
+
+  rmem_chunk->free_atoms = NULL;
+
+  if (rmem_chunk->mem_tree)
+    g_tree_destroy (rmem_chunk->mem_tree);
+  rmem_chunk->mem_tree = g_tree_new ((GCompareFunc) g_mem_chunk_area_compare);
+}
+
+void
+g_mem_chunk_print (GMemChunk *mem_chunk)
+{
+  GRealMemChunk *rmem_chunk;
+  GMemArea *mem_areas;
+  gulong mem;
+
+  g_assert (mem_chunk != NULL);
+
+  rmem_chunk = (GRealMemChunk*) mem_chunk;
+  mem_areas = rmem_chunk->mem_areas;
+  mem = 0;
+
+  while (mem_areas)
+    {
+      mem += rmem_chunk->area_size - mem_areas->free;
+      mem_areas = mem_areas->next;
+    }
+
+  g_print ("%s: %ld bytes using %d mem areas", rmem_chunk->name, mem, rmem_chunk->num_mem_areas);
+}
+
+void
+g_mem_chunk_info ()
+{
+  GRealMemChunk *mem_chunk;
+  gint count;
+
+  count = 0;
+  mem_chunk = mem_chunks;
+  while (mem_chunk)
+    {
+      count += 1;
+      mem_chunk = mem_chunk->next;
+    }
+
+  g_print ("%d mem chunks", count);
+
+  mem_chunk = mem_chunks;
+  while (mem_chunk)
+    {
+      g_mem_chunk_print ((GMemChunk*) mem_chunk);
+      mem_chunk = mem_chunk->next;
+    }
+}
+
+void
+g_blow_chunks ()
+{
+  GRealMemChunk *mem_chunk;
+
+  mem_chunk = mem_chunks;
+  while (mem_chunk)
+    {
+      g_mem_chunk_clean ((GMemChunk*) mem_chunk);
+      mem_chunk = mem_chunk->next;
+    }
+}
+
+
+static gulong
+g_mem_chunk_compute_size (gulong size)
+{
+  gulong power_of_2;
+  gulong lower, upper;
+
+  power_of_2 = 16;
+  while (power_of_2 < size)
+    power_of_2 <<= 1;
+
+  lower = power_of_2 >> 1;
+  upper = power_of_2;
+
+  if ((size - lower) < (upper - size))
+    return lower;
+  return upper;
+}
+
+static gint
+g_mem_chunk_area_compare (GMemArea *a,
+                         GMemArea *b)
+{
+  return (a->mem - b->mem);
+}
+
+static gint
+g_mem_chunk_area_search (GMemArea *a,
+                        gchar    *addr)
+{
+  if (a->mem <= addr)
+    {
+      if (addr < &a->mem[a->index])
+       return 0;
+      return 1;
+    }
+  return -1;
+}
diff --git a/glib/gprimes.c b/glib/gprimes.c
new file mode 100644 (file)
index 0000000..8887c0e
--- /dev/null
@@ -0,0 +1,61 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "glib.h"
+
+
+gint g_primes[] =
+{
+  11,
+  15,
+  23,
+  35,
+  49,
+  73,
+  109,
+  163,
+  251,
+  367,
+  557,
+  823,
+  1237,
+  1861,
+  2777,
+  4177,
+  6247,
+  9371,
+  14057,
+  21089,
+  31627,
+  47431,
+  71143,
+  106721,
+  160073,
+  240101,
+  360163,
+  540217,
+  810343,
+  1215497,
+  1823231,
+  2734867,
+  4102283,
+  6153409,
+  9230113,
+  13845163,
+};
+
+gint g_nprimes = sizeof (g_primes) / sizeof (g_primes[0]);
diff --git a/glib/gslist.c b/glib/gslist.c
new file mode 100644 (file)
index 0000000..e091985
--- /dev/null
@@ -0,0 +1,324 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "glib.h"
+
+
+typedef struct _GRealListAllocator GRealListAllocator;
+
+struct _GRealListAllocator
+{
+  GMemChunk *list_mem_chunk;
+  GSList    *free_list;
+};
+
+
+static GRealListAllocator *default_allocator = NULL;
+static GRealListAllocator *current_allocator = NULL;
+
+GListAllocator*
+g_slist_set_allocator (GListAllocator* fallocator)
+{
+  GRealListAllocator* allocator = (GRealListAllocator *) fallocator;
+  GRealListAllocator* old_allocator = current_allocator;
+
+  if (allocator)
+    current_allocator = allocator;
+  else
+    {
+      if (!default_allocator)
+       default_allocator = (GRealListAllocator*) g_list_allocator_new ();
+      current_allocator = default_allocator;
+    }
+
+  if (!current_allocator->list_mem_chunk)
+    current_allocator->list_mem_chunk = g_mem_chunk_new ("slist mem chunk",
+                                                        sizeof (GSList),
+                                                        1024,
+                                                        G_ALLOC_ONLY);
+
+  return (GListAllocator*) (old_allocator == default_allocator ? NULL : old_allocator);
+}
+
+
+GSList*
+g_slist_alloc ()
+{
+  GSList *new_list;
+
+  g_slist_set_allocator (NULL);
+  if (current_allocator->free_list)
+    {
+      new_list = current_allocator->free_list;
+      current_allocator->free_list = current_allocator->free_list->next;
+    }
+  else
+    {
+      new_list = g_chunk_new (GSList, current_allocator->list_mem_chunk);
+    }
+
+  new_list->data = NULL;
+  new_list->next = NULL;
+
+  return new_list;
+}
+
+void
+g_slist_free (GSList *list)
+{
+  GSList *last;
+
+  if (list)
+    {
+      last = g_slist_last (list);
+      last->next = current_allocator->free_list;
+      current_allocator->free_list = list;
+    }
+}
+
+void
+g_slist_free_1 (GSList *list)
+{
+  if (list)
+    {
+      list->next = current_allocator->free_list;
+      current_allocator->free_list = list;
+    }
+}
+
+GSList*
+g_slist_append (GSList   *list,
+               gpointer  data)
+{
+  GSList *new_list;
+  GSList *last;
+
+  new_list = g_slist_alloc ();
+  new_list->data = data;
+
+  if (!list)
+    {
+      list = new_list;
+    }
+  else
+    {
+      last = g_slist_last (list);
+      g_assert (last != NULL);
+      last->next = new_list;
+    }
+
+  return list;
+}
+
+GSList*
+g_slist_prepend (GSList   *list,
+                gpointer  data)
+{
+  GSList *new_list;
+
+  new_list = g_slist_alloc ();
+  new_list->data = data;
+  new_list->next = list;
+
+  return new_list;
+}
+
+GSList*
+g_slist_insert (GSList   *list,
+               gpointer  data,
+               gint      position)
+{
+  GSList *prev_list;
+  GSList *tmp_list;
+  GSList *new_list;
+
+  prev_list = NULL;
+  tmp_list = list;
+
+  while (tmp_list && (position-- > 0))
+    {
+      prev_list = tmp_list;
+      tmp_list = tmp_list->next;
+    }
+
+  if (!tmp_list && !prev_list)
+    return list;
+
+  new_list = g_slist_alloc ();
+
+  if (!prev_list)
+    {
+      new_list->next = list;
+      list = new_list;
+    }
+  else
+    {
+      new_list->next = prev_list->next;
+      prev_list->next = new_list;
+    }
+
+  return list;
+}
+
+GSList*
+g_slist_remove (GSList   *list,
+               gpointer  data)
+{
+  GSList *tmp;
+  GSList *prev;
+
+  prev = NULL;
+  tmp = list;
+
+  while (tmp)
+    {
+      if (tmp->data == data)
+       {
+         if (prev)
+           prev->next = tmp->next;
+         if (list == tmp)
+           list = list->next;
+
+         tmp->next = NULL;
+         g_slist_free (tmp);
+
+         break;
+       }
+
+      prev = tmp;
+      tmp = tmp->next;
+    }
+
+  return list;
+}
+
+GSList*
+g_slist_remove_link (GSList *list,
+                    GSList *link)
+{
+  GSList *tmp;
+  GSList *prev;
+
+  prev = NULL;
+  tmp = list;
+
+  while (tmp)
+    {
+      if (tmp == link)
+       {
+         if (prev)
+           prev->next = tmp->next;
+         if (list == tmp)
+           list = list->next;
+
+         tmp->next = NULL;
+         break;
+       }
+
+      prev = tmp;
+      tmp = tmp->next;
+    }
+
+  return list;
+}
+
+GSList*
+g_slist_reverse (GSList *list)
+{
+  GSList *tmp;
+  GSList *prev;
+  GSList *last;
+
+  last = NULL;
+  prev = NULL;
+
+  while (list)
+    {
+      last = list;
+
+      tmp = list->next;
+      list->next = prev;
+
+      prev = list;
+      list = tmp;
+    }
+
+  return last;
+}
+
+GSList*
+g_slist_nth (GSList *list,
+            gint    n)
+{
+  while ((n-- > 0) && list)
+    list = list->next;
+
+  return list;
+}
+
+GSList*
+g_slist_find (GSList   *list,
+             gpointer  data)
+{
+  while (list)
+    {
+      if (list->data == data)
+       break;
+      list = list->next;
+    }
+
+  return list;
+}
+
+GSList*
+g_slist_last (GSList *list)
+{
+  if (list)
+    {
+      while (list->next)
+       list = list->next;
+    }
+
+  return list;
+}
+
+gint
+g_slist_length (GSList *list)
+{
+  gint length;
+
+  length = 0;
+  while (list)
+    {
+      length++;
+      list = list->next;
+    }
+
+  return length;
+}
+
+void
+g_slist_foreach (GSList   *list,
+                GFunc     func,
+                gpointer  user_data)
+{
+  while (list)
+    {
+      (*func) (list->data, user_data);
+      list = list->next;
+    }
+}
diff --git a/glib/gstring.c b/glib/gstring.c
new file mode 100644 (file)
index 0000000..457d47e
--- /dev/null
@@ -0,0 +1,487 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <glib.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+
+typedef struct _GRealStringChunk GRealStringChunk;
+typedef struct _GRealString      GRealString;
+
+struct _GRealStringChunk
+{
+  GHashTable *const_table;
+  GSList     *storage_list;
+  gint        storage_next;
+  gint        this_size;
+  gint        default_size;
+};
+
+struct _GRealString
+{
+  gchar *str;
+  gint   len;
+  gint   alloc;
+};
+
+
+static GMemChunk *string_mem_chunk = NULL;
+
+/* Hash Functions.
+ */
+
+/* Pete, you may have these elsewhere. */
+gint
+g_string_equal(gpointer v, gpointer v2)
+{
+  return strcmp ((gchar*) v, (gchar*)v2) == 0;
+}
+
+/* a char* hash function from ASU */
+guint
+g_string_hash(gpointer v)
+{
+  char *s = (char*)v;
+  char *p;
+  guint h=0, g;
+
+  for(p = s; *p != '\0'; p += 1) {
+    h = ( h << 4 ) + *p;
+    if ( ( g = h & 0xf0000000 ) ) {
+      h = h ^ (g >> 24);
+      h = h ^ g;
+    }
+  }
+
+  return h /* % M */;
+}
+
+
+/* String Chunks.
+ */
+
+GStringChunk*
+g_string_chunk_new (gint default_size)
+{
+  GRealStringChunk *new_chunk = g_new (GRealStringChunk, 1);
+  gint size = 1;
+
+  while (size < default_size)
+    size <<= 1;
+
+  new_chunk->const_table       = NULL;
+  new_chunk->storage_list      = NULL;
+  new_chunk->storage_next      = size;
+  new_chunk->default_size      = size;
+  new_chunk->this_size         = size;
+
+  return (GStringChunk*) new_chunk;
+}
+
+void
+g_string_chunk_free (GStringChunk *fchunk)
+{
+  GRealStringChunk *chunk = (GRealStringChunk*) fchunk;
+  GSList *tmp_list;
+
+  if (chunk->storage_list)
+    {
+      GListAllocator *tmp_allocator = g_slist_set_allocator (NULL);
+
+      for (tmp_list = chunk->storage_list; tmp_list; tmp_list = tmp_list->next)
+       g_free (tmp_list->data);
+
+      g_slist_free (chunk->storage_list);
+
+      g_slist_set_allocator (tmp_allocator);
+    }
+
+  if (chunk->const_table)
+    g_hash_table_destroy (chunk->const_table);
+
+  g_free (chunk);
+}
+
+gchar*
+g_string_chunk_insert (GStringChunk *fchunk,
+                      gchar*        string)
+{
+  GRealStringChunk *chunk = (GRealStringChunk*) fchunk;
+  gint len = strlen (string);
+  char* pos;
+
+  if ((chunk->storage_next + len + 1) > chunk->this_size)
+    {
+      GListAllocator *tmp_allocator = g_slist_set_allocator (NULL);
+      gint new_size = chunk->default_size;
+
+      while (new_size < len+1)
+       new_size <<= 1;
+
+      chunk->storage_list = g_slist_prepend (chunk->storage_list,
+                                            g_new (char, new_size));
+
+      chunk->this_size = new_size;
+      chunk->storage_next = 0;
+
+      g_slist_set_allocator (tmp_allocator);
+    }
+
+  pos = ((char*)chunk->storage_list->data) + chunk->storage_next;
+
+  strcpy (pos, string);
+
+  chunk->storage_next += len + 1;
+
+  return pos;
+}
+
+gchar*
+g_string_chunk_insert_const (GStringChunk *fchunk,
+                            gchar*        string)
+{
+  GRealStringChunk *chunk = (GRealStringChunk*) fchunk;
+  char* lookup;
+
+  if (!chunk->const_table)
+    chunk->const_table = g_hash_table_new (g_string_hash, g_string_equal);
+
+  lookup = (char*) g_hash_table_lookup (chunk->const_table, string);
+
+  if (!lookup)
+    {
+      lookup = g_string_chunk_insert (fchunk, string);
+      g_hash_table_insert (chunk->const_table, lookup, lookup);
+    }
+
+  return lookup;
+}
+
+/* Strings.
+ */
+static gint
+nearest_pow (gint num)
+{
+  gint n = 1;
+
+  while (n < num)
+    n <<= 1;
+
+  return n;
+}
+
+static void
+g_string_maybe_expand (GRealString* string, gint len)
+{
+  if (string->len + len >= string->alloc)
+    {
+      string->alloc = nearest_pow (string->len + len + 1);
+      string->str = g_realloc (string->str, string->alloc);
+    }
+}
+
+GString*
+g_string_new (gchar *init)
+{
+  GRealString *string;
+
+  if (!string_mem_chunk)
+    string_mem_chunk = g_mem_chunk_new ("string mem chunk",
+                                       sizeof (GRealString),
+                                       1024, G_ALLOC_AND_FREE);
+
+  string = g_chunk_new (GRealString, string_mem_chunk);
+
+  string->alloc = 2;
+  string->len   = 0;
+  string->str   = g_new0(char, 2);
+
+  if (init)
+    g_string_append ((GString*)string, init);
+
+  return (GString*) string;
+}
+
+void
+g_string_free (GString *string, gint free_segment)
+{
+  if (free_segment)
+    g_free (string->str);
+
+  g_mem_chunk_free (string_mem_chunk, string);
+}
+
+GString*
+g_string_assign (GString *lval,
+                char *rval)
+{
+  g_string_truncate (lval, 0);
+  g_string_append (lval, rval);
+
+  return lval;
+}
+
+GString*
+g_string_truncate (GString* fstring, gint len)
+{
+  GRealString *string = (GRealString*)fstring;
+
+  string->len = len;
+
+  string->str[len] = 0;
+
+  return fstring;
+}
+
+GString*
+g_string_append (GString *fstring, gchar *val)
+{
+  GRealString *string = (GRealString*)fstring;
+  int len = strlen (val);
+
+  g_string_maybe_expand (string, len);
+
+  strcpy (string->str + string->len, val);
+
+  string->len += len;
+
+  return fstring;
+}
+
+GString*
+g_string_append_c (GString *fstring, char c)
+{
+  GRealString *string = (GRealString*)fstring;
+
+  g_string_maybe_expand (string, 1);
+
+  string->str[string->len++] = c;
+  string->str[string->len] = 0;
+
+  return fstring;
+}
+
+GString*
+g_string_prepend (GString *fstring, gchar *val)
+{
+  GRealString *string = (GRealString*)fstring;
+  gint len = strlen (val);
+
+  g_string_maybe_expand (string, len);
+
+  memmove (string->str, string->str + len, string->len);
+
+  strncpy (string->str, val, len);
+
+  string->len += len;
+
+  string->str[string->len] = 0;
+
+  return fstring;
+}
+
+GString*
+g_string_prepend_c (GString *fstring, char c)
+{
+  GRealString *string = (GRealString*)fstring;
+
+  g_string_maybe_expand (string, 1);
+
+  memmove (string->str, string->str + 1, string->len);
+
+  string->str[0] = c;
+
+  string->len += 1;
+
+  string->str[string->len] = 0;
+
+  return fstring;
+}
+
+static int
+get_length_upper_bound (gchar* fmt, va_list *args)
+{
+  int len = 0;
+  int short_int;
+  int long_int;
+  int done;
+
+  while (*fmt)
+    {
+      char c = *fmt++;
+
+      short_int = FALSE;
+      long_int = FALSE;
+
+      if (c == '%')
+       {
+         done = FALSE;
+         while (*fmt && !done)
+           {
+             switch (*fmt++)
+               {
+               case '*':
+                 len += va_arg(*args, int);
+                 break;
+               case '1':
+               case '2':
+               case '3':
+               case '4':
+               case '5':
+               case '6':
+               case '7':
+               case '8':
+               case '9':
+                 fmt -= 1;
+                 len += strtol (fmt, &fmt, 10);
+                 break;
+               case 'h':
+                 short_int = TRUE;
+                 break;
+               case 'l':
+                 long_int = TRUE;
+                 break;
+
+                 /* I ignore 'q' and 'L', they're not portable anyway. */
+
+               case 's':
+                 len += strlen (va_arg (*args, char *));
+                 done = TRUE;
+                 break;
+               case 'd':
+               case 'i':
+               case 'o':
+               case 'u':
+               case 'x':
+               case 'X':
+                 if (long_int)
+                   (void)va_arg (*args, long);
+                 else if (short_int)
+                   (void)va_arg (*args, int);
+                 else
+                   (void)va_arg (*args, int);
+                 len += 32;
+                 done = TRUE;
+                 break;
+               case 'D':
+               case 'O':
+               case 'U':
+                 (void)va_arg (*args, long);
+                 len += 32;
+                 done = TRUE;
+                 break;
+               case 'e':
+               case 'E':
+               case 'f':
+               case 'g':
+                 (void)va_arg (*args, double);
+                 len += 32;
+                 done = TRUE;
+                 break;
+               case 'c':
+                 (void)va_arg (*args, int);
+                 len += 1;
+                 done = TRUE;
+                 break;
+               case 'p':
+               case 'n':
+                 (void)va_arg (*args, void*);
+                 len += 32;
+                 done = TRUE;
+                 break;
+               case '%':
+                 len += 1;
+                 done = TRUE;
+                 break;
+               default:
+                 break;
+               }
+           }
+       }
+      else
+       len += 1;
+    }
+
+  return len;
+}
+
+char*
+g_vsprintf (gchar *fmt,
+          va_list *args,
+          va_list *args2)
+{
+  static gchar *buf = NULL;
+  static gint   alloc = 0;
+
+  gint len = get_length_upper_bound (fmt, args);
+
+  if (len >= alloc)
+    {
+      if (buf)
+       g_free (buf);
+
+      alloc = nearest_pow (MAX(len + 1, 1024));
+
+      buf = g_new (char, alloc);
+    }
+
+  vsprintf (buf, fmt, *args2);
+
+  return buf;
+}
+
+static void
+g_string_sprintfa_int (GString *string,
+                      gchar *fmt,
+                      va_list *args,
+                      va_list *args2)
+{
+  g_string_append (string, g_vsprintf (fmt, args, args2));
+}
+
+void
+g_string_sprintf (GString *string, gchar *fmt, ...)
+{
+  va_list args, args2;
+
+  va_start(args, fmt);
+  va_start(args2, fmt);
+
+  g_string_truncate (string, 0);
+
+  g_string_sprintfa_int (string, fmt, &args, &args2);
+
+  va_end(args);
+  va_end(args2);
+}
+
+void
+g_string_sprintfa (GString *string, gchar *fmt, ...)
+{
+  va_list args, args2;
+
+  va_start(args, fmt);
+  va_start(args2, fmt);
+
+  g_string_sprintfa_int (string, fmt, &args, &args2);
+
+  va_end(args);
+  va_end(args2);
+}
diff --git a/glib/gtimer.c b/glib/gtimer.c
new file mode 100644 (file)
index 0000000..c3b720d
--- /dev/null
@@ -0,0 +1,119 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <sys/time.h>
+#include <unistd.h>
+#include "glib.h"
+
+
+typedef struct _GRealTimer GRealTimer;
+
+struct _GRealTimer
+{
+  struct timeval start;
+  struct timeval end;
+  gint active;
+};
+
+
+GTimer*
+g_timer_new ()
+{
+  GRealTimer *timer;
+
+  timer = g_new (GRealTimer, 1);
+  timer->active = TRUE;
+
+  gettimeofday (&timer->start, NULL);
+
+  return ((GTimer*) timer);
+}
+
+void
+g_timer_destroy (GTimer *timer)
+{
+  g_assert (timer != NULL);
+
+  g_free (timer);
+}
+
+void
+g_timer_start (GTimer *timer)
+{
+  GRealTimer *rtimer;
+
+  g_assert (timer != NULL);
+
+  rtimer = (GRealTimer*) timer;
+  gettimeofday (&rtimer->start, NULL);
+  rtimer->active = 1;
+}
+
+void
+g_timer_stop (GTimer *timer)
+{
+  GRealTimer *rtimer;
+
+  g_assert (timer != NULL);
+
+  rtimer = (GRealTimer*) timer;
+  gettimeofday (&rtimer->end, NULL);
+  rtimer->active = 0;
+}
+
+void
+g_timer_reset (GTimer *timer)
+{
+  GRealTimer *rtimer;
+
+  g_assert (timer != NULL);
+
+  rtimer = (GRealTimer*) timer;
+  gettimeofday (&rtimer->start, NULL);
+}
+
+gdouble
+g_timer_elapsed (GTimer *timer,
+                gulong *microseconds)
+{
+  GRealTimer *rtimer;
+  struct timeval elapsed;
+  gdouble total;
+
+  g_assert (timer != NULL);
+
+  rtimer = (GRealTimer*) timer;
+
+  if (rtimer->active)
+    gettimeofday (&rtimer->end, NULL);
+
+  if (rtimer->start.tv_usec > rtimer->end.tv_usec)
+    {
+      rtimer->end.tv_usec += 1000000;
+      rtimer->end.tv_sec--;
+    }
+
+  elapsed.tv_usec = rtimer->end.tv_usec - rtimer->start.tv_usec;
+  elapsed.tv_sec = rtimer->end.tv_sec - rtimer->start.tv_sec;
+
+  total = elapsed.tv_sec + ((gdouble) elapsed.tv_usec / 1e6);
+
+  if (microseconds)
+    *microseconds = elapsed.tv_usec;
+
+  return total;
+}
diff --git a/glib/gtree.c b/glib/gtree.c
new file mode 100644 (file)
index 0000000..61a32a4
--- /dev/null
@@ -0,0 +1,718 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "glib.h"
+
+
+typedef struct _GRealTree  GRealTree;
+typedef struct _GTreeNode  GTreeNode;
+
+struct _GRealTree
+{
+  GTreeNode *root;
+  GCompareFunc key_compare;
+};
+
+struct _GTreeNode
+{
+  gint balance;      /* height (left) - height (right) */
+  GTreeNode *left;   /* left subtree */
+  GTreeNode *right;  /* right subtree */
+  gpointer key;      /* key for this node */
+  gpointer value;    /* value stored at this node */
+};
+
+
+static GTreeNode* g_tree_node_new                   (gpointer        key,
+                                                    gpointer        value);
+static void       g_tree_node_destroy               (GTreeNode      *node);
+static GTreeNode* g_tree_node_insert                (GTreeNode      *node,
+                                                    GCompareFunc    compare,
+                                                    gpointer        key,
+                                                    gpointer        value,
+                                                    gint           *inserted);
+static GTreeNode* g_tree_node_remove                (GTreeNode      *node,
+                                                    GCompareFunc    compare,
+                                                    gpointer        key);
+static GTreeNode* g_tree_node_balance               (GTreeNode      *node);
+static GTreeNode* g_tree_node_remove_leftmost       (GTreeNode      *node,
+                                                    GTreeNode     **leftmost);
+static GTreeNode* g_tree_node_restore_left_balance  (GTreeNode      *node,
+                                                    gint            old_balance);
+static GTreeNode* g_tree_node_restore_right_balance (GTreeNode      *node,
+                                                    gint            old_balance);
+static gpointer   g_tree_node_lookup                (GTreeNode      *node,
+                                                    GCompareFunc    compare,
+                                                    gpointer        key);
+static gint       g_tree_node_count                 (GTreeNode      *node);
+static gint       g_tree_node_pre_order             (GTreeNode      *node,
+                                                    GTraverseFunc   traverse_func,
+                                                    gpointer        data);
+static gint       g_tree_node_in_order              (GTreeNode      *node,
+                                                    GTraverseFunc   traverse_func,
+                                                    gpointer        data);
+static gint       g_tree_node_post_order            (GTreeNode      *node,
+                                                    GTraverseFunc   traverse_func,
+                                                    gpointer        data);
+static gpointer   g_tree_node_search                (GTreeNode      *node,
+                                                    GSearchFunc     search_func,
+                                                    gpointer        data);
+static gint       g_tree_node_height                (GTreeNode      *node);
+static GTreeNode* g_tree_node_rotate_left           (GTreeNode      *node);
+static GTreeNode* g_tree_node_rotate_right          (GTreeNode      *node);
+static void       g_tree_node_check                 (GTreeNode      *node);
+
+
+static GMemChunk *node_mem_chunk = NULL;
+static GSList *node_free_list = NULL;
+
+
+GTree*
+g_tree_new (GCompareFunc key_compare_func)
+{
+  GRealTree *rtree;
+
+  rtree = g_new (GRealTree, 1);
+  rtree->root = NULL;
+  rtree->key_compare = key_compare_func;
+
+  return (GTree*) rtree;
+}
+
+void
+g_tree_destroy (GTree *tree)
+{
+  GRealTree *rtree;
+
+  g_return_if_fail (tree != NULL);
+
+  rtree = (GRealTree*) tree;
+
+  g_tree_node_destroy (rtree->root);
+  g_free (rtree);
+}
+
+void
+g_tree_insert (GTree    *tree,
+              gpointer  key,
+              gpointer  value)
+{
+  GRealTree *rtree;
+  gint inserted;
+
+  g_return_if_fail (tree != NULL);
+
+  rtree = (GRealTree*) tree;
+
+  inserted = FALSE;
+  rtree->root = g_tree_node_insert (rtree->root, rtree->key_compare,
+                                   key, value, &inserted);
+}
+
+void
+g_tree_remove (GTree    *tree,
+              gpointer  key)
+{
+  GRealTree *rtree;
+
+  g_return_if_fail (tree != NULL);
+
+  rtree = (GRealTree*) tree;
+
+  rtree->root = g_tree_node_remove (rtree->root, rtree->key_compare, key);
+}
+
+gpointer
+g_tree_lookup (GTree    *tree,
+              gpointer  key)
+{
+  GRealTree *rtree;
+
+  g_return_val_if_fail (tree != NULL, NULL);
+
+  rtree = (GRealTree*) tree;
+
+  return g_tree_node_lookup (rtree->root, rtree->key_compare, key);
+}
+
+void
+g_tree_traverse (GTree         *tree,
+                GTraverseFunc  traverse_func,
+                GTraverseType  traverse_type,
+                gpointer       data)
+{
+  GRealTree *rtree;
+
+  g_return_if_fail (tree != NULL);
+
+  rtree = (GRealTree*) tree;
+
+  g_return_if_fail (rtree->root != NULL);
+
+  switch (traverse_type)
+    {
+    case G_PRE_ORDER:
+      g_tree_node_pre_order (rtree->root, traverse_func, data);
+      break;
+
+    case G_IN_ORDER:
+      g_tree_node_in_order (rtree->root, traverse_func, data);
+      break;
+
+    case G_POST_ORDER:
+      g_tree_node_post_order (rtree->root, traverse_func, data);
+      break;
+    }
+}
+
+gpointer
+g_tree_search (GTree       *tree,
+              GSearchFunc  search_func,
+              gpointer     data)
+{
+  GRealTree *rtree;
+
+  g_return_val_if_fail (tree != NULL, NULL);
+
+  rtree = (GRealTree*) tree;
+
+  if (rtree->root)
+    return g_tree_node_search (rtree->root, search_func, data);
+  return NULL;
+}
+
+gint
+g_tree_height (GTree *tree)
+{
+  GRealTree *rtree;
+
+  g_return_val_if_fail (tree != NULL, 0);
+
+  rtree = (GRealTree*) tree;
+
+  if (rtree->root)
+    return g_tree_node_height (rtree->root);
+  return 0;
+}
+
+gint
+g_tree_nnodes (GTree *tree)
+{
+  GRealTree *rtree;
+
+  g_return_val_if_fail (tree != NULL, 0);
+
+  rtree = (GRealTree*) tree;
+
+  if (rtree->root)
+    return g_tree_node_count (rtree->root);
+  return 0;
+}
+
+
+static GTreeNode*
+g_tree_node_new (gpointer key,
+                gpointer value)
+{
+  GTreeNode *node;
+  GSList *tmp_list;
+
+  if (node_free_list)
+    {
+      tmp_list = node_free_list;
+      node_free_list = node_free_list->next;
+
+      node = tmp_list->data;
+
+      {
+       GListAllocator *tmp_allocator = g_list_set_allocator (NULL);
+       g_slist_free_1 (tmp_list);
+       g_list_set_allocator (tmp_allocator);
+      }
+    }
+  else
+    {
+      if (!node_mem_chunk)
+       node_mem_chunk = g_mem_chunk_new ("tree node mem chunk", sizeof (GTreeNode), 1024, G_ALLOC_ONLY);
+
+      node = g_chunk_new (GTreeNode, node_mem_chunk);
+    }
+
+  node->balance = 0;
+  node->left = NULL;
+  node->right = NULL;
+  node->key = key;
+  node->value = value;
+
+  return node;
+}
+
+static void
+g_tree_node_destroy (GTreeNode *node)
+{
+  if (node)
+    {
+      node_free_list = g_slist_prepend (node_free_list, node);
+      g_tree_node_destroy (node->right);
+      g_tree_node_destroy (node->left);
+    }
+}
+
+static GTreeNode*
+g_tree_node_insert (GTreeNode    *node,
+                   GCompareFunc  compare,
+                   gpointer      key,
+                   gpointer      value,
+                   gint         *inserted)
+{
+  gint old_balance;
+  gint cmp;
+
+  if (!node)
+    {
+      *inserted = TRUE;
+      return g_tree_node_new (key, value);
+    }
+
+  cmp = (* compare) (key, node->key);
+  if (cmp == 0)
+    {
+      *inserted = FALSE;
+      node->value = value;
+      return node;
+    }
+
+  if (cmp < 0)
+    {
+      if (node->left)
+       {
+         old_balance = node->left->balance;
+         node->left = g_tree_node_insert (node->left, compare, key, value, inserted);
+
+         if ((old_balance != node->left->balance) && node->left->balance)
+           node->balance -= 1;
+       }
+      else
+       {
+         *inserted = TRUE;
+         node->left = g_tree_node_new (key, value);
+         node->balance -= 1;
+       }
+    }
+  else if (cmp > 0)
+    {
+      if (node->right)
+       {
+         old_balance = node->right->balance;
+         node->right = g_tree_node_insert (node->right, compare, key, value, inserted);
+
+         if ((old_balance != node->right->balance) && node->right->balance)
+           node->balance += 1;
+       }
+      else
+       {
+         *inserted = TRUE;
+         node->right = g_tree_node_new (key, value);
+         node->balance += 1;
+       }
+    }
+
+  if (*inserted)
+    {
+      if ((node->balance < -1) || (node->balance > 1))
+       node = g_tree_node_balance (node);
+    }
+
+  return node;
+}
+
+static GTreeNode*
+g_tree_node_remove (GTreeNode    *node,
+                   GCompareFunc  compare,
+                   gpointer      key)
+{
+  GTreeNode *garbage;
+  GTreeNode *new_root;
+  gint old_balance;
+  gint cmp;
+
+  if (!node)
+    return NULL;
+
+  cmp = (* compare) (key, node->key);
+  if (cmp == 0)
+    {
+      garbage = node;
+
+      if (!node->right)
+       {
+         node = node->left;
+       }
+      else
+       {
+         old_balance = node->right->balance;
+         node->right = g_tree_node_remove_leftmost (node->right, &new_root);
+         new_root->left = node->left;
+         new_root->right = node->right;
+         new_root->balance = node->balance;
+         node = g_tree_node_restore_right_balance (new_root, old_balance);
+       }
+
+      node_free_list = g_slist_prepend (node_free_list, garbage);
+    }
+  else if (cmp < 0)
+    {
+      if (node->left)
+       {
+         old_balance = node->left->balance;
+         node->left = g_tree_node_remove (node->left, compare, key);
+         node = g_tree_node_restore_left_balance (node, old_balance);
+       }
+    }
+  else if (cmp > 0)
+    {
+      if (node->right)
+       {
+         old_balance = node->right->balance;
+         node->right = g_tree_node_remove (node->right, compare, key);
+         node = g_tree_node_restore_right_balance (node, old_balance);
+       }
+    }
+
+  return node;
+}
+
+static GTreeNode*
+g_tree_node_balance (GTreeNode *node)
+{
+  if (node->balance < -1)
+    {
+      if (node->left->balance > 0)
+       node->left = g_tree_node_rotate_left (node->left);
+      node = g_tree_node_rotate_right (node);
+    }
+  else if (node->balance > 1)
+    {
+      if (node->right->balance < 0)
+       node->right = g_tree_node_rotate_right (node->right);
+      node = g_tree_node_rotate_left (node);
+    }
+
+  return node;
+}
+
+static GTreeNode*
+g_tree_node_remove_leftmost (GTreeNode  *node,
+                            GTreeNode **leftmost)
+{
+  gint old_balance;
+
+  if (!node->left)
+    {
+      *leftmost = node;
+      return node->right;
+    }
+
+  old_balance = node->left->balance;
+  node->left = g_tree_node_remove_leftmost (node->left, leftmost);
+  return g_tree_node_restore_left_balance (node, old_balance);
+}
+
+static GTreeNode*
+g_tree_node_restore_left_balance (GTreeNode *node,
+                                 gint       old_balance)
+{
+  if (!node->left)
+    node->balance += 1;
+  else if ((node->left->balance != old_balance) &&
+          (node->left->balance == 0))
+    node->balance += 1;
+
+  if (node->balance > 1)
+    return g_tree_node_balance (node);
+  return node;
+}
+
+static GTreeNode*
+g_tree_node_restore_right_balance (GTreeNode *node,
+                                  gint       old_balance)
+{
+  if (!node->right)
+    node->balance -= 1;
+  else if ((node->right->balance != old_balance) &&
+          (node->right->balance == 0))
+    node->balance -= 1;
+
+  if (node->balance < -1)
+    return g_tree_node_balance (node);
+  return node;
+}
+
+static gpointer
+g_tree_node_lookup (GTreeNode    *node,
+                   GCompareFunc  compare,
+                   gpointer      key)
+{
+  gint cmp;
+
+  if (!node)
+    return NULL;
+
+  cmp = (* compare) (key, node->key);
+  if (cmp == 0)
+    return node->value;
+
+  if (cmp < 0)
+    {
+      if (node->left)
+       return g_tree_node_lookup (node->left, compare, key);
+    }
+  else if (cmp > 0)
+    {
+      if (node->right)
+       return g_tree_node_lookup (node->right, compare, key);
+    }
+
+  return NULL;
+}
+
+static gint
+g_tree_node_count (GTreeNode *node)
+{
+  gint count;
+
+  count = 1;
+  if (node->left)
+    count += g_tree_node_count (node->left);
+  if (node->right)
+    count += g_tree_node_count (node->right);
+
+  return count;
+}
+
+static gint
+g_tree_node_pre_order (GTreeNode     *node,
+                      GTraverseFunc  traverse_func,
+                      gpointer       data)
+{
+  if ((*traverse_func) (node->key, node->value, data))
+    return TRUE;
+  if (node->left)
+    {
+      if (g_tree_node_pre_order (node->left, traverse_func, data))
+       return TRUE;
+    }
+  if (node->right)
+    {
+      if (g_tree_node_pre_order (node->right, traverse_func, data))
+       return TRUE;
+    }
+
+  return FALSE;
+}
+
+static gint
+g_tree_node_in_order (GTreeNode     *node,
+                     GTraverseFunc  traverse_func,
+                     gpointer       data)
+{
+  if (node->left)
+    {
+      if (g_tree_node_in_order (node->left, traverse_func, data))
+       return TRUE;
+    }
+  if ((*traverse_func) (node->key, node->value, data))
+    return TRUE;
+  if (node->right)
+    {
+      if (g_tree_node_in_order (node->right, traverse_func, data))
+       return TRUE;
+    }
+
+  return FALSE;
+}
+
+static gint
+g_tree_node_post_order (GTreeNode     *node,
+                       GTraverseFunc  traverse_func,
+                       gpointer       data)
+{
+  if (node->left)
+    {
+      if (g_tree_node_post_order (node->left, traverse_func, data))
+       return TRUE;
+    }
+  if (node->right)
+    {
+      if (g_tree_node_post_order (node->right, traverse_func, data))
+       return TRUE;
+    }
+  if ((*traverse_func) (node->key, node->value, data))
+    return TRUE;
+
+  return FALSE;
+}
+
+static gpointer
+g_tree_node_search (GTreeNode   *node,
+                   GSearchFunc  search_func,
+                   gpointer     data)
+{
+  gint dir;
+
+  if (!node)
+    return NULL;
+
+  do {
+    dir = (* search_func) (node->key, data);
+    if (dir == 0)
+      return node->value;
+
+    if (dir < 0)
+      node = node->left;
+    else if (dir > 0)
+      node = node->right;
+  } while (node && (dir != 0));
+
+  return NULL;
+}
+
+static gint
+g_tree_node_height (GTreeNode *node)
+{
+  gint left_height;
+  gint right_height;
+
+  if (node)
+    {
+      left_height = 0;
+      right_height = 0;
+
+      if (node->left)
+       left_height = g_tree_node_height (node->left);
+
+      if (node->right)
+       right_height = g_tree_node_height (node->right);
+
+      return MAX (left_height, right_height) + 1;
+    }
+
+  return 0;
+}
+
+static GTreeNode*
+g_tree_node_rotate_left (GTreeNode *node)
+{
+  GTreeNode *left;
+  GTreeNode *right;
+  gint a_bal;
+  gint b_bal;
+
+  left = node->left;
+  right = node->right;
+
+  node->right = right->left;
+  right->left = node;
+
+  a_bal = node->balance;
+  b_bal = right->balance;
+
+  if (b_bal <= 0)
+    {
+      if (a_bal >= 1)
+       right->balance = b_bal - 1;
+      else
+       right->balance = a_bal + b_bal - 2;
+      node->balance = a_bal - 1;
+    }
+  else
+    {
+      if (a_bal <= b_bal)
+       right->balance = a_bal - 2;
+      else
+       right->balance = b_bal - 1;
+      node->balance = a_bal - b_bal - 1;
+    }
+
+  return right;
+}
+
+static GTreeNode*
+g_tree_node_rotate_right (GTreeNode *node)
+{
+  GTreeNode *left;
+  GTreeNode *right;
+  gint a_bal;
+  gint b_bal;
+
+  left = node->left;
+  right = node->right;
+
+  node->left = left->right;
+  left->right = node;
+
+  a_bal = node->balance;
+  b_bal = left->balance;
+
+  if (b_bal <= 0)
+    {
+      if (b_bal > a_bal)
+       left->balance = b_bal + 1;
+      else
+       left->balance = a_bal + 2;
+      node->balance = a_bal - b_bal + 1;
+    }
+  else
+    {
+      if (a_bal <= -1)
+       left->balance = b_bal + 1;
+      else
+       left->balance = a_bal + b_bal + 2;
+      node->balance = a_bal + 1;
+    }
+
+  return left;
+}
+
+static void
+g_tree_node_check (GTreeNode *node)
+{
+  gint left_height;
+  gint right_height;
+  gint balance;
+
+  if (node)
+    {
+      left_height = 0;
+      right_height = 0;
+
+      if (node->left)
+       left_height = g_tree_node_height (node->left);
+      if (node->right)
+       right_height = g_tree_node_height (node->right);
+
+      balance = right_height - left_height;
+      if (balance != node->balance)
+       g_print ("g_tree_node_check: failed: %d ( %d )\n",
+                balance, node->balance);
+
+      if (node->left)
+       g_tree_node_check (node->left);
+      if (node->right)
+       g_tree_node_check (node->right);
+    }
+}
diff --git a/glib/gutils.c b/glib/gutils.c
new file mode 100644 (file)
index 0000000..c153328
--- /dev/null
@@ -0,0 +1,732 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include "glib.h"
+
+
+static GErrorFunc error_func = NULL;
+static GWarningFunc warning_func = NULL;
+static GPrintFunc message_func = NULL;
+static GPrintFunc print_func = NULL;
+
+extern char* g_vsprintf (gchar *fmt, va_list *args, va_list *args2);
+
+gchar*
+g_strdup (const gchar *str)
+{
+  gchar *new_str;
+
+  new_str = NULL;
+  if (str)
+    {
+      new_str = g_new (char, strlen (str) + 1);
+      strcpy (new_str, str);
+    }
+
+  return new_str;
+}
+
+gchar*
+g_strerror (gint errnum)
+{
+  static char msg[64];
+
+#ifdef HAVE_STRERROR
+  return strerror (errnum);
+#elif NO_SYS_ERRLIST
+  switch (errnum)
+    {
+#ifdef E2BIG
+    case E2BIG: return "argument list too long";
+#endif
+#ifdef EACCES
+    case EACCES: return "permission denied";
+#endif
+#ifdef EADDRINUSE
+    case EADDRINUSE: return "address already in use";
+#endif
+#ifdef EADDRNOTAVAIL
+    case EADDRNOTAVAIL: return "can't assign requested address";
+#endif
+#ifdef EADV
+    case EADV: return "advertise error";
+#endif
+#ifdef EAFNOSUPPORT
+    case EAFNOSUPPORT: return "address family not supported by protocol family";
+#endif
+#ifdef EAGAIN
+    case EAGAIN: return "no more processes";
+#endif
+#ifdef EALIGN
+    case EALIGN: return "EALIGN";
+#endif
+#ifdef EALREADY
+    case EALREADY: return "operation already in progress";
+#endif
+#ifdef EBADE
+    case EBADE: return "bad exchange descriptor";
+#endif
+#ifdef EBADF
+    case EBADF: return "bad file number";
+#endif
+#ifdef EBADFD
+    case EBADFD: return "file descriptor in bad state";
+#endif
+#ifdef EBADMSG
+    case EBADMSG: return "not a data message";
+#endif
+#ifdef EBADR
+    case EBADR: return "bad request descriptor";
+#endif
+#ifdef EBADRPC
+    case EBADRPC: return "RPC structure is bad";
+#endif
+#ifdef EBADRQC
+    case EBADRQC: return "bad request code";
+#endif
+#ifdef EBADSLT
+    case EBADSLT: return "invalid slot";
+#endif
+#ifdef EBFONT
+    case EBFONT: return "bad font file format";
+#endif
+#ifdef EBUSY
+    case EBUSY: return "mount device busy";
+#endif
+#ifdef ECHILD
+    case ECHILD: return "no children";
+#endif
+#ifdef ECHRNG
+    case ECHRNG: return "channel number out of range";
+#endif
+#ifdef ECOMM
+    case ECOMM: return "communication error on send";
+#endif
+#ifdef ECONNABORTED
+    case ECONNABORTED: return "software caused connection abort";
+#endif
+#ifdef ECONNREFUSED
+    case ECONNREFUSED: return "connection refused";
+#endif
+#ifdef ECONNRESET
+    case ECONNRESET: return "connection reset by peer";
+#endif
+#if defined(EDEADLK) && (!defined(EWOULDBLOCK) || (EDEADLK != EWOULDBLOCK))
+    case EDEADLK: return "resource deadlock avoided";
+#endif
+#ifdef EDEADLOCK
+    case EDEADLOCK: return "resource deadlock avoided";
+#endif
+#ifdef EDESTADDRREQ
+    case EDESTADDRREQ: return "destination address required";
+#endif
+#ifdef EDIRTY
+    case EDIRTY: return "mounting a dirty fs w/o force";
+#endif
+#ifdef EDOM
+    case EDOM: return "math argument out of range";
+#endif
+#ifdef EDOTDOT
+    case EDOTDOT: return "cross mount point";
+#endif
+#ifdef EDQUOT
+    case EDQUOT: return "disk quota exceeded";
+#endif
+#ifdef EDUPPKG
+    case EDUPPKG: return "duplicate package name";
+#endif
+#ifdef EEXIST
+    case EEXIST: return "file already exists";
+#endif
+#ifdef EFAULT
+    case EFAULT: return "bad address in system call argument";
+#endif
+#ifdef EFBIG
+    case EFBIG: return "file too large";
+#endif
+#ifdef EHOSTDOWN
+    case EHOSTDOWN: return "host is down";
+#endif
+#ifdef EHOSTUNREACH
+    case EHOSTUNREACH: return "host is unreachable";
+#endif
+#ifdef EIDRM
+    case EIDRM: return "identifier removed";
+#endif
+#ifdef EINIT
+    case EINIT: return "initialization error";
+#endif
+#ifdef EINPROGRESS
+    case EINPROGRESS: return "operation now in progress";
+#endif
+#ifdef EINTR
+    case EINTR: return "interrupted system call";
+#endif
+#ifdef EINVAL
+    case EINVAL: return "invalid argument";
+#endif
+#ifdef EIO
+    case EIO: return "I/O error";
+#endif
+#ifdef EISCONN
+    case EISCONN: return "socket is already connected";
+#endif
+#ifdef EISDIR
+    case EISDIR: return "illegal operation on a directory";
+#endif
+#ifdef EISNAME
+    case EISNAM: return "is a name file";
+#endif
+#ifdef ELBIN
+    case ELBIN: return "ELBIN";
+#endif
+#ifdef EL2HLT
+    case EL2HLT: return "level 2 halted";
+#endif
+#ifdef EL2NSYNC
+    case EL2NSYNC: return "level 2 not synchronized";
+#endif
+#ifdef EL3HLT
+    case EL3HLT: return "level 3 halted";
+#endif
+#ifdef EL3RST
+    case EL3RST: return "level 3 reset";
+#endif
+#ifdef ELIBACC
+    case ELIBACC: return "can not access a needed shared library";
+#endif
+#ifdef ELIBBAD
+    case ELIBBAD: return "accessing a corrupted shared library";
+#endif
+#ifdef ELIBEXEC
+    case ELIBEXEC: return "can not exec a shared library directly";
+#endif
+#ifdef ELIBMAX
+    case ELIBMAX: return "attempting to link in more shared libraries than system limit";
+#endif
+#ifdef ELIBSCN
+    case ELIBSCN: return ".lib section in a.out corrupted";
+#endif
+#ifdef ELNRNG
+    case ELNRNG: return "link number out of range";
+#endif
+#ifdef ELOOP
+    case ELOOP: return "too many levels of symbolic links";
+#endif
+#ifdef EMFILE
+    case EMFILE: return "too many open files";
+#endif
+#ifdef EMLINK
+    case EMLINK: return "too many links";
+#endif
+#ifdef EMSGSIZE
+    case EMSGSIZE: return "message too long";
+#endif
+#ifdef EMULTIHOP
+    case EMULTIHOP: return "multihop attempted";
+#endif
+#ifdef ENAMETOOLONG
+    case ENAMETOOLONG: return "file name too long";
+#endif
+#ifdef ENAVAIL
+    case ENAVAIL: return "not available";
+#endif
+#ifdef ENET
+    case ENET: return "ENET";
+#endif
+#ifdef ENETDOWN
+    case ENETDOWN: return "network is down";
+#endif
+#ifdef ENETRESET
+    case ENETRESET: return "network dropped connection on reset";
+#endif
+#ifdef ENETUNREACH
+    case ENETUNREACH: return "network is unreachable";
+#endif
+#ifdef ENFILE
+    case ENFILE: return "file table overflow";
+#endif
+#ifdef ENOANO
+    case ENOANO: return "anode table overflow";
+#endif
+#if defined(ENOBUFS) && (!defined(ENOSR) || (ENOBUFS != ENOSR))
+    case ENOBUFS: return "no buffer space available";
+#endif
+#ifdef ENOCSI
+    case ENOCSI: return "no CSI structure available";
+#endif
+#ifdef ENODATA
+    case ENODATA: return "no data available";
+#endif
+#ifdef ENODEV
+    case ENODEV: return "no such device";
+#endif
+#ifdef ENOENT
+    case ENOENT: return "no such file or directory";
+#endif
+#ifdef ENOEXEC
+    case ENOEXEC: return "exec format error";
+#endif
+#ifdef ENOLCK
+    case ENOLCK: return "no locks available";
+#endif
+#ifdef ENOLINK
+    case ENOLINK: return "link has be severed";
+#endif
+#ifdef ENOMEM
+    case ENOMEM: return "not enough memory";
+#endif
+#ifdef ENOMSG
+    case ENOMSG: return "no message of desired type";
+#endif
+#ifdef ENONET
+    case ENONET: return "machine is not on the network";
+#endif
+#ifdef ENOPKG
+    case ENOPKG: return "package not installed";
+#endif
+#ifdef ENOPROTOOPT
+    case ENOPROTOOPT: return "bad proocol option";
+#endif
+#ifdef ENOSPC
+    case ENOSPC: return "no space left on device";
+#endif
+#ifdef ENOSR
+    case ENOSR: return "out of stream resources";
+#endif
+#ifdef ENOSTR
+    case ENOSTR: return "not a stream device";
+#endif
+#ifdef ENOSYM
+    case ENOSYM: return "unresolved symbol name";
+#endif
+#ifdef ENOSYS
+    case ENOSYS: return "function not implemented";
+#endif
+#ifdef ENOTBLK
+    case ENOTBLK: return "block device required";
+#endif
+#ifdef ENOTCONN
+    case ENOTCONN: return "socket is not connected";
+#endif
+#ifdef ENOTDIR
+    case ENOTDIR: return "not a directory";
+#endif
+#ifdef ENOTEMPTY
+    case ENOTEMPTY: return "directory not empty";
+#endif
+#ifdef ENOTNAM
+    case ENOTNAM: return "not a name file";
+#endif
+#ifdef ENOTSOCK
+    case ENOTSOCK: return "socket operation on non-socket";
+#endif
+#ifdef ENOTTY
+    case ENOTTY: return "inappropriate device for ioctl";
+#endif
+#ifdef ENOTUNIQ
+    case ENOTUNIQ: return "name not unique on network";
+#endif
+#ifdef ENXIO
+    case ENXIO: return "no such device or address";
+#endif
+#ifdef EOPNOTSUPP
+    case EOPNOTSUPP: return "operation not supported on socket";
+#endif
+#ifdef EPERM
+    case EPERM: return "not owner";
+#endif
+#ifdef EPFNOSUPPORT
+    case EPFNOSUPPORT: return "protocol family not supported";
+#endif
+#ifdef EPIPE
+    case EPIPE: return "broken pipe";
+#endif
+#ifdef EPROCLIM
+    case EPROCLIM: return "too many processes";
+#endif
+#ifdef EPROCUNAVAIL
+    case EPROCUNAVAIL: return "bad procedure for program";
+#endif
+#ifdef EPROGMISMATCH
+    case EPROGMISMATCH: return "program version wrong";
+#endif
+#ifdef EPROGUNAVAIL
+    case EPROGUNAVAIL: return "RPC program not available";
+#endif
+#ifdef EPROTO
+    case EPROTO: return "protocol error";
+#endif
+#ifdef EPROTONOSUPPORT
+    case EPROTONOSUPPORT: return "protocol not suppored";
+#endif
+#ifdef EPROTOTYPE
+    case EPROTOTYPE: return "protocol wrong type for socket";
+#endif
+#ifdef ERANGE
+    case ERANGE: return "math result unrepresentable";
+#endif
+#if defined(EREFUSED) && (!defined(ECONNREFUSED) || (EREFUSED != ECONNREFUSED))
+    case EREFUSED: return "EREFUSED";
+#endif
+#ifdef EREMCHG
+    case EREMCHG: return "remote address changed";
+#endif
+#ifdef EREMDEV
+    case EREMDEV: return "remote device";
+#endif
+#ifdef EREMOTE
+    case EREMOTE: return "pathname hit remote file system";
+#endif
+#ifdef EREMOTEIO
+    case EREMOTEIO: return "remote i/o error";
+#endif
+#ifdef EREMOTERELEASE
+    case EREMOTERELEASE: return "EREMOTERELEASE";
+#endif
+#ifdef EROFS
+    case EROFS: return "read-only file system";
+#endif
+#ifdef ERPCMISMATCH
+    case ERPCMISMATCH: return "RPC version is wrong";
+#endif
+#ifdef ERREMOTE
+    case ERREMOTE: return "object is remote";
+#endif
+#ifdef ESHUTDOWN
+    case ESHUTDOWN: return "can't send afer socket shutdown";
+#endif
+#ifdef ESOCKTNOSUPPORT
+    case ESOCKTNOSUPPORT: return "socket type not supported";
+#endif
+#ifdef ESPIPE
+    case ESPIPE: return "invalid seek";
+#endif
+#ifdef ESRCH
+    case ESRCH: return "no such process";
+#endif
+#ifdef ESRMNT
+    case ESRMNT: return "srmount error";
+#endif
+#ifdef ESTALE
+    case ESTALE: return "stale remote file handle";
+#endif
+#ifdef ESUCCESS
+    case ESUCCESS: return "Error 0";
+#endif
+#ifdef ETIME
+    case ETIME: return "timer expired";
+#endif
+#ifdef ETIMEDOUT
+    case ETIMEDOUT: return "connection timed out";
+#endif
+#ifdef ETOOMANYREFS
+    case ETOOMANYREFS: return "too many references: can't splice";
+#endif
+#ifdef ETXTBSY
+    case ETXTBSY: return "text file or pseudo-device busy";
+#endif
+#ifdef EUCLEAN
+    case EUCLEAN: return "structure needs cleaning";
+#endif
+#ifdef EUNATCH
+    case EUNATCH: return "protocol driver not attached";
+#endif
+#ifdef EUSERS
+    case EUSERS: return "too many users";
+#endif
+#ifdef EVERSION
+    case EVERSION: return "version mismatch";
+#endif
+#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
+    case EWOULDBLOCK: return "operation would block";
+#endif
+#ifdef EXDEV
+    case EXDEV: return "cross-domain link";
+#endif
+#ifdef EXFULL
+    case EXFULL: return "message tables full";
+#endif
+    }
+#else /* NO_SYS_ERRLIST */
+  extern int sys_nerr;
+  extern char *sys_errlist[];
+
+  if ((errnum > 0) && (errnum <= sys_nerr))
+    return sys_errlist [errnum];
+#endif /* NO_SYS_ERRLIST */
+
+  sprintf (msg, "unknown error (%d)", errnum);
+  return msg;
+}
+
+gchar*
+g_strsignal (gint signum)
+{
+  static char msg[64];
+
+#ifdef HAVE_STRSIGNAL
+  extern char *strsignal (int sig);
+  return strsignal (signum);
+#elif NO_SYS_SIGLIST
+  switch (signum)
+    {
+#ifdef SIGHUP
+    case SIGHUP: return "Hangup";
+#endif
+#ifdef SIGINT
+    case SIGINT: return "Interrupt";
+#endif
+#ifdef SIGQUIT
+    case SIGQUIT: return "Quit";
+#endif
+#ifdef SIGILL
+    case SIGILL: "Illegal instruction";
+#endif
+#ifdef SIGTRAP
+    case SIGTRAP: "Trace/breakpoint trap";
+#endif
+#ifdef SIGABRT
+    case SIGABRT: "IOT trap/Abort";
+#endif
+#ifdef SIGBUS
+    case SIGBUS: "Bus error";
+#endif
+#ifdef SIGFPE
+    case SIGFPE: "Floating point exception";
+#endif
+#ifdef SIGKILL
+    case SIGKILL: "Killed";
+#endif
+#ifdef SIGUSR1
+    case SIGUSR1: "User defined signal 1";
+#endif
+#ifdef SIGSEGV
+    case SIGSEGV: "Segmentation fault";
+#endif
+#ifdef SIGUSR2
+    case SIGUSR2: "User defined signal 2";
+#endif
+#ifdef SIGPIPE
+    case SIGPIPE: "Broken pipe";
+#endif
+#ifdef SIGALRM
+    case SIGALRM: "Alarm clock";
+#endif
+#ifdef SIGTERM
+    case SIGTERM: "Terminated";
+#endif
+#ifdef SIGSTKFLT
+    case SIGSTKFLT: "Stack fault";
+#endif
+#ifdef SIGCHLD
+    case SIGCHLD: "Child exited";
+#endif
+#ifdef SIGCONT
+    case SIGCONT: "Continued";
+#endif
+#ifdef SIGSTOP
+    case SIGSTOP: "Stopped (signal)";
+#endif
+#ifdef SIGTSTP
+    case SIGTSTP: "Stopped";
+#endif
+#ifdef SIGTTIN
+    case SIGTTIN: "Stopped (tty input)";
+#endif
+#ifdef SIGTTOU
+    case SIGTTOU: "Stopped (tty output)";
+#endif
+#ifdef SIGURG
+    case SIGURG: "Urgent condition";
+#endif
+#ifdef SIGXCPU
+    case SIGXCPU: "CPU time limit exceeded";
+#endif
+#ifdef SIGXFSZ
+    case SIGXFSZ: "File size limit exceeded";
+#endif
+#ifdef SIGVTALRM
+    case SIGVTALRM: "Virtual time alarm";
+#endif
+#ifdef SIGPROF
+    case SIGPROF: "Profile signal";
+#endif
+#ifdef SIGWINCH
+    case SIGWINCH: "Window size changed";
+#endif
+#ifdef SIGIO
+    case SIGIO: "Possible I/O";
+#endif
+#ifdef SIGPWR
+    case SIGPWR: "Power failure";
+#endif
+#ifdef SIGUNUSED
+    case SIGUNUSED: return "Unused signal";
+#endif
+    }
+#else /* NO_SYS_SIGLIST */
+  extern char *sys_siglist[];
+  return sys_siglist [signum];
+#endif /* NO_SYS_SIGLIST */
+
+  sprintf (msg, "unknown signal (%d)", signum);
+  return msg;
+}
+
+void
+g_error (gchar *format, ...)
+{
+  va_list args, args2;
+  char *buf;
+
+  va_start (args, format);
+  va_start (args2, format);
+  buf = g_vsprintf (format, &args, &args2);
+  va_end (args);
+  va_end (args2);
+
+  if (error_func)
+    {
+      (* error_func) (buf);
+    }
+  else
+    {
+      fputs ("\n** ERROR **: ", stderr);
+      fputs (buf, stderr);
+      fputc ('\n', stderr);
+    }
+
+  abort ();
+}
+
+void
+g_warning (gchar *format, ...)
+{
+  va_list args, args2;
+  char *buf;
+
+  va_start (args, format);
+  va_start (args2, format);
+  buf = g_vsprintf (format, &args, &args2);
+  va_end (args);
+  va_end (args2);
+
+  if (warning_func)
+    {
+      (* warning_func) (buf);
+    }
+  else
+    {
+      fputs ("\n** WARNING **: ", stderr);
+      fputs (buf, stderr);
+      fputc ('\n', stderr);
+    }
+}
+
+void
+g_message (gchar *format, ...)
+{
+  va_list args, args2;
+  char *buf;
+
+  va_start (args, format);
+  va_start (args2, format);
+  buf = g_vsprintf (format, &args, &args2);
+  va_end (args);
+  va_end (args2);
+
+  if (message_func)
+    {
+      (* message_func) (buf);
+    }
+  else
+    {
+      fputs ("message: ", stdout);
+      fputs (buf, stdout);
+      fputc ('\n', stdout);
+    }
+}
+
+void
+g_print (gchar *format, ...)
+{
+  va_list args, args2;
+  char *buf;
+
+  va_start (args, format);
+  va_start (args2, format);
+  buf = g_vsprintf (format, &args, &args2);
+  va_end (args);
+  va_end (args2);
+
+  if (print_func)
+    {
+      (* print_func) (buf);
+    }
+  else
+    {
+      fputs (buf, stdout);
+    }
+}
+
+GErrorFunc
+g_set_error_handler (GErrorFunc func)
+{
+  GErrorFunc old_error_func;
+
+  old_error_func = error_func;
+  error_func = func;
+
+  return old_error_func;
+}
+
+GWarningFunc
+g_set_warning_handler (GWarningFunc func)
+{
+  GWarningFunc old_warning_func;
+
+  old_warning_func = warning_func;
+  warning_func = func;
+
+  return old_warning_func;
+}
+
+GPrintFunc
+g_set_message_handler (GPrintFunc func)
+{
+  GPrintFunc old_message_func;
+
+  old_message_func = message_func;
+  message_func = func;
+
+  return old_message_func;
+}
+
+GPrintFunc
+g_set_print_handler (GPrintFunc func)
+{
+  GPrintFunc old_print_func;
+
+  old_print_func = print_func;
+  print_func = func;
+
+  return old_print_func;
+}
diff --git a/glib/install-sh b/glib/install-sh
new file mode 100755 (executable)
index 0000000..89fc9b0
--- /dev/null
@@ -0,0 +1,238 @@
+#! /bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+tranformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+       -c) instcmd="$cpprog"
+           shift
+           continue;;
+
+       -d) dir_arg=true
+           shift
+           continue;;
+
+       -m) chmodcmd="$chmodprog $2"
+           shift
+           shift
+           continue;;
+
+       -o) chowncmd="$chownprog $2"
+           shift
+           shift
+           continue;;
+
+       -g) chgrpcmd="$chgrpprog $2"
+           shift
+           shift
+           continue;;
+
+       -s) stripcmd="$stripprog"
+           shift
+           continue;;
+
+       -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+           shift
+           continue;;
+
+       -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+           shift
+           continue;;
+
+       *)  if [ x"$src" = x ]
+           then
+               src=$1
+           else
+               # this colon is to work around a 386BSD /bin/sh bug
+               :
+               dst=$1
+           fi
+           shift
+           continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+       echo "install:  no input file specified"
+       exit 1
+else
+       true
+fi
+
+if [ x"$dir_arg" != x ]; then
+       dst=$src
+       src=""
+       
+       if [ -d $dst ]; then
+               instcmd=:
+       else
+               instcmd=mkdir
+       fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+       if [ -f $src -o -d $src ]
+       then
+               true
+       else
+               echo "install:  $src does not exist"
+               exit 1
+       fi
+       
+       if [ x"$dst" = x ]
+       then
+               echo "install:  no destination specified"
+               exit 1
+       else
+               true
+       fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+       if [ -d $dst ]
+       then
+               dst="$dst"/`basename $src`
+       else
+               true
+       fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='   
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+       pathcomp="${pathcomp}${1}"
+       shift
+
+       if [ ! -d "${pathcomp}" ] ;
+        then
+               $mkdirprog "${pathcomp}"
+       else
+               true
+       fi
+
+       pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+       $doit $instcmd $dst &&
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+       if [ x"$transformarg" = x ] 
+       then
+               dstfile=`basename $dst`
+       else
+               dstfile=`basename $dst $transformbasename | 
+                       sed $transformarg`$transformbasename
+       fi
+
+# don't allow the sed command to completely eliminate the filename
+
+       if [ x"$dstfile" = x ] 
+       then
+               dstfile=`basename $dst`
+       else
+               true
+       fi
+
+# Make a temp file name in the proper directory.
+
+       dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+       $doit $instcmd $src $dsttmp &&
+
+       trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+       $doit $rmcmd -f $dstdir/$dstfile &&
+       $doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
diff --git a/glib/ltconfig b/glib/ltconfig
new file mode 100755 (executable)
index 0000000..e9d3a83
--- /dev/null
@@ -0,0 +1,1415 @@
+#! /bin/sh
+
+# ltconfig - Create a system-specific libtool.
+# Generated automatically from ltconfig.in by configure.
+# Copyright (C) 1996, 1997, Free Software Foundation, Inc.
+# Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# A lot of this script is taken from autoconf-2.10.
+
+# The name of this program.
+progname=`echo "$0" | sed 's%^.*/%%'`
+
+# Constants:
+PROGRAM=ltconfig
+PACKAGE=libtool
+VERSION=1.0f
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.c 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.c $LIBS 1>&5'
+rm="rm -f"
+
+help="Try \`$progname --help' for more information."
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s/\([\\"$\\\\]\)/\\\1/g'
+
+# Same as above, but don't quote variable references.
+double_quote_subst='s/\([\\"\\\\]\)/\\\1/g'
+
+# Global variables:
+can_build_shared=yes
+enable_shared=yes
+# All known linkers require a `.a' archive for static linking.
+enable_static=yes
+ltmain=
+silent=
+srcdir=
+ac_config_guess=
+ac_config_sub=
+host=
+nonopt=
+verify_host=yes
+with_gcc=no
+with_gnu_ld=no
+
+old_AR="$AR"
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+old_CPPFLAGS="$CPPFLAGS"
+old_LD="$LD"
+old_LN_S="$LN_S"
+old_NM="$NM"
+old_RANLIB="$RANLIB"
+
+# Parse the command line options.
+args=
+prev=
+for option
+do
+  case "$option" in
+  -*=*) optarg=`echo "$option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$prev"; then
+    eval "$prev=\$option"
+    prev=
+    continue
+  fi
+
+  case "$option" in
+  --help) cat <<EOM
+Usage: $progname [OPTION]... LTMAIN [HOST]
+
+Generate a system-specific libtool script.
+
+    --disable-shared       do not build shared libraries
+    --disable-static       do not build static libraries
+    --help                 display this help and exit
+    --no-verify            do not verify that HOST is a valid host type
+    --quiet                same as \`--silent'
+    --silent               don't print informational messages
+    --srcdir=DIR           find \`config.guess' in DIR
+    --version              output version information and exit
+    --with-gcc             assume that the GNU C compiler will be used
+    --with-gnu-ld          assume that the C compiler uses the GNU linker
+
+LTMAIN is the \`ltmain.sh' shell script fragment that provides basic libtool
+functionality.
+
+HOST is the canonical host system name [default=guessed].
+EOM
+  exit 0
+  ;;
+
+  --disable-shared) enable_shared=no ;;
+
+  --disable-static) enable_static=no ;;
+
+  --quiet | --silent) silent=yes ;;
+
+  --srcdir) prev=srcdir ;;
+  --srcdir=*) srcdir="$optarg" ;;
+
+  --no-verify) verify_host=no ;;
+
+  --version) echo "$PROGRAM (GNU $PACKAGE) $VERSION"; exit 0 ;;
+
+  --with-gcc) with_gcc=yes ;;
+  --with-gnu-ld) with_gnu_ld=yes ;;
+
+  -*)
+    echo "$progname: unrecognized option \`$option'" 1>&2
+    echo "$help" 1>&2
+    exit 1
+    ;;
+
+  *)
+    if test -z "$ltmain"; then
+      ltmain="$option"
+    elif test -z "$host"; then
+# FIXME This generates an unnecessary warning for sparc-sun-solaris4.1.3_U1
+#      if test -n "`echo $option| sed 's/[-a-z0-9.]//g'`"; then
+#        echo "$progname: warning \`$option' is not a valid host type" 1>&2
+#      fi
+      host="$option"
+    else
+      echo "$progname: too many arguments" 1>&2
+      echo "$help" 1>&2
+      exit 1
+    fi ;;
+  esac
+done
+
+if test -z "$ltmain"; then
+  echo "$progname: you must specify a LTMAIN file" 1>&2
+  echo "$help" 1>&2
+  exit 1
+fi
+
+if test -f "$ltmain"; then :
+else
+  echo "$progname: warning: \`$ltmain' does not exist" 1>&2
+fi
+
+# Quote any args containing shell metacharacters.
+ltconfig_args=
+for arg
+do
+  case "$arg" in
+  *" "*|*"     "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+  ltconfig_args="$ltconfig_args '$arg'" ;;
+  *) ltconfig_args="$ltconfig_args $arg" ;;
+  esac
+done
+
+# A relevant subset of AC_INIT.
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 5 compiler messages saved in config.log
+# 6 checking for... messages and results
+if test "$silent" = yes; then
+  exec 6>/dev/null
+else
+  exec 6>&1
+fi
+exec 5>>./config.log
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+    ac_n= ac_c='
+' ac_t='       '
+  else
+    ac_n=-n ac_c= ac_t=
+  fi
+else
+  ac_n= ac_c='\c' ac_t=
+fi
+
+if test -z "$srcdir"; then
+  # Assume the source directory is the same one as the path to ltmain.sh.
+  srcdir=`echo "$ltmain" | sed 's%/[^/]*$%%'`
+  test "$srcdir" = "$ltmain" && srcdir=.
+fi
+
+trap "$rm conftest*; exit 1" 1 2 15
+if test "$verify_host" = yes; then
+  # Check for config.guess and config.sub.
+  ac_aux_dir=
+  for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+    if test -f $ac_dir/config.guess; then
+      ac_aux_dir=$ac_dir
+      break
+    fi
+  done
+  if test -z "$ac_aux_dir"; then
+    echo "$progname: cannot find config.guess in $srcdir $srcdir/.. $srcdir/../.." 1>&2
+    echo "$help" 1>&2
+    exit 1
+  fi
+  ac_config_guess=$ac_aux_dir/config.guess
+  ac_config_sub=$ac_aux_dir/config.sub
+
+  # Make sure we can run config.sub.
+  if $ac_config_sub sun4 >/dev/null 2>&1; then :
+  else
+    echo "$progname: cannot run $ac_config_sub" 1>&2
+    echo "$help" 1>&2
+    exit 1
+  fi
+
+  echo $ac_n "checking host system type""... $ac_c" 1>&6
+
+  host_alias=$host
+  case "$host_alias" in
+  "")
+    if host_alias=`$ac_config_guess`; then :
+    else
+      echo "$progname: cannot guess host type; you must specify one" 1>&2
+      echo "$help" 1>&2
+      exit 1
+    fi ;;
+  esac
+  host=`$ac_config_sub $host_alias`
+  echo "$ac_t$host" 1>&6
+
+  # Make sure the host verified.
+  test -z "$host" && exit 1
+
+elif test -z "$host"; then
+  echo "$progname: you must specify a host type if you use \`--no-verify'" 1>&2
+  echo "$help" 1>&2
+  exit 1
+else
+  host_alias=$host
+fi
+
+# Transform *-*-linux* to *-*-linux-gnu*, to support old configure scripts.
+case "$host" in
+*-*-linux-gnu*) ;;
+*-*-linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
+esac
+
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+case "$host_os" in
+aix*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "${COLLECT_NAMES+set}" != set; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR cru $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+
+# Set a sane default for `AR'.
+test -z "$AR" && AR=ar
+
+# If RANLIB is not set, then run the test.
+if test "${RANLIB+set}" != "set"; then
+  result=no
+
+  echo $ac_n "checking for ranlib... $ac_c" 1>&6
+  IFS="${IFS=  }"; save_ifs="$IFS"; IFS="${IFS}:"
+  for dir in $PATH; do
+    test -z "$dir" && dir=.
+    if test -f $dir/ranlib; then
+      RANLIB="ranlib"
+      result="ranlib"
+      break
+    fi
+  done
+  IFS="$save_ifs"
+
+  echo "$ac_t$result" 1>&6
+fi
+
+if test -n "$RANLIB"; then
+  old_archive_cmds="$old_archive_cmds;\$RANLIB \$oldlib"
+  old_postinstall_cmds="$old_postinstall_cmds;\$RANLIB \$oldlib"
+fi
+
+# Check to see if we are using GCC.
+if test "$with_gcc" != yes || test -z "$CC"; then
+  # If CC is not set, then try to find GCC or a usable CC.
+  if test -z "$CC"; then
+    echo $ac_n "checking for gcc... $ac_c" 1>&6
+    IFS="${IFS=        }"; save_ifs="$IFS"; IFS="${IFS}:"
+    for dir in $PATH; do
+      IFS="$save_ifs"
+      test -z "$dir" && dir=.
+      if test -f $dir/gcc; then
+       CC="gcc"
+       break
+      fi
+    done
+    IFS="$save_ifs"
+
+    if test -n "$CC"; then
+      echo "$ac_t$CC" 1>&6
+    else
+      echo "$ac_t"no 1>&6
+    fi
+  fi
+
+  # Not "gcc", so try "cc", rejecting "/usr/ucb/cc".
+  if test -z "$CC"; then
+    echo $ac_n "checking for cc... $ac_c" 1>&6
+    IFS="${IFS=        }"; save_ifs="$IFS"; IFS="${IFS}:"
+    cc_rejected=no
+    for dir in $PATH; do
+      test -z "$dir" && dir=.
+      if test -f $dir/cc; then
+       if test "$dir/cc" = "/usr/ucb/cc"; then
+         cc_rejected=yes
+         continue
+       fi
+       CC="cc"
+       break
+      fi
+    done
+    IFS="$save_ifs"
+    if test $cc_rejected = yes; then
+      # We found a bogon in the path, so make sure we never use it.
+      set dummy $CC
+      shift
+      if test $# -gt 0; then
+       # We chose a different compiler from the bogus one.
+       # However, it has the same name, so the bogon will be chosen
+       # first if we set CC to just the name; use the full file name.
+       shift
+       set dummy "$dir/cc" "$@"
+       shift
+       CC="$@"
+      fi
+    fi
+
+    if test -n "$CC"; then
+      echo "$ac_t$CC" 1>&6
+    else
+      echo "$ac_t"no 1>&6
+    fi
+
+    if test -z "$CC"; then
+      echo "$progname: error: no acceptable cc found in \$PATH" 1>&2
+      exit 1
+    fi
+  fi
+
+  # Now see if the compiler is really GCC.
+  with_gcc=no
+  echo $ac_n "checking whether we are using GNU C... $ac_c" 1>&6
+  echo "$progname:394: checking whether we are using GNU C" >&5
+
+  $rm conftest.c
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+  if { ac_try='${CC-cc} -E conftest.c'; { (eval echo $progname:402: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+    with_gcc=yes
+  fi
+  $rm conftest.c
+  echo "$ac_t$with_gcc" 1>&6
+fi
+
+# Allow CC to be a program name with arguments.
+set dummy $CC
+compiler="$2"
+
+echo $ac_n "checking for $compiler option to produce PIC... $ac_c" 1>&6
+pic_flag=
+profile_flag_pattern=
+special_shlib_compile_flags=
+wl=
+link_static_flag=
+no_builtin_flag=
+
+if test "$with_gcc" = yes; then
+  profile_flag_pattern='-pg?'
+  wl='-Wl,'
+  link_static_flag='-static'
+  no_builtin_flag=' -fno-builtin'
+
+  case "$host_os" in
+  aix3* | aix4* | irix5* | irix6* | osf3* | osf4*)
+    # PIC is the default for these OSes.
+    ;;
+  os2*)
+    # We can build DLLs from non-PIC.
+    ;;
+  *)
+    pic_flag='-fPIC'
+    ;;
+  esac
+else
+  # PORTME Check for PIC flags for the system compiler.
+  case "$host_os" in
+  aix3* | aix4*)
+    # All AIX code is PIC.
+    link_static_flag='-bnso -bI:/lib/syscalls.exp'
+    ;;
+
+  hpux9* | hpux10*)
+    # Is there a better link_static_flag that works with the bundled CC?
+    wl='-Wl,'
+    link_static_flag='${wl}-a ${wl}archive'
+    pic_flag='+Z'
+    ;;
+
+  irix5* | irix6*)
+    wl='-Wl,'
+    link_static_flag='-non_shared'
+    # PIC (with -KPIC) is the default.
+    ;;
+
+  os2*)
+    # We can build DLLs from non-PIC.
+    ;;
+
+  osf3* | osf4*)
+    # All OSF/1 code is PIC.
+    wl='-Wl,'
+    link_static_flag='-non_shared'
+    ;;
+
+  sco3.2v5*)
+    pic_flag='-Kpic'
+    link_static_flag='-dn'
+    special_shlib_compile_flags='-belf'
+    ;;
+
+  solaris2*)
+    pic_flag='-KPIC'
+    link_static_flag='-Bstatic'
+    wl='-Wl,'
+    ;;
+
+  sunos4*)
+    pic_flag='-PIC'
+    link_static_flag='-Bstatic'
+    wl='-Qoption ld '
+    ;;
+
+  uts4*)
+    pic_flag='-pic'
+    link_static_flag='-Bstatic'
+    ;;
+
+  *)
+    can_build_shared=no
+    ;;
+  esac
+fi
+
+if test -n "$pic_flag"; then
+  echo "$ac_t$pic_flag" 1>&6
+
+  # Check to make sure the pic_flag actually works.
+  echo $ac_n "checking if $compiler PIC flag $pic_flag works... $ac_c" 1>&6
+  $rm conftest*
+  echo > conftest.c
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS $pic_flag -DPIC"
+  echo "$progname:507: checking if $compiler PIC flag $pic_flag works" >&5
+  if { (eval echo $progname:508: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.o; then
+    # Append any errors to the config.log.
+    cat conftest.err 1>&5
+
+    # On HP-UX, the stripped-down bundled CC doesn't accept +Z, but also
+    # reports no error.  So, we need to grep stderr for (Bundled).
+    if grep '(Bundled)' conftest.err >/dev/null; then
+      echo "$ac_t"no 1>&6
+      can_build_shared=no
+      pic_flag=
+    else
+      echo "$ac_t"yes 1>&6
+      pic_flag=" $pic_flag"
+    fi
+  else
+    # Append any errors to the config.log.
+    cat conftest.err 1>&5
+    can_build_shared=no
+    pic_flag=
+    echo "$ac_t"no 1>&6
+  fi
+  CFLAGS="$save_CFLAGS"
+  $rm conftest*
+else
+  echo "$ac_t"none 1>&6
+fi
+
+# Check for any special shared library compilation flags.
+if test -n "$special_shlib_compile_flags"; then
+  echo "$progname: warning: \`$CC' requires \`$special_shlib_compile_flags' to build shared libraries" 1>&2
+  if echo "$old_CC $old_CFLAGS " | egrep -e "[         ]$special_shlib_compile_flags[  ]" >/dev/null; then :
+  else
+    echo "$progname: add \`$special_shlib_compile_flags' to the CC or CFLAGS env variable and reconfigure" 1>&2
+    can_build_shared=no
+  fi
+fi
+
+echo $ac_n "checking if $compiler static flag $link_static_flag works... $ac_c" 1>&6
+$rm conftest*
+echo 'main(){return(0);}' > conftest.c
+save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$LDFLAGS $link_static_flag"
+echo "$progname:550: checking if $compiler static flag $link_static_flag works" >&5
+if { (eval echo $progname:551: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  echo "$ac_t$link_static_flag" 1>&6
+else
+  echo "$ac_t"none 1>&6
+  link_static_flag=
+fi
+LDFLAGS="$save_LDFLAGS"
+$rm conftest*
+
+if test -z "$LN_S"; then
+  # Check to see if we can use ln -s, or we need hard links.
+  echo $ac_n "checking whether ln -s works... $ac_c" 1>&6
+  $rm conftestdata
+  if ln -s X conftestdata 2>/dev/null; then
+    $rm conftestdata
+    LN_S="ln -s"
+  else
+    LN_S=ln
+  fi
+  if test "$LN_S" = "ln -s"; then
+    echo "$ac_t"yes 1>&6
+  else
+    echo "$ac_t"no 1>&6
+  fi
+fi
+
+# Make sure LD is an absolute path.
+if test -z "$LD"; then
+  ac_prog=ld
+  if test "$with_gcc" = yes; then
+    # Check if gcc -print-prog-name=ld gives a path.
+    echo $ac_n "checking for ld used by GCC... $ac_c" 1>&6
+    echo "$progname:583: checking for ld used by GCC" >&5
+    ac_prog=`($CC -print-prog-name=ld) 2>&5`
+    case "$ac_prog" in
+    # Accept absolute paths.
+    /*)
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+    "")
+      # If it fails, then pretend we aren't using GCC.
+      ac_prog=ld
+      ;;
+    *)
+      # If it is relative, then search for the first ld in PATH.
+      with_gnu_ld=unknown
+      ;;
+    esac
+  elif test "$with_gnu_ld" = yes; then
+    echo $ac_n "checking for GNU ld... $ac_c" 1>&6
+    echo "$progname:601: checking for GNU ld" >&5
+  else
+    echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+    echo "$progname:604: checking for non-GNU ld" >&5
+  fi
+
+  if test -z "$LD"; then
+    IFS="${IFS=        }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+    for ac_dir in $PATH; do
+      test -z "$ac_dir" && ac_dir=.
+      if test -f "$ac_dir/$ac_prog"; then
+       LD="$ac_dir/$ac_prog"
+       # Check to see if the program is GNU ld.  I'd rather use --version,
+       # but apparently some GNU ld's only accept -v.
+       # Break only if it was the GNU/non-GNU ld that we prefer.
+       if "$LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+         test "$with_gnu_ld" != no && break
+       else
+         test "$with_gnu_ld" != yes && break
+       fi
+      fi
+    done
+    IFS="$ac_save_ifs"
+  fi
+
+  if test -n "$LD"; then
+    echo "$ac_t$LD" 1>&6
+  else
+    echo "$ac_t"no 1>&6
+  fi
+
+  if test -z "$LD"; then
+    echo "$progname: error: no acceptable ld found in \$PATH" 1>&2
+    exit 1
+  fi
+fi
+
+# Check to see if it really is or isn't GNU ld.
+echo $ac_n "checking if the linker ($LD) is GNU ld... $ac_c" 1>&6
+# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+echo "$ac_t$with_gnu_ld" 1>&6
+
+# See if the linker supports building shared libraries.
+echo $ac_n "checking whether the linker ($LD) supports shared libraries... $ac_c" 1>&6
+
+allow_undefined_flag=
+archive_cmds=
+old_archive_from_new_cmds=
+export_dynamic_flag_spec=
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+hardcode_runpath_var=no
+hardcode_shlibpath_var=unsupported
+runpath_var=
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+  # See if GNU ld supports shared libraries.
+
+  case "$host_os" in
+  sunos4*)
+    ld_shlibs=yes
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  *)
+    if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      runpath_var=LD_RUN_PATH
+      hardcode_runpath_var=yes
+      ld_shlibs=yes
+    else
+      ld_shlibs=no
+    fi
+    ;;
+  esac
+
+  if test "$ld_shlibs" = yes; then
+    archive_cmds='$CC -shared ${wl}-soname $wl$soname -o $lib$libobjs$deplibs'
+    hardcode_libdir_flag_spec='${wl}-rpath $wl$libdir'
+    export_dynamic_flag_spec='${wl}-export-dynamic'
+  fi
+else
+  # PORTME fill in a description of your system's linker (not GNU ld)
+  case "$host_os" in
+  aix3*)
+    allow_undefined_flag=unsupported
+    archive_cmds='$NM$libobjs | $global_symbol_pipe | sed '"'s/.* //'"' > $lib.exp;$LD -o $objdir/$soname$libobjs -bE:$lib.exp -T512 -H512 -bM:SRE$deplibs;$AR cru $lib $objdir/$soname'
+    # Note: this linker hardcodes the directories in LIBPATH if there
+    # are no directories specified by -L.
+    hardcode_minus_L=yes
+    if test "$with_gcc" = yes && test -z "$link_static_flag"; then
+      # Neither direct hardcoding nor static linking is supported with a
+      # broken collect2.
+      hardcode_direct=unsupported
+    fi
+    ;;
+
+  aix4*)
+    allow_undefined_flag=unsupported
+    archive_cmds='$NM$libobjs | $global_symbol_pipe | sed '"'s/.* //'"' > $lib.exp;$CC -o $objdir/$soname$libobjs ${wl}-bE:$lib.exp ${wl}-bM:SRE ${wl}-bnoentry$deplibs;$AR cru $lib $objdir/$soname'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    ;;
+
+  # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+  # support.  Future versions do this automatically, but an explicit c++rt0.o
+  # doesn't break anything, and helps significantly (at the cost of a little
+  # extra space).
+  freebsd2.2*)
+    archive_cmds='$LD -Bshareable -o $lib$libobjs$deplibs /usr/lib/c++rt0.o'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  # Unfortunately, older versions of FreeBSD 2 don't have this feature.
+  freebsd2*)
+    archive_cmds='$LD -Bshareable -o $lib$libobjs$deplibs'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  # FreeBSD 3, at last, uses gcc -shared to do shared libraries.
+  freebsd3*)
+    archive_cmds='$CC -shared -o $lib$libobjs$deplibs'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  hpux9*)
+    archive_cmds='$rm $objdir/$soname;$LD -b +s +b $install_libdir -o $objdir/$soname$libobjs$deplibs;mv $objdir/$soname $lib'
+    hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    ;;
+
+  hpux10*)
+    archive_cmds='$LD -b +h $soname +s +b $install_libdir -o $lib$libobjs$deplibs'
+    hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    ;;
+
+  irix5* | irix6*)
+    archive_cmds='$LD -shared -o $lib -soname $soname -set_version $verstring$libobjs$deplibs'
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    ;;
+
+  netbsd*)
+    # Tested with NetBSD 1.2 ld
+    archive_cmds='$LD -Bshareable -o $lib$libobjs'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  openbsd*)
+    archive_cmds='$LD -Bshareable -o $lib$libobjs$deplibs'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  os2*)
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+    allow_undefined_flag=unsupported
+    archive_cmds='echo "LIBRARY $libname INITINSTANCE" > $objdir/$libname.def;echo "DESCRIPTION \"$libname\"" >> $objdir/$libname.def;echo DATA >> $objdir/$libname.def;echo " SINGLE NONSHARED" >> $objdir/$libname.def;echo EXPORTS >> $objdir/$libname.def;emxexp$libobjs >> $objdir/$libname.def;$CC -Zdll -Zcrtdll -o $lib$libobjs $objdir/$libname.def'
+    old_archive_from_new_cmds='emximp -o $objdir/$libname.a $objdir/$libname.def'
+    ;;
+
+  osf3* | osf4*)
+    allow_undefined_flag=' -expect_unresolved \*'
+    archive_cmds='$LD -shared${allow_undefined_flag} -o $lib -soname $soname -set_version $verstring$libobjs$deplibs'
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator=:
+    ;;
+
+  sco3.2v5*)
+    archive_cmds='$LD -G -o $lib$libobjs$deplibs'
+    hardcode_direct=yes
+    ;;
+
+  solaris2*)
+    archive_cmds='$LD -G -z text -h $soname -o $lib$libobjs$deplibs'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_shlibpath_var=no
+    ;;
+
+  sunos4*)
+    archive_cmds='$LD -assert pure-text -Bstatic -o $lib$libobjs'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+   uts4*)
+     archive_cmds='$LD -G -h $soname -o $lib$libobjs$deplibs'
+     hardcode_libdir_flag_spec='-L$libdir'
+     hardcode_direct=no
+     hardcode_minus_L=no
+     hardcode_shlibpath_var=no
+     ;;
+
+  *)
+    ld_shlibs=no
+    can_build_shared=no
+    ;;
+  esac
+fi
+echo "$ac_t$ld_shlibs" 1>&6
+
+if test -z "$NM"; then
+  echo $ac_n "checking for BSD-compatible nm... $ac_c" 1>&6
+  case "$NM" in
+  /*) ;; # Let the user override the test with a path.
+  *)
+    IFS="${IFS=        }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+    for ac_dir in /usr/ucb $PATH /bin; do
+      test -z "$ac_dir" && dir=.
+      if test -f $ac_dir/nm; then
+        # Check to see if the nm accepts a BSD-compat flag.
+        if ($ac_dir/nm -B /dev/null 2>&1; exit 0) | grep /dev/null >/dev/null; then
+          NM="$ac_dir/nm -B"
+        elif ($ac_dir/nm -p /dev/null 2>&1; exit 0) | grep /dev/null >/dev/null; then
+          NM="$ac_dir/nm -p"
+       else
+          NM="$ac_dir/nm"
+       fi
+        break
+      fi
+    done
+    IFS="$ac_save_ifs"
+    test -z "$NM" && NM=nm
+    ;;
+  esac
+  echo "$ac_t$NM" 1>&6
+fi
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+echo $ac_n "checking command to parse $NM output... $ac_c" 1>&6
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRSTU]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+symxfrm='\1 \1'
+
+# Define system-specific variables.
+case "$host_os" in
+aix*)
+  symcode='[BCDTU]'
+  ;;
+solaris2*)
+  symcode='[BDTU]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+  symcode='[ABCDGISTUW]'
+fi
+
+# Write the raw and C identifiers.
+global_symbol_pipe="sed -n -e 's/^.* $symcode $sympat$/$symxfrm/p'"
+
+# Check to see that the pipe works correctly.
+pipe_works=no
+$rm conftest*
+cat > conftest.c <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+echo "$progname:900: checking if global_symbol_pipe works" >&5
+if { (eval echo $progname:901: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.o; then
+  # Now try to grab the symbols.
+  nlist=conftest.nm
+  if { echo "$progname:904: eval \"$NM conftest.o | $global_symbol_pipe > $nlist\"" >&5; eval "$NM conftest.o | $global_symbol_pipe > $nlist 2>&5"; } && test -s "$nlist"; then
+
+    # Try sorting and uniquifying the output.
+    if sort "$nlist" | uniq > "$nlist"T; then
+      mv -f "$nlist"T "$nlist"
+      wcout=`wc "$nlist" 2>/dev/null`
+      count=`echo "$wcout" | sed 's/^[         ]*\([0-9][0-9]*\).*$/\1/'`
+      (test "$count" -ge 0) 2>/dev/null || count=-1
+    else
+      rm -f "$nlist"T
+      count=-1
+    fi
+
+    # Make sure that we snagged all the symbols we need.
+    if egrep ' nm_test_var$' "$nlist" >/dev/null; then
+      if egrep ' nm_test_func$' "$nlist" >/dev/null; then
+       cat <<EOF > conftest.c
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+        # Now generate the symbol file.
+        sed 's/^.* \(.*\)$/extern char \1;/' < "$nlist" >> conftest.c
+
+       cat <<EOF >> conftest.c
+#if defined (__STDC__) && __STDC__
+# define __ptr_t void *
+#else
+# define __ptr_t char *
+#endif
+
+/* The number of symbols in dld_preloaded_symbols, -1 if unsorted. */
+int dld_preloaded_symbol_count = $count;
+
+/* The mapping between symbol names and symbols. */
+struct {
+  char *name;
+  __ptr_t address;
+}
+dld_preloaded_symbols[] =
+{
+EOF
+        sed 's/^\(.*\) \(.*\)$/  {"\1", \&\2},/' < "$nlist" >> conftest.c
+        cat <<\EOF >> conftest.c
+  {0},
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+        # Now try linking the two files.
+        mv conftest.o conftestm.o
+       save_LIBS="$LIBS"
+       save_CFLAGS="$CFLAGS"
+        LIBS='conftestm.o'
+       CFLAGS="$CFLAGS$no_builtin_flag"
+        if { (eval echo $progname:962: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+          pipe_works=yes
+        else
+          echo "$progname: failed program was:" >&5
+          cat conftest.c >&5
+        fi
+        LIBS="$save_LIBS"
+      else
+        echo "cannot find nm_test_func in $nlist" >&5
+      fi
+    else
+      echo "cannot find nm_test_var in $nlist" >&5
+    fi
+  else
+    echo "cannot run $global_symbol_pipe" >&5
+  fi
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.c >&5
+fi
+$rm conftest*
+
+# Don't use the global_symbol_pipe unless it works.
+echo "$ac_t$pipe_works" 1>&6
+test "$pipe_works" = yes || global_symbol_pipe=
+
+# Check hardcoding attributes.
+echo $ac_n "checking how to hardcode library paths into programs... $ac_c" 1>&6
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" || \
+   test "$hardcode_runpath_var" = yes; then
+
+  # We can hardcode non-existant directories.
+  if test "$hardcode_direct" != no && \
+     test "$hardcode_minus_L" != no && \
+     test "$hardcode_shlibpath_var" != no; then
+
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action=immediate
+  fi
+elif test "$hardcode_direct" != yes && \
+     test "$hardcode_minus_L" != yes && \
+     test "$hardcode_shlibpath_var" != yes; then
+  # We can't hardcode anything.
+  hardcode_action=unsupported
+else
+  # We can only hardcode existing directories.
+  hardcode_action=relink
+fi
+echo "$ac_t$hardcode_action" 1>&6
+test "$hardcode_action" = unsupported && can_build_shared=no
+
+
+reload_flag=
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+echo $ac_n "checking for $LD option to reload object files... $ac_c" 1>&6
+# PORTME Some linker may need a different reload flag.
+reload_flag='-r'
+echo "$ac_t$reload_flag"
+test -n "$reload_flag" && reload_flag=" $reload_flag"
+
+# PORTME Fill in your ld.so characteristics
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+postinstall_cmds=
+finish_cmds=
+shlibpath_var=
+version_type=none
+dynamic_linker="$host_os ld.so"
+
+echo $ac_n "checking dynamic linker characteristics... $ac_c" 1>&6
+case "$host_os" in
+aix3* | aix4*)
+  version_type=linux
+  library_names_spec='$libname.so.$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX has no versioning support, so we append a major version to the name.
+  soname_spec='$libname.so.$major'
+  ;;
+
+freebsd2* | freebsd3*)
+  version_type=sunos
+  library_names_spec='$libname.so.$versuffix $libname.so'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+gnu*)
+  version_type=sunos
+  library_names_spec='$libname.so.$versuffix'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+hpux9* | hpux10*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  dynamic_linker="$host_os dld.sl"
+  version_type=sunos
+  shlibpath_var=SHLIB_PATH
+  library_names_spec='$libname.sl.$versuffix $libname.sl.$major $libname.sl'
+  soname_spec='$libname.sl.$major'
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+irix5* | irix6*)
+  version_type=osf
+  soname_spec='$libname.so'
+  library_names_spec='$libname.so.$versuffix $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+  version_type=linux
+  library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so'
+  soname_spec='$libname.so.$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+
+  if test -f /lib/ld.so.1; then
+    dynamic_linker='GNU ld.so'
+  else
+    # Only the GNU ld.so supports shared libraries on MkLinux.
+    case "$host_cpu" in
+    powerpc*) dynamic_linker=no ;;
+    *) dynamic_linker='Linux ld.so' ;;
+    esac
+  fi
+  ;;
+
+netbsd* | openbsd*)
+  version_type=sunos
+  library_names_spec='$libname.so.$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+os2*)
+  version_type=none
+  libname_spec='$name'
+  library_names_spec='$libname.dll $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4*)
+  version_type=osf
+  soname_spec='$libname.so'
+  library_names_spec='$libname.so.$versuffix $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+sco3.2v5*)
+  version_type=osf
+  soname_spec='$libname.so.$major'
+  library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+solaris2*)
+  version_type=linux
+  library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so'
+  soname_spec='$libname.so.$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='$libname.so.$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so'
+  soname_spec='$libname.so.$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+echo "$ac_t$dynamic_linker"
+test "$dynamic_linker" = no && can_build_shared=no
+
+# FIXME add checks for striplib and old_striplib here.
+# strip -x works for most platforms, though not for static libraries on NetBSD
+# HP-UX requires "-r" for library stripping
+striplib=
+old_striplib=
+
+# Report the final consequences.
+echo "checking if libtool supports shared libraries... $can_build_shared" 1>&6
+
+echo $ac_n "checking whether to build shared libraries... $ac_c" 1>&6
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix*)
+  test "$enable_shared" = yes && enable_static=no
+  if test -n "$RANLIB"; then
+    archive_cmds="$archive_cmds;\$RANLIB \$lib"
+    postinstall_cmds='$RANLIB $lib'
+  fi
+  ;;
+esac
+
+echo "$ac_t$enable_shared" 1>&6
+
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+
+echo "checking whether to build static libraries... $enable_static" 1>&6
+
+echo $ac_n "checking for objdir... $ac_c" 1>&6
+rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+echo "$ac_t$objdir" 1>&6
+
+# Now quote all the things that may contain metacharacters.
+for var in old_CC old_CFLAGS old_CPPFLAGS old_LD old_NM old_RANLIB \
+  old_LN_S AR CC LD LN_S NM reload_flag reload_cmds wl pic_flag \
+  link_static_flag no_builtin_flag export_dynamic_flag_spec \
+  profile_flag_pattern libname_spec library_names_spec soname_spec RANLIB \
+  old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \
+  archive_cmds postinstall_cmds \
+  allow_undefined_flag finish_cmds global_symbol_pipe \
+  striplib old_striplib \
+  hardcode_libdir_flag_spec hardcode_libdir_separator; do
+
+  case "$var" in
+  reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \
+  old_postinstall_cmds | archive_cmds | postinstall_cmds | finish_cmds)
+    # Double-quote double-evaled strings.
+    eval "$var=\`echo \"\$$var\" | sed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\"\`"
+    ;;
+  *)
+    eval "$var=\`echo \"\$$var\" | sed \"\$sed_quote_subst\"\`"
+    ;;
+  esac
+done
+
+ofile=libtool
+trap "$rm $ofile; exit 1" 1 2 15
+echo creating $ofile
+$rm $ofile
+cat <<EOF > $ofile
+#! /bin/sh
+
+# libtool - Provide generalized library-building support services.
+#
+# Generated automatically by $PROGRAM - GNU $PACKAGE $VERSION
+# This program was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# CC="$old_CC" CFLAGS="$old_CFLAGS" CPPFLAGS="$old_CPPFLAGS" \\
+# LD="$old_LD" NM="$old_NM" RANLIB="$old_RANLIB" LN_S="$old_LN_S" \\
+#   $0$ltconfig_args
+#
+# Compiler and other test output produced by $progname, useful for
+# debugging $progname, is in ./config.log if it exists.
+
+# The version of $progname that generated this script.
+LTCONFIG_VERSION="$VERSION"
+
+# Shell to use when invoking shell scripts.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Whether or not to build libtool libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build old-style libraries.
+build_old_libs=$enable_static
+
+# The host system.
+host_alias="$host_alias"
+host="$host"
+
+# The archiver.
+AR="$AR"
+
+# The default C compiler.
+CC="$CC"
+
+# The linker used to build libraries.
+LD="$LD"
+
+# Whether we need hard or soft links.
+LN_S="$LN_S"
+
+# A BSD-compatible nm program.
+NM="$NM"
+
+# The name of the directory that contains temporary libtool files.
+objdir="$objdir"
+
+# How to create reloadable object files.
+reload_flag="$reload_flag"
+reload_cmds="$reload_cmds"
+
+# How to pass a linker flag through the compiler.
+wl="$wl"
+
+# Additional compiler flags for building library objects.
+pic_flag="$pic_flag"
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag="$link_static_flag"
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag="$no_builtin_flag"
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec="$export_dynamic_flag_spec"
+
+# Pattern to match compiler flags for creating libNAME_p libraries:
+profile_flag_pattern="$profile_flag_pattern"
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec="$libname_spec"
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec="$library_names_spec"
+
+# The coded name of the library, if different from the real name.
+soname_spec="$soname_spec"
+
+# Commands used to build and install an old-style archive.
+RANLIB="$RANLIB"
+old_archive_cmds="$old_archive_cmds"
+old_postinstall_cmds="$old_postinstall_cmds"
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds="$old_archive_from_new_cmds"
+
+# Commands used to build and install a shared archive.
+archive_cmds="$archive_cmds"
+postinstall_cmds="$postinstall_cmds"
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag="$allow_undefined_flag"
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds="$finish_cmds"
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe="$global_symbol_pipe"
+
+# How to strip a library file.
+striplib="$striplib"
+old_striplib="$old_striplib"
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec="$hardcode_libdir_flag_spec"
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator="$hardcode_libdir_separator"
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to yes if using RUNPATH_VAR=DIR during linking hardcodes DIR into the
+# resulting binary.
+hardcode_runpath_var=$hardcode_runpath_var
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+EOF
+
+case "$host_os" in
+aix*)
+  cat <<\EOF >> $ofile
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "${COLLECT_NAMES+set}" != set; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+
+EOF
+  ;;
+esac
+
+# Detect if we are using a relative or absolute path to ltmain.sh.
+case "$ltmain" in
+/*) cat <<EOF >> $ofile
+# Execute the libtool backend.
+. $ltmain
+EOF
+  ;;
+*) cat <<EOF >> $ofile
+# Find the path to this script.
+thisdir=\`echo "\$0" | sed -e 's%/[^/]*\$%%'\`
+test "X\$0" = "X\$thisdir" && thisdir=.
+
+# Execute the libtool backend.
+. \$thisdir/$ltmain
+EOF
+  ;;
+esac
+
+echo 'exit 1' >> $ofile
+
+chmod +x $ofile
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/glib/ltmain.sh b/glib/ltmain.sh
new file mode 100644 (file)
index 0000000..cb46c84
--- /dev/null
@@ -0,0 +1,2372 @@
+# ltmain.sh - Provide generalized library-building support services.
+# Generated automatically from ltmain.in by configure.
+# Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+# Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+#FIXME: echo=echo
+echo='printf %s\n'
+if test "X`$echo '\t'`" = 'X\t'; then :
+else
+  # The Solaris and AIX default echo program unquotes backslashes.
+  # This makes it impossible to quote backslashes using
+  #   echo "$something" | sed 's/\\/\\\\/g'
+  # So, we emulate echo with printf '%s\n'
+  echo='printf %s\n'
+  if test "X`$echo '\t'`" = 'X\t'; then :
+  else
+    # Oops.  We have no working printf.  Try to find a not-so-buggy echo.
+    echo=echo
+    IFS="${IFS=        }"; save_ifs="$IFS"; IFS="${IFS}:"
+    save_PATH="$PATH"
+    PATH="$PATH":/usr/ucb
+    for dir in $PATH; do
+      if test -f $dir/echo && test "X`$dir/echo '\t'`" = 'X\t'; then
+        echo="$dir/echo"
+        break
+      fi
+    done
+    IFS="$save_ifs"
+    PATH="$save_PATH"
+  fi
+fi
+
+# The name of this program.
+progname=`$echo "$0" | sed 's%^.*/%%'`
+
+# Constants.
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION=1.0f
+
+default_mode=
+help="Try \`$progname --help' for more information."
+magic="%%%MAGIC variable%%%"
+mkdir="mkdir"
+mv="mv -f"
+rm="rm -f"
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s/\([\\"$\\\\]\)/\\\1/g'
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+
+if test "$LTCONFIG_VERSION" != "$VERSION"; then
+  $echo "$progname: ltconfig version \`$LTCONFIG_VERSION' does not match $PROGRAM version \`$VERSION'" 1>&2
+  $echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+  exit 1
+fi
+
+if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+  $echo "$progname: not configured to build any kind of library" 1>&2
+  $echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+  exit 1
+fi
+
+# Global variables.
+mode=$default_mode
+nonopt=
+prev=
+prevopt=
+run=
+show="$echo"
+show_help=
+execute_dlfiles=
+
+# Parse our command line options once, thoroughly.
+while test $# -gt 0
+do
+  arg="$1"
+  shift
+
+  case "$arg" in
+  -*=*) optarg=`$echo "$arg" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$prev"; then
+    case "$prev" in
+    execute_dlfiles)
+      eval "$prev=\"\$$prev \$arg\""
+      ;;
+    *)
+      eval "$prev=\$arg"
+      ;;
+    esac
+
+    prev=
+    prevopt=
+    continue
+  fi
+
+  # Have we seen a non-optional argument yet?
+  case "$arg" in
+  --help)
+    show_help=yes
+    ;;
+
+  --version)
+    $echo "$PROGRAM (GNU $PACKAGE) $VERSION"
+    exit 0
+    ;;
+
+  --dry-run | -n)
+    run=:
+    ;;
+
+  --features)
+    $echo "host: $host"
+    if test "$build_libtool_libs" = yes; then
+      $echo "enable shared libraries"
+    else
+      $echo "disable shared libraries"
+    fi
+    if test "$build_old_libs" = yes; then
+      $echo "enable static libraries"
+    else
+      $echo "disable static libraries"
+    fi
+    exit 0
+    ;;
+
+  --finish) mode="finish" ;;
+
+  --mode) prevopt="--mode" prev=mode ;;
+  --mode=*) mode="$optarg" ;;
+
+  --quiet | --silent)
+    show=:
+    ;;
+
+  -dlopen)
+    prevopt="-dlopen"
+    prev=execute_dlfiles
+    ;;
+
+  -*)
+    $echo "$progname: unrecognized option \`$arg'" 1>&2
+    $echo "$help" 1>&2
+    exit 1
+    ;;
+
+  *)
+    nonopt="$arg"
+    break
+    ;;
+  esac
+done
+
+if test -n "$prevopt"; then
+  $echo "$progname: option \`$prevopt' requires an argument" 1>&2
+  $echo "$help" 1>&2
+  exit 1
+fi
+
+if test -z "$show_help"; then
+
+  # Infer the operation mode.
+  if test -z "$mode"; then
+    case "$nonopt" in
+    *cc | *++)
+      mode=link
+      for arg
+      do
+        case "$arg" in
+        -c)
+           mode=compile
+           break
+           ;;
+        esac
+      done
+      ;;
+    *db | *dbx)
+      mode=execute
+      ;;
+    *install*|cp)
+      mode=install
+      ;;
+    *rm)
+      mode=uninstall
+      ;;
+    *)
+      # If we have no mode, but dlfiles were specified, then do execute mode.
+      test -n "$execute_dlfiles" && mode=execute
+
+      # Just use the default operation mode.
+      if test -z "$mode"; then
+        if test -n "$nonopt"; then
+          $echo "$progname: warning: cannot infer operation mode from \`$nonopt'" 1>&2
+        else
+          $echo "$progname: warning: cannot infer operation mode without MODE-ARGS" 1>&2
+        fi
+      fi
+      ;;
+    esac
+  fi
+
+  # Only execute mode is allowed to have -dlopen flags.
+  if test -n "$execute_dlfiles" && test "$mode" != execute; then
+    $echo "$progname: unrecognized option \`-dlopen'" 1>&2
+    $echo "$help" 1>&2
+    exit 1
+  fi
+
+  # Change the help message to a mode-specific one.
+  generic_help="$help"
+  help="Try \`$progname --help --mode=$mode' for more information."
+
+  # These modes are in order of execution frequency so that they run quickly.
+  case "$mode" in
+  # libtool compile mode
+  compile)
+    progname="$progname: compile"
+    # Get the compilation command and the source file.
+    base_compile=
+    lastarg=
+    srcfile="$nonopt"
+    suppress_output=
+
+    for arg
+    do
+      # The only flag that cannot be specified is the output filename.
+      if test "X$arg" = "X-o"; then
+       $echo "$progname: you cannot specify the output filename with \`-o'" 1>&2
+       $echo "$help" 1>&2
+       exit 1
+      fi
+
+      # Accept the current argument as the source file.
+      lastarg="$srcfile"
+      srcfile="$arg"
+
+      # Aesthetically quote the previous argument.
+
+      # Backslashify any backslashes, double quotes, and dollar signs.
+      # These are the only characters that are still specially
+      # interpreted inside of double-quoted scrings.
+      lastarg=`$echo "$lastarg" | sed "$sed_quote_subst"`
+
+      # Double-quote args containing other shell metacharacters.
+      # Many Bourne shells cannot handle close brackets correctly in scan
+      # sets, so we specify it separately.
+      case "$lastarg" in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*)
+       lastarg="\"$lastarg\""
+       ;;
+      esac
+
+      # Add the previous argument to base_compile.
+      if test -z "$base_compile"; then
+       base_compile="$lastarg"
+      else
+       base_compile="$base_compile $lastarg"
+      fi
+    done
+
+    # Get the name of the library object.
+    libobj=`$echo "$srcfile" | sed -e 's%^.*/%%'`
+
+    # Recognize several different file suffixes.
+    xform='[cCFSfm]'
+    case "$libobj" in
+    *.c++) xform=c++ ;;
+    *.cc) xform=cc ;;
+    *.cpp) xform=cpp ;;
+    *.cxx) xform=cxx ;;
+    *.f90) xform=f90 ;;
+    *.for) xform=for ;;
+    esac
+
+    libobj=`$echo "$libobj" | sed -e "s/\.$xform$/.lo/"`
+
+    case "$libobj" in
+    *.lo) obj=`$echo "$libobj" | sed -e 's/\.lo$/.o/'` ;;
+    *)
+      $echo "$progname: cannot determine name of library object from \`$srcfile'" 1>&2
+      exit 1
+      ;;
+    esac
+
+    if test -z "$base_compile"; then
+      $echo "$progname: you must specify a compilation command" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    # Delete any leftover library objects.
+    if test "$build_old_libs" = yes; then
+      $run $rm $obj $libobj
+      trap "$run $rm $obj $libobj; exit 1" 1 2 15
+    else
+      $run $rm $libobj
+      trap "$run $rm $libobj; exit 1" 1 2 15
+    fi
+
+    # Only build a PIC object if we are building libtool libraries.
+    if test "$build_libtool_libs" = yes; then
+      # Without this assignment, base_compile gets emptied.
+      fbsd_hideous_sh_bug=$base_compile
+
+      # All platforms use -DPIC, to notify preprocessed assembler code.
+      $show "$base_compile$pic_flag -DPIC $srcfile"
+      if $run eval "$base_compile\$pic_flag -DPIC \$srcfile"; then :
+      else
+        test -n "$obj" && $run $rm $obj
+        exit 1
+      fi
+
+      # If we have no pic_flag, then copy the object into place and finish.
+      if test -z "$pic_flag"; then
+        $show "$LN_S $obj $libobj"
+        $run $LN_S $obj $libobj
+        exit $?
+      fi
+
+      # Just move the object, then go on to compile the next one
+      $show "$mv $obj $libobj"
+      $run $mv $obj $libobj || exit 1
+
+      # Allow error messages only from the first compilation.
+      suppress_output=' >/dev/null 2>&1'
+    fi
+
+    # Only build a position-dependent object if we build old libraries.
+    if test "$build_old_libs" = yes; then
+      # Suppress compiler output if we already did a PIC compilation.
+      $show "$base_compile $srcfile$suppress_output"
+      if $run eval "$base_compile \$srcfile$suppress_output"; then :
+      else
+        $run $rm $obj $libobj
+        exit 1
+      fi
+    fi
+
+    # Create an invalid libtool object if no PIC, so that we don't accidentally
+    # link it into a program.
+    if test "$build_libtool_libs" != yes; then
+      $show "$echo timestamp > $libobj"
+      $run eval "\$echo timestamp > \$libobj" || exit $?
+    fi
+
+    exit 0
+    ;;
+
+  # libtool link mode
+  link)
+    progname="$progname: link"
+    CC="$nonopt"
+    allow_undefined=no
+    compile_command="$CC"
+    finalize_command="$CC"
+
+    compile_shlibpath=
+    finalize_shlibpath=
+    deplibs=
+    dlfiles=
+    dlprefiles=
+    export_dynamic=no
+    hardcode_libdirs=
+    libobjs=
+    link_against_libtool_libs=
+    ltlibs=
+    objs=
+    prev=
+    prevarg=
+    rpath=
+    perm_rpath=
+    temp_rpath=
+    vinfo=
+
+    # We need to know -static, to get the right output filenames.
+    for arg
+    do
+      case "$arg" in
+      -all-static | -static)
+        if test "X$arg" = "X-all-static" && test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+           $echo "$progname: warning: complete static linking is impossible in this configuration" 1>&2
+        fi
+        build_libtool_libs=no
+       build_old_libs=yes
+        break
+        ;;
+      esac
+    done
+
+    # See if our shared archives depend on static archives.
+    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+    # Go through the arguments, transforming them on the way.
+    for arg
+    do
+      # If the previous option needs an argument, assign it.
+      if test -n "$prev"; then
+        case "$prev" in
+        output)
+          compile_command="$compile_command @OUTPUT@"
+          finalize_command="$finalize_command @OUTPUT@"
+          ;;
+        esac
+
+        case "$prev" in
+        dlfiles|dlprefiles)
+          case "$arg" in
+          *.la | *.lo) ;;  # We handle these cases below.
+          *)
+            dlprefiles="$dlprefiles $arg"
+            test "$prev" = dlfiles && dlfiles="$dlfiles $arg"
+            prev=
+            ;;
+          esac
+          ;;
+        rpath)
+          rpath="$rpath $arg"
+         prev=
+         continue
+         ;;
+        *)
+          eval "$prev=\"\$arg\""
+          prev=
+          continue
+          ;;
+        esac
+      fi
+
+      prevarg="$arg"
+
+      case "$arg" in
+      -all-static)
+       if test -n "$link_static_flag"; then
+          compile_command="$compile_command $link_static_flag"
+         finalize_command="$finalize_command $link_static_flag"
+        fi
+        continue
+       ;;
+
+      -allow-undefined)
+       allow_undefined=yes
+       continue
+       ;;
+
+      -dlopen)
+        prev=dlfiles
+        continue
+        ;;
+
+      -dlpreopen)
+        prev=dlprefiles
+        continue
+        ;;
+
+      -export-dynamic)
+        if test "$export_dynamic" != yes; then
+          export_dynamic=yes
+         if test -n "$export_dynamic_flag_spec"; then
+           arg=`eval \\$echo "$export_dynamic_flag_spec"`
+         else
+           arg=
+         fi
+
+          # Add the symbol object into the linking commands.
+         compile_command="$compile_command @SYMFILE@"
+         finalize_command="$finalize_command @SYMFILE@"
+        fi
+        ;;
+
+      -L*)
+        dir=`$echo "$arg" | sed 's%^-L\(.*\)$%\1%'`
+        case "$dir" in
+        /*)
+         # Add the corresponding hardcode_libdir_flag, if it is not identical.
+          ;;
+        *)
+          $echo "$progname: \`-L$dir' cannot specify a relative directory" 1>&2
+          exit 1
+          ;;
+        esac
+        deplibs="$deplibs $arg"
+        ;;
+
+      -l*) deplibs="$deplibs $arg" ;;
+
+      -o) prev=output ;;
+
+      -rpath)
+        prev=rpath
+        continue
+        ;;
+
+      -static)
+       # If we have no pic_flag, then this is the same as -all-static.
+       if test -z "$pic_flag" && test -n "$link_static_flag"; then
+          compile_command="$compile_command $link_static_flag"
+         finalize_command="$finalize_command $link_static_flag"
+        fi
+       continue
+       ;;
+
+      -version-info)
+        prev=vinfo
+        continue
+        ;;
+
+      # Some other compiler flag.
+      -* | +*)
+       # Unknown arguments in both finalize_command and compile_command need
+       # to be aesthetically quoted because they are evaled later.
+       arg=`$echo "$arg" | sed "$sed_quote_subst"`
+       case "$arg" in
+       *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \   ]*|*]*)
+         arg="\"$arg\""
+         ;;
+       esac
+        ;;
+
+      *.o | *.a)
+        # A standard object.
+        objs="$objs $arg"
+        ;;
+
+      *.lo)
+        # A library object.
+       if test "$prev" = dlfiles; then
+         dlfiles="$dlfiles $arg"
+         if test "$build_libtool_libs" = yes; then
+           prev=
+           continue
+         else
+           # If libtool objects are unsupported, then we need to preload.
+           prev=dlprefiles
+         fi
+       fi
+
+       if test "$prev" = dlprefiles; then
+         # Preload the old-style object.
+         dlprefiles="$dlprefiles "`$echo "$arg" | sed 's/\.lo$/\.o/'`
+         prev=
+       fi
+       libobjs="$libobjs $arg"
+        ;;
+
+      *.la)
+        # A libtool-controlled library.
+
+        dlname=
+        libdir=
+        library_names=
+        old_library=
+
+        # Check to see that this really is a libtool archive.
+        if egrep '^# Generated by ltmain.sh' $arg >/dev/null 2>&1; then :
+        else
+          $echo "$progname: \`$arg' is not a valid libtool archive" 1>&2
+          exit 1
+        fi
+
+        # If there is no directory component, then add one.
+        case "$arg" in
+        */*) . $arg ;;
+        *) . ./$arg ;;
+        esac
+
+        if test -z "$libdir"; then
+          $echo "$progname: \`$arg' contains no -rpath information" 1>&2
+          exit 1
+        fi
+
+        # Get the name of the library we link against.
+        linklib=
+        for l in $old_library $library_names; do
+          linklib="$l"
+        done
+
+        if test -z "$linklib"; then
+          $echo "$progname: cannot find name of link library for \`$arg'" 1>&2
+          exit 1
+        fi
+
+        # Find the relevant object directory and library name.
+        name=`$echo "$arg" | sed -e 's%^.*/%%' -e 's/\.la$//' -e 's/^lib//'`
+        dir=`$echo "$arg" | sed 's%/[^/]*$%%'`
+        if test "X$dir" = "X$arg"; then
+          dir="$objdir"
+        else
+          dir="$dir/$objdir"
+        fi
+
+        # This library was specified with -dlopen.
+        if test "$prev" = dlfiles; then
+          dlfiles="$dlfiles $arg"
+          if test -z "$dlname"; then
+            # If there is no dlname, we need to preload.
+            prev=dlprefiles
+          else
+            # We should not create a dependency on this library.
+            prev=
+            continue
+          fi
+        fi
+
+        # The library was specified with -dlpreopen.
+        if test "$prev" = dlprefiles; then
+          # Prefer using a static library (so that no silly _DYNAMIC symbols
+          # are required to link).
+          if test -n "$old_library"; then
+            dlprefiles="$dlprefiles $dir/$old_library"
+          else
+            dlprefiles="$dlprefiles $dir/$linklib"
+          fi
+          prev=
+        fi
+
+        if test "$build_libtool_libs" = yes && test -n "$library_names"; then
+          link_against_libtool_libs="$link_against_libtool_libs $arg"
+          if test -n "$shlibpath_var"; then
+            # Make sure the rpath contains only unique directories.
+            case "$temp_rpath " in
+            *" $dir "*) ;;
+            *) temp_rpath="$temp_rpath $dir" ;;
+            esac
+          fi
+
+         # This is the magic to use -rpath.
+          if test -n "$hardcode_libdir_flag_spec"; then
+            if test -n "$hardcode_libdir_separator"; then
+              if test -z "$hardcode_libdirs"; then
+                # Put the magic libdir with the hardcode flag.
+                hardcode_libdirs="$libdir"
+                libdir="@HARDCODE_LIBDIRS@"
+              else
+                # Just accumulate the unique libdirs.
+               case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+               *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+                 ;;
+               *)
+                 hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+                 ;;
+               esac
+                libdir=
+              fi
+            fi
+
+            if test -n "$libdir"; then
+              flag=`eval \\$echo \"$hardcode_libdir_flag_spec\"`
+
+              compile_command="$compile_command $flag"
+              finalize_command="$finalize_command $flag"
+            fi
+          elif test "$hardcode_runpath_var" = yes; then
+            # Do the same for the permanent run path.
+            case "$perm_rpath " in
+            *" $libdir "*) ;;
+            *) perm_rpath="$perm_rpath $libdir" ;;
+            esac
+          fi
+
+
+          case "$hardcode_action" in
+          immediate)
+            if test "$hardcode_direct" = no; then
+              compile_command="$compile_command $dir/$linklib"
+            elif test "$hardcode_minus_L" = no; then
+              compile_command="$compile_command -L$dir -l$name"
+            elif test "$hardcode_shlibpath_var" = no; then
+              compile_shlibpath="$compile_shlibpath$dir:"
+              compile_command="$compile_command -l$name"
+            fi
+            ;;
+
+          relink)
+            # We need an absolute path.
+            case "$dir" in
+            /*) ;;
+            *)
+              absdir=`cd "$dir" && pwd`
+              if test -z "$absdir"; then
+                $echo "$progname: cannot determine absolute directory name of \`$dir'" 1>&2
+                exit 1
+              fi
+              dir="$absdir"
+              ;;
+            esac
+
+            if test "$hardcode_direct" = yes; then
+              compile_command="$compile_command $dir/$linklib"
+            elif test "$hardcode_minus_L" = yes; then
+              compile_command="$compile_command -L$dir -l$name"
+            elif test "$hardcode_shlibpath_var" = yes; then
+              compile_shlibpath="$compile_shlibpath$dir:"
+              compile_command="$compile_command -l$name"
+            fi
+            ;;
+
+          *)
+            $echo "$progname: \`$hardcode_action' is an unknown hardcode action" 1>&2
+            exit 1
+            ;;
+          esac
+
+          # Finalize command for both is simple: just hardcode it.
+          if test "$hardcode_direct" = yes; then
+            finalize_command="$finalize_command $libdir/$linklib"
+          elif test "$hardcode_minus_L" = yes; then
+            finalize_command="$finalize_command -L$libdir -l$name"
+          elif test "$hardcode_shlibpath_var" = yes; then
+            finalize_shlibpath="$finalize_shlibpath$libdir:"
+            finalize_command="$finalize_command -l$name"
+          else
+            # We can't seem to hardcode it, guess we'll fake it.
+            finalize_command="$finalize_command -L$libdir -l$name"
+          fi
+        else
+          # Transform directly to old archives if we don't build new libraries.
+          if test -n "$pic_flag" && test -z "$old_library"; then
+            $echo "$progname: cannot find static library for \`$arg'" 1>&2
+            exit 1
+          fi
+
+         # Here we assume that one of hardcode_direct or hardcode_minus_L
+         # is not unsupported.  This is valid on all known static and
+         # shared platforms.
+         if test "$hardcode_direct" != unsupported; then
+           test -n "$old_library" && linklib="$old_library"
+           compile_command="$compile_command $dir/$linklib"
+           finalize_command="$finalize_command $dir/$linklib"
+         else
+           compile_command="$compile_command -L$dir -l$name"
+           finalize_command="$finalize_command -L$dir -l$name"
+         fi
+        fi
+       continue
+        ;;
+
+      # Some other compiler argument.
+      *)
+       # Unknown arguments in both finalize_command and compile_command need
+       # to be aesthetically quoted because they are evaled later.
+       arg=`$echo "$arg" | sed "$sed_quote_subst"`
+       case "$arg" in
+       *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \   ]*|*]*)
+         arg="\"$arg\""
+         ;;
+       esac
+        ;;
+      esac
+
+      # Now actually substitute the argument into the commands.
+      compile_command="$compile_command $arg"
+      finalize_command="$finalize_command $arg"
+    done
+
+    if test -n "$prev"; then
+      $echo "$progname: the \`$prevarg' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    oldlib=
+    oldobjs=
+    case "$output" in
+    "")
+      $echo "$progname: you must specify an output file" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+      ;;
+
+    */*)
+      $echo "$progname: output file \`$output' must have no directory components" 1>&2
+      exit 1
+      ;;
+
+    *.la)
+      # Make sure we only generate libraries of the form `libNAME.la'.
+      case "$output" in
+      lib*) ;;
+      *)
+       $echo "$progname: libtool library \`$arg' must begin with \`lib'" 1>&2
+       $echo "$help" 1>&2
+       exit 1
+       ;;
+      esac
+
+      name=`$echo "$output" | sed -e 's/\.la$//' -e 's/^lib//'`
+      libname=`eval \\$echo \"$libname_spec\"`
+
+      # All the library-specific variables (install_libdir is set above).
+      library_names=
+      old_library=
+      dlname=
+      current=0
+      revision=0
+      age=0
+
+      if test -n "$objs"; then
+        $echo "$progname: cannot build libtool library \`$output' from non-libtool objects:$objs" 2>&1
+        exit 1
+      fi
+
+      # How the heck are we supposed to write a wrapper for a shared library?
+      if test -n "$link_against_libtool_libs"; then
+        $echo "$progname: libtool library \`$output' may not depend on uninstalled libraries:$link_against_libtool_libs" 1>&2
+        exit 1
+      fi
+
+      # Add libc to deplibs on all systems.
+      deplibs="$deplibs -lc"
+
+      if test -n "$dlfiles$dlprefiles"; then
+        $echo "$progname: warning: \`-dlopen' is ignored while creating libtool libraries" 1>&2
+        # Nullify the symbol file.
+        compile_command=`$echo "$compile_command" | sed "s% @SYMFILE@%%"`
+        finalize_command=`$echo "$finalize_command" | sed "s% @SYMFILE@%%"`
+      fi
+
+      if test -z "$rpath"; then
+        $echo "$progname: you must specify an installation directory with \`-rpath'" 1>&2
+       $echo "$help" 1>&2
+        exit 1
+      fi
+
+      set dummy $rpath
+      if test $# -gt 2; then
+       $echo "$progname: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
+      fi
+      install_libdir="$2"
+
+      # Parse the version information argument.
+      IFS="${IFS=      }"; save_ifs="$IFS"; IFS=':'
+      set dummy $vinfo
+      IFS="$save_ifs"
+
+      if test -n "$5"; then
+        $echo "$progname: too many parameters to \`-version-info'" 1>&2
+        $echo "$help" 1>&2
+        exit 1
+      fi
+
+      test -n "$2" && current="$2"
+      test -n "$3" && revision="$3"
+      test -n "$4" && age="$4"
+
+      # Check that each of the things are valid numbers.
+      case "$current" in
+      0 | [1-9] | [1-9][0-9]*) ;;
+      *)
+        $echo "$progname: CURRENT \`$current' is not a nonnegative integer" 1>&2
+        $echo "$progname: \`$vinfo' is not valid version information" 1>&2
+        exit 1
+        ;;
+      esac
+
+      case "$revision" in
+      0 | [1-9] | [1-9][0-9]*) ;;
+      *)
+        $echo "$progname: REVISION \`$revision' is not a nonnegative integer" 1>&2
+        $echo "$progname: \`$vinfo' is not valid version information" 1>&2
+        exit 1
+        ;;
+      esac
+
+      case "$age" in
+      0 | [1-9] | [1-9][0-9]*) ;;
+      *)
+        $echo "$progname: AGE \`$age' is not a nonnegative integer" 1>&2
+        $echo "$progname: \`$vinfo' is not valid version information" 1>&2
+        exit 1
+        ;;
+      esac
+
+      if test $age -gt $current; then
+        $echo "$progname: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
+        $echo "$progname: \`$vinfo' is not valid version information" 1>&2
+        exit 1
+      fi
+
+      # Calculate the version variables.
+      version_vars="version_type current age revision"
+      case "$version_type" in
+      none) ;;
+
+      linux)
+        version_vars="$version_vars major versuffix"
+        major=`expr $current - $age`
+        versuffix="$major.$age.$revision"
+        ;;
+
+      osf)
+        version_vars="$version_vars versuffix verstring"
+        major=`expr $current - $age`
+        versuffix="$current.$age.$revision"
+        verstring="$versuffix"
+
+        # Add in all the interfaces that we are compatible with.
+        loop=$age
+        while test $loop != 0; do
+          iface=`expr $current - $loop`
+          loop=`expr $loop - 1`
+          verstring="$verstring:${iface}.0"
+        done
+
+        # Make executables depend on our current version.
+        verstring="$verstring:${current}.0"
+        ;;
+
+      sunos)
+        version_vars="$version_vars major versuffix"
+        major="$current"
+        versuffix="$current.$revision"
+        ;;
+
+      *)
+        $echo "$progname: unknown library version type \`$version_type'" 1>&2
+        $echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+        exit 1
+        ;;
+      esac
+
+      # Create the output directory, or remove our outputs if we need to.
+      if test -d $objdir; then
+        $show "$rm $objdir/$output $objdir/$libname.*"
+        $run $rm $objdir/$output $objdir/$libname.*
+      else
+        $show "$mkdir $objdir"
+        $run $mkdir $objdir
+       status=$?
+       if test $status -eq 0 || test -d $objdir; then :
+       else
+         exit $status
+       fi
+      fi
+
+      # Check to see if the archive will have undefined symbols.
+      if test "$allow_undefined" = yes; then
+        if test "$allow_undefined_flag" = unsupported; then
+          $echo "$progname: warning: undefined symbols not allowed in $host shared libraries" 1>&2
+          build_libtool_libs=no
+         build_old_libs=yes
+        fi
+      else
+        # Clear the flag.
+        allow_undefined_flag=
+      fi
+
+      if test "$build_libtool_libs" = yes; then
+        # Get the real and link names of the library.
+        library_names=`eval \\$echo \"$library_names_spec\"`
+        set dummy $library_names
+        realname="$2"
+        shift; shift
+
+        if test -n "$soname_spec"; then
+          soname=`eval \\$echo \"$soname_spec\"`
+        else
+          soname="$realname"
+        fi
+
+        lib="$objdir/$realname"
+       for link
+       do
+         linknames="$linknames $link"
+       done
+
+        # Use standard objects if they are PIC.
+        test -z "$pic_flag" && libobjs=`$echo "$libobjs " | sed -e 's/\.lo /.o /g' -e 's/ $//g'`
+
+        # Do each of the archive commands.
+        cmds=`eval \\$echo \"$archive_cmds\"`
+        IFS="${IFS=    }"; save_ifs="$IFS"; IFS=';'
+        for cmd in $cmds; do
+          IFS="$save_ifs"
+          $show "$cmd"
+          $run eval "$cmd" || exit $?
+        done
+        IFS="$save_ifs"
+
+        # Create links to the real library.
+        for link in $linknames; do
+          $show "(cd $objdir && $LN_S $realname $link)"
+          $run eval '(cd $objdir && $LN_S $realname $link)' || exit $?
+        done
+
+        # If -export-dynamic was specified, set the dlname.
+        if test "$export_dynamic" = yes; then
+          # On all known operating systems, these are identical.
+          dlname="$soname"
+        fi
+      fi
+      ;;
+
+    *.lo | *.o)
+      if test -n "$link_against_libtool_libs"; then
+        $echo "$progname: error: cannot link libtool libraries into reloadable objects" 1>&2
+        exit 1
+      fi
+
+      if test -n "$deplibs"; then
+        $echo "$progname: warning: \`-l' and \`-L' are ignored while creating objects" 1>&2
+      fi
+
+      if test -n "$dlfiles$dlprefiles"; then
+        $echo "$progname: warning: \`-dlopen' is ignored while creating objects" 1>&2
+        # Nullify the symbol file.
+        compile_command=`$echo "$compile_command" | sed "s% @SYMFILE@%%"`
+        finalize_command=`$echo "$finalize_command" | sed "s% @SYMFILE@%%"`
+      fi
+
+      if test -n "$rpath"; then
+        $echo "$progname: warning: \`-rpath' is ignored while creating objects" 1>&2
+      fi
+
+      if test -n "$vinfo"; then
+        $echo "$progname: warning: \`-version-info' is ignored while creating objects" 1>&2
+      fi
+
+      case "$output" in
+      *.lo)
+        if test -n "$objs"; then
+          $echo "$progname: cannot build library object \`$output' from non-libtool objects" 1>&2
+          exit 1
+        fi
+        libobj="$output"
+        obj=`$echo "$output" | sed 's/\.lo$/.o/'`
+        ;;
+      *)
+        libobj=
+        obj="$output"
+        ;;
+      esac
+
+      # Delete the old objects.
+      $run $rm $obj $libobj
+
+      # Create the old-style object.
+      reload_objs="$objs"`$echo "$libobjs " | sed -e 's/[^       ]*\.a //g' -e 's/\.lo /.o /g' -e 's/ $//g'`
+
+      output="$obj"
+      cmds=`eval \\$echo \"$reload_cmds\"`
+      IFS="${IFS=      }"; save_ifs="$IFS"; IFS=';'
+      for cmd in $cmds; do
+        IFS="$save_ifs"
+        $show "$cmd"
+        $run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+
+      # Exit if we aren't doing a library object file.
+      test -z "$libobj" && exit 0
+
+      if test "$build_libtool_libs" != yes; then
+        # Create an invalid libtool object if no PIC, so that we don't
+        # accidentally link it into a program.
+        $show "$echo timestamp > $libobj"
+        $run eval "\$echo timestamp > $libobj" || exit $?
+        exit 0
+      fi
+
+      if test -n "$pic_flag"; then
+        # Only do commands if we really have different PIC objects.
+        reload_objs="$libobjs"
+        output="$libobj"
+        cmds=`eval \\$echo \"$reload_cmds\"`
+        IFS="${IFS=    }"; save_ifs="$IFS"; IFS=';'
+        for cmd in $cmds; do
+          IFS="$save_ifs"
+          $show "$cmd"
+          $run eval "$cmd" || exit $?
+        done
+        IFS="$save_ifs"
+      else
+        # Just create a symlink.
+        $show "$LN_S $obj $libobj"
+        $run $LN_S $obj $libobj || exit 1
+      fi
+
+      exit 0
+      ;;
+
+    *)
+      if test -n "$vinfo"; then
+        $echo "$progname: warning: \`-version-info' is ignored while linking programs" 1>&2
+      fi
+
+      if test -n "$rpath"; then
+       # If the user specified any rpath flags, then add them.
+       for libdir in $rpath; do
+          if test -n "$hardcode_libdir_flag_spec"; then
+            if test -n "$hardcode_libdir_separator"; then
+              if test -z "$hardcode_libdirs"; then
+                # Put the magic libdir with the hardcode flag.
+                hardcode_libdirs="$libdir"
+                libdir="@HARDCODE_LIBDIRS@"
+              else
+                # Just accumulate the unique libdirs.
+               case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+               *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+                 ;;
+               *)
+                 hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+                 ;;
+               esac
+                libdir=
+              fi
+            fi
+
+            if test -n "$libdir"; then
+              flag=`eval \\$echo \"$hardcode_libdir_flag_spec\"`
+
+              compile_command="$compile_command $flag"
+              finalize_command="$finalize_command $flag"
+            fi
+          elif test "$hardcode_runpath_var" = yes; then
+            case "$perm_rpath " in
+            *" $libdir "*) ;;
+            *) perm_rpath="$perm_rpath $libdir" ;;
+            esac
+          fi
+       done
+      fi
+
+      # Substitute the hardcoded libdirs into the compile commands.
+      if test -n "$hardcode_libdir_separator"; then
+       compile_command=`$echo "$compile_command" | sed "s%@HARDCODE_LIBDIRS@%$hardcode_libdirs%g"`
+       finalize_command=`$echo "$finalize_command" | sed "s%@HARDCODE_LIBDIRS@%$hardcode_libdirs%g"`
+      fi
+
+      if test -n "$libobjs" && test "$build_old_libs" = yes; then
+        # Transform all the library objects into standard objects.
+        compile_command=`$echo "$compile_command " | sed -e 's/\.lo /.o /g' -e 's/ $//'`
+        finalize_command=`$echo "$finalize_command " | sed -e 's/\.lo /.o /g' -e 's/ $//'`
+      fi
+
+      if test "$export_dynamic" = yes && test -n "$NM" && test -n "$global_symbol_pipe"; then
+        dlsyms="${output}S.c"
+      else
+        dlsyms=
+      fi
+
+      if test -n "$dlsyms"; then
+        # Add our own program objects to the preloaded list.
+        dlprefiles=`$echo "$objs$dlprefiles " | sed -e 's/\.lo /.o /g' -e 's/ $//'`
+
+       # Discover the nlist of each of the dlfiles.
+        nlist="$objdir/${output}.nm"
+
+       if test -d $objdir; then
+         $show "$rm $nlist ${nlist}T"
+         $run $rm "$nlist" "${nlist}T"
+       else
+         $show "$mkdir $objdir"
+         $run $mkdir $objdir
+         status=$?
+         if test $status -eq 0 || test -d $objdir; then :
+         else
+           exit $status
+         fi
+       fi
+
+        for arg in $dlprefiles; do
+         $show "extracting global C symbols from \`$arg'"
+         $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+        done
+
+        # Parse the name list into a source file.
+        $show "creating $objdir/$dlsyms"
+        if test -z "$run"; then
+         # Make sure we at least have an empty file.
+         test -f "$nlist" || : > "$nlist"
+
+         # Try sorting and uniquifying the output.
+         if sort "$nlist" | uniq > "$nlist"T; then
+           mv -f "$nlist"T "$nlist"
+           wcout=`wc "$nlist" 2>/dev/null`
+           count=`$echo "$wcout" | sed 's/^[   ]*\([0-9][0-9]*\).*$/\1/'`
+           (test "$count" -ge 0) 2>/dev/null || count=-1
+         else
+           $rm "$nlist"T
+           count=-1
+         fi
+
+         case "$dlsyms" in
+         "") ;;
+         *.c)
+           cat <<EOF > "$objdir/$dlsyms"
+/* $dlsyms - symbol resolution table for \`$output' dlsym emulation. */
+/* Generated by $PROGRAM - GNU $PACKAGE $VERSION */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Prevent the only kind of declaration conflicts we can make. */
+#define dld_preloaded_symbol_count some_other_symbol
+#define dld_preloaded_symbols some_other_symbol
+
+/* External symbol declarations for the compiler. */
+EOF
+           if test -f "$nlist"; then
+             sed -e 's/^.* \(.*\)$/extern char \1;/' < "$nlist" >> "$objdir/$dlsyms"
+           else
+             $echo '/* NONE */' >> "$objdir/$dlsyms"
+EOF
+           fi
+
+           cat <<EOF >> "$objdir/$dlsyms"
+
+#undef dld_preloaded_symbol_count
+#undef dld_preloaded_symbols
+
+#if defined (__STDC__) && __STDC__
+# define __ptr_t void *
+#else
+# define __ptr_t char *
+#endif
+
+/* The number of symbols in dld_preloaded_symbols, -1 if unsorted. */
+int dld_preloaded_symbol_count = $count;
+
+/* The mapping between symbol names and symbols. */
+struct {
+  char *name;
+  __ptr_t address;
+}
+dld_preloaded_symbols[] =
+{
+EOF
+
+           if test -f "$nlist"; then
+             sed 's/^\(.*\) \(.*\)$/  {"\1", \&\2},/' < "$nlist" >> "$objdir/$dlsyms"
+           fi
+
+           cat <<\EOF >> "$objdir/$dlsyms"
+  {0},
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+           ;;
+
+         *)
+           echo "$progname: unknown suffix for \`$dlsyms'" 1>&2
+           exit 1
+           ;;
+         esac
+        fi
+
+        # Now compile the dynamic symbol file.
+        $show "(cd $objdir && $CC -c$no_builtin_flag \"$dlsyms\")"
+        $run eval '(cd $objdir && $CC -c$no_builtin_flag "$dlsyms")' || exit $?
+
+        # Transform the symbol file into the correct name.
+        compile_command=`$echo "$compile_command" | sed "s%@SYMFILE@%$objdir/${output}S.o%"`
+        finalize_command=`$echo "$finalize_command" | sed "s%@SYMFILE@%$objdir/${output}S.o%"`
+      elif test "$export_dynamic" != yes; then
+        test -n "$dlfiles$dlprefiles" && $echo "$progname: warning: \`-dlopen' and \`-dlpreopen' are ignored without \`-export-dynamic'" 1>&2
+      else
+        # We keep going just in case the user didn't refer to
+        # dld_preloaded_symbols.  The linker will fail if global_symbol_pipe
+        # really was required.
+        $echo "$progname: not configured to extract global symbols from dlpreopened files" 1>&2
+
+        # Nullify the symbol file.
+        compile_command=`$echo "$compile_command" | sed "s% @SYMFILE@%%"`
+        finalize_command=`$echo "$finalize_command" | sed "s% @SYMFILE@%%"`
+      fi
+
+      if test -z "$link_against_libtool_libs" || test "$build_libtool_libs" != yes; then
+        # Replace the output file specification.
+        compile_command=`$echo "$compile_command" | sed 's%@OUTPUT@%'"$output"'%g'`
+        finalize_command=`$echo "$finalize_command" | sed 's%@OUTPUT@%'"$output"'%g'`
+
+        # We have no uninstalled library dependencies, so finalize right now.
+        $show "$compile_command"
+        $run eval "$compile_command"
+        exit $?
+      fi
+
+      # Replace the output file specification.
+      compile_command=`$echo "$compile_command" | sed 's%@OUTPUT@%'"$objdir/$output"'%g'`
+      finalize_command=`$echo "$finalize_command" | sed 's%@OUTPUT@%'"$objdir/$output"'T%g'`
+
+      # Create the binary in the object directory, then wrap it.
+      if test -d $objdir; then :
+      else
+        $show "$mkdir $objdir"
+        $run $mkdir $objdir || exit $?
+      fi
+
+      if test -n "$shlibpath_var"; then
+        # We should set the shlibpath_var
+        rpath=
+        for dir in $temp_rpath; do
+          case "$dir" in
+          /*)
+            # Absolute path.
+            rpath="$rpath$dir:"
+            ;;
+          *)
+            # Relative path: add a thisdir entry.
+            rpath="$rpath\$thisdir/$dir:"
+            ;;
+          esac
+        done
+        temp_rpath="$rpath"
+      fi
+
+      # Delete the old output file.
+      $run $rm $output
+
+      if test -n "$compile_shlibpath"; then
+        compile_command="$shlibpath_var=\"$compile_shlibpath\$$shlibpath_var\" $compile_command"
+      fi
+      if test -n "$finalize_shlibpath"; then
+        finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+      fi
+
+      if test -n "$perm_rpath"; then
+        # We should set the runpath_var.
+        rpath=
+        for dir in $perm_rpath; do
+          rpath="$rpath$dir:"
+        done
+        compile_command="$runpath_var=\"$rpath\$$runpath_var\" $compile_command"
+        finalize_command="$runpath_var=\"$rpath\$$runpath_var\" $finalize_command"
+      fi
+
+      case "$hardcode_action" in
+      relink)
+        # AGH! Flame the AIX and HP-UX people for me, will ya?
+        $echo "$progname: warning: using a buggy system linker" 1>&2
+        $echo "$progname: relinking will be required before \`$output' can be installed" 1>&2
+        ;;
+      esac
+
+      $show "$compile_command"
+      $run eval "$compile_command" || exit $?
+
+      # Now create the wrapper script.
+      $show "creating $output"
+
+      # Quote the finalize command for shipping.
+      finalize_command=`$echo "$finalize_command" | sed "$sed_quote_subst"`
+
+      # Only actually do things if our run command is non-null.
+      if test -z "$run"; then
+        $rm $output
+        trap "$rm $output; exit 1" 1 2 15
+
+        cat > $output <<EOF
+#! /bin/sh
+
+# $output - temporary wrapper script for $objdir/$output
+# Generated by ltmain.sh - GNU $PACKAGE $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of \``pwd`'.
+# If it is, it will not operate correctly.
+
+# This environment variable determines our operation mode.
+if test "\$libtool_install_magic" = "$magic"; then
+  # install mode needs the following variables:
+  link_against_libtool_libs='$link_against_libtool_libs'
+  finalize_command="$finalize_command"
+else
+  # When we are sourced in execute mode, \$file and \$echo are already set.
+  if test "\$libtool_execute_magic" = "$magic"; then :
+  else
+    echo='$echo'
+    file="\$0"
+  fi
+
+  # Find the directory that this script lives in.
+  thisdir=\`\$echo "\$file" | sed 's%/[^/]*$%%'\`
+  test "x\$thisdir" = "x\$file" && thisdir=.
+
+  # Follow symbolic links until we get to the real thisdir.
+  file=\`ls -ld "\$file" | sed -n 's/.*-> //p'\`
+  while test -n "\$file"; do
+    destdir=\`\$echo "\$file" | sed 's%/[^/]*\$%%'\`
+
+    # If there was a directory component, then change thisdir.
+    if test "x\$destdir" != "x\$file"; then
+      case "\$destdir" in
+      /*) thisdir="\$destdir" ;;
+      *) thisdir="\$thisdir/\$destdir" ;;
+      esac
+    fi
+
+    file=\`\$echo "\$file" | sed 's%^.*/%%'\`
+    file=\`ls -ld "\$thisdir/\$file" | sed -n 's/.*-> //p'\`
+  done
+
+  # Try to get the absolute directory name.
+  absdir=\`cd "\$thisdir" && pwd\`
+  test -n "\$absdir" && thisdir="\$absdir"
+
+  progdir="\$thisdir/$objdir"
+  program='$output'
+
+  if test -f "\$progdir/\$program"; then
+EOF
+
+        # Export our shlibpath_var if we have one.
+        if test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+          cat >> $output <<EOF
+    # Add our own library path to $shlibpath_var
+    $shlibpath_var="$temp_rpath\$$shlibpath_var"
+
+    # Some systems cannot cope with colon-terminated $shlibpath_var
+    $shlibpath_var=\`\$echo \$$shlibpath_var | sed -e 's/:*\$//'\`
+
+    export $shlibpath_var
+
+EOF
+        fi
+
+        cat >> $output <<EOF
+    if test "\$libtool_execute_magic" != "$magic"; then
+      # Run the actual program with our arguments.
+      args=
+      for arg
+      do
+        # Quote arguments (to preserve shell metacharacters).
+       sed_quote_subst='$sed_quote_subst'
+       arg=\`\$echo "\$arg" | sed "\$sed_quote_subst"\`
+        args="\$args \\"\$arg\\""
+      done
+
+      # Export the path to the program.
+      PATH="\$progdir:\$PATH"
+      export PATH
+
+      eval "exec \$program \$args"
+
+      \$echo "\$0: cannot exec \$program \$args"
+      exit 1
+    fi
+  else
+    # The program doesn't exist.
+    \$echo "\$0: error: \$progdir/\$program does not exist" 1>&2
+    \$echo "This script is just a wrapper for \$program." 1>&2
+    \$echo "See the $PACKAGE documentation for more information." 1>&2
+    exit 1
+  fi
+fi
+EOF
+        chmod +x $output
+      fi
+      exit 0
+      ;;
+    esac
+
+
+    # See if we need to build an old-fashioned archive.
+    if test "$build_old_libs" = "yes"; then
+      # Now set the variables for building old libraries.
+      oldlib="$objdir/$libname.a"
+
+      # Transform .lo files to .o files.
+      oldobjs="$objs"`$echo "$libobjs " | sed -e 's/[^   ]*\.a //g' -e 's/\.lo /.o /g' -e 's/ $//g'`
+
+      if test -d "$objdir"; then
+        $show "$rm $oldlib"
+        $run $rm $oldlib
+      else
+        $show "$mkdir $objdir"
+        $run $mkdir $objdir
+      fi
+
+      # Do each command in the archive commands.
+      if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+       cmds=`eval \\$echo \"$old_archive_from_new_cmds\"`
+      else
+       cmds=`eval \\$echo \"$old_archive_cmds\"`
+      fi
+      IFS="${IFS=      }"; save_ifs="$IFS"; IFS=';'
+      for cmd in $cmds; do
+        IFS="$save_ifs"
+        $show "$cmd"
+        $run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+    fi
+
+    # Now create the libtool archive.
+    case "$output" in
+    *.la)
+      old_library=
+      test "$build_old_libs" = yes && old_library="$libname.a"
+
+      $show "creating $output"
+
+      # Only create the output if not a dry run.
+      if test -z "$run"; then
+        cat > $output <<EOF
+# $output - a libtool library file
+# Generated by ltmain.sh - GNU $PACKAGE $VERSION
+
+# The name that we can dlopen(3).
+dlname='$dlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'
+EOF
+      fi
+
+      # Do a symbolic link so that the libtool archive can be found in
+      # LD_LIBRARY_PATH before the program is installed.
+      $show "(cd $objdir && $LN_S ../$output $output)"
+      $run eval "(cd $objdir && $LN_S ../$output $output)" || exit 1
+      ;;
+    esac
+    exit 0
+    ;;
+
+  # libtool install mode
+  install)
+    progname="$progname: install"
+
+    # There may be an optional /bin/sh argument at the beginning of
+    # install_prog (especially on Windows NT).
+    if test "$nonopt" = "$SHELL"; then
+      # Aesthetically quote it.
+      arg=`$echo "$nonopt" | sed "$sed_quote_subst"`
+      case "$arg" in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*)
+       arg="\"$arg\""
+       ;;
+      esac
+      install_prog="$arg "
+      arg="$1"
+      shift
+    else
+      install_prog=
+      arg="$nonopt"
+    fi
+
+    # The real first argument should be the name of the installation program.
+    # Aesthetically quote it.
+    arg=`$echo "$arg" | sed "$sed_quote_subst"`
+    case "$arg" in
+    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \      ]*|*]*)
+      arg="\"$arg\""
+      ;;
+    esac
+    install_prog="$install_prog$arg"
+
+    # We need to accept at least all the BSD install flags.
+    dest=
+    files=
+    opts=
+    prev=
+    install_type=
+    isdir=
+    stripme=
+    for arg
+    do
+      if test -n "$dest"; then
+        files="$files $dest"
+        dest="$arg"
+        continue
+      fi
+
+      case "$arg" in
+      -d) isdir=yes ;;
+      -f) prev="-f" ;;
+      -g) prev="-g" ;;
+      -m) prev="-m" ;;
+      -o) prev="-o" ;;
+      -s)
+        stripme=" -s"
+        continue
+        ;;
+      -*) ;;
+
+      *)
+        # If the previous option needed an argument, then skip it.
+        if test -n "$prev"; then
+          prev=
+        else
+          dest="$arg"
+          continue
+        fi
+        ;;
+      esac
+
+      # Aesthetically quote the argument.
+      arg=`$echo "$arg" | sed "$sed_quote_subst"`
+      case "$arg" in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*)
+       arg="\"$arg\""
+       ;;
+      esac
+      install_prog="$install_prog $arg"
+    done
+
+    if test -z "$install_prog"; then
+      $echo "$progname: you must specify an install program" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    if test -n "$prev"; then
+      $echo "$progname: the \`$prev' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    if test -z "$files"; then
+      if test -z "$dest"; then
+        $echo "$progname: no file or destination specified" 1>&2
+      else
+        $echo "$progname: you must specify a destination" 1>&2
+      fi
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    # Strip any trailing slash from the destination.
+    dest=`$echo "$dest" | sed 's%/$%%'`
+
+    # Check to see that the destination is a directory.
+    test -d "$dest" && isdir=yes
+    if test -n "$isdir"; then
+      destdir="$dest"
+      destname=
+    else
+      destdir=`$echo "$dest" | sed 's%/[^/]*$%%'`
+      test "X$destdir" = "X$dest" && destdir=.
+      destname=`$echo "$dest" | sed 's%^.*/%%'`
+
+      # Not a directory, so check to see that there is only one file specified.
+      set dummy $files
+      if test $# -gt 2; then
+        $echo "$progname: \`$dest' is not a directory" 1>&2
+        $echo "$help" 1>&2
+        exit 1
+      fi
+    fi
+    case "$destdir" in
+    /*) ;;
+    *)
+      for file in $files; do
+        case "$file" in
+        *.lo) ;;
+        *)
+          $echo "$progname: \`$destdir' must be an absolute directory name" 1>&2
+          $echo "$help" 1>&2
+          exit 1
+          ;;
+        esac
+      done
+      ;;
+    esac
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    staticlibs=
+    future_libdirs=
+    current_libdirs=
+    for file in $files; do
+
+      # Do each installation.
+      case "$file" in
+      *.a)
+        # Do the static libraries later.
+        staticlibs="$staticlibs $file"
+        ;;
+
+      *.la)
+        # Check to see that this really is a libtool archive.
+        if egrep '^# Generated by ltmain.sh' $file >/dev/null 2>&1; then :
+        else
+          $echo "$progname: \`$file' is not a valid libtool archive" 1>&2
+          $echo "$help" 1>&2
+          exit 1
+        fi
+
+        library_names=
+        old_library=
+        # If there is no directory component, then add one.
+        case "$file" in
+        */*) . $file ;;
+        *) . ./$file ;;
+        esac
+
+        # Add the libdir to current_libdirs if it is the destination.
+        if test "X$destdir" = "X$libdir"; then
+          case "$current_libdirs " in
+          *" $libdir "*) ;;
+          *) current_libdirs="$current_libdirs $libdir" ;;
+          esac
+        else
+          # Note the libdir as a future libdir.
+          case "$future_libdirs " in
+          *" $libdir "*) ;;
+          *) future_libdirs="$future_libdirs $libdir" ;;
+          esac
+        fi
+
+        dir="`$echo "$file" | sed 's%/[^/]*$%%'`/"
+        test "X$dir" = "X$file/" && dir=
+        dir="$dir$objdir"
+
+        # See the names of the shared library.
+        set dummy $library_names
+        if test -n "$2"; then
+          realname="$2"
+          shift
+          shift
+
+          # Install the shared library and build the symlinks.
+          $show "$install_prog $dir/$realname $destdir/$realname"
+          $run eval "$install_prog $dir/$realname $destdir/$realname" || exit $?
+          test "X$dlname" = "X$realname" && dlname=
+
+          # Support stripping libraries.
+          if test -n "$stripme"; then
+            if test -n "$striplib"; then
+              $show "$striplib $destdir/$realname"
+              $run $striplib $destdir/$realname || exit $?
+            else
+              $echo "$progname: warning: no library stripping program" 1>&2
+            fi
+          fi
+
+          if test $# -gt 0; then
+            # Delete the old symlinks.
+            rmcmd="$rm"
+            for linkname
+            do
+              rmcmd="$rmcmd $destdir/$linkname"
+            done
+            $show "$rmcmd"
+            $run $rmcmd
+
+            # ... and create new ones.
+            for linkname
+            do
+              test "X$dlname" = "X$linkname" && dlname=
+              $show "(cd $destdir && $LN_S $realname $linkname)"
+              $run eval "(cd $destdir && $LN_S $realname $linkname)"
+            done
+          fi
+
+          if test -n "$dlname"; then
+            # Install the dynamically-loadable library.
+            $show "$install_prog $dir/$dlname $destdir/$dlname"
+            $run eval "$install_prog $dir/$dlname $destdir/$dlname" || exit $?
+          fi
+
+          # Do each command in the postinstall commands.
+          lib="$destdir/$realname"
+          cmds=`eval \\$echo \"$postinstall_cmds\"`
+          IFS="${IFS=  }"; save_ifs="$IFS"; IFS=';'
+          for cmd in $cmds; do
+            IFS="$save_ifs"
+            $show "$cmd"
+            $run eval "$cmd" || exit $?
+          done
+          IFS="$save_ifs"
+        fi
+
+        # Install the pseudo-library for information purposes.
+        name=`$echo "$file" | sed 's%^.*/%%'`
+        $show "$install_prog $file $destdir/$name"
+        $run eval "$install_prog $file $destdir/$name" || exit $?
+
+        # Maybe install the static library, too.
+        test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+        ;;
+
+      *.lo)
+        # Install (i.e. copy) a libtool object.
+
+        # Figure out destination file name, if it wasn't already specified.
+        if test -n "$destname"; then
+          destfile="$destdir/$destname"
+        else
+          destfile=`$echo "$file" | sed 's%^.*/%%'`
+          destfile="$destdir/$destfile"
+        fi
+
+        # Deduce the name of the destination old-style object file.
+        case "$destfile" in
+        *.lo)
+          staticdest=`$echo "$destfile" | sed 's/\.lo$/\.o/'`
+          ;;
+        *.o)
+          staticdest="$destfile"
+          destfile=
+          ;;
+        *)
+          $echo "$progname: cannot copy a libtool object to \`$destfile'" 1>&2
+          $echo "$help" 1>&2
+          exit 1
+          ;;
+        esac
+
+        # Install the libtool object if requested.
+        if test -n "$destfile"; then
+          $show "$install_prog $file $destfile"
+          $run eval "$install_prog $file $destfile" || exit $?
+        fi
+
+        # Install the old object if enabled.
+        if test "$build_old_libs" = yes; then
+          # Deduce the name of the old-style object file.
+          staticobj=`$echo "$file" | sed 's/\.lo$/\.o/'`
+
+          $show "$install_prog $staticobj $staticdest"
+          $run eval "$install_prog \$staticobj \$staticdest" || exit $?
+        fi
+        exit 0
+        ;;
+
+      *)
+        # Do a test to see if this is really a libtool program.
+        if egrep '^# Generated by ltmain.sh' $file >/dev/null 2>&1; then
+          link_against_libtool_libs=
+          finalize_command=
+
+          # If there is no directory component, then add one.
+          case "$file" in
+          */*) . $file ;;
+          *) . ./$file ;;
+          esac
+
+          # Check the variables that should have been set.
+          if test -z "$link_against_libtool_libs" || test -z "$finalize_command"; then
+            $echo "$progname: invalid libtool wrapper script \`$file'" 1>&2
+            exit 1
+          fi
+
+          finalize=yes
+          for lib in $link_against_libtool_libs; do
+            # Check to see that each library is installed.
+            libdir=
+            if test -f "$lib"; then
+              # If there is no directory component, then add one.
+              case "$lib" in
+              */*) . $lib ;;
+              *) . ./$lib ;;
+              esac
+            fi
+            libfile="$libdir/`$echo "$lib" | sed 's%^.*/%%g'`"
+            if test -z "$libdir"; then
+              $echo "$progname: warning: \`$lib' contains no -rpath information" 1>&2
+            elif test -f "$libfile"; then :
+            else
+              $echo "$progname: warning: \`$lib' has not been installed in \`$libdir'" 1>&2
+              finalize=no
+            fi
+          done
+
+          if test "$hardcode_action" = relink; then
+            if test "$finalize" = yes; then
+              $echo "$progname: warning: relinking \`$file' on behalf of your buggy system linker" 1>&2
+              $show "$finalize_command"
+              if $run eval "$finalize_command"; then :
+              else
+                $echo "$progname: error: relink \`$file' with the above command before installing it" 1>&2
+                continue
+              fi
+              file="$objdir/$file"T
+            else
+              $echo "$progname: warning: cannot relink \`$file' on behalf of your buggy system linker" 1>&2
+            fi
+          else
+            # Install the binary that we compiled earlier.
+           file=`$echo "$file" | sed "s%\([^/]*\)$%$objdir/\1%"`
+          fi
+        fi
+
+        $show "$install_prog$stripme $file $dest"
+        $run eval "$install_prog\$stripme \$file \$dest" || exit $?
+        ;;
+      esac
+    done
+
+    for file in $staticlibs; do
+      name=`$echo "$file" | sed 's%^.*/%%'`
+
+      # Set up the ranlib parameters.
+      oldlib="$destdir/$name"
+
+      $show "$install_prog $file $oldlib"
+      $run eval "$install_prog \$file \$oldlib" || exit $?
+
+      # Support stripping libraries.
+      if test -n "$stripme"; then
+        if test -n "$old_striplib"; then
+          $show "$old_striplib $oldlib"
+          $run $old_striplib $oldlib || exit $?
+        else
+          $echo "$progname: warning: no static library stripping program" 1>&2
+        fi
+      fi
+
+      # Do each command in the postinstall commands.
+      cmds=`eval \\$echo \"$old_postinstall_cmds\"`
+      IFS="${IFS=      }"; save_ifs="$IFS"; IFS=';'
+      for cmd in $cmds; do
+        IFS="$save_ifs"
+        $show "$cmd"
+        $run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+    done
+
+    if test -n "$future_libdirs"; then
+      $echo "$progname: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2
+    fi
+
+    if test -n "$current_libdirs"; then
+      # Maybe just do a dry run.
+      test -n "$run" && current_libdirs=" -n$current_libdirs"
+      exec $SHELL $0 --finish$current_libdirs
+      exit 1
+    fi
+
+    exit 0
+    ;;
+
+  # libtool finish mode
+  finish)
+    progname="$progname: finish"
+    libdirs="$nonopt"
+
+    if test -n "$finish_cmds" && test -n "$libdirs"; then
+      for dir
+      do
+        libdirs="$libdirs $dir"
+      done
+
+      for libdir in $libdirs; do
+        # Do each command in the postinstall commands.
+        cmds=`eval \\$echo \"$finish_cmds\"`
+        IFS="${IFS=    }"; save_ifs="$IFS"; IFS=';'
+        for cmd in $cmds; do
+          IFS="$save_ifs"
+          $show "$cmd"
+          $run eval "$cmd"
+        done
+        IFS="$save_ifs"
+      done
+    fi
+
+    $echo "To link against installed libraries in LIBDIR, users may have to:"
+    if test -n "$shlibpath_var"; then
+      $echo "   - add LIBDIR to their \`$shlibpath_var' environment variable"
+    fi
+    $echo "   - use the \`-LLIBDIR' linker flag"
+    exit 0
+    ;;
+
+  # libtool execute mode
+  execute)
+    progname="$progname: execute"
+
+    # The first argument is the command name.
+    cmd="$nonopt"
+    if test -z "$cmd"; then
+      $echo "$progname: you must specify a COMMAND" 1>&2
+      $echo "$help"
+      exit 1
+    fi
+
+    # Handle -dlopen flags immediately.
+    for file in $execute_dlfiles; do
+      if test -f "$file"; then :
+      else
+       $echo "$progname: \`$file' is not a file" 1>&2
+       $echo "$help" 1>&2
+       exit 1
+      fi
+
+      dir=
+      case "$file" in
+      *.la)
+        # Check to see that this really is a libtool archive.
+        if egrep '^# Generated by ltmain.sh' $file >/dev/null 2>&1; then :
+        else
+          $echo "$progname: \`$lib' is not a valid libtool archive" 1>&2
+          $echo "$help" 1>&2
+          exit 1
+        fi
+
+       # Read the libtool library.
+       dlname=
+       library_names=
+
+        # If there is no directory component, then add one.
+       case "$file" in
+       */*) . $file ;;
+        *) . ./$file ;;
+       esac
+
+       # Skip this library if it cannot be dlopened.
+       if test -z "$dlname"; then
+         # Warn if it was a shared library.
+         test -n "$library_names" && $echo "$progname: warning: \`$file' was not linked with \`-export-dynamic'"
+         continue
+       fi
+
+       dir=`$echo "$file" | sed 's%/[^/]*$%%'`
+       test "X$dir" = "X$file" && dir=.
+
+       if test -f "$dir/$objdir/$dlname"; then
+         dir="$dir/$objdir"
+       else
+         $echo "$progname: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
+         exit 1
+       fi
+       ;;
+
+      *.lo)
+       # Just add the directory containing the .lo file.
+       dir=`$echo "$file" | sed 's%/[^/]*$%%'`
+       test "X$dir" = "X$file" && dir=.
+       ;;
+
+      *)
+       $echo "$progname: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2
+        continue
+       ;;
+      esac
+
+      # Get the absolute pathname.
+      absdir=`cd "$dir" && pwd`
+      test -n "$absdir" && dir="$absdir"
+
+      # Now add the directory to shlibpath_var.
+      if eval "test -z \"\$$shlibpath_var\""; then
+       eval "$shlibpath_var=\"\$dir\""
+      else
+       eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+      fi
+    done
+
+    # This variable tells wrapper scripts just to set shlibpath_var
+    # rather than running their programs.
+    libtool_execute_magic="$magic"
+
+    # Check if any of the arguments is a wrapper script.
+    args=
+    for file
+    do
+      case "$file" in
+      -*) ;;
+      *)
+       if egrep '^# Generated by ltmain.sh' $file >/dev/null 2>&1; then
+         # If there is no directory component, then add one.
+         case "$file" in
+         */*) . $file ;;
+         *) . ./$file ;;
+         esac
+
+         # Transform arg to wrapped name.
+         file="$progdir/$program"
+       fi
+        ;;
+      esac
+      # Quote arguments (to preserve shell metacharacters).
+      file=`$echo "$file" | sed "$sed_quote_subst"`
+      args="$args \"$file\""
+    done
+
+    if test -z "$run"; then
+      # Export the shlibpath_var.
+      eval "export $shlibpath_var"
+
+      # Now actually exec the command.
+      eval "exec \$cmd$args"
+
+      $echo "$progname: cannot exec \$cmd$args"
+      exit 1
+    else
+      # Display what would be done.
+      eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\""
+      $echo "export $shlibpath_var"
+      $echo "$cmd$args"
+      exit 0
+    fi
+    ;;
+
+  # libtool uninstall mode
+  uninstall)
+    progname="$progname: uninstall"
+    rm="$nonopt"
+    files=
+
+    for arg
+    do
+      case "$arg" in
+      -*) rm="$rm $arg" ;;
+      *) files="$files $arg" ;;
+      esac
+    done
+
+    if test -z "$rm"; then
+      $echo "$progname: you must specify an RM program" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    for file in $files; do
+      dir=`$echo "$file" | sed -e 's%/[^/]*$%%'`
+      test "X$dir" = "X$file" && dir=.
+      name=`$echo "$file" | sed -e 's%^.*/%%'`
+
+      rmfiles="$file"
+
+      case "$name" in
+      *.la)
+        # Possibly a libtool archive, so verify it.
+        if egrep '^# Generated by ltmain.sh' $file >/dev/null 2>&1; then
+          . $dir/$name
+
+          # Delete the libtool libraries and symlinks.
+          for n in $library_names; do
+            rmfiles="$rmfiles $dir/$n"
+            test "X$n" = "X$dlname" && dlname=
+          done
+          test -n "$dlname" && rmfiles="$rmfiles $dir/$dlname"
+          test -n "$old_library" && rmfiles="$rmfiles $dir/$old_library"
+
+          # FIXME: should reinstall the best remaining shared library.
+        fi
+        ;;
+
+      *.lo)
+        if test "$build_old_libs" = yes; then
+          oldobj=`$echo "$name" | sed 's/\.lo$/\.o/'`
+          rmfiles="$rmfiles $dir/$oldobj"
+        fi
+        ;;
+      esac
+
+      $show "$rm $rmfiles"
+      $run $rm $rmfiles
+    done
+    exit 0
+    ;;
+
+  "")
+    $echo "$progname: you must specify a MODE" 1>&2
+    $echo "$generic_help" 1>&2
+    exit 1
+    ;;
+  esac
+
+  $echo "$progname: invalid operation mode \`$mode'" 1>&2
+  $echo "$generic_help" 1>&2
+  exit 1
+fi # test -z "$show_help"
+
+# We need to display help for each of the modes.
+case "$mode" in
+"") cat <<EOF
+Usage: $progname [OPTION]... [MODE-ARG]...
+
+Provide generalized library-building support services.
+
+-n, --dry-run         display commands without modifying any files
+    --features        display configuration information and exit
+    --finish          same as \`--mode=finish'
+    --help            display this help message and exit
+    --mode=MODE       use operation mode MODE [default=inferred from MODE-ARGS]
+    --quiet           same as \`--silent'
+    --silent          don't print informational messages
+    --version         print version information
+
+MODE must be one of the following:
+
+      compile         compile a source file into a libtool object
+      execute         automatically set library path, then run a program
+      finish          complete the installation of libtool libraries
+      install         install libraries or executables
+      link            create a library or an executable
+      uninstall       remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE.  Try \`$progname --help --mode=MODE' for
+a more detailed description of MODE.
+EOF
+  ;;
+
+compile)
+  cat <<EOF
+Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'.
+EOF
+  ;;
+
+execute)
+  cat <<EOF
+Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+  -dlopen FILE      add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments.
+EOF
+  ;;
+
+finish)
+  cat <<EOF
+Usage: $progname [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges.  Use
+the \`--dry-run' option if you just want to see what would be executed.
+EOF
+  ;;
+
+install)
+  cat <<EOF
+Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command.  The first component should be
+either the \`install' or \`cp' program.
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized).
+EOF
+  ;;
+
+link)
+  cat <<EOF
+Usage: $progname [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+  -all-static       do not do any dynamic linking at all
+  -allow-undefined  allow a libtool library to reference undefined symbols
+  -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
+  -dlpreopen FILE   link in FILE and add its symbols to dld_preloaded_symbols
+  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+  -LLIBDIR          search LIBDIR for required installed libraries
+  -lNAME            OUTPUT-FILE requires the installed library libNAME
+  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
+  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
+  -static           do not do any dynamic linking of libtool libraries
+  -version-info CURRENT[:REVISION[:AGE]]
+                    specify library version info [each variable defaults to 0]
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename.  Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created, only
+library objects (\`.lo' files) may be specified, and \`-rpath' is required.
+
+If OUTPUT-FILE ends in \`.a', then a standard library is created using \`ar'
+and \`ranlib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.o', then a reloadable object file is
+created, otherwise an executable program is created.
+EOF
+  ;;
+
+uninstall)
+  cat <<EOF
+Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM.
+EOF
+  ;;
+
+*)
+  $echo "$progname: invalid operation mode \`$mode'" 1>&2
+  $echo "$help" 1>&2
+  exit 1
+  ;;
+esac
+
+$echo
+$echo "Try \`$progname --help' for more information about other modes."
+
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/glib/missing b/glib/missing
new file mode 100755 (executable)
index 0000000..e4b838c
--- /dev/null
@@ -0,0 +1,134 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+# Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+# Franc,ois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try \`$0 --help' for more information"
+  exit 1
+fi
+
+case "$1" in
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+
+Supported PROGRAM values:
+  aclocal      touch file \`aclocal.m4'
+  autoconf     touch file \`configure'
+  autoheader   touch file \`config.h.in'
+  automake     touch all \`Makefile.in' files
+  bison        touch file \`y.tab.c'
+  makeinfo     touch the output file
+  yacc         touch file \`y.tab.c'"
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing - GNU libit 0.0"
+    ;;
+
+  -*)
+    echo 1>&2 "$0: Unknown \`$1' option"
+    echo 1>&2 "Try \`$0 --help' for more information"
+    exit 1
+    ;;
+
+  aclocal)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  It should be needed only if
+         you modified \`acinclude.m4' or \`configure.in'.  You might want
+         to install the \`Automake' and \`Perl' packages.  Grab them from
+         any GNU archive site."
+    touch aclocal.m4
+    ;;
+
+  autoconf)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  It should be needed only if
+         you modified \`configure.in'.  You might want to install the
+         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
+         archive site."
+    touch configure
+    ;;
+
+  autoheader)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  It should be needed only if
+         you modified \`acconfig.h' or \`configure.in'.  You might want
+         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
+         from any GNU archive site."
+    touch config.h.in
+    ;;
+
+  automake)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  It should be needed only if
+         you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'.
+         You might want to install the \`Automake' and \`Perl' packages.
+         Grab them from any GNU archive site."
+    find . -type f -name Makefile.am -print \
+      | sed 's/^\(.*\).am$/touch \1.in/' \
+      | sh
+    ;;
+
+  bison|yacc)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  It should be needed only if
+         your modified any \`.y' file.  For being effective, your
+         modifications might require the \`Bison' package.  Grab it from
+         any GNU archive site."
+    touch y.tab.c
+    ;;
+
+  makeinfo)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  It should be needed only if
+         you modified a \`.texi' or \`.texinfo' file, or any other file
+         indirectly affecting the aspect of the manual.  The spurious
+         call might also be the consequence of using a buggy \`make' (AIX,
+         DU, IRIX).  You might want to install the \`Texinfo' package or
+         the \`GNU make' package.  Grab either from any GNU archive site."
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+      file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+      file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
+    fi
+    touch $file
+    ;;
+
+  *)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and you do not seem to have it handy on your
+         system.  You might have modified some files without having the
+         proper tools for further handling them.  Check the \`README' file,
+         it often tells you about the needed prerequirements for installing
+         this package.  You may also peek at any GNU archive site, in case
+         some other package would contain this missing \`$1' program."
+    exit 1
+    ;;
+esac
+
+exit 0
diff --git a/glib/mkinstalldirs b/glib/mkinstalldirs
new file mode 100755 (executable)
index 0000000..fef1eb9
--- /dev/null
@@ -0,0 +1,36 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Last modified: 1994-03-25
+# Public domain
+
+errstatus=0
+
+for file in ${1+"$@"} ; do
+   set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+   shift
+
+   pathcomp=
+   for d in ${1+"$@"} ; do
+     pathcomp="$pathcomp$d"
+     case "$pathcomp" in
+       -* ) pathcomp=./$pathcomp ;;
+     esac
+
+     if test ! -d "$pathcomp"; then
+        echo "mkdir $pathcomp" 1>&2
+        mkdir "$pathcomp" > /dev/null 2>&1 || lasterr=$?
+     fi
+
+     if test ! -d "$pathcomp"; then
+       errstatus=$lasterr
+     fi
+
+     pathcomp="$pathcomp/"
+   done
+done
+
+exit $errstatus
+
+# mkinstalldirs ends here
diff --git a/glib/stamp-h.in b/glib/stamp-h.in
new file mode 100644 (file)
index 0000000..9788f70
--- /dev/null
@@ -0,0 +1 @@
+timestamp
diff --git a/glib/testglib.c b/glib/testglib.c
new file mode 100644 (file)
index 0000000..4357b23
--- /dev/null
@@ -0,0 +1,296 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdio.h>
+#include <string.h>
+#include "glib.h"
+
+int array[10000];
+
+void
+my_hash_callback (gpointer key,
+                 gpointer value,
+                 gpointer user_data)
+{
+  int *d = value;
+  *d = 1;
+}
+
+guint
+my_hash (gpointer key)
+{
+  return (guint) *((gint*) key);
+}
+
+gint
+my_hash_compare (gpointer a,
+                gpointer b)
+{
+  return *((gint*) a) == *((gint*) b);
+}
+
+gint
+my_compare (gpointer a,
+           gpointer b)
+{
+  char *cha = a;
+  char *chb = b;
+
+  return *cha - *chb;
+}
+
+gint
+my_traverse (gpointer key,
+            gpointer value,
+            gpointer data)
+{
+  char *ch = key;
+  g_print ("%c ", *ch);
+  return FALSE;
+}
+
+int
+main (int   argc,
+      char *argv[])
+{
+  GList *list, *t;
+  GSList *slist, *st;
+  GHashTable *hash_table;
+  GMemChunk *mem_chunk;
+  GStringChunk *string_chunk;
+  GTimer *timer;
+  gint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+  gchar *mem[10000], *tmp_string, *tmp_string_2;
+  gint i, j;
+  GArray *garray;
+  GString *string1, *string2;
+  GTree *tree;
+  char chars[62];
+
+  g_print ("checking size of gint8...%d (should be 1)\n", sizeof (gint8));
+  g_print ("checking size of gint16...%d (should be 2)\n", sizeof (gint16));
+  g_print ("checking size of gint32...%d (should be 4)\n", sizeof (gint32));
+
+  g_print ("checking doubly linked lists...");
+
+  list = NULL;
+  for (i = 0; i < 10; i++)
+    list = g_list_append (list, &nums[i]);
+  list = g_list_reverse (list);
+
+  for (i = 0; i < 10; i++)
+    {
+      t = g_list_nth (list, i);
+      if (*((gint*) t->data) != (9 - i))
+       g_error ("failed");
+    }
+
+  g_list_free (list);
+
+  g_print ("ok\n");
+
+
+  g_print ("checking singly linked lists...");
+
+  slist = NULL;
+  for (i = 0; i < 10; i++)
+    slist = g_slist_append (slist, &nums[i]);
+  slist = g_slist_reverse (slist);
+
+  for (i = 0; i < 10; i++)
+    {
+      st = g_slist_nth (slist, i);
+      if (*((gint*) st->data) != (9 - i))
+       g_error ("failed");
+    }
+
+  g_slist_free (slist);
+
+  g_print ("ok\n");
+
+
+  g_print ("checking trees...\n");
+
+  tree = g_tree_new (my_compare);
+  i = 0;
+  for (j = 0; j < 10; j++, i++)
+    {
+      chars[i] = '0' + j;
+      g_tree_insert (tree, &chars[i], &chars[i]);
+    }
+  for (j = 0; j < 26; j++, i++)
+    {
+      chars[i] = 'A' + j;
+      g_tree_insert (tree, &chars[i], &chars[i]);
+    }
+  for (j = 0; j < 26; j++, i++)
+    {
+      chars[i] = 'a' + j;
+      g_tree_insert (tree, &chars[i], &chars[i]);
+    }
+
+  g_print ("tree height: %d\n", g_tree_height (tree));
+  g_print ("tree nnodes: %d\n", g_tree_nnodes (tree));
+
+  g_print ("tree: ");
+  g_tree_traverse (tree, my_traverse, G_IN_ORDER, NULL);
+  g_print ("\n");
+
+  for (i = 0; i < 10; i++)
+    g_tree_remove (tree, &chars[i]);
+
+  g_print ("tree height: %d\n", g_tree_height (tree));
+  g_print ("tree nnodes: %d\n", g_tree_nnodes (tree));
+
+  g_print ("tree: ");
+  g_tree_traverse (tree, my_traverse, G_IN_ORDER, NULL);
+  g_print ("\n");
+
+  g_print ("ok\n");
+
+
+  g_print ("checking mem chunks...");
+
+  mem_chunk = g_mem_chunk_new ("test mem chunk", 50, 100, G_ALLOC_AND_FREE);
+
+  for (i = 0; i < 10000; i++)
+    {
+      mem[i] = g_chunk_new (gchar, mem_chunk);
+
+      for (j = 0; j < 50; j++)
+       mem[i][j] = i * j;
+    }
+
+  for (i = 0; i < 10000; i++)
+    {
+      g_mem_chunk_free (mem_chunk, mem[i]);
+    }
+
+  g_print ("ok\n");
+
+
+  g_print ("checking hash tables...");
+
+  hash_table = g_hash_table_new (my_hash, my_hash_compare);
+  for (i = 0; i < 10000; i++)
+    {
+      array[i] = i;
+      g_hash_table_insert (hash_table, &array[i], &array[i]);
+    }
+  g_hash_table_foreach (hash_table, my_hash_callback, NULL);
+
+  for (i = 0; i < 10000; i++)
+    if (array[i] == 0)
+      g_print ("%d\n", i);
+
+  for (i = 0; i < 10000; i++)
+    g_hash_table_remove (hash_table, &array[i]);
+
+  g_hash_table_destroy (hash_table);
+
+  g_print ("ok\n");
+
+
+  g_print ("checking string chunks...");
+
+  string_chunk = g_string_chunk_new (1024);
+
+  for (i = 0; i < 100000; i ++)
+    {
+      tmp_string = g_string_chunk_insert (string_chunk, "hi pete");
+
+      if (strcmp ("hi pete", tmp_string) != 0)
+       g_error ("string chunks are broken.\n");
+    }
+
+  tmp_string_2 = g_string_chunk_insert_const (string_chunk, tmp_string);
+
+  g_assert (tmp_string_2 != tmp_string &&
+           strcmp(tmp_string_2, tmp_string) == 0);
+
+  tmp_string = g_string_chunk_insert_const (string_chunk, tmp_string);
+
+  g_assert (tmp_string_2 == tmp_string);
+
+  g_string_chunk_free (string_chunk);
+
+  g_print ("ok\n");
+
+
+  g_print ("checking arrays...");
+
+  garray = g_array_new (FALSE);
+  for (i = 0; i < 10000; i++)
+    g_array_append_val (garray, gint, i);
+
+  for (i = 0; i < 10000; i++)
+    if (g_array_index (garray, gint, i) != i)
+      g_print ("uh oh: %d ( %d )\n", g_array_index (garray, gint, i), i);
+
+  g_array_free (garray, TRUE);
+
+  garray = g_array_new (FALSE);
+  for (i = 0; i < 10000; i++)
+    g_array_prepend_val (garray, gint, i);
+
+  for (i = 0; i < 10000; i++)
+    if (g_array_index (garray, gint, i) != (10000 - i - 1))
+      g_print ("uh oh: %d ( %d )\n", g_array_index (garray, gint, i), 10000 - i - 1);
+
+  g_array_free (garray, TRUE);
+
+  g_print ("ok\n");
+
+
+  g_print ("checking strings...");
+
+  string1 = g_string_new ("hi pete!");
+  string2 = g_string_new ("");
+
+  g_assert (strcmp ("hi pete!", string1->str) == 0);
+
+  for (i = 0; i < 10000; i++)
+    g_string_append_c (string1, 'a'+(i%26));
+
+  g_string_sprintf (string2, "%s|%0100d|%s|%s|%0*d|%*.*f|%10000.10000f",
+                   "this pete guy sure is a wuss, like he's the number ",
+                   1,
+                   " wuss.  everyone agrees.\n",
+                   string1->str,
+                   10, 666, 15, 15, 666.666666666, 666.666666666);
+
+  g_print ("ok\n");
+
+  g_print ("checking timers...\n");
+
+  timer = g_timer_new ();
+  g_print ("  spinning for 3 seconds...\n");
+
+  g_timer_start (timer);
+  while (g_timer_elapsed (timer, NULL) < 3)
+    ;
+
+  g_timer_stop (timer);
+  g_timer_destroy (timer);
+
+  g_print ("ok\n");
+
+  /* g_debug (argv[0]); */
+
+
+  return 0;
+}
diff --git a/gtk+.prj b/gtk+.prj
new file mode 100644 (file)
index 0000000..2c16fec
--- /dev/null
+++ b/gtk+.prj
@@ -0,0 +1,334 @@
+;; -*- Lisp -*-
+(Created-By-Prcs-Version 1 1 0)
+(Project-Description "")
+(Project-Version gtk+ 0 16)
+(Parent-Version gtk+ 0 15)
+(Descends-From -*- -*- -*-)
+(Version-Log "")
+(New-Version-Log "")
+(Checkin-Time "Wed, 19 Feb 1997 15:49:10 -0800")
+(Checkin-Login pmattis)
+(Populate-Ignore ("\\.o$" "\\.a$" "^core$" "^.*/core$"
+                  ".*.deps/.*" "\\.dvi$" "\\.aux$" "\\.log"
+                  "Makefile$" "config.cache$" "config.log$"
+                  "configure$" "gconfig.h$" "stamp-h$"))
+(Files
+;; This is a comment.  Fill in files here.
+;; For example:  (prcs/checkout.cc ())
+
+; Files added by populate at Thu, 21 Nov 1996 16:48:40 -0800:
+
+  (docs/texinfo.tex (gtk+/1_texinfo.te 1.1 644))
+  (docs/gtk.texi (gtk+/2_gtk.texi 1.5 644))
+  (docs/gdk.texi (gtk+/3_gdk.texi 1.2 644))
+  (docs/Makefile.in (gtk+/4_Makefile.i 1.5 644))
+  (docs/Makefile.am (gtk+/5_Makefile.a 1.2 644))
+  (gtk/testgtk.c (gtk+/6_testgtk.c 1.14 644))
+  (gtk/gtkwindow.h (gtk+/7_gtkwindow. 1.6 644))
+  (gtk/gtkwindow.c (gtk+/8_gtkwindow. 1.10 644))
+  (gtk/gtkwidget.h (gtk+/9_gtkwidget. 1.8 644))
+  (gtk/gtkwidget.c (gtk+/10_gtkwidget. 1.14 644))
+  (gtk/gtkvseparator.h (gtk+/11_gtkvsepara 1.3 644))
+  (gtk/gtkvseparator.c (gtk+/12_gtkvsepara 1.5 644))
+  (gtk/gtkvscrollbar.h (gtk+/13_gtkvscroll 1.3 644))
+  (gtk/gtkvscrollbar.c (gtk+/14_gtkvscroll 1.5 644))
+  (gtk/gtkvscale.h (gtk+/15_gtkvscale. 1.2 644))
+  (gtk/gtkvscale.c (gtk+/16_gtkvscale. 1.7 644))
+  (gtk/gtkvruler.h (gtk+/17_gtkvruler. 1.4 644))
+  (gtk/gtkvruler.c (gtk+/18_gtkvruler. 1.7 644))
+  (gtk/gtkviewport.h (gtk+/19_gtkviewpor 1.3 644))
+  (gtk/gtkviewport.c (gtk+/20_gtkviewpor 1.6 644))
+  (gtk/gtkvbox.h (gtk+/21_gtkvbox.h 1.2 644))
+  (gtk/gtkvbox.c (gtk+/22_gtkvbox.c 1.5 644))
+  (gtk/gtktypeutils.h (gtk+/23_gtktypeuti 1.4 644))
+  (gtk/gtktypeutils.c (gtk+/24_gtktypeuti 1.6 644))
+  (gtk/gtktreeitem.h (gtk+/25_gtktreeite 1.3 644))
+  (gtk/gtktreeitem.c (gtk+/26_gtktreeite 1.4 644))
+  (gtk/gtktree.h (gtk+/27_gtktree.h 1.3 644))
+  (gtk/gtktree.c (gtk+/28_gtktree.c 1.4 644))
+  (gtk/gtktogglebutton.h (gtk+/29_gtktoggleb 1.5 644))
+  (gtk/gtktogglebutton.c (gtk+/30_gtktoggleb 1.8 644))
+  (gtk/gtktable.h (gtk+/31_gtktable.h 1.2 644))
+  (gtk/gtktable.c (gtk+/32_gtktable.c 1.8 644))
+  (gtk/gtkstyle.h (gtk+/33_gtkstyle.h 1.3 644))
+  (gtk/gtkstyle.c (gtk+/34_gtkstyle.c 1.7 644))
+  (gtk/gtksignal.h (gtk+/35_gtksignal. 1.7 644))
+  (gtk/gtksignal.c (gtk+/36_gtksignal. 1.9 644))
+  (gtk/gtkseparator.h (gtk+/37_gtkseparat 1.2 644))
+  (gtk/gtkseparator.c (gtk+/38_gtkseparat 1.4 644))
+  (gtk/gtkscrolledwindow.h (gtk+/39_gtkscrolle 1.2 644))
+  (gtk/gtkscrolledwindow.c (gtk+/40_gtkscrolle 1.8 644))
+  (gtk/gtkscrollbar.h (gtk+/41_gtkscrollb 1.2 644))
+  (gtk/gtkscrollbar.c (gtk+/42_gtkscrollb 1.4 644))
+  (gtk/gtkscale.h (gtk+/43_gtkscale.h 1.4 644))
+  (gtk/gtkscale.c (gtk+/44_gtkscale.c 1.7 644))
+  (gtk/gtkruler.h (gtk+/45_gtkruler.h 1.5 644))
+  (gtk/gtkruler.c (gtk+/46_gtkruler.c 1.8 644))
+  (gtk/gtkrc.h (gtk+/47_gtkrc.h 1.3 644))
+  (gtk/gtkrc.c (gtk+/48_gtkrc.c 1.4 644))
+  (gtk/gtkrange.h (gtk+/49_gtkrange.h 1.4 644))
+  (gtk/gtkrange.c (gtk+/50_gtkrange.c 1.6 644))
+  (gtk/gtkradiobutton.h (gtk+/51_gtkradiobu 1.3 644))
+  (gtk/gtkradiobutton.c (gtk+/b/0_gtkradiobutton.c 1.7 644))
+  (gtk/gtkpixmap.h (gtk+/b/1_gtkpixmap. 1.3 644))
+  (gtk/gtkpixmap.c (gtk+/b/2_gtkpixmap. 1.5 644))
+  (gtk/gtkoptionmenu.h (gtk+/b/3_gtkoptionm 1.5 644))
+  (gtk/gtkoptionmenu.c (gtk+/b/4_gtkoptionm 1.7 644))
+  (gtk/gtkobject.h (gtk+/b/5_gtkobject. 1.6 644))
+  (gtk/gtkobject.c (gtk+/b/6_gtkobject. 1.9 644))
+  (gtk/gtkmisc.h (gtk+/b/7_gtkmisc.h 1.2 644))
+  (gtk/gtkmisc.c (gtk+/b/8_gtkmisc.c 1.4 644))
+  (gtk/gtkmenushell.h (gtk+/b/9_gtkmenushe 1.5 644))
+  (gtk/gtkmenushell.c (gtk+/b/10_gtkmenushe 1.8 644))
+  (gtk/gtkmenuitem.h (gtk+/b/11_gtkmenuite 1.6 644))
+  (gtk/gtkmenuitem.c (gtk+/b/12_gtkmenuite 1.8 644))
+  (gtk/gtkmenubar.h (gtk+/b/13_gtkmenubar 1.4 644))
+  (gtk/gtkmenubar.c (gtk+/b/14_gtkmenubar 1.7 644))
+  (gtk/gtkmenu.h (gtk+/b/15_gtkmenu.h 1.5 644))
+  (gtk/gtkmenu.c (gtk+/b/16_gtkmenu.c 1.8 644))
+  (gtk/gtkmain.h (gtk+/b/17_gtkmain.h 1.4 644))
+  (gtk/gtkmain.c (gtk+/b/18_gtkmain.c 1.11 644))
+  (gtk/gtklistitem.h (gtk+/b/19_gtklistite 1.3 644))
+  (gtk/gtklistitem.c (gtk+/b/20_gtklistite 1.9 644))
+  (gtk/gtklist.h (gtk+/b/21_gtklist.h 1.5 644))
+  (gtk/gtklist.c (gtk+/b/22_gtklist.c 1.10 644))
+  (gtk/gtklabel.h (gtk+/b/23_gtklabel.h 1.2 644))
+  (gtk/gtklabel.c (gtk+/b/24_gtklabel.c 1.7 644))
+  (gtk/gtkitem.h (gtk+/b/25_gtkitem.h 1.3 644))
+  (gtk/gtkitem.c (gtk+/b/26_gtkitem.c 1.7 644))
+  (gtk/gtkimage.h (gtk+/b/27_gtkimage.h 1.2 644))
+  (gtk/gtkimage.c (gtk+/b/28_gtkimage.c 1.4 644))
+  (gtk/gtkhseparator.h (gtk+/b/29_gtkhsepara 1.2 644))
+  (gtk/gtkhseparator.c (gtk+/b/30_gtkhsepara 1.4 644))
+  (gtk/gtkhscrollbar.h (gtk+/b/31_gtkhscroll 1.2 644))
+  (gtk/gtkhscrollbar.c (gtk+/b/32_gtkhscroll 1.4 644))
+  (gtk/gtkhscale.h (gtk+/b/33_gtkhscale. 1.2 644))
+  (gtk/gtkhscale.c (gtk+/b/34_gtkhscale. 1.7 644))
+  (gtk/gtkhruler.h (gtk+/b/35_gtkhruler. 1.4 644))
+  (gtk/gtkhruler.c (gtk+/b/36_gtkhruler. 1.7 644))
+  (gtk/gtkhbox.h (gtk+/b/37_gtkhbox.h 1.2 644))
+  (gtk/gtkhbox.c (gtk+/b/38_gtkhbox.c 1.5 644))
+  (gtk/gtkgc.h (gtk+/b/39_gtkgc.h 1.3 644))
+  (gtk/gtkgc.c (gtk+/b/40_gtkgc.c 1.5 644))
+  (gtk/gtkframe.h (gtk+/b/41_gtkframe.h 1.2 644))
+  (gtk/gtkframe.c (gtk+/b/42_gtkframe.c 1.5 644))
+  (gtk/gtkenums.h (gtk+/b/45_gtkenums.h 1.6 644))
+  (gtk/gtkentry.h (gtk+/b/46_gtkentry.h 1.5 644))
+  (gtk/gtkentry.c (gtk+/b/47_gtkentry.c 1.9 644))
+  (gtk/gtkdrawingarea.h (gtk+/b/48_gtkdrawing 1.4 644))
+  (gtk/gtkdrawingarea.c (gtk+/b/49_gtkdrawing 1.6 644))
+  (gtk/gtkdata.h (gtk+/b/50_gtkdata.h 1.2 644))
+  (gtk/gtkdata.c (gtk+/b/51_gtkdata.c 1.7 644))
+  (gtk/gtkcontainer.h (gtk+/c/0_gtkcontainer.h 1.6 644))
+  (gtk/gtkcontainer.c (gtk+/c/1_gtkcontain 1.10 644))
+  (gtk/gtkcheckbutton.h (gtk+/c/2_gtkcheckbu 1.3 644))
+  (gtk/gtkcheckbutton.c (gtk+/c/3_gtkcheckbu 1.6 644))
+  (gtk/gtkbutton.h (gtk+/c/4_gtkbutton. 1.4 644))
+  (gtk/gtkbutton.c (gtk+/c/5_gtkbutton. 1.9 644))
+  (gtk/gtkbox.h (gtk+/c/6_gtkbox.h 1.2 644))
+  (gtk/gtkbox.c (gtk+/c/7_gtkbox.c 1.5 644))
+  (gtk/gtkbin.h (gtk+/c/8_gtkbin.h 1.2 644))
+  (gtk/gtkbin.c (gtk+/c/9_gtkbin.c 1.6 644))
+  (gtk/gtkarrow.h (gtk+/c/10_gtkarrow.h 1.2 644))
+  (gtk/gtkarrow.c (gtk+/c/11_gtkarrow.c 1.4 644))
+  (gtk/gtkalignment.h (gtk+/c/12_gtkalignme 1.2 644))
+  (gtk/gtkalignment.c (gtk+/c/13_gtkalignme 1.5 644))
+  (gtk/gtkadjustment.h (gtk+/c/14_gtkadjustm 1.3 644))
+  (gtk/gtkadjustment.c (gtk+/c/15_gtkadjustm 1.7 644))
+  (gtk/gtkaccelerator.h (gtk+/c/16_gtkacceler 1.4 644))
+  (gtk/gtkaccelerator.c (gtk+/c/17_gtkacceler 1.4 644))
+  (gtk/gtk.h (gtk+/c/18_gtk.h 1.7 644))
+  (gtk/fnmatch.h (gtk+/c/19_fnmatch.h 1.1 644))
+  (gtk/fnmatch.c (gtk+/c/20_fnmatch.c 1.1 644))
+  (TODO (gtk+/c/21_TODO 1.13 644))
+  (gtk/Makefile.in (gtk+/c/22_Makefile.i 1.10 644))
+  (gtk/Makefile.am (gtk+/c/23_Makefile.a 1.10 644))
+  (gdk/makekeysyms.sed (gtk+/c/24_makekeysym 1.1 644))
+  (gdk/makekeysyms (gtk+/c/25_makekeysym 1.1 755))
+  (gdk/makecursors.sed (gtk+/c/26_makecursor 1.1 644))
+  (gdk/makecursors (gtk+/c/27_makecursor 1.1 755))
+  (gdk/gdkx.h (gtk+/c/28_gdkx.h 1.2 644))
+  (gdk/gdkwindow.c (gtk+/c/29_gdkwindow. 1.8 644))
+  (gdk/gdkvisual.c (gtk+/c/30_gdkvisual. 1.2 644))
+  (gdk/gdktypes.h (gtk+/c/31_gdktypes.h 1.6 644))
+  (gdk/gdkrectangle.c (gtk+/c/32_gdkrectang 1.3 644))
+  (gdk/gdkprivate.h (gtk+/c/33_gdkprivate 1.4 644))
+  (gdk/gdkpixmap.c (gtk+/c/34_gdkpixmap. 1.6 644))
+  (gdk/gdkkeysyms.h (gtk+/c/35_gdkkeysyms 1.2 644))
+  (gdk/gdkimage.c (gtk+/c/36_gdkimage.c 1.4 644))
+  (gdk/gdkglobals.c (gtk+/c/37_gdkglobals 1.3 644))
+  (gdk/gdkgc.c (gtk+/c/38_gdkgc.c 1.6 644))
+  (gdk/gdkfont.c (gtk+/c/39_gdkfont.c 1.4 644))
+  (gdk/gdkdraw.c (gtk+/c/40_gdkdraw.c 1.4 644))
+  (gdk/gdkcursors.h (gtk+/c/41_gdkcursors 1.3 644))
+  (gdk/gdkcursor.c (gtk+/c/42_gdkcursor. 1.3 644))
+  (gdk/gdkcolor.c (gtk+/c/43_gdkcolor.c 1.4 644))
+  (gdk/gdk.h (gtk+/c/44_gdk.h 1.6 644))
+  (gdk/gdk.c (gtk+/c/45_gdk.c 1.8 644))
+  (gdk/Makefile.in (gtk+/c/46_Makefile.i 1.7 644))
+  (gdk/Makefile.am (gtk+/c/47_Makefile.a 1.7 644))
+  (glib/testglib.c (gtk+/c/48_testglib.c 1.8 644))
+  (glib/stamp-h.in (gtk+/c/49_stamp-h.in 1.1 644))
+  (glib/mkinstalldirs (gtk+/c/50_mkinstalld 1.1 755))
+  (glib/install-sh (gtk+/c/51_install-sh 1.1 755))
+  (glib/gutils.c (gtk+/d/0_gutils.c 1.3 644))
+  (glib/gtimer.c (gtk+/d/1_gtimer.c 1.2 644))
+  (glib/gslist.c (gtk+/d/2_gslist.c 1.6 644))
+  (glib/gprimes.c (gtk+/d/3_gprimes.c 1.2 644))
+  (glib/gmem.c (gtk+/d/4_gmem.c 1.9 644))
+  (glib/glist.c (gtk+/d/5_glist.c 1.4 644))
+  (glib/glib.h (gtk+/d/6_glib.h 1.8 644))
+  (glib/ghash.c (gtk+/d/7_ghash.c 1.5 644))
+  (glib/gerror.c (gtk+/d/8_gerror.c 1.4 644))
+  (glib/gconfig.h.in (gtk+/d/9_gconfig.h. 1.3 644))
+  (glib/gconfig.h (gtk+/d/10_gconfig.h 1.6 644))
+  (glib/gcache.c (gtk+/d/11_gcache.c 1.6 644))
+  (glib/configure.in (gtk+/d/12_configure. 1.4 644))
+  (glib/configure (gtk+/d/13_configure 1.4 755))
+  (glib/config.sub (gtk+/d/14_config.sub 1.2 755))
+  (glib/config.guess (gtk+/d/15_config.gue 1.2 755))
+  (glib/aclocal.m4 (gtk+/d/16_aclocal.m4 1.4 644))
+  (glib/acconfig.h (gtk+/d/17_acconfig.h 1.3 644))
+  (glib/README (gtk+/d/18_README 1.1 644))
+  (glib/NEWS (gtk+/d/19_NEWS 1.1 644))
+  (glib/Makefile.in (gtk+/d/20_Makefile.i 1.7 644))
+  (glib/Makefile.am (gtk+/d/21_Makefile.a 1.7 644))
+  (glib/INSTALL (gtk+/d/22_INSTALL 1.1 644))
+  (glib/ChangeLog (gtk+/d/23_ChangeLog 1.2 644))
+  (glib/COPYING (gtk+/d/24_COPYING 1.1 644))
+  (glib/AUTHORS (gtk+/d/25_AUTHORS 1.2 644))
+  (stamp-h.in (gtk+/d/26_stamp-h.in 1.1 644))
+  (mkinstalldirs (gtk+/d/27_mkinstalld 1.1 755))
+  (install-sh (gtk+/d/28_install-sh 1.1 755))
+  (configure.in (gtk+/d/30_configure. 1.8 644))
+  (configure (gtk+/d/31_configure 1.8 755))
+  (config.sub (gtk+/d/32_config.sub 1.2 755))
+  (config.h.in (gtk+/d/33_config.h.i 1.4 644))
+  (config.guess (gtk+/d/34_config.gue 1.2 755))
+  (aclocal.m4 (gtk+/d/35_aclocal.m4 1.4 644))
+  (acconfig.h (gtk+/d/36_acconfig.h 1.3 644))
+  (README (gtk+/d/37_README 1.1 644))
+  (NEWS (gtk+/d/38_NEWS 1.1 644))
+  (Makefile.in (gtk+/d/39_Makefile.i 1.9 644))
+  (Makefile.am (gtk+/d/40_Makefile.a 1.7 644))
+  (INSTALL (gtk+/d/41_INSTALL 1.1 644))
+  (ChangeLog (gtk+/d/42_ChangeLog 1.14 644))
+  (COPYING (gtk+/d/43_COPYING 1.2 644))
+  (AUTHORS (gtk+/d/44_AUTHORS 1.2 644))
+
+; Files added by populate at Mon, 30 Dec 1996 13:14:24 -0800:
+
+  (gtk/gtkmenufactory.h (gtk+/0_gtkmenufac 1.4 644))
+  (gtk/gtkmenufactory.c (gtk+/1_gtkmenufac 1.4 644))
+
+; Files added by populate at Thu, 02 Jan 1997 15:31:44 -0800:
+
+  (gtk/testgtkrc (gtk+/0_testgtkrc 1.2 644))
+
+
+; Files added by populate at Fri, 10 Jan 1997 14:19:47 -0800:
+
+  (gtk/gtkfilesel.h (gtk+/b/0_gtkfilesel.h 1.3 644))
+  (gtk/gtkfilesel.c (gtk+/c/0_gtkfilesel.c 1.7 644))
+  (glib/gstring.c (gtk+/d/0_gstring.c 1.4 644))
+
+; Files added by populate at Fri, 10 Jan 1997 18:01:19 -0800:
+
+  (gdk/gdkselection.c (gtk+/b/0_gdkselection.c 1.5 644))
+
+; Files added by populate at Sun, 19 Jan 1997 18:29:12 -0800:
+
+  (gtk/gtktext.h (gtk+/b/0_gtktext.h 1.4 644))
+  (gtk/gtktext.c (gtk+/c/0_gtktext.c 1.7 644))
+  (gtk/gtkdialog.h (gtk+/d/0_gtkdialog.h 1.2 644))
+  (gtk/gtkdialog.c (gtk+/d/47_gtkdialog. 1.4 644))
+  (gdk/gdkxid.c (gtk+/d/48_gdkxid.c 1.2 644))
+
+; Files added by populate at Thu, 23 Jan 1997 01:29:17 -0800:
+
+  (gtk/gtknotebook.h (gtk+/b/0_gtknotebook.h 1.3 644))
+  (gtk/gtknotebook.c (gtk+/c/0_gtknotebook.c 1.6 644))
+
+; Files added by populate at Thu, 23 Jan 1997 02:06:11 -0800:
+
+  (gtk/line-wrap.xbm (gtk+/b/0_line-wrap.xbm 1.1 644))
+  (gtk/line-arrow.xbm (gtk+/c/0_line-arrow.xbm 1.1 644))
+
+; Files added by populate at Fri, 24 Jan 1997 13:02:44 -0800:
+
+  
+  
+  
+  
+
+; Files deleted by populate at Fri, 24 Jan 1997 13:02:44 -0800:
+
+  ; `docs/texinfo3.7.patch'
+
+; Files added by populate at Tue, 28 Jan 1997 16:54:35 -0800:
+
+  (gtk/simple.c (gtk+/e/0_simple.c 1.1 644))
+  (glib/ltmain.sh (gtk+/e/1_ltmain.sh 1.3 644))
+  (glib/ltconfig (gtk+/e/2_ltconfig 1.3 755))
+  (ltmain.sh (gtk+/e/3_ltmain.sh 1.3 644))
+  (ltconfig (gtk+/e/4_ltconfig 1.3 755))
+
+; Files added by populate at Thu, 30 Jan 1997 01:30:38 -0800:
+
+  (glib/gtree.c (gtk+/b/0_gtree.c 1.3 644))
+
+; Files added by populate at Mon, 03 Feb 1997 19:46:14 -0800:
+
+  (makecopyright (gtk+/b/0_makecopyright 1.1 755))
+
+; Files added by populate at Sat, 08 Feb 1997 14:41:52 -0800:
+
+  (gtk/gtkprogressbar.h (gtk+/b/0_gtkprogressbar.h 1.1 644))
+  (gtk/gtkprogressbar.c (gtk+/c/0_gtkprogressbar.c 1.1 644))
+  (glib/garray.c (gtk+/d/0_garray.c 1.1 644))
+
+; Files deleted by populate at Sat, 08 Feb 1997 14:41:52 -0800:
+
+  ; `interp/Makefile.am'
+  ; `interp/Makefile.in'
+  ; `interp/interp.c'
+
+;; Files added by populate at Wed, 19 Feb 1997 15:48:04 -0800:
+
+  (gtk+.xconfig.in (gtk+/b/0_gtk+.xconfig.in 1.1 644))
+
+;; Files deleted by populate at Wed, 19 Feb 1997 15:48:04 -0800:
+
+  ; docs/proposal.tex
+
+;; Files added by populate at Thu, 17 Apr 1997 17:39:47 -0700:
+
+  (docs/macros.texi ())
+  (gdk/gdkproperty.c ())
+  (glib/missing () :symlink)
+  (missing () :symlink)
+
+;; Files deleted by populate at Thu, 17 Apr 1997 17:39:47 -0700:
+
+  ; gtk/gtkcanvas.c
+  ; gtk/gtkcanvas.h
+  ; gtk/gtkfill.c
+  ; gtk/gtkfill.h
+
+;; Files added by populate at Thu, 17 Apr 1997 17:41:14 -0700:
+
+  (gtk/gtktooltips.h ())
+  (gtk/gtktooltips.c ())
+  (gtk/gtkradiomenuitem.h ())
+  (gtk/gtkradiomenuitem.c ())
+  (gtk/gtkpreview.h ())
+  (gtk/gtkpreview.c ())
+  (gtk/gtkcolorsel.h ())
+  (gtk/gtkcolorsel.c ())
+  (gtk/gtkcheckmenuitem.h ())
+  (gtk/gtkcheckmenuitem.c ())
+  (gtk/gtkaspectframe.h ())
+  (gtk/gtkaspectframe.c ())
+)
+(Merge-Parents)
+(New-Merge-Parents)
diff --git a/gtk+.xconfig.in b/gtk+.xconfig.in
new file mode 100644 (file)
index 0000000..8843df6
--- /dev/null
@@ -0,0 +1,3 @@
+X_CFLAGS = @x_cflags@
+X_LDFLAGS = @x_ldflags@
+X_LIBS = @x_libs@
diff --git a/gtk/.cvsignore b/gtk/.cvsignore
new file mode 100644 (file)
index 0000000..e5ac5d9
--- /dev/null
@@ -0,0 +1,9 @@
+*.lo
+Makefile
+.deps
+_libs
+libgtk.la
+testgtk
+testinput
+testselection
+simple
diff --git a/gtk/3DRings.xpm b/gtk/3DRings.xpm
new file mode 100644 (file)
index 0000000..1ca75da
--- /dev/null
@@ -0,0 +1,116 @@
+/* XPM */
+static char * DRings_xpm[] = {
+"48 48 65 1",
+"      c None",
+".     c #104010404103",
+"X     c #1040208130C2",
+"o     c #104014515144",
+"O     c #000010402081",
+"+     c #1040104030C2",
+"@     c #208120815144",
+"#     c #28A241035965",
+"$     c #30C230C26185",
+"%     c #208130C24103",
+"&     c #104010402081",
+"*     c #104000002081",
+"=     c #000010401040",
+"-     c #492441036185",
+";     c #596559659E79",
+":     c #30C220815144",
+">     c #0820186128A2",
+",     c #000000001040",
+"<     c #2081104030C2",
+"1     c #514459659658",
+"2     c #514455556185",
+"3     c #104000001040",
+"4     c #000008200000",
+"5     c #618569A6AEBA",
+"6     c #618569A69658",
+"7     c #410345148E38",
+"8     c #104020814103",
+"9     c #79E782079658",
+"0     c #208120814103",
+"q     c #596571C69E79",
+"w     c #4103514471C6",
+"e     c #2081208130C2",
+"r     c #6185618571C6",
+"t     c #28A228A25965",
+"y     c #596561858617",
+"u     c #96589E79BEFB",
+"i     c #28A230C271C6",
+"p     c #38E345145144",
+"a     c #79E78207A699",
+"s     c #30C2492469A6",
+"d     c #410330C25965",
+"f     c #410351446185",
+"g     c #AEBAAAAAD75C",
+"h     c #38E338E34103",
+"j     c #EFBEEBADEFBE",
+"k     c #208130C25144",
+"l     c #9658A289DF7D",
+"z     c #208110404103",
+"x     c #28A228A26185",
+"c     c #8E388A28BEFB",
+"v     c #208118612081",
+"b     c #38E3451479E7",
+"n     c #4924618579E7",
+"m     c #86178617B6DA",
+"M     c #30C220814103",
+"N     c #104030C25144",
+"B     c #4103410371C6",
+"V     c #86178A28D75C",
+"C     c #DF7DDB6CE79D",
+"Z     c #BEFBC30BD75C",
+"A     c #410330C271C6",
+"S     c #30C228A230C2",
+"D     c #082008201861",
+"F     c #186130C238E3",
+"G     c #0000208130C2",
+"                                .Xo             ",
+"                              O+O@#$%           ",
+"                             &*=+X-;:           ",
+"                            >&=,=<11#2          ",
+"                            +O34,X567&          ",
+"                           8X+=,90q9w.          ",
+"                          +e<>3r tyu-&          ",
+"                          Xi%.=  paus+          ",
+"                         Od-@=   fga$h          ",
+"                         @y7X,  Xrjak           ",
+"                       2:eaw+   $ag;@           ",
+"                   .X@8@k@o@X+ +pl9tO           ",
+"                 +zX@x$$isikt8o02crv            ",
+"                8@%ip7757ywbs$Ohn6#.            ",
+"               &0%$p7r215ybw1pzp2-0=            ",
+"              8tk$#yw21665n;1+%-p$O             ",
+"             O<e7pbryq5am9ay6XMpM>3&            ",
+"            9.NtpBw16amclVcm1t%kX*88            ",
+"            +&etd7r6y9ulgglm6>e>3s@83           ",
+"            +0k$y-y69cgCCCZVam%+#ik8X           ",
+"           O&oi$d725amgCjCZu962ybtx8+p          ",
+"           &X0x$sBym9VZCCCZca;yBbi%08&          ",
+"           =++@sApMy5muZZgum6y2wds:>+&          ",
+"          #tp;1;yB#i25cVucma5;w-pti@8&          ",
+"        .#2alumnBp:@1r59y9y6ywBS$%0X+=          ",
+"      %$wmZVu;#tX8X07r1656y2wbp$k@%@OD          ",
+"     0Byc9a;h%0>&D&hBrr2r1bwB-AF:0<&*=          ",
+"    kBf;yr#@X+&<%MkhsBwBwpsB#Bktkt8+Oh          ",
+"   xt7B-t8*,3O.X00:$i#dBd#bptFek0X.+*           ",
+"  Xt#b#@=,  =&O+X0Ft%ibsp$p$ki%l5sX&=           ",
+" &<kvX&4    +O*&<X0e:%$pAti%:edugn0=            ",
+" +X@&+,     V,O&>+Xt>tktktv0%@k;Cls+            ",
+" =+O*4*X:p;9cy3&&8ve0FMtt$ee0>z7cZ6k            ",
+" D=D4,=.k$sBs$ee=+X0Fk%-#t%0X&O0nu9bG           ",
+" ,,434*&ze@F<eeeeee><tdhdSMe<&&XAaawx           ",
+"  4,4,=+><peeeeee&=<%M%$hSF0X&O&kw5r%Z          ",
+"                   D&vSFMF<>&D =0S-2i&          ",
+"                       +>puB>   >0h7s.          ",
+"                       SM5VqM   &0t#$8          ",
+"                        XpVV70  &0kMk.          ",
+"                         XdyB%z *X<%@+          ",
+"                         &k$b0X+=8X08o          ",
+"                          &e:e+=*X.X+&          ",
+"                           +X.O+X0O.=,          ",
+"                            +>&+0>3&*           ",
+"                             &X0k+O,            ",
+"                               >v,3             ",
+"                                                "};
diff --git a/gtk/FilesQueue.xpm b/gtk/FilesQueue.xpm
new file mode 100644 (file)
index 0000000..586d27e
--- /dev/null
@@ -0,0 +1,98 @@
+/* XPM */
+static char * FilesQueue_xpm[] = {
+"44 31 64 1",
+"      c None",
+".     c #E79DE38DDF7D",
+"X     c #CF3CC71BCF3C",
+"o     c #71C675D671C6",
+"O     c #B6DAB2CAB6DA",
+"+     c #CF3CD34CCF3C",
+"@     c #DF7DE38DE79D",
+"#     c #FFFFFBEEFFFF",
+"$     c #EFBEEFBEEFBE",
+"%     c #DF7DDB6CDF7D",
+"&     c #BEFBBAEAC71B",
+"*     c #BEFBBAEABEFB",
+"=     c #BEFBC30BC71B",
+"-     c #71C66DB671C6",
+";     c #D75CD34CD75C",
+":     c #9E799A699E79",
+">     c #E79DE38DE79D",
+",     c #CF3CCB2BC71B",
+"<     c #B6DAB2CABEFB",
+"1     c #BEFBBAEAB6DA",
+"2     c #B6DAB6DAB6DA",
+"3     c #618561856185",
+"4     c #C71BBAEABEFB",
+"5     c #AEBAAAAAAEBA",
+"6     c #965892488E38",
+"7     c #A699A699A699",
+"8     c #38E338E338E3",
+"9     c #F7DEF7DEF7DE",
+"0     c #E79DEFBEEFBE",
+"q     c #DF7DE38DDF7D",
+"w     c #C71BC71BC71B",
+"e     c #C71BC30BBEFB",
+"r     c #BEFBC30BBEFB",
+"t     c #B6DAAAAAAEBA",
+"y     c #410345144103",
+"u     c #D75CDB6CD75C",
+"i     c #C71BCB2BC71B",
+"p     c #BEFBCB2BBEFB",
+"a     c #9E79A289A699",
+"s     c #86178E388E38",
+"d     c #CF3CCF3CD75C",
+"f     c #CF3CD75CCF3C",
+"g     c #C71BC30BCF3C",
+"h     c #28A22CB228A2",
+"j     c #000000000000",
+"k     c #D75CD34CDF7D",
+"l     c #10400C300820",
+"z     c #E79DEBADEFBE",
+"x     c #DF7DDB6CD75C",
+"c     c #514459655965",
+"v     c #8617861779E7",
+"b     c #DF7DD34CD75C",
+"n     c #CF3CCB2BCF3C",
+"m     c #618555555965",
+"M     c #861786178617",
+"N     c #30C234D330C2",
+"B     c #EFBEEBADE79D",
+"V     c #DF7DDB6CE79D",
+"C     c #D75CE38DD75C",
+"Z     c #514449245144",
+"A     c #186120812081",
+"S     c #79E77DF779E7",
+"D     c #6185659569A6",
+"F     c #9E7992489E79",
+"                      .XoOX+                ",
+"                   @#$%&*=-o;:              ",
+"                  @>,=O<12*&:-<3X           ",
+"                 >%&1*4*2*OO**56758790      ",
+"               9qX+we=r*&e<<<251t5555yu9    ",
+"             $qu++;ipi=p*=p**2tOOO27a5s<-   ",
+"           #9udfXi;,gi&**4**4r*Ot5t55tehj   ",
+"          0qku+u;+d,gg=*=r*&**&<255t<*yl1   ",
+"       $$zq@%xk%uf;,w,i=i=e**r=12tO1=8cvj   ",
+"     $@%>.%.%%%xbkx,w+ni,wwrwe*4*1=;8mMNj   ",
+"    zz@Bz>>>V%%%C+u;;dfnnfwggi&=&X+yZsNll   ",
+"  af#9@B0>q>qqq>xk.;;;kfX+XnXw=g,fycMhhN5   ",
+"  al5#9$$>qzBV.%x%%b;x+fnf+,X,iiqym6NAo-j   ",
+"  #roS%#$zz>>V%%xkk%f;;+df,XnwnVZD:8AS-j*   ",
+"  D-9Oy*9$Bz>q%qx%%u;x;;dknX+d>Zm:hhSDjr    ",
+"  a3o+>S3z#90@@z.%>qCC%uu;ff%@Zm:NhMoj=     ",
+"  wlvvo#:3599$>B>q>%%%%+f;fk$ymaalMvjr      ",
+"  0.a--S49mct9$z@.qkkqC;xu%@Zm5AlvSj*       ",
+"  ohu%3:Z:9@y609q@@>..>Cx>$Zm5NhMvjr        ",
+"   -j797Zv5705y=#$0>>V.%>#Z378AMMj*         ",
+"     Zj9Xo-McBXDv%90.%%#9cc78AsMj*          ",
+"      8hM#M-DSF96cvz0>z#c35Nhs6j1           ",
+"        jl9#o63vx#-D###mmt8N66j*            ",
+"         5jc@fZF3o%+ZFDm<8A6FjO             ",
+"           :j50sSay<$ss2Nh:FjO              ",
+"            6880&SDMF.rNNFFj1               ",
+"              8jr#:SFScA6ajO                ",
+"                Alr$DSysajO                 ",
+"                 >jy#51:jO                  ",
+"                  %Dy*gjO                   ",
+"                    alla                    "};
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
new file mode 100644 (file)
index 0000000..60d43b1
--- /dev/null
@@ -0,0 +1,248 @@
+## Process this file with automake to produce Makefile.in
+
+gtkincludedir = $(includedir)/gtk
+
+lib_LTLIBRARIES = libgtk.la
+
+libgtk_la_SOURCES = \
+       gtkaccelerator.c        \
+       gtkadjustment.c         \
+       gtkaspectframe.c        \
+       gtkalignment.c          \
+       gtkarrow.c              \
+       gtkbin.c                \
+       gtkbbox.c               \
+       gtkbox.c                \
+       gtkbutton.c             \
+       gtkcheckbutton.c        \
+       gtkcheckmenuitem.c      \
+       gtkcolorsel.c           \
+       gtkcontainer.c          \
+       gtkcurve.c              \
+       gtkdata.c               \
+       gtkdialog.c             \
+       gtkdrawingarea.c        \
+       gtkentry.c              \
+       gtkeventbox.c           \
+       gtkfilesel.c            \
+       gtkfixed.c              \
+       gtkframe.c              \
+       gtkgamma.c              \
+       gtkgc.c                 \
+       gtkhbbox.c              \
+       gtkhbox.c               \
+       gtkhpaned.c             \
+       gtkhruler.c             \
+       gtkhscale.c             \
+       gtkhscrollbar.c         \
+       gtkhseparator.c         \
+       gtkimage.c              \
+       gtkinputdialog.c        \
+       gtkitem.c               \
+       gtklabel.c              \
+       gtklist.c               \
+       gtklistitem.c           \
+       gtkmain.c               \
+       gtkmenu.c               \
+       gtkmenubar.c            \
+       gtkmenufactory.c        \
+       gtkmenuitem.c           \
+       gtkmenushell.c          \
+       gtkmisc.c               \
+       gtknotebook.c           \
+       gtkobject.c             \
+       gtkoptionmenu.c         \
+       gtkpaned.c              \
+       gtkpixmap.c             \
+       gtkpreview.c            \
+       gtkprogressbar.c        \
+       gtkradiobutton.c        \
+       gtkradiomenuitem.c      \
+       gtkrange.c              \
+       gtkrc.c                 \
+       gtkruler.c              \
+       gtkscale.c              \
+       gtkscrollbar.c          \
+       gtkscrolledwindow.c     \
+       gtkselection.c          \
+       gtkseparator.c          \
+       gtksignal.c             \
+       gtkstyle.c              \
+       gtktable.c              \
+       gtktext.c               \
+       gtktogglebutton.c       \
+       gtktooltips.c           \
+       gtktree.c               \
+       gtktreeitem.c           \
+       gtktypeutils.c          \
+       gtkvbbox.c              \
+       gtkvbox.c               \
+       gtkviewport.c           \
+       gtkvpaned.c             \
+       gtkvruler.c             \
+       gtkvscale.c             \
+       gtkvscrollbar.c         \
+       gtkvseparator.c         \
+       gtkwidget.c             \
+       gtkwindow.c             \
+       fnmatch.c               \
+       fnmatch.h
+
+gtkinclude_HEADERS = \
+       gtk.h                   \
+       gtkaccelerator.h        \
+       gtkadjustment.h         \
+       gtkaspectframe.h        \
+       gtkalignment.h          \
+       gtkarrow.h              \
+       gtkbin.h                \
+       gtkbbox.h               \
+       gtkbox.h                \
+       gtkbutton.h             \
+       gtkcheckbutton.h        \
+       gtkcheckmenuitem.h      \
+       gtkcolorsel.h           \
+       gtkcontainer.h          \
+       gtkcurve.h              \
+       gtkdata.h               \
+       gtkdialog.h             \
+       gtkdrawingarea.h        \
+       gtkentry.h              \
+       gtkenums.h              \
+       gtkeventbox.h           \
+       gtkfilesel.h            \
+       gtkfixed.h              \
+       gtkframe.h              \
+       gtkgamma.h              \
+       gtkgc.h                 \
+       gtkhbbox.h              \
+       gtkhbox.h               \
+       gtkhpaned.h             \
+       gtkhruler.h             \
+       gtkhscale.h             \
+       gtkhscrollbar.h         \
+       gtkhseparator.h         \
+       gtkimage.h              \
+       gtkinputdialog.h        \
+       gtkitem.h               \
+       gtklabel.h              \
+       gtklist.h               \
+       gtklistitem.h           \
+       gtkmain.h               \
+       gtkmenu.h               \
+       gtkmenubar.h            \
+       gtkmenufactory.h        \
+       gtkmenuitem.h           \
+       gtkmenushell.h          \
+       gtkmisc.h               \
+       gtknotebook.h           \
+       gtkobject.h             \
+       gtkoptionmenu.h         \
+       gtkpaned.h              \
+       gtkpixmap.h             \
+       gtkpreview.h            \
+       gtkprogressbar.h        \
+       gtkradiobutton.h        \
+       gtkradiomenuitem.h      \
+       gtkrange.h              \
+       gtkrc.h                 \
+       gtkruler.h              \
+       gtkscale.h              \
+       gtkscrollbar.h          \
+       gtkscrolledwindow.h     \
+       gtkselection.h          \
+       gtkseparator.h          \
+       gtksignal.h             \
+       gtkstyle.h              \
+       gtktable.h              \
+       gtktext.h               \
+       gtktogglebutton.h       \
+       gtktooltips.h           \
+       gtktree.h               \
+       gtktreeitem.h           \
+       gtktypeutils.h          \
+       gtkvbbox.h              \
+       gtkvbox.h               \
+       gtkviewport.h           \
+       gtkvpaned.h             \
+       gtkvruler.h             \
+       gtkvscale.h             \
+       gtkvscrollbar.h         \
+       gtkvseparator.h         \
+       gtkwidget.h             \
+       gtkwindow.h             \
+       gtktypebuiltins.h
+
+../gtk/gtktypebuiltins.h: gtk.defs gentypeinfo.el
+       $(srcdir)/runelisp $(srcdir)/gentypeinfo.el idmac $< $@
+
+gtktypebuiltins.c: gtk.defs gentypeinfo.el
+       $(srcdir)/runelisp $(srcdir)/gentypeinfo.el id $< $@
+
+libgtk_la_LDFLAGS = -version-info 1:0:
+
+EXTRA_DIST = \
+       line-arrow.xbm          \
+       line-wrap.xbm           \
+       testgtkrc               \
+       gtk.defs                \
+       runelisp                \
+       gentypeinfo.el          \
+       gtktypebuiltins.c       \
+       test.xpm                \
+       marble.xpm              \
+       3DRings.xpm             \
+       FilesQueue.xpm          \
+       Modeller.xpm
+
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/glib @x_cflags@ 
+
+noinst_PROGRAMS = testgtk testinput testselection simple
+testgtk_LDADD = \
+       libgtk.la                               \
+       $(top_builddir)/gdk/libgdk.la           \
+       @x_ldflags@                             \
+       @x_libs@                                \
+       $(top_builddir)/glib/libglib.la         \
+       -lm
+
+testinput_LDADD = \
+       libgtk.la                               \
+       $(top_builddir)/gdk/libgdk.la           \
+       @x_ldflags@                             \
+       @x_libs@                                \
+       $(top_builddir)/glib/libglib.la         \
+       -lm
+
+testselection_LDADD = \
+       libgtk.la                               \
+       $(top_builddir)/gdk/libgdk.la           \
+       @x_ldflags@                             \
+       @x_libs@                                \
+       $(top_builddir)/glib/libglib.la         \
+       -lm
+
+simple_LDADD = \
+       libgtk.la                               \
+       $(top_builddir)/gdk/libgdk.la           \
+       @x_ldflags@                             \
+       @x_libs@                                \
+       $(top_builddir)/glib/libglib.la         \
+       -lm
+
+DEPS = \
+       $(top_builddir)/gtk/libgtk.la           \
+       $(top_builddir)/gdk/libgdk.la           \
+       $(top_builddir)/glib/libglib.la
+
+testgtk_DEPENDENCIES = $(DEPS)
+testinput_DEPENDENCIES = $(DEPS)
+testselection_DEPENDENCIES = $(DEPS)
+simple_DEPENDENCIES = $(DEPS)
+
+.PHONY: files
+
+files:
+       @files=`ls $(DISTFILES) 2> /dev/null `; for p in $$files; do \
+         echo $$p; \
+       done
diff --git a/gtk/Modeller.xpm b/gtk/Modeller.xpm
new file mode 100644 (file)
index 0000000..62e27f9
--- /dev/null
@@ -0,0 +1,117 @@
+/* XPM */
+static char * InterfaceModeller_app_2_Tile_xpm[] = {
+"48 48 66 1",
+"      c None",
+".     c #86174D344103",
+"X     c #69A651445144",
+"o     c #8617410330C2",
+"O     c #69A6410338E3",
+"+     c #30C218611861",
+"@     c #AEBA6DB66185",
+"#     c #71C638E328A2",
+"$     c #69A634D328A2",
+"%     c #30C228A228A2",
+"&     c #79E73CF330C2",
+"*     c #BEFB9E799E79",
+"=     c #8E3869A66185",
+"-     c #514424921861",
+";     c #A699A289B6DA",
+":     c #A6999E79A699",
+">     c #71C65D756185",
+",     c #9E799A69A699",
+"<     c #8E3882078E38",
+"1     c #861779E78617",
+"2     c #A6999A69AEBA",
+"3     c #8E388A289658",
+"4     c #71C675D679E7",
+"5     c #96588A289E79",
+"6     c #30C230C238E3",
+"7     c #C71BC71BC71B",
+"8     c #9E79A289AEBA",
+"9     c #AEBAAAAABEFB",
+"0     c #96589248A699",
+"q     c #A699AAAAB6DA",
+"w     c #AEBAAAAAB6DA",
+"e     c #D75CD34CD75C",
+"r     c #EFBEE79DEFBE",
+"t     c #BEFBB6DABEFB",
+"y     c #B6DABAEAC71B",
+"u     c #AEBAAEBAB6DA",
+"i     c #E79DDB6CDF7D",
+"p     c #96588E389658",
+"a     c #596559656185",
+"s     c #AEBA8E388E38",
+"d     c #CF3CCB2BCF3C",
+"f     c #9E799A699E79",
+"g     c #86177DF78E38",
+"h     c #69A6659571C6",
+"j     c #AEBAAEBABEFB",
+"k     c #96589E799E79",
+"l     c #B6DAA699A699",
+"z     c #E79DC71BC71B",
+"x     c #B6DAB6DAB6DA",
+"c     c #861786179658",
+"v     c #B6DAB2CABEFB",
+"b     c #BEFBAAAAAEBA",
+"n     c #C71BBEFBC71B",
+"m     c #514441034103",
+"M     c #41033CF34103",
+"N     c #492428A228A2",
+"B     c #AEBAA289B6DA",
+"V     c #618530C22081",
+"C     c #69A630C228A2",
+"Z     c #69A630C22081",
+"A     c #596528A22081",
+"S     c #492428A22081",
+"D     c #618528A22081",
+"F     c #596520811861",
+"G     c #69A628A22081",
+"H     c #FFFF14514103",
+"                                            .X  ",
+"                                           .oO+ ",
+"                                         @.o#++ ",
+"                                        @.o$%+  ",
+"                                       @.&#++   ",
+"                                      @.o#++    ",
+"                                     @.o$++     ",
+"                                    @.&#++      ",
+"                                    .O#++       ",
+"                                  *=-$++        ",
+"                                 ;:>+++         ",
+"                                ;,<1%           ",
+"                               2,34             ",
+"                             2;,51              ",
+"                            2,,,,6              ",
+"           7777            28888,6              ",
+"         77777777        2829,,,06              ",
+"    9qwwe7rrrrr77rr     828,9tyt,6              ",
+" uuwriirrieiiieii77pa< 82,8,,,8,06              ",
+" s=1ttiieeeeded77eufgh>j,8,8,k,0,6              ",
+" =@lzieeeeee77eeex:fpcg4>9,,,,qjv6              ",
+" =O=blt7eeee7deenw:ffp<gha:t979;06              ",
+" =OO@=@zieeee7ex:::fffff0,v72444h6              ",
+" =OOo&Osst7iee7wkf:f:ff;t721444ham              ",
+" =#&&&&OO@di7eu:ff:fferiv114444hmMX             ",
+" =O&&&..o.sdp33fff:errrii7cc1hhh6mmNX=          ",
+" =O&&&@.o.@sberrrrrriiuxuxnB;44aMmVCO#OX        ",
+" =O&&o@..o.zrrrie777nnxtuxx:x;n:>mV##&&O$mX     ",
+" =O&&o....zrrieieuxunx7txx:nnfwpMmVZ#$ZZZVVN    ",
+" =O&oooo.*rrde77ewxnxxtnw:f4M%M%+NA#$Z$ZZVmN>   ",
+" =Oo&ooo@iree7inxn7nnuuff4h%M>m%S-AZ$CCZDZmSX   ",
+" =O&o.o.@rrn7eulun7xxuwp4mm6ahM%--AZCCZDDDANX   ",
+" =Ooooo.*rixenuwwn7nxupph%M>>h6mAADVVZVVDDANX   ",
+" =O&o.o.zrexwwnwuxxnughX%mahhmMN-AZCCVVDDAAN>   ",
+" *XOoo.*iin7n777xxxtphaM+ama>MSNFVCZZVVDAAAS>   ",
+"   1O..izewxux7nuuux4%++%hha>%N-DDCZZVDAAAASX   ",
+"    1.=ituu:uButnxxuX%>hh>M%++NADZZZVDADAA--X   ",
+"     :e7f::lnn7*ppnx6ahm6++mNN-ADCZVDDAAAA-SX   ",
+"     7nupp:wxxg%MMau6%++NmmmADADVVVVVDAA---NX   ",
+"    7uBgh1wwxg6h>m%:MmmVNAVDZVZCVZZDAAAAF-S+X   ",
+"    nfgaM%pnwhX6%mXb6$DVVZC$C#C$ZZDVAAA---+NX   ",
+"   27a%MaM47:mN.OoolmODGZ####$$ZZVDDA-----SSX   ",
+"   2gmg<m6p7wmmOo...O$GZ####$$CZVVDAAA----++X   ",
+"  qBcaM  <gxgmXmo.@.o&$$##$$$CZZZDADA-A-++-NX   ",
+"   M6>    paMa HX.@@@oZ$###$$CZVDDAAAA---SS+X   ",
+"  43            p=&@@&&$##$CCCVVVAAA--+S+S+%X   ",
+"        k         =o@.##$VVmmmNNNSSSSSS%XXXX    ",
+"                   s>OSSNmN>>aaa177777          "};
diff --git a/gtk/fnmatch.c b/gtk/fnmatch.c
new file mode 100644 (file)
index 0000000..0a45770
--- /dev/null
@@ -0,0 +1,200 @@
+/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include "fnmatch.h"
+#include <ctype.h>
+
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+   actually compiling the library itself.  This code is part of the GNU C
+   Library, but also included in many other GNU distributions.  Compiling
+   and linking in this code is a waste when using the GNU C library
+   (especially if it is a shared library).  Rather than having every GNU
+   program understand `configure --with-gnu-libc' and omit the object files,
+   it is simpler to just do this in the source for each such file.  */
+
+#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
+
+
+#if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)
+extern int errno;
+#endif
+
+/* Match STRING against the filename pattern PATTERN, returning zero if
+   it matches, nonzero if not.  */
+int
+fnmatch (pattern, string, flags)
+     const char *pattern;
+     const char *string;
+     int flags;
+{
+  register const char *p = pattern, *n = string;
+  register char c;
+
+/* Note that this evalutes C many times.  */
+#define FOLD(c)        ((flags & FNM_CASEFOLD) && isupper (c) ? tolower (c) : (c))
+
+  while ((c = *p++) != '\0')
+    {
+      c = FOLD (c);
+
+      switch (c)
+       {
+       case '?':
+         if (*n == '\0')
+           return FNM_NOMATCH;
+         else if ((flags & FNM_FILE_NAME) && *n == '/')
+           return FNM_NOMATCH;
+         else if ((flags & FNM_PERIOD) && *n == '.' &&
+                  (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+           return FNM_NOMATCH;
+         break;
+
+       case '\\':
+         if (!(flags & FNM_NOESCAPE))
+           {
+             c = *p++;
+             c = FOLD (c);
+           }
+         if (FOLD (*n) != c)
+           return FNM_NOMATCH;
+         break;
+
+       case '*':
+         if ((flags & FNM_PERIOD) && *n == '.' &&
+             (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+           return FNM_NOMATCH;
+
+         for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
+           if (((flags & FNM_FILE_NAME) && *n == '/') ||
+               (c == '?' && *n == '\0'))
+             return FNM_NOMATCH;
+
+         if (c == '\0')
+           return 0;
+
+         {
+           char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
+           c1 = FOLD (c1);
+           for (--p; *n != '\0'; ++n)
+             if ((c == '[' || FOLD (*n) == c1) &&
+                 fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
+               return 0;
+           return FNM_NOMATCH;
+         }
+
+       case '[':
+         {
+           /* Nonzero if the sense of the character class is inverted.  */
+           register int not;
+
+           if (*n == '\0')
+             return FNM_NOMATCH;
+
+           if ((flags & FNM_PERIOD) && *n == '.' &&
+               (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+             return FNM_NOMATCH;
+
+           not = (*p == '!' || *p == '^');
+           if (not)
+             ++p;
+
+           c = *p++;
+           for (;;)
+             {
+               register char cstart = c, cend = c;
+
+               if (!(flags & FNM_NOESCAPE) && c == '\\')
+                 cstart = cend = *p++;
+
+               cstart = cend = FOLD (cstart);
+
+               if (c == '\0')
+                 /* [ (unterminated) loses.  */
+                 return FNM_NOMATCH;
+
+               c = *p++;
+               c = FOLD (c);
+
+               if ((flags & FNM_FILE_NAME) && c == '/')
+                 /* [/] can never match.  */
+                 return FNM_NOMATCH;
+
+               if (c == '-' && *p != ']')
+                 {
+                   cend = *p++;
+                   if (!(flags & FNM_NOESCAPE) && cend == '\\')
+                     cend = *p++;
+                   if (cend == '\0')
+                     return FNM_NOMATCH;
+                   cend = FOLD (cend);
+
+                   c = *p++;
+                 }
+
+               if (FOLD (*n) >= cstart && FOLD (*n) <= cend)
+                 goto matched;
+
+               if (c == ']')
+                 break;
+             }
+           if (!not)
+             return FNM_NOMATCH;
+           break;
+
+         matched:;
+           /* Skip the rest of the [...] that already matched.  */
+           while (c != ']')
+             {
+               if (c == '\0')
+                 /* [... (unterminated) loses.  */
+                 return FNM_NOMATCH;
+
+               c = *p++;
+               if (!(flags & FNM_NOESCAPE) && c == '\\')
+                 /* XXX 1003.2d11 is unclear if this is right.  */
+                 ++p;
+             }
+           if (not)
+             return FNM_NOMATCH;
+         }
+         break;
+
+       default:
+         if (c != FOLD (*n))
+           return FNM_NOMATCH;
+       }
+
+      ++n;
+    }
+
+  if (*n == '\0')
+    return 0;
+
+  if ((flags & FNM_LEADING_DIR) && *n == '/')
+    /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz".  */
+    return 0;
+
+  return FNM_NOMATCH;
+}
+
+#endif /* _LIBC or not __GNU_LIBRARY__.  */
diff --git a/gtk/fnmatch.h b/gtk/fnmatch.h
new file mode 100644 (file)
index 0000000..d9d73b3
--- /dev/null
@@ -0,0 +1,67 @@
+/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#ifndef        _FNMATCH_H
+
+#define        _FNMATCH_H      1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined (__cplusplus) || (defined (__STDC__) && __STDC__)
+#undef __P
+#define        __P(protos)     protos
+#else /* Not C++ or ANSI C.  */
+#undef __P
+#define        __P(protos)     ()
+/* We can get away without defining `const' here only because in this file
+   it is used only inside the prototype for `fnmatch', which is elided in
+   non-ANSI C where `const' is problematical.  */
+#endif /* C++ or ANSI C.  */
+
+
+/* We #undef these before defining them because some losing systems
+   (HP-UX A.08.07 for example) define these in <unistd.h>.  */
+#undef FNM_PATHNAME
+#undef FNM_NOESCAPE
+#undef FNM_PERIOD
+
+/* Bits set in the FLAGS argument to `fnmatch'.  */
+#define        FNM_PATHNAME    (1 << 0) /* No wildcard can ever match `/'.  */
+#define        FNM_NOESCAPE    (1 << 1) /* Backslashes don't quote special chars.  */
+#define        FNM_PERIOD      (1 << 2) /* Leading `.' is matched only explicitly.  */
+
+#if !defined (_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined (_GNU_SOURCE)
+#define        FNM_FILE_NAME   FNM_PATHNAME /* Preferred GNU name.  */
+#define        FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match.  */
+#define        FNM_CASEFOLD    (1 << 4) /* Compare without regard to case.  */
+#endif
+
+/* Value returned by `fnmatch' if STRING does not match PATTERN.  */
+#define        FNM_NOMATCH     1
+
+/* Match STRING against the filename pattern PATTERN,
+   returning zero if it matches, FNM_NOMATCH if not.  */
+extern int fnmatch __P ((const char *__pattern, const char *__string,
+                        int __flags));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* fnmatch.h */
diff --git a/gtk/gentypeinfo.el b/gtk/gentypeinfo.el
new file mode 100644 (file)
index 0000000..2de6a92
--- /dev/null
@@ -0,0 +1,137 @@
+(require 'cl)
+
+;;; file access
+
+(defun read-file (name)
+  (let ((buf (generate-new-buffer "infile"))
+       (res nil))
+    (save-excursion
+      (set-buffer buf)
+      (insert-file-contents name)
+      (condition-case nil
+         (while t
+           (setq res (cons (read buf) res)))
+       (end-of-file (reverse res))))))
+
+(defun setup-outfile ()
+  (setq standard-output (generate-new-buffer "outfile")))
+
+(defun write-outfile (name)
+  (save-excursion
+    (set-buffer standard-output)
+    (write-region (point-min) (point-max) name)))
+
+;;; string stunts
+
+(defun char-upper-case-p (ch)
+  (eql (upcase ch) ch))
+
+(defun char-lower-case-p (ch)
+  (eql (downcase ch) ch))
+
+(defun canonicalize (str)
+  (if (symbolp str)
+      (setq str (symbol-name str)))
+  (let ((res nil)
+       (start 0)
+       (pos 0)
+       (end (length str))
+       (prevlower nil))
+    (while (< pos end)
+      (let ((ch (elt str pos)))
+       (cond ((memq ch '(?- ?_))
+              (setq res (cons (substring str start pos) res)
+                    prevlower nil
+                    pos (1+ pos)
+                    start pos))
+             ((and (char-upper-case-p ch)
+                   prevlower)
+              (setq res (cons (substring str start pos) res)
+                    start pos
+                    pos (1+ pos)
+                    prevlower nil))
+             (t
+              (setq pos (1+ pos)
+                    prevlower (char-lower-case-p ch))))))
+    (reverse (mapcar 'downcase (cons (substring str start end) res)))))
+
+(defun syllables-to-string (syls del)
+  (let ((res ""))
+    (while syls
+      (setq res (format "%s%s%s" res (car syls)
+                       (if (cdr syls) del ""))
+           syls (cdr syls)))
+    res))
+
+(defun macroname (canon)
+  (syllables-to-string (mapcar 'upcase canon) "_"))
+
+(defun funcname (canon)
+  (syllables-to-string canon "_"))
+
+(defun typename (canon)
+  (syllables-to-string (mapcar 'capitalize canon) ""))
+
+(defun scmname (canon)
+  (syllables-to-string canon "-"))
+
+(defun short-name (canon)
+  (if (equal (car canon) "gtk") (cdr canon) canon))
+
+;;; Code generation
+
+(defun printf (&rest args)
+  (princ (apply 'format args)))
+
+(defun interestingp (form)
+  (and (listp form)
+       (memq (car form) '(define-enum define-flags define-boxed))))
+
+(defun map-interesting (func defs)
+  (mapcar #'(lambda (form)
+             (if (interestingp form)
+                 (funcall func form)))
+         defs))
+
+(defun emit-idmacs (defs)
+  (let ((i 0))
+    (map-interesting 
+     #'(lambda (form)
+        (let ((name (canonicalize (cadr form))))
+          (printf "#define GTK_TYPE_%s (gtk_type_builtins[%d])\n"
+                  (macroname (short-name name)) i))
+        (setq i (1+ i)))
+     defs)
+    (printf "#define GTK_TYPE_NUM_BUILTINS %d\n" i)))
+
+(defun emit-ids (defs)
+  (map-interesting
+   #'(lambda (form)
+       (printf "  { %S, %s },\n"
+              (symbol-name (cadr form))
+              (case (car form)
+                ((define-enum) "GTK_TYPE_ENUM")
+                ((define-flags) "GTK_TYPE_FLAGS")
+                ((define-boxed) "GTK_TYPE_BOXED"))))
+   defs))
+
+       
+       
+(if (< (length command-line-args-left) 3)
+    (error "args: op def-file output-file"))
+
+(setq op (intern (car command-line-args-left)))
+(setq defs (read-file (cadr command-line-args-left)))
+(setq outfile (caddr command-line-args-left))
+(setq command-line-args-left nil)
+
+(setup-outfile)
+(printf "/* generated by gentypeinfo from \"gtk.defs\" */\n\n")
+(case op
+  ((idmac)
+   (emit-idmacs defs))
+  ((id)
+   (emit-ids defs))
+  (else
+   (error "supported ops are: idmac id")))
+(write-outfile outfile)
diff --git a/gtk/gtk.defs b/gtk/gtk.defs
new file mode 100644 (file)
index 0000000..0228e7a
--- /dev/null
@@ -0,0 +1,810 @@
+; -*- scheme -*-
+
+;;; Gtk enums
+
+(define-enum GtkWindowType
+  (toplevel GTK_WINDOW_TOPLEVEL)
+  (dialog GTK_WINDOW_DIALOG)
+  (popup GTK_WINDOW_POPUP))
+
+(define-enum GtkStateType
+  (normal GTK_STATE_NORMAL)
+  (active GTK_STATE_ACTIVE)
+  (prelight GTK_STATE_PRELIGHT)
+  (selected GTK_STATE_SELECTED)
+  (insensitive GTK_STATE_INSENSITIVE))
+
+(define-enum GtkDirectionType
+  (tab-forward GTK_DIR_TAB_FORWARD)
+  (tab-backward GTK_DIR_TAB_BACKWARD)
+  (up GTK_DIR_UP)
+  (down GTK_DIR_DOWN)
+  (left GTK_DIR_LEFT)
+  (right GTK_DIR_RIGHT))
+
+(define-enum GtkShadowType
+  (none GTK_SHADOW_NONE)
+  (in GTK_SHADOW_IN)
+  (out GTK_SHADOW_OUT)
+  (etched-in GTK_SHADOW_ETCHED_IN)
+  (etched-out GTK_SHADOW_ETCHED_OUT))
+
+(define-enum GtkArrowType
+  (up GTK_ARROW_UP)
+  (down GTK_ARROW_DOWN)
+  (left GTK_ARROW_LEFT)
+  (right GTK_ARROW_RIGHT))
+
+(define-enum GtkPackType
+  (start GTK_PACK_START)
+  (end GTK_PACK_END))
+
+(define-enum GtkPolicyType
+  (always GTK_POLICY_ALWAYS)
+  (automatic GTK_POLICY_AUTOMATIC))
+
+(define-enum GtkUpdateType
+  (continous GTK_UPDATE_CONTINUOUS)
+  (discontinous GTK_UPDATE_DISCONTINUOUS)
+  (delayed GTK_UPDATE_DELAYED))
+
+(define-flags GtkAttachOptions
+  (expand GTK_EXPAND)
+  (shrink GTK_SHRINK)
+  (fill GTK_FILL))
+
+(define-flags GtkSignalRunType
+  (first GTK_RUN_FIRST)
+  (last GTK_RUN_LAST)
+  (both GTK_RUN_BOTH)
+  (mask GTK_RUN_MASK)
+  (no-recurse GTK_RUN_NO_RECURSE))
+
+(define-enum GtkWindowPosition
+  (none GTK_WIN_POS_NONE)
+  (center GTK_WIN_POS_CENTER)
+  (mouse GTK_WIN_POS_MOUSE))
+
+(define-enum GtkSubmenuDirection
+  (left GTK_DIRECTION_LEFT)
+  (right GTK_DIRECTION_RIGHT))
+
+(define-enum GtkSubmenuPlacement
+  (top-bottom GTK_TOP_BOTTOM)
+  (left-right GTK_LEFT_RIGHT))
+
+(define-enum GtkMenuFactoryType
+  (menu GTK_MENU_FACTORY_MENU)
+  (menu-bar GTK_MENU_FACTORY_MENU_BAR)
+  (option-menu GTK_MENU_FACTORY_OPTION_MENU))
+
+(define-enum GtkMetricType
+  (pixels GTK_PIXELS)
+  (inches GTK_INCHES)
+  (centimeters GTK_CENTIMETERS))
+
+(define-enum GtkScrollType
+  (none GTK_SCROLL_NONE)
+  (step-backward GTK_SCROLL_STEP_BACKWARD)
+  (step-forward GTK_SCROLL_STEP_FORWARD)
+  (page-backward GTK_SCROLL_PAGE_BACKWARD)
+  (page-forward GTK_SCROLL_PAGE_FORWARD))
+
+(define-enum GtkTroughType
+  (none GTK_TROUGH_NONE)
+  (start GTK_TROUGH_START)
+  (end GTK_TROUGH_END))
+
+(define-enum GtkPositionType
+  (left GTK_POS_LEFT)
+  (right GTK_POS_RIGHT)
+  (top GTK_POS_TOP)
+  (bottom GTK_POS_BOTTOM))
+
+(define-enum GtkPreviewType
+  (color GTK_PREVIEW_COLOR)
+  (grayscale GTK_PREVIEW_GRAYSCALE))
+
+(define-flags GtkWidgetFlags
+  (visible GTK_VISIBLE)
+  (mapped GTK_MAPPED)
+  (unmapped GTK_UNMAPPED)
+  (realized GTK_REALIZED)
+  (sensitive GTK_SENSITIVE)
+  (parent-sensitive GTK_PARENT_SENSITIVE)
+  (no-window GTK_NO_WINDOW)
+  (has-focus GTK_HAS_FOCUS)
+  (can-focus GTK_CAN_FOCUS)
+  (has-default GTK_HAS_DEFAULT)
+  (can-default GTK_CAN_DEFAULT)
+  (propagate-state GTK_PROPAGATE_STATE)
+  (anchored GTK_ANCHORED)
+  (basic GTK_BASIC)
+  (user-style GTK_USER_STYLE))
+
+;;; Gdk enums
+
+(define-enum GdkWindowType
+  (root GDK_WINDOW_ROOT)
+  (toplevel GDK_WINDOW_TOPLEVEL)
+  (child GDK_WINDOW_CHILD)
+  (dialog GDK_WINDOW_DIALOG)
+  (temp GDK_WINDOW_TEMP)
+  (pixmap GDK_WINDOW_PIXMAP))
+
+(define-enum GdkWindowClass
+  (input-output GDK_INPUT_OUTPUT)
+  (input-only GDK_INPUT_ONLY))
+
+(define-enum GdkImageType
+  (normal GDK_IMAGE_NORMAL)
+  (shared GDK_IMAGE_SHARED)
+  (fastest GDK_IMAGE_FASTEST))
+
+(define-enum GdkVisualType
+  (static-gray GDK_VISUAL_STATIC_GRAY)
+  (grayscale GDK_VISUAL_GRAYSCALE)
+  (static-color GDK_VISUAL_STATIC_COLOR)
+  (pseudo-color GDK_VISUAL_PSEUDO_COLOR)
+  (true-color GDK_VISUAL_TRUE_COLOR)
+  (direct-color GDK_VISUAL_DIRECT_COLOR))
+
+(define-flags GdkWindowAttributesType
+  (title GDK_WA_TITLE)
+  (x GDK_WA_X)
+  (y GDK_WA_Y)
+  (cursor GDK_WA_CURSOR)
+  (colormap GDK_WA_COLORMAP)
+  (visual GDK_WA_VISUAL))
+
+(define-flags GdkWindowHints
+  (pos GDK_HINT_POS)
+  (min-size GDK_HINT_MIN_SIZE)
+  (max-size GDK_HINT_MAX_SIZE))
+
+(define-enum GdkFunction
+  (copy GDK_COPY)
+  (invert GDK_INVERT)
+  (xor GDK_XOR))
+
+(define-enum GdkFill
+  (solid GDK_SOLID)
+  (tiled GDK_TILED)
+  (stippled GDK_STIPPLED)
+  (opaque-stippled GDK_OPAQUE_STIPPLED))
+
+(define-enum GdkLineStyle
+  (solid GDK_LINE_SOLID)
+  (on-off-dash GDK_LINE_ON_OFF_DASH)
+  (double-dash GDK_LINE_DOUBLE_DASH))
+
+(define-enum GdkCapStyle
+  (not-last GDK_CAP_NOT_LAST)
+  (butt GDK_CAP_BUTT)
+  (round GDK_CAP_ROUND)
+  (projecting GDK_CAP_PROJECTING))
+
+(define-enum GdkJoinStyle
+  (miter GDK_JOIN_MITER)
+  (round GDK_JOIN_ROUND)
+  (bevel GDK_JOIN_BEVEL))
+
+(define-enum GdkCursorType
+  (cursor GDK_LAST_CURSOR))
+
+(define-enum GdkEventType
+  (nothing GDK_NOTHING)
+  (delete GDK_DELETE)
+  (destroy GDK_DESTROY)
+  (expose GDK_EXPOSE)
+  (motion-notify GDK_MOTION_NOTIFY)
+  (button-press GDK_BUTTON_PRESS)
+  (2button-press GDK_2BUTTON_PRESS)
+  (3button-press GDK_3BUTTON_PRESS)
+  (button-release GDK_BUTTON_RELEASE)
+  (key-press GDK_KEY_PRESS)
+  (key-release GDK_KEY_RELEASE)
+  (enter-notify GDK_ENTER_NOTIFY)
+  (leave-notify GDK_LEAVE_NOTIFY)
+  (focus-change GDK_FOCUS_CHANGE)
+  (configure GDK_CONFIGURE)
+  (map GDK_MAP)
+  (unmap GDK_UNMAP)
+  (property-notify GDK_PROPERTY_NOTIFY)
+  (selection-clear GDK_SELECTION_CLEAR)
+  (selection-request GDK_SELECTION_REQUEST)
+  (selection-notify GDK_SELECTION_NOTIFY)
+  (other-event GDK_OTHER_EVENT))
+
+(define-flags GdkEventMask
+  (exposure-mask GDK_EXPOSURE_MASK)
+  (pointer-motion-mask GDK_POINTER_MOTION_MASK)
+  (pointer-motion-hint-mask GDK_POINTER_MOTION_HINT_MASK)
+  (button-motion-mask GDK_BUTTON_MOTION_MASK)
+  (button1-motion-mask GDK_BUTTON1_MOTION_MASK)
+  (button2-motion-mask GDK_BUTTON2_MOTION_MASK)
+  (button3-motion-mask GDK_BUTTON3_MOTION_MASK)
+  (button-press-mask GDK_BUTTON_PRESS_MASK)
+  (button-release-mask GDK_BUTTON_RELEASE_MASK)
+  (key-press-mask GDK_KEY_PRESS_MASK)
+  (key-release-mask GDK_KEY_RELEASE_MASK)
+  (enter-notify-mask GDK_ENTER_NOTIFY_MASK)
+  (leave-notify-mask GDK_LEAVE_NOTIFY_MASK)
+  (focus-change-mask GDK_FOCUS_CHANGE_MASK)
+  (structure-mask GDK_STRUCTURE_MASK)
+  (all-events-mask GDK_ALL_EVENTS_MASK))
+
+(define-enum GdkNotifyType
+  (ancestor GDK_NOTIFY_ANCESTOR)
+  (virtual GDK_NOTIFY_VIRTUAL)
+  (inferior GDK_NOTIFY_INFERIOR)
+  (nonlinear GDK_NOTIFY_NONLINEAR)
+  (nonlinear-virtual GDK_NOTIFY_NONLINEAR_VIRTUAL)
+  (unknown GDK_NOTIFY_UNKNOWN))
+
+(define-flags GdkModifierType
+  (shift-mask GDK_SHIFT_MASK)
+  (lock-mask GDK_LOCK_MASK)
+  (control-mask GDK_CONTROL_MASK)
+  (mod1-mask GDK_MOD1_MASK)
+  (mod2-mask GDK_MOD2_MASK)
+  (mod3-mask GDK_MOD3_MASK)
+  (mod4-mask GDK_MOD4_MASK)
+  (mod5-mask GDK_MOD5_MASK)
+  (button1-mask GDK_BUTTON1_MASK)
+  (button2-mask GDK_BUTTON2_MASK)
+  (button3-mask GDK_BUTTON3_MASK)
+  (button4-mask GDK_BUTTON4_MASK)
+  (button5-mask GDK_BUTTON5_MASK))
+
+(define-enum GdkSubwindowMode
+  (clip-by-children GDK_CLIP_BY_CHILDREN)
+  (include-inferiors GDK_INCLUDE_INFERIORS))
+
+(define-flags GdkInputCondition
+  (read GDK_INPUT_READ)
+  (write GDK_INPUT_WRITE)
+  (exception GDK_INPUT_EXCEPTION))
+
+(define-enum GdkStatus
+  (ok GDK_OK)
+  (error GDK_ERROR)
+  (error-param GDK_ERROR_PARAM)
+  (error-file GDK_ERROR_FILE)
+  (error-mem GDK_ERROR_MEM))
+
+(define-enum GdkByteOrder
+  (lsb-first GDK_LSB_FIRST)
+  (msb-first GDK_MSB_FIRST))
+
+(define-flags GdkGCValuesMask
+  (foreground GDK_GC_FOREGROUND)
+  (background GDK_GC_BACKGROUND)
+  (font GDK_GC_FONT)
+  (function GDK_GC_FUNCTION)
+  (fill GDK_GC_FILL)
+  (tile GDK_GC_TILE)
+  (stipple GDK_GC_STIPPLE)
+  (clip-mask GDK_GC_CLIP_MASK)
+  (subwindow GDK_GC_SUBWINDOW)
+  (ts-x-origin GDK_GC_TS_X_ORIGIN)
+  (ts-y-origin GDK_GC_TS_Y_ORIGIN)
+  (clip-x-origin GDK_GC_CLIP_X_ORIGIN)
+  (clip-y-origin GDK_GC_CLIP_Y_ORIGIN)
+  (exposures GDK_GC_EXPOSURES)
+  (line-width GDK_GC_LINE_WIDTH)
+  (line-style GDK_GC_LINE_STYLE)
+  (cap-style GDK_GC_CAP_STYLE)
+  (join-style GDK_GC_JOIN_STYLE))
+
+(define-enum GdkSelection
+  (primary GDK_SELECTION_PRIMARY)
+  (secondary GDK_SELECTION_SECONDARY))
+
+(define-enum GdkPropertyState
+  (new-value GDK_PROPERTY_NEW_VALUE)
+  (delete GDK_PROPERTY_DELETE))
+
+(define-enum GdkPropMode
+  (replace GDK_PROP_MODE_REPLACE)
+  (prepend GDK_PROP_MODE_PREPEND)
+  (append GDK_PROP_MODE_APPEND))
+
+;;; Gtk boxed types
+
+(define-boxed GtkAcceleratorTable
+  gtk_accelerator_table_ref
+  gtk_accelerator_table_unref)
+
+(define-boxed GtkStyle
+  gtk_style_ref
+  gtk_style_unref)
+
+;;; Gdk boxed types
+
+;(define-boxed GdkPoint
+;  gdk_point_copy
+;  gdk_point_destroy)
+
+(define-boxed GdkColormap
+  gdk_colormap_ref
+  gdk_colormap_unref)
+
+(define-boxed GdkVisual
+  gdk_visual_ref
+  gdk_visual_unref)
+
+(define-boxed GdkFont
+  gdk_font_ref
+  gdk_font_free)
+
+(define-boxed GdkWindow
+  gdk_window_ref
+  gdk_window_unref)
+
+(define-boxed GdkEvent
+  gdk_event_copy
+  gdk_event_free)
+
+;;; Functions
+
+(define-func gtk_exit
+  none
+  (int code 0))
+
+(define-func gtk_rc_parse
+  none
+  (string file))
+
+(define-func g_mem_chunk_info
+  none)
+
+;; GtkObject
+
+(define-func gtk_object_destroy
+  none
+  (GtkObject object))
+
+;; GtkWidget
+
+(define-object GtkWidget (GtkObject))
+
+(define-func GTK_WIDGET_STATE
+  GtkStateType
+  (GtkWidget widget))
+
+(define-func GTK_WIDGET_FLAGS
+  GtkWidgetFlags
+  (GtkWidget widget))
+
+(define-func GTK_WIDGET_SET_FLAGS
+  none
+  (GtkWidget widget)
+  (GtkWidgetFlags flags))
+
+(define-func GTK_WIDGET_UNSET_FLAGS
+  none
+  (GtkWidget widget)
+  (GtkWidgetFlags flags))
+
+(define-func gtk_widget_destroy
+  none
+  (GtkWidget widget))
+
+(define-func gtk_widget_unparent
+  none
+  (GtkWidget widget))
+
+(define-func gtk_widget_show
+  none
+  (GtkWidget widget))
+
+(define-func gtk_widget_hide
+  none
+  (GtkWidget widget))
+
+(define-func gtk_widget_map
+  none
+  (GtkWidget widget))
+
+(define-func gtk_widget_unmap
+  none
+  (GtkWidget widget))
+
+(define-func gtk_widget_realize
+  none
+  (GtkWidget widget))
+
+(define-func gtk_widget_unrealize
+  none
+  (GtkWidget widget))
+
+;(define-func gtk_widget_install_accelerator
+;  none
+;  (GtkWidget widget)
+;  (GtkAcceleratorTable table)
+;  (string signal_name)
+;  (char key)
+;  (...))
+
+(define-func gtk_widget_remove_accelerator
+  none
+  (GtkWidget widget)
+  (GtkAcceleratorTable table)
+  (string signal_name))
+
+;(define-func gtk_widget_event
+;  bool
+;  (GtkWidget widget)
+;  (GdkEvent event))
+
+(define-func gtk_widget_activate
+  none
+  (GtkWidget widget))
+
+(define-func gtk_widget_reparent
+  none
+  (GtkWidget widget)
+  (GtkWidget new_parent))
+
+(define-func gtk_widget_popup
+  none
+  (GtkWidget widget)
+  (int x)
+  (int y))
+
+(define-func gtk_widget_basic
+  bool
+  (GtkWidget widget))
+
+(define-func gtk_widget_grab_focus
+  none
+  (GtkWidget widget))
+
+(define-func gtk_widget_grab_default
+  none
+  (GtkWidget widget))
+
+(define-func gtk_widget_restore_state
+  none
+  (GtkWidget widget))
+
+(define-func gtk_widget_set_name
+  none
+  (GtkWidget widget)
+  (string name))
+
+(define-func gtk_widget_get_name
+  static_string
+  (GtkWidget widget))
+
+(define-func gtk_widget_set_state
+  none
+  (GtkWidget widget)
+  (GtkStateType state))
+
+(define-func gtk_widget_set_sensitive
+  none
+  (GtkWidget widget)
+  (bool sensitive))
+
+(define-func gtk_widget_set_style
+  none
+  (GtkWidget widget)
+  (GtkStyle style))
+
+(define-func gtk_widget_set_uposition
+  none
+  (GtkWidget widget)
+  (int x)
+  (int y))
+
+(define-func gtk_widget_set_usize
+  none
+  (GtkWidget widget)
+  (int height)
+  (int width))
+
+(define-func gtk_widget_set_events
+  none
+  (GtkWidget widget)
+  (GdkEventMask events))
+
+(define-func gtk_widget_set_extension_events
+  none
+  (GtkWidget widget)
+  (GdkEventMask events))
+
+(define-func gtk_widget_get_toplevel
+  GtkWidget
+  (GtkWidget widget))
+
+;(define-func gtk_widget_get_ancestor
+;  GtkWidget
+;  (GtkWidget widget)
+;  (GtkType type))
+
+(define-func gtk_widget_get_colormap
+  GdkColormap
+  (GtkWidget widget))
+
+(define-func gtk_widget_get_visual
+  GdkVisual
+  (GtkWidget widget))
+
+(define-func gtk_widget_get_style
+  GtkStyle
+  (GtkWidget widget))
+
+(define-func gtk_widget_get_events
+  GdkEventMask
+  (GtkWidget widget))
+
+(define-func gtk_widget_get_extension_events
+  GdkEventMask
+  (GtkWidget widget))
+
+(define-func gtk_widget_push_colormap
+  none
+  (GdkColormap cmap))
+
+(define-func gtk_widget_push_visual
+  none
+  (GdkVisual visual))
+
+(define-func gtk_widget_push_style
+  none
+  (GtkStyle style))
+
+(define-func gtk_widget_pop_colormap
+  none)
+
+(define-func gtk_widget_pop_visual
+  none)
+
+(define-func gtk_widget_pop_style
+  none)
+
+(define-func gtk_widget_set_default_colormap
+  none
+  (GdkColormap cmap))
+
+(define-func gtk_widget_set_default_visual
+  none
+  (GdkVisual visual))
+
+(define-func gtk_widget_set_default_style
+  none
+  (GtkStyle style))
+
+(define-func gtk_widget_get_default_colormap
+  GdkColormap)
+
+(define-func gtk_widget_get_default_visual
+  GdkVisual)
+
+(define-func gtk_widget_get_default_style
+  GtkStyle)
+
+;;; Container
+
+(define-object GtkContainer (GtkWidget))
+
+(define-func gtk_container_border_width
+  none
+  (GtkContainer container)
+  (int border_width))
+
+(define-func gtk_container_add
+  none
+  (GtkContainer container)
+  (GtkWidget widget))
+
+(define-func gtk_container_remove
+  none
+  (GtkContainer container)
+  (GtkWidget widget))
+
+(define-func gtk_container_disable_resize
+  none
+  (GtkContainer container))
+
+(define-func gtk_container_enable_resize
+  none
+  (GtkContainer container))
+
+(define-func gtk_container_block_resize
+  none
+  (GtkContainer container))
+
+(define-func gtk_container_unblock_resize
+  none
+  (GtkContainer container))
+
+(define-func gtk_container_need_resize
+  bool
+  (GtkContainer container)
+  (GtkWidget widget))
+
+(define-func gtk_container_check_resize
+  none
+  (GtkContainer container)
+  (GtkWidget widget))
+
+(define-func gtk_container_focus
+  GtkDirectionType
+  (GtkContainer container)
+  (GtkDirectionType direction))
+
+;;; Bin
+
+(define-object GtkBin (GtkContainer))
+
+;;; Window
+
+(define-object GtkWindow (GtkBin))
+
+(define-func gtk_window_new
+  GtkWidget
+  (GtkWindowType type))
+
+(define-func gtk_window_set_title
+  none
+  (GtkWindow window)
+  (string title))
+
+(define-func gtk_window_set_focus
+  none
+  (GtkWindow window)
+  (GtkWidget focus))
+
+(define-func gtk_window_set_default
+  none
+  (GtkWindow window)
+  (GtkWidget default))
+
+(define-func gtk_window_set_policy
+  none
+  (GtkWindow window)
+  (bool allow_shrink)
+  (bool allow_grow)
+  (bool auto_shrink))
+
+(define-func gtk_window_add_accelerator_table
+  none
+  (GtkWindow window)
+  (GtkAcceleratorTable table))
+
+(define-func gtk_window_remove_accelerator_table
+  none
+  (GtkWindow window)
+  (GtkAcceleratorTable table))
+
+(define-func gtk_window_position
+  none
+  (GtkWindow window)
+  (GtkWindowPosition position))
+
+;;; Box
+
+(define-object GtkBox (GtkContainer))
+
+;;; Table
+
+(define-object GtkTable (GtkContainer))
+
+;;; Button
+
+(define-object GtkButton (GtkContainer))
+
+;;; ToggleButton
+
+(define-object GtkToggleButton (GtkButton))
+
+;;; CheckButton
+
+(define-object GtkCheckButton (GtkToggleButton))
+
+;;; RadioButton
+
+(define-object GtkRadioButton (GtkCheckButton))
+
+
+;; misc
+
+
+(define-func gtk_button_new_with_label
+  GtkWidget
+  (string label))
+
+(define-func gtk_vbox_new
+  GtkWidget
+  (bool homogenous)
+  (int spacing))
+
+(define-func gtk_hbox_new
+  GtkWidget
+  (bool homogenous)
+  (int spacing))
+
+(define-func gtk_hseparator_new
+  GtkWidget)
+
+(define-func gtk_box_pack_start
+  none
+  (GtkBox box)
+  (GtkWidget child)
+  (bool expand)
+  (bool fill)
+  (int padding))
+
+(define-func gtk_table_new
+  GtkWidget
+  (int rows)
+  (int columns)
+  (bool homogenous))
+
+(define-func gtk_table_attach
+  none
+  (GtkTable table)
+  (GtkWidget child)
+  (int left_attach)
+  (int right_attach)
+  (int top_attach)
+  (int bottom_attach)
+  (GtkAttachOptions xoptions)
+  (GtkAttachOptions yoptions)
+  (int xpadding)
+  (int ypadding))
+
+(define-func gtk_table_attach_defaults
+  none
+  (GtkTable table)
+  (GtkWidget child)
+  (int left_attach)
+  (int right_attach)
+  (int top_attach)
+  (int bottom_attach))
+
+(define-func gtk_table_set_row_spacing
+  none
+  (GtkTable table)
+  (int row)
+  (int spacing))
+
+(define-func gtk_table_set_col_spacing
+  none
+  (GtkTable table)
+  (int col)
+  (int spacing))
+
+(define-func gtk_table_set_row_spacings
+  none
+  (GtkTable table)
+  (int spacing))
+
+(define-func gtk_table_set_col_spacings
+  none
+  (GtkTable table)
+  (int spacing))
+
+(define-func gtk_toggle_button_new_with_label
+  GtkWidget
+  (string label))
+
+(define-func gtk_check_button_new_with_label
+  GtkWidget
+  (string label))
+
+(define-func gtk_radio_button_new_with_label_from_widget
+  GtkWidget
+  (GtkRadioButton group)
+  (string label))
+
+(define-func gtk_label_new
+  GtkWidget
+  (string label))
+
+(define-func gtk_frame_new
+  GtkWidget
+  (string label))
diff --git a/gtk/gtk.h b/gtk/gtk.h
new file mode 100644 (file)
index 0000000..acd1b10
--- /dev/null
+++ b/gtk/gtk.h
@@ -0,0 +1,106 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_H__
+#define __GTK_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkaccelerator.h>
+#include <gtk/gtkadjustment.h>
+#include <gtk/gtkalignment.h>
+#include <gtk/gtkaspectframe.h>
+#include <gtk/gtkarrow.h>
+#include <gtk/gtkbin.h>
+#include <gtk/gtkbox.h>
+#include <gtk/gtkbbox.h>
+#include <gtk/gtkbutton.h>
+#include <gtk/gtkcheckbutton.h>
+#include <gtk/gtkcheckmenuitem.h>
+#include <gtk/gtkcolorsel.h>
+#include <gtk/gtkcontainer.h>
+#include <gtk/gtkcurve.h>
+#include <gtk/gtkdata.h>
+#include <gtk/gtkdialog.h>
+#include <gtk/gtkdrawingarea.h>
+#include <gtk/gtkentry.h>
+#include <gtk/gtkenums.h>
+#include <gtk/gtkeventbox.h>
+#include <gtk/gtkfilesel.h>
+#include <gtk/gtkfixed.h>
+#include <gtk/gtkframe.h>
+#include <gtk/gtkgamma.h>
+#include <gtk/gtkgc.h>
+#include <gtk/gtkhbox.h>
+#include <gtk/gtkhbbox.h>
+#include <gtk/gtkhpaned.h>
+#include <gtk/gtkhruler.h>
+#include <gtk/gtkhscale.h>
+#include <gtk/gtkhscrollbar.h>
+#include <gtk/gtkhseparator.h>
+#include <gtk/gtkimage.h>
+#include <gtk/gtkinputdialog.h>
+#include <gtk/gtkitem.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtklist.h>
+#include <gtk/gtklistitem.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtkmenu.h>
+#include <gtk/gtkmenubar.h>
+#include <gtk/gtkmenufactory.h>
+#include <gtk/gtkmenuitem.h>
+#include <gtk/gtkmenushell.h>
+#include <gtk/gtkmisc.h>
+#include <gtk/gtknotebook.h>
+#include <gtk/gtkobject.h>
+#include <gtk/gtkoptionmenu.h>
+#include <gtk/gtkpaned.h>
+#include <gtk/gtkpixmap.h>
+#include <gtk/gtkpreview.h>
+#include <gtk/gtkprogressbar.h>
+#include <gtk/gtkradiobutton.h>
+#include <gtk/gtkradiomenuitem.h>
+#include <gtk/gtkrange.h>
+#include <gtk/gtkrc.h>
+#include <gtk/gtkruler.h>
+#include <gtk/gtkscale.h>
+#include <gtk/gtkscrollbar.h>
+#include <gtk/gtkscrolledwindow.h>
+#include <gtk/gtkselection.h>
+#include <gtk/gtkseparator.h>
+#include <gtk/gtksignal.h>
+#include <gtk/gtkstyle.h>
+#include <gtk/gtktable.h>
+#include <gtk/gtktext.h>
+#include <gtk/gtktogglebutton.h>
+#include <gtk/gtktooltips.h>
+#include <gtk/gtktree.h>
+#include <gtk/gtktreeitem.h>
+#include <gtk/gtktypeutils.h>
+#include <gtk/gtkvbox.h>
+#include <gtk/gtkvbbox.h>
+#include <gtk/gtkviewport.h>
+#include <gtk/gtkvpaned.h>
+#include <gtk/gtkvruler.h>
+#include <gtk/gtkvscale.h>
+#include <gtk/gtkvscrollbar.h>
+#include <gtk/gtkvseparator.h>
+#include <gtk/gtkwidget.h>
+#include <gtk/gtkwindow.h>
+
+
+#endif /* __GTK_H__ */
diff --git a/gtk/gtkaccelerator.c b/gtk/gtkaccelerator.c
new file mode 100644 (file)
index 0000000..a06a06a
--- /dev/null
@@ -0,0 +1,352 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <ctype.h>
+#include "gtkaccelerator.h"
+#include "gtksignal.h"
+#include "gtkwidget.h"
+
+
+typedef struct _GtkAcceleratorEntry GtkAcceleratorEntry;
+
+struct _GtkAcceleratorEntry
+{
+  guint8 modifiers;
+  GtkObject *object;
+  gint signal_num;
+};
+
+
+static void gtk_accelerator_table_init  (GtkAcceleratorTable *table);
+static void gtk_accelerator_table_clean (GtkAcceleratorTable *table);
+
+
+static GtkAcceleratorTable *default_table = NULL;
+static GSList *tables = NULL;
+static guint8 gtk_accelerator_table_default_mod_mask = ~0;
+
+
+GtkAcceleratorTable*
+gtk_accelerator_table_new ()
+{
+  GtkAcceleratorTable *table;
+
+  table = g_new (GtkAcceleratorTable, 1);
+  gtk_accelerator_table_init (table);
+
+  tables = g_slist_prepend (tables, table);
+
+  return table;
+}
+
+GtkAcceleratorTable*
+gtk_accelerator_table_find (GtkObject   *object,
+                           const gchar *signal_name,
+                           guchar       accelerator_key,
+                           guint8       accelerator_mods)
+{
+  GtkAcceleratorTable *table;
+  GtkAcceleratorEntry *entry;
+  GSList *tmp_list;
+  GList *entries;
+  gint signal_num;
+  guint hash;
+
+  g_return_val_if_fail (object != NULL, NULL);
+  g_return_val_if_fail (signal_name != NULL, NULL);
+
+  signal_num = gtk_signal_lookup (signal_name, GTK_OBJECT_TYPE (object));
+  hash = (guint) accelerator_key;
+
+  tmp_list = tables;
+  while (tmp_list)
+    {
+      table = tmp_list->data;
+      tmp_list = tmp_list->next;
+
+      entries = table->entries[hash];
+      while (entries)
+       {
+         entry = entries->data;
+         entries = entries->next;
+
+         if ((entry->object == object) &&
+             (entry->signal_num == signal_num) &&
+             ((entry->modifiers & table->modifier_mask) ==
+              (accelerator_mods & table->modifier_mask)))
+           return table;
+       }
+    }
+
+  return NULL;
+}
+
+void
+gtk_accelerator_table_destroy (GtkAcceleratorTable *table)
+{
+  g_return_if_fail (table != NULL);
+  g_return_if_fail (table->ref_count <= 0);
+
+  tables = g_slist_remove (tables, table);
+  gtk_accelerator_table_clean (table);
+  g_free (table);
+}
+
+GtkAcceleratorTable*
+gtk_accelerator_table_ref (GtkAcceleratorTable *table)
+{
+  g_return_val_if_fail (table != NULL, NULL);
+
+  table->ref_count += 1;
+  return table;
+}
+
+void
+gtk_accelerator_table_unref (GtkAcceleratorTable *table)
+{
+  g_return_if_fail (table != NULL);
+
+  table->ref_count -= 1;
+  if (table->ref_count <= 0)
+    gtk_accelerator_table_destroy (table);
+}
+
+void
+gtk_accelerator_table_install (GtkAcceleratorTable *table,
+                              GtkObject           *object,
+                              const gchar         *signal_name,
+                              guchar               accelerator_key,
+                              guint8               accelerator_mods)
+{
+  GtkAcceleratorEntry *entry;
+  GList *entries;
+  gchar *signame;
+  gint signal_num;
+  guint hash;
+
+  g_return_if_fail (object != NULL);
+
+  if (!table)
+    {
+      if (!default_table)
+       default_table = gtk_accelerator_table_new ();
+      table = default_table;
+    }
+
+  signal_num = gtk_signal_lookup (signal_name, GTK_OBJECT_TYPE (object));
+  g_return_if_fail (signal_num != 0);
+
+  hash = (guint) accelerator_key;
+  entries = table->entries[hash];
+
+  while (entries)
+    {
+      entry = entries->data;
+
+      if ((entry->modifiers & table->modifier_mask) ==
+          (accelerator_mods & table->modifier_mask))
+       {
+         if (GTK_IS_WIDGET (entry->object))
+           {
+             signame = gtk_signal_name (entry->signal_num);
+             gtk_signal_emit_by_name (entry->object,
+                                      "remove_accelerator",
+                                      signame);
+           }
+
+         entry->modifiers = accelerator_mods;
+         entry->object = object;
+         entry->signal_num = signal_num;
+         return;
+       }
+
+      entries = entries->next;
+    }
+
+  entry = g_new (GtkAcceleratorEntry, 1);
+  entry->modifiers = accelerator_mods;
+  entry->object = object;
+  entry->signal_num = signal_num;
+
+  table->entries[hash] = g_list_prepend (table->entries[hash], entry);
+}
+
+void
+gtk_accelerator_table_remove (GtkAcceleratorTable *table,
+                             GtkObject           *object,
+                             const gchar         *signal_name)
+{
+  GtkAcceleratorEntry *entry;
+  GList *entries;
+  GList *temp_list;
+  gint signal_num;
+  gint i;
+
+  g_return_if_fail (object != NULL);
+
+  if (!table)
+    {
+      if (!default_table)
+       default_table = gtk_accelerator_table_new ();
+      table = default_table;
+    }
+
+  signal_num = gtk_signal_lookup (signal_name, GTK_OBJECT_TYPE (object));
+  g_return_if_fail (signal_num != 0);
+
+  for (i = 0; i < 256; i++)
+    {
+      entries = table->entries[i];
+
+      while (entries)
+       {
+         entry = entries->data;
+
+         if ((entry->object == object) && (entry->signal_num == signal_num))
+           {
+             g_free (entry);
+
+             temp_list = entries;
+             if (entries->next)
+               entries->next->prev = entries->prev;
+             if (entries->prev)
+               entries->prev->next = entries->next;
+             if (table->entries[i] == entries)
+               table->entries[i] = entries->next;
+
+             temp_list->next = NULL;
+             temp_list->prev = NULL;
+             g_list_free (temp_list);
+
+             return;
+           }
+
+         entries = entries->next;
+       }
+    }
+}
+
+gint
+gtk_accelerator_table_check (GtkAcceleratorTable *table,
+                            const guchar         accelerator_key,
+                            guint8               accelerator_mods)
+{
+  GtkAcceleratorEntry *entry;
+  GList *entries;
+  guint hash;
+
+  if (!table)
+    {
+      if (!default_table)
+       default_table = gtk_accelerator_table_new ();
+      table = default_table;
+    }
+
+  hash = (guint) accelerator_key;
+  entries = table->entries[hash];
+
+  while (entries)
+    {
+      entry = entries->data;
+
+      if ((entry->modifiers & table->modifier_mask) ==
+          (accelerator_mods & table->modifier_mask))
+       {
+         gtk_signal_emit (entry->object, entry->signal_num);
+         return TRUE;
+       }
+
+      entries = entries->next;
+    }
+
+  if (!isupper (hash))
+    {
+      hash = toupper (hash);
+      entries = table->entries[hash];
+
+      while (entries)
+       {
+         entry = entries->data;
+
+         if (((entry->modifiers & table->modifier_mask) ==
+              (accelerator_mods & table->modifier_mask)) &&
+             (GTK_IS_WIDGET (entry->object) &&
+              GTK_WIDGET_SENSITIVE (entry->object)))
+           {
+             gtk_signal_emit (entry->object, entry->signal_num);
+             return TRUE;
+           }
+
+         entries = entries->next;
+       }
+    }
+
+  return FALSE;
+}
+
+void
+gtk_accelerator_table_set_mod_mask (GtkAcceleratorTable *table,
+                                    guint8               modifier_mask)
+{
+  if (table == NULL)
+    {
+      gtk_accelerator_table_default_mod_mask = modifier_mask;
+    }
+  else
+    {
+      table->modifier_mask = modifier_mask;
+    }
+}
+
+static void
+gtk_accelerator_table_init (GtkAcceleratorTable *table)
+{
+  gint i;
+
+  g_return_if_fail (table != NULL);
+
+  for (i = 0; i < 256; i++)
+    table->entries[i] = NULL;
+
+  table->ref_count = 0;
+  table->modifier_mask = gtk_accelerator_table_default_mod_mask;
+}
+
+static void
+gtk_accelerator_table_clean (GtkAcceleratorTable *table)
+{
+  GtkAcceleratorEntry *entry;
+  GList *entries;
+  gint i;
+
+  g_return_if_fail (table != NULL);
+
+  for (i = 0; i < 256; i++)
+    {
+      entries = table->entries[i];
+      while (entries)
+       {
+         entry = entries->data;
+         entries = entries->next;
+
+         g_free (entry);
+       }
+
+      g_list_free (table->entries[i]);
+      table->entries[i] = NULL;
+    }
+}
diff --git a/gtk/gtkaccelerator.h b/gtk/gtkaccelerator.h
new file mode 100644 (file)
index 0000000..ac63232
--- /dev/null
@@ -0,0 +1,73 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_ACCELERATOR_H__
+#define __GTK_ACCELERATOR_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkobject.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+typedef struct _GtkAcceleratorTable GtkAcceleratorTable;
+
+struct _GtkAcceleratorTable
+{
+  GList *entries[256];
+  gint ref_count;
+  guint8 modifier_mask;
+};
+
+
+/* Accelerator tables.
+ */
+GtkAcceleratorTable* gtk_accelerator_table_new  (void);
+GtkAcceleratorTable* gtk_accelerator_table_find (GtkObject *object,
+                                                const gchar     *signal_name,
+                                                guchar     accelerator_key,
+                                                guint8     accelerator_mods);
+
+void gtk_accelerator_table_destroy (GtkAcceleratorTable *table);
+GtkAcceleratorTable *gtk_accelerator_table_ref (GtkAcceleratorTable *table);
+void gtk_accelerator_table_unref   (GtkAcceleratorTable *table);
+void gtk_accelerator_table_install (GtkAcceleratorTable *table,
+                                   GtkObject           *object,
+                                   const gchar         *signal_name,
+                                   guchar               accelerator_key,
+                                   guint8               accelerator_mods);
+void gtk_accelerator_table_remove  (GtkAcceleratorTable *table,
+                                   GtkObject           *object,
+                                   const gchar         *signal_name);
+gint gtk_accelerator_table_check   (GtkAcceleratorTable *table,
+                                   const guchar         accelerator_key,
+                                   guint8               accelerator_mods);
+
+void gtk_accelerator_table_set_mod_mask (GtkAcceleratorTable *table,
+                                        guint8               modifier_mask);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_ACCELERATOR_H__ */
diff --git a/gtk/gtkadjustment.c b/gtk/gtkadjustment.c
new file mode 100644 (file)
index 0000000..ab6e63d
--- /dev/null
@@ -0,0 +1,118 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkadjustment.h"
+#include "gtksignal.h"
+
+
+enum {
+  CHANGED,
+  VALUE_CHANGED,
+  LAST_SIGNAL
+};
+
+
+static void gtk_adjustment_class_init (GtkAdjustmentClass *klass);
+static void gtk_adjustment_init       (GtkAdjustment      *adjustment);
+
+
+static gint adjustment_signals[LAST_SIGNAL] = { 0 };
+
+
+guint
+gtk_adjustment_get_type ()
+{
+  static guint adjustment_type = 0;
+
+  if (!adjustment_type)
+    {
+      GtkTypeInfo adjustment_info =
+      {
+       "GtkAdjustment",
+       sizeof (GtkAdjustment),
+       sizeof (GtkAdjustmentClass),
+       (GtkClassInitFunc) gtk_adjustment_class_init,
+       (GtkObjectInitFunc) gtk_adjustment_init,
+       (GtkArgFunc) NULL,
+      };
+
+      adjustment_type = gtk_type_unique (gtk_data_get_type (), &adjustment_info);
+    }
+
+  return adjustment_type;
+}
+
+static void
+gtk_adjustment_class_init (GtkAdjustmentClass *class)
+{
+  GtkObjectClass *object_class;
+
+  object_class = (GtkObjectClass*) class;
+
+  adjustment_signals[CHANGED] =
+    gtk_signal_new ("changed",
+                    GTK_RUN_FIRST | GTK_RUN_NO_RECURSE,
+                    object_class->type,
+                    GTK_SIGNAL_OFFSET (GtkAdjustmentClass, changed),
+                    gtk_signal_default_marshaller,
+                   GTK_TYPE_NONE, 0);
+  adjustment_signals[VALUE_CHANGED] =
+    gtk_signal_new ("value_changed",
+                    GTK_RUN_FIRST | GTK_RUN_NO_RECURSE,
+                    object_class->type,
+                    GTK_SIGNAL_OFFSET (GtkAdjustmentClass, value_changed),
+                    gtk_signal_default_marshaller,
+                   GTK_TYPE_NONE, 0);
+
+  gtk_object_class_add_signals (object_class, adjustment_signals, LAST_SIGNAL);
+
+  class->changed = NULL;
+  class->value_changed = NULL;
+}
+
+static void
+gtk_adjustment_init (GtkAdjustment *adjustment)
+{
+  adjustment->value = 0.0;
+  adjustment->lower = 0.0;
+  adjustment->upper = 0.0;
+  adjustment->step_increment = 0.0;
+  adjustment->page_increment = 0.0;
+  adjustment->page_size = 0.0;
+}
+
+GtkObject*
+gtk_adjustment_new (gfloat value,
+                   gfloat lower,
+                   gfloat upper,
+                   gfloat step_increment,
+                   gfloat page_increment,
+                   gfloat page_size)
+{
+  GtkAdjustment *adjustment;
+
+  adjustment = gtk_type_new (gtk_adjustment_get_type ());
+
+  adjustment->value = value;
+  adjustment->lower = lower;
+  adjustment->upper = upper;
+  adjustment->step_increment = step_increment;
+  adjustment->page_increment = page_increment;
+  adjustment->page_size = page_size;
+
+  return GTK_OBJECT (adjustment);
+}
diff --git a/gtk/gtkadjustment.h b/gtk/gtkadjustment.h
new file mode 100644 (file)
index 0000000..7832d1d
--- /dev/null
@@ -0,0 +1,74 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_ADJUSTMENT_H__
+#define __GTK_ADJUSTMENT_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkdata.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_ADJUSTMENT(obj)          GTK_CHECK_CAST (obj, gtk_adjustment_get_type (), GtkAdjustment)
+#define GTK_ADJUSTMENT_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_adjustment_get_type (), GtkAdjustmentClass)
+#define GTK_IS_ADJUSTMENT(obj)       GTK_CHECK_TYPE (obj, gtk_adjustment_get_type ())
+
+
+typedef struct _GtkAdjustment       GtkAdjustment;
+typedef struct _GtkAdjustmentClass  GtkAdjustmentClass;
+
+struct _GtkAdjustment
+{
+  GtkData data;
+
+  gfloat lower;
+  gfloat upper;
+  gfloat value;
+  gfloat step_increment;
+  gfloat page_increment;
+  gfloat page_size;
+};
+
+struct _GtkAdjustmentClass
+{
+  GtkDataClass parent_class;
+
+  void (* changed)       (GtkAdjustment *adjustment);
+  void (* value_changed) (GtkAdjustment *adjustment);
+};
+
+
+guint      gtk_adjustment_get_type   (void);
+GtkObject* gtk_adjustment_new        (gfloat              value,
+                                     gfloat              lower,
+                                     gfloat              upper,
+                                     gfloat              step_increment,
+                                     gfloat              page_increment,
+                                     gfloat              page_size);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_ADJUSTMENT_H__ */
diff --git a/gtk/gtkalignment.c b/gtk/gtkalignment.c
new file mode 100644 (file)
index 0000000..b562cff
--- /dev/null
@@ -0,0 +1,193 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkalignment.h"
+
+
+static void gtk_alignment_class_init    (GtkAlignmentClass *klass);
+static void gtk_alignment_init          (GtkAlignment      *alignment);
+static void gtk_alignment_size_request  (GtkWidget         *widget,
+                                        GtkRequisition    *requisition);
+static void gtk_alignment_size_allocate (GtkWidget         *widget,
+                                        GtkAllocation     *allocation);
+
+
+guint
+gtk_alignment_get_type ()
+{
+  static guint alignment_type = 0;
+
+  if (!alignment_type)
+    {
+      GtkTypeInfo alignment_info =
+      {
+       "GtkAlignment",
+       sizeof (GtkAlignment),
+       sizeof (GtkAlignmentClass),
+       (GtkClassInitFunc) gtk_alignment_class_init,
+       (GtkObjectInitFunc) gtk_alignment_init,
+       (GtkArgFunc) NULL,
+      };
+
+      alignment_type = gtk_type_unique (gtk_bin_get_type (), &alignment_info);
+    }
+
+  return alignment_type;
+}
+
+static void
+gtk_alignment_class_init (GtkAlignmentClass *class)
+{
+  GtkWidgetClass *widget_class;
+
+  widget_class = (GtkWidgetClass*) class;
+
+  widget_class->size_request = gtk_alignment_size_request;
+  widget_class->size_allocate = gtk_alignment_size_allocate;
+}
+
+static void
+gtk_alignment_init (GtkAlignment *alignment)
+{
+  GTK_WIDGET_SET_FLAGS (alignment, GTK_NO_WINDOW | GTK_BASIC);
+
+  alignment->xalign = 0.5;
+  alignment->yalign = 0.5;
+  alignment->xscale = 1.0;
+  alignment->yscale = 1.0;
+}
+
+GtkWidget*
+gtk_alignment_new (gfloat xalign,
+                  gfloat yalign,
+                  gfloat xscale,
+                  gfloat yscale)
+{
+  GtkAlignment *alignment;
+
+  alignment = gtk_type_new (gtk_alignment_get_type ());
+
+  alignment->xalign = CLAMP (xalign, 0.0, 1.0);
+  alignment->yalign = CLAMP (yalign, 0.0, 1.0);
+  alignment->xscale = CLAMP (xscale, 0.0, 1.0);
+  alignment->yscale = CLAMP (yscale, 0.0, 1.0);
+
+  return GTK_WIDGET (alignment);
+}
+
+void
+gtk_alignment_set (GtkAlignment *alignment,
+                  gfloat        xalign,
+                  gfloat        yalign,
+                  gfloat        xscale,
+                  gfloat        yscale)
+{
+  g_return_if_fail (alignment != NULL);
+  g_return_if_fail (GTK_IS_ALIGNMENT (alignment));
+
+  xalign = CLAMP (xalign, 0.0, 1.0);
+  yalign = CLAMP (yalign, 0.0, 1.0);
+  xscale = CLAMP (xscale, 0.0, 1.0);
+  yscale = CLAMP (yscale, 0.0, 1.0);
+
+  if ((alignment->xalign != xalign) ||
+      (alignment->yalign != yalign) ||
+      (alignment->xscale != xscale) ||
+      (alignment->yscale != yscale))
+    {
+      alignment->xalign = xalign;
+      alignment->yalign = yalign;
+      alignment->xscale = xscale;
+      alignment->yscale = yscale;
+
+      gtk_widget_size_allocate (GTK_WIDGET (alignment), &(GTK_WIDGET (alignment)->allocation));
+      gtk_widget_queue_draw (GTK_WIDGET (alignment));
+    }
+}
+
+
+static void
+gtk_alignment_size_request (GtkWidget      *widget,
+                           GtkRequisition *requisition)
+{
+  GtkAlignment *alignment;
+  GtkBin *bin;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_ALIGNMENT (widget));
+  g_return_if_fail (requisition != NULL);
+
+  alignment = GTK_ALIGNMENT (widget);
+  bin = GTK_BIN (widget);
+
+  requisition->width = GTK_CONTAINER (widget)->border_width * 2;
+  requisition->height = GTK_CONTAINER (widget)->border_width * 2;
+
+  if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
+    {
+      gtk_widget_size_request (bin->child, &bin->child->requisition);
+
+      requisition->width += bin->child->requisition.width;
+      requisition->height += bin->child->requisition.height;
+    }
+}
+
+static void
+gtk_alignment_size_allocate (GtkWidget     *widget,
+                            GtkAllocation *allocation)
+{
+  GtkAlignment *alignment;
+  GtkBin *bin;
+  GtkAllocation child_allocation;
+  gint width, height;
+  gint x, y;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_ALIGNMENT (widget));
+  g_return_if_fail (allocation != NULL);
+
+  widget->allocation = *allocation;
+  alignment = GTK_ALIGNMENT (widget);
+  bin = GTK_BIN (widget);
+
+  if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
+    {
+      x = GTK_CONTAINER (alignment)->border_width;
+      y = GTK_CONTAINER (alignment)->border_width;
+      width = allocation->width - 2 * x;
+      height = allocation->height - 2 * y;
+
+      if (width > bin->child->requisition.width)
+       child_allocation.width = (bin->child->requisition.width *
+                                 (1.0 - alignment->xscale) +
+                                 width * alignment->xscale);
+      else
+       child_allocation.width = width;
+
+      if (height > bin->child->requisition.height)
+       child_allocation.height = (bin->child->requisition.height *
+                                 (1.0 - alignment->yscale) +
+                                 height * alignment->yscale);
+      else
+       child_allocation.height = height;
+
+      child_allocation.x = alignment->xalign * (width - child_allocation.width) + allocation->x + x;
+      child_allocation.y = alignment->yalign * (height - child_allocation.height) + allocation->y + y;
+
+      gtk_widget_size_allocate (bin->child, &child_allocation);
+    }
+}
diff --git a/gtk/gtkalignment.h b/gtk/gtkalignment.h
new file mode 100644 (file)
index 0000000..c80ad7f
--- /dev/null
@@ -0,0 +1,72 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_ALIGNMENT_H__
+#define __GTK_ALIGNMENT_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkbin.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_ALIGNMENT(obj)          GTK_CHECK_CAST (obj, gtk_alignment_get_type (), GtkAlignment)
+#define GTK_ALIGNMENT_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_alignment_get_type (), GtkAlignmentClass)
+#define GTK_IS_ALIGNMENT(obj)       GTK_CHECK_TYPE (obj, gtk_alignment_get_type ())
+
+
+typedef struct _GtkAlignment       GtkAlignment;
+typedef struct _GtkAlignmentClass  GtkAlignmentClass;
+
+struct _GtkAlignment
+{
+  GtkBin bin;
+
+  gfloat xalign;
+  gfloat yalign;
+  gfloat xscale;
+  gfloat yscale;
+};
+
+struct _GtkAlignmentClass
+{
+  GtkBinClass parent_class;
+};
+
+
+guint      gtk_alignment_get_type   (void);
+GtkWidget* gtk_alignment_new        (gfloat             xalign,
+                                    gfloat             yalign,
+                                    gfloat             xscale,
+                                    gfloat             yscale);
+void       gtk_alignment_set        (GtkAlignment      *alignment,
+                                    gfloat             xalign,
+                                    gfloat             yalign,
+                                    gfloat             xscale,
+                                    gfloat             yscale);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_ALIGNMENT_H__ */
diff --git a/gtk/gtkarrow.c b/gtk/gtkarrow.c
new file mode 100644 (file)
index 0000000..b8bc214
--- /dev/null
@@ -0,0 +1,165 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkarrow.h"
+
+
+#define MIN_ARROW_SIZE  11
+
+
+static void gtk_arrow_class_init (GtkArrowClass  *klass);
+static void gtk_arrow_init       (GtkArrow       *arrow);
+static gint gtk_arrow_expose     (GtkWidget      *widget,
+                                 GdkEventExpose *event);
+
+
+guint
+gtk_arrow_get_type ()
+{
+  static guint arrow_type = 0;
+
+  if (!arrow_type)
+    {
+      GtkTypeInfo arrow_info =
+      {
+       "GtkArrow",
+       sizeof (GtkArrow),
+       sizeof (GtkArrowClass),
+       (GtkClassInitFunc) gtk_arrow_class_init,
+       (GtkObjectInitFunc) gtk_arrow_init,
+       (GtkArgFunc) NULL,
+      };
+
+      arrow_type = gtk_type_unique (gtk_misc_get_type (), &arrow_info);
+    }
+
+  return arrow_type;
+}
+
+static void
+gtk_arrow_class_init (GtkArrowClass *class)
+{
+  GtkWidgetClass *widget_class;
+
+  widget_class = (GtkWidgetClass*) class;
+
+  widget_class->expose_event = gtk_arrow_expose;
+}
+
+static void
+gtk_arrow_init (GtkArrow *arrow)
+{
+  GTK_WIDGET_SET_FLAGS (arrow, GTK_NO_WINDOW);
+
+  arrow->arrow_type = GTK_ARROW_RIGHT;
+  arrow->shadow_type = GTK_SHADOW_OUT;
+}
+
+GtkWidget*
+gtk_arrow_new (GtkArrowType  arrow_type,
+              GtkShadowType shadow_type)
+{
+  GtkArrow *arrow;
+
+  arrow = gtk_type_new (gtk_arrow_get_type ());
+
+  GTK_WIDGET (arrow)->requisition.width = MIN_ARROW_SIZE + GTK_MISC (arrow)->xpad * 2;
+  GTK_WIDGET (arrow)->requisition.height = MIN_ARROW_SIZE + GTK_MISC (arrow)->ypad * 2;
+
+  arrow->arrow_type = arrow_type;
+  arrow->shadow_type = shadow_type;
+
+  return GTK_WIDGET (arrow);
+}
+
+void
+gtk_arrow_set (GtkArrow      *arrow,
+              GtkArrowType   arrow_type,
+              GtkShadowType  shadow_type)
+{
+  g_return_if_fail (arrow != NULL);
+  g_return_if_fail (GTK_IS_ARROW (arrow));
+
+  if (((GtkArrowType) arrow->arrow_type != arrow_type) ||
+      ((GtkShadowType) arrow->shadow_type != shadow_type))
+    {
+      arrow->arrow_type = arrow_type;
+      arrow->shadow_type = shadow_type;
+
+      if (GTK_WIDGET_DRAWABLE (arrow))
+       {
+         gdk_window_clear_area (GTK_WIDGET (arrow)->window,
+                                GTK_WIDGET (arrow)->allocation.x + 1,
+                                GTK_WIDGET (arrow)->allocation.y + 1,
+                                GTK_WIDGET (arrow)->allocation.width - 2,
+                                GTK_WIDGET (arrow)->allocation.height - 2);
+         gtk_widget_queue_draw (GTK_WIDGET (arrow));
+       }
+    }
+}
+
+
+static gint
+gtk_arrow_expose (GtkWidget      *widget,
+                 GdkEventExpose *event)
+{
+  GtkArrow *arrow;
+  GtkMisc *misc;
+  GtkShadowType shadow_type;
+  gint width, height;
+  gint x, y;
+  gint extent;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_ARROW (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      arrow = GTK_ARROW (widget);
+      misc = GTK_MISC (widget);
+
+      width = widget->allocation.width - misc->xpad * 2;
+      height = widget->allocation.height - misc->ypad * 2;
+      extent = MIN (width, height);
+
+      x = ((widget->allocation.x + misc->xpad) * (1.0 - misc->xalign) +
+          (widget->allocation.x + widget->allocation.width - extent - misc->ypad) * misc->xalign);
+      y = ((widget->allocation.y + misc->ypad) * (1.0 - misc->yalign) +
+          (widget->allocation.y + widget->allocation.height - extent - misc->ypad) * misc->yalign);
+
+      shadow_type = arrow->shadow_type;
+
+      if (widget->state == GTK_STATE_ACTIVE)
+       {
+          if (shadow_type == GTK_SHADOW_IN)
+            shadow_type = GTK_SHADOW_OUT;
+          else if (shadow_type == GTK_SHADOW_OUT)
+            shadow_type = GTK_SHADOW_IN;
+          else if (shadow_type == GTK_SHADOW_ETCHED_IN)
+            shadow_type = GTK_SHADOW_ETCHED_OUT;
+          else if (shadow_type == GTK_SHADOW_ETCHED_OUT)
+            shadow_type = GTK_SHADOW_ETCHED_IN;
+       }
+
+      gtk_draw_arrow (widget->style, widget->window,
+                     widget->state, shadow_type, arrow->arrow_type, TRUE,
+                     x, y, extent, extent);
+    }
+
+  return FALSE;
+}
diff --git a/gtk/gtkarrow.h b/gtk/gtkarrow.h
new file mode 100644 (file)
index 0000000..5a2edb0
--- /dev/null
@@ -0,0 +1,66 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_ARROW_H__
+#define __GTK_ARROW_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkmisc.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_ARROW(obj)          GTK_CHECK_CAST (obj, gtk_arrow_get_type (), GtkArrow)
+#define GTK_ARROW_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_arrow_get_type (), GtkArrowClass)
+#define GTK_IS_ARROW(obj)       GTK_CHECK_TYPE (obj, gtk_arrow_get_type ())
+
+
+typedef struct _GtkArrow       GtkArrow;
+typedef struct _GtkArrowClass  GtkArrowClass;
+
+struct _GtkArrow
+{
+  GtkMisc misc;
+
+  gint16 arrow_type;
+  gint16 shadow_type;
+};
+
+struct _GtkArrowClass
+{
+  GtkMiscClass parent_class;
+};
+
+
+guint      gtk_arrow_get_type   (void);
+GtkWidget* gtk_arrow_new        (GtkArrowType   arrow_type,
+                                GtkShadowType  shadow_type);
+void       gtk_arrow_set        (GtkArrow      *arrow,
+                                GtkArrowType   arrow_type,
+                                GtkShadowType  shadow_type);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_ARROW_H__ */
diff --git a/gtk/gtkaspectframe.c b/gtk/gtkaspectframe.c
new file mode 100644 (file)
index 0000000..2e4795b
--- /dev/null
@@ -0,0 +1,336 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * GtkAspectFrame: Ensure that the child window has a specified aspect ratio
+ *    or, if obey_child, has the same aspect ratio as its requested size
+ *
+ *     Copyright Owen Taylor                          4/9/97
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkaspectframe.h"
+
+static void gtk_aspect_frame_class_init    (GtkAspectFrameClass *klass);
+static void gtk_aspect_frame_init          (GtkAspectFrame      *aspect_frame);
+static void gtk_aspect_frame_draw          (GtkWidget      *widget,
+                                           GdkRectangle   *area);
+static void gtk_aspect_frame_paint         (GtkWidget      *widget,
+                                           GdkRectangle   *area);
+static gint gtk_aspect_frame_expose        (GtkWidget      *widget,
+                                           GdkEventExpose *event);
+static void gtk_aspect_frame_size_allocate (GtkWidget         *widget,
+                                           GtkAllocation     *allocation);
+
+#define MAX_RATIO 10000.0
+#define MIN_RATIO 0.0001
+
+guint
+gtk_aspect_frame_get_type ()
+{
+  static guint aspect_frame_type = 0;
+
+  if (!aspect_frame_type)
+    {
+      GtkTypeInfo aspect_frame_info =
+      {
+       "GtkAspectFrame",
+       sizeof (GtkAspectFrame),
+       sizeof (GtkAspectFrameClass),
+       (GtkClassInitFunc) gtk_aspect_frame_class_init,
+       (GtkObjectInitFunc) gtk_aspect_frame_init,
+       (GtkArgFunc) NULL,
+      };
+
+      aspect_frame_type = gtk_type_unique (gtk_frame_get_type (), &aspect_frame_info);
+    }
+
+  return aspect_frame_type;
+}
+
+static void
+gtk_aspect_frame_class_init (GtkAspectFrameClass *class)
+{
+  GtkWidgetClass *widget_class;
+
+  widget_class = (GtkWidgetClass*) class;
+
+  widget_class->draw = gtk_aspect_frame_draw;
+  widget_class->expose_event = gtk_aspect_frame_expose;
+  widget_class->size_allocate = gtk_aspect_frame_size_allocate;
+}
+
+static void
+gtk_aspect_frame_init (GtkAspectFrame *aspect_frame)
+{
+  aspect_frame->xalign = 0.5;
+  aspect_frame->yalign = 0.5;
+  aspect_frame->ratio = 1.0;
+  aspect_frame->obey_child = 1;
+  aspect_frame->center_allocation.x = -1;
+  aspect_frame->center_allocation.y = -1;
+  aspect_frame->center_allocation.width = 1;
+  aspect_frame->center_allocation.height = 1;
+}
+
+GtkWidget*
+gtk_aspect_frame_new (const gchar *label,
+                     gfloat xalign,
+                     gfloat yalign,
+                     gfloat ratio,
+                     gint   obey_child)
+{
+  GtkAspectFrame *aspect_frame;
+
+  aspect_frame = gtk_type_new (gtk_aspect_frame_get_type ());
+
+  aspect_frame->xalign = CLAMP (xalign, 0.0, 1.0);
+  aspect_frame->yalign = CLAMP (yalign, 0.0, 1.0);
+  aspect_frame->ratio = CLAMP (ratio, MIN_RATIO, MAX_RATIO);
+  aspect_frame->obey_child = obey_child;
+
+  gtk_frame_set_label (GTK_FRAME(aspect_frame), label);
+
+  return GTK_WIDGET (aspect_frame);
+}
+
+void
+gtk_aspect_frame_set (GtkAspectFrame *aspect_frame,
+                     gfloat        xalign,
+                     gfloat        yalign,
+                     gfloat        ratio,
+                     gint          obey_child)
+{
+  g_return_if_fail (aspect_frame != NULL);
+  g_return_if_fail (GTK_IS_ASPECT_FRAME (aspect_frame));
+
+  xalign = CLAMP (xalign, 0.0, 1.0);
+  yalign = CLAMP (yalign, 0.0, 1.0);
+  ratio = CLAMP (ratio, MIN_RATIO, MAX_RATIO);
+
+  if ((aspect_frame->xalign != xalign) ||
+      (aspect_frame->yalign != yalign) ||
+      (aspect_frame->ratio != ratio) ||
+      (aspect_frame->obey_child != obey_child))
+    {
+      aspect_frame->xalign = xalign;
+      aspect_frame->yalign = yalign;
+      aspect_frame->ratio = ratio;
+      aspect_frame->obey_child = obey_child;
+
+      gtk_widget_size_allocate (GTK_WIDGET (aspect_frame), &(GTK_WIDGET (aspect_frame)->allocation));
+      gtk_widget_queue_draw (GTK_WIDGET (aspect_frame));
+    }
+}
+
+static void
+gtk_aspect_frame_paint (GtkWidget    *widget,
+                       GdkRectangle *area)
+{
+  GtkFrame *frame;
+  GtkStateType state;
+  gint height_extra;
+  gint label_area_width;
+  gint x, y;
+  GtkAllocation *allocation;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_ASPECT_FRAME (widget));
+  g_return_if_fail (area != NULL);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      frame = GTK_FRAME (widget);
+      allocation = &GTK_ASPECT_FRAME(widget)->center_allocation;
+
+      state = widget->state;
+      if (!GTK_WIDGET_IS_SENSITIVE (widget))
+        state = GTK_STATE_INSENSITIVE;
+
+      height_extra = frame->label_height - widget->style->klass->xthickness;
+      height_extra = MAX (height_extra, 0);
+
+      x = GTK_CONTAINER (frame)->border_width;
+      y = GTK_CONTAINER (frame)->border_width;
+
+      gtk_draw_shadow (widget->style, widget->window,
+                      GTK_STATE_NORMAL, frame->shadow_type,
+                      allocation->x + x,
+                      allocation->y + y + height_extra / 2,
+                      allocation->width - x * 2,
+                      allocation->height - y * 2 - height_extra / 2);
+
+      if (frame->label)
+       {
+         label_area_width = (allocation->width +
+                             GTK_CONTAINER (frame)->border_width * 2 -
+                             widget->style->klass->xthickness * 2);
+
+         x = ((label_area_width - frame->label_width) * frame->label_xalign +
+              GTK_CONTAINER (frame)->border_width + widget->style->klass->xthickness);
+         y = (GTK_CONTAINER (frame)->border_width + widget->style->font->ascent);
+
+         gdk_window_clear_area (widget->window,
+                                allocation->x + x + 2,
+                                allocation->y + GTK_CONTAINER (frame)->border_width,
+                                frame->label_width - 4, frame->label_height);
+         gtk_draw_string (widget->style, widget->window, state,
+                          allocation->x + x + 3,
+                          allocation->y + y,
+                          frame->label);
+       }
+    }
+}
+
+/* the only modification to the next two routines is to call
+   gtk_aspect_frame_paint instead of gtk_frame_paint */
+
+static void
+gtk_aspect_frame_draw (GtkWidget    *widget,
+                      GdkRectangle *area)
+{
+  GtkBin *bin;
+  GdkRectangle child_area;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_ASPECT_FRAME (widget));
+  g_return_if_fail (area != NULL);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      bin = GTK_BIN (widget);
+
+      gtk_aspect_frame_paint (widget, area);
+
+      if (bin->child && gtk_widget_intersect (bin->child, area, &child_area))
+       gtk_widget_draw (bin->child, &child_area);
+    }
+}
+
+static gint
+gtk_aspect_frame_expose (GtkWidget      *widget,
+                        GdkEventExpose *event)
+{
+  GtkBin *bin;
+  GdkEventExpose child_event;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_ASPECT_FRAME (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      bin = GTK_BIN (widget);
+
+      gtk_aspect_frame_paint (widget, &event->area);
+
+      child_event = *event;
+      if (bin->child &&
+         GTK_WIDGET_NO_WINDOW (bin->child) &&
+         gtk_widget_intersect (bin->child, &event->area, &child_event.area))
+       gtk_widget_event (bin->child, (GdkEvent*) &child_event);
+    }
+
+  return FALSE;
+}
+
+static void
+gtk_aspect_frame_size_allocate (GtkWidget     *widget,
+                         GtkAllocation *allocation)
+{
+  GtkFrame *frame;
+  GtkAspectFrame *aspect_frame;
+  GtkBin *bin;
+
+  GtkAllocation child_allocation;
+  gint x,y;
+  gint width,height;
+  gdouble ratio;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_ASPECT_FRAME (widget));
+  g_return_if_fail (allocation != NULL);
+
+  aspect_frame = GTK_ASPECT_FRAME (widget);
+  frame = GTK_FRAME (widget);
+  bin = GTK_BIN (widget);
+
+  if (GTK_WIDGET_MAPPED (widget) &&
+      ((widget->allocation.x != allocation->x) ||
+       (widget->allocation.y != allocation->y) ||
+       (widget->allocation.width != allocation->width) ||
+       (widget->allocation.height != allocation->height)) &&
+      (widget->allocation.width != 0) &&
+      (widget->allocation.height != 0))
+    gdk_window_clear_area (widget->window,
+                          widget->allocation.x,
+                          widget->allocation.y,
+                          widget->allocation.width,
+                          widget->allocation.height);
+
+  widget->allocation = *allocation;
+
+  if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
+    {
+      if (aspect_frame->obey_child)
+       {
+         if (bin->child->requisition.height != 0)
+           {
+             ratio = (gdouble)bin->child->requisition.width /
+               bin->child->requisition.height;
+             if (ratio < MIN_RATIO) ratio = MIN_RATIO;
+           }
+         else
+           if (bin->child->requisition.height != 0)
+             ratio = MAX_RATIO;
+         else
+           ratio = 1.0;
+       }
+      else
+       ratio = aspect_frame->ratio;
+
+      x = (GTK_CONTAINER (frame)->border_width +
+          GTK_WIDGET (frame)->style->klass->xthickness);
+      width = allocation->width - x * 2;
+
+      y = (GTK_CONTAINER (frame)->border_width +
+                           MAX (frame->label_height, GTK_WIDGET (frame)->style->klass->ythickness));
+      height = (allocation->height - y -
+                                GTK_CONTAINER (frame)->border_width -
+                                GTK_WIDGET (frame)->style->klass->ythickness);
+
+      if (ratio * height > width)
+       {
+         child_allocation.width = width;
+         child_allocation.height = width/ratio;
+       }
+      else
+       {
+         child_allocation.width = ratio*height;
+         child_allocation.height = height;
+       }
+
+      child_allocation.x = aspect_frame->xalign * (width - child_allocation.width) + allocation->x + x;
+      child_allocation.y = aspect_frame->yalign * (height - child_allocation.height) + allocation->y + y;
+
+      aspect_frame->center_allocation.width = child_allocation.width + 2*x;
+      aspect_frame->center_allocation.x = child_allocation.x - x;
+      aspect_frame->center_allocation.height = child_allocation.height + y +
+                                GTK_CONTAINER (frame)->border_width +
+                                GTK_WIDGET (frame)->style->klass->ythickness;
+      aspect_frame->center_allocation.y = child_allocation.y - y;
+
+      gtk_widget_size_allocate (bin->child, &child_allocation);
+    }
+}
diff --git a/gtk/gtkaspectframe.h b/gtk/gtkaspectframe.h
new file mode 100644 (file)
index 0000000..07f08a4
--- /dev/null
@@ -0,0 +1,75 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_ASPECT_FRAME_H__
+#define __GTK_ASPECT_FRAME_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkbin.h>
+#include <gtk/gtkframe.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_ASPECT_FRAME(obj)        ((GtkAspectFrame*) obj)
+#define GTK_ASPECT_FRAME_CLASS(obj)  ((GtkAspectFrameClass*) GTK_OBJECT_CLASS (obj))
+#define GTK_IS_ASPECT_FRAME(obj)     (gtk_type_is_a (GTK_WIDGET_TYPE (obj), gtk_aspect_frame_get_type ()))
+
+
+typedef struct _GtkAspectFrame       GtkAspectFrame;
+typedef struct _GtkAspectFrameClass  GtkAspectFrameClass;
+
+struct _GtkAspectFrame
+{
+  GtkFrame frame;
+
+  gfloat xalign;
+  gfloat yalign;
+  gfloat ratio;
+  gint obey_child;
+
+  GtkAllocation center_allocation;
+};
+
+struct _GtkAspectFrameClass
+{
+  GtkBinClass parent_class;
+};
+
+
+guint      gtk_aspect_frame_get_type   (void);
+GtkWidget* gtk_aspect_frame_new        (const gchar       *label,
+                                       gfloat             xalign,
+                                       gfloat             yalign,
+                                       gfloat             ratio,
+                                       gint               obey_child);
+void       gtk_aspect_frame_set        (GtkAspectFrame      *aspect_frame,
+                                       gfloat             xalign,
+                                       gfloat             yalign,
+                                       gfloat             ratio,
+                                       gint               obey_child);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_ASPECT_FRAME_H__ */
diff --git a/gtk/gtkbbox.c b/gtk/gtkbbox.c
new file mode 100644 (file)
index 0000000..818493f
--- /dev/null
@@ -0,0 +1,228 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkbbox.h"
+
+
+static void gtk_button_box_class_init    (GtkButtonBoxClass   *klass);
+static void gtk_button_box_init          (GtkButtonBox        *box);
+
+
+static gint default_child_min_width = 85;
+static gint default_child_min_height = 27;
+static gint default_child_ipad_x = 7;
+static gint default_child_ipad_y = 0;
+
+
+guint
+gtk_button_box_get_type ()
+{
+  static guint button_box_type = 0;
+
+  if (!button_box_type)
+    {
+      GtkTypeInfo button_box_info =
+      {
+       "GtkButtonBox",
+       sizeof (GtkButtonBox),
+       sizeof (GtkButtonBoxClass),
+       (GtkClassInitFunc) gtk_button_box_class_init,
+       (GtkObjectInitFunc) gtk_button_box_init,
+       (GtkArgFunc) NULL,
+      };
+
+      button_box_type = gtk_type_unique (gtk_box_get_type (), &button_box_info);
+    }
+
+  return button_box_type;
+}
+
+static void
+gtk_button_box_class_init (GtkButtonBoxClass *class)
+{
+  GtkWidgetClass *widget_class;
+
+  widget_class = (GtkWidgetClass*) class;
+}
+
+static void
+gtk_button_box_init (GtkButtonBox *button_box)
+{
+  button_box->spacing = GTK_BUTTONBOX_DEFAULT;
+  button_box->child_min_width = GTK_BUTTONBOX_DEFAULT;
+  button_box->child_min_height = GTK_BUTTONBOX_DEFAULT;
+  button_box->child_ipad_x = GTK_BUTTONBOX_DEFAULT;
+  button_box->child_ipad_y = GTK_BUTTONBOX_DEFAULT;
+  button_box->layout_style = GTK_BUTTONBOX_DEFAULT;
+}
+
+
+/* set default values for child size and child internal padding */
+/* default spacing is in defined in subclasses */
+
+void gtk_button_box_set_child_size_default (gint width, gint height)
+{
+  default_child_min_width = width;
+  default_child_min_height = height;
+}
+
+void gtk_button_box_set_child_ipadding_default (gint ipad_x, gint ipad_y)
+{
+  default_child_ipad_x = ipad_x;
+  default_child_ipad_y = ipad_y;
+}
+
+/* get default values for child size and child internal padding */
+
+void gtk_button_box_get_child_size_default (gint *width, gint *height)
+{
+  *width = default_child_min_width;
+  *height = default_child_min_height;
+}
+
+void gtk_button_box_get_child_ipadding_default (gint *ipad_x, gint *ipad_y)
+{
+  *ipad_x = default_child_ipad_x;
+  *ipad_y = default_child_ipad_y;
+}
+
+/* set per widget values for spacing, child size and child internal padding */
+
+void gtk_button_box_set_spacing (GtkButtonBox *widget, gint spacing)
+{
+  widget->spacing = spacing;
+}
+
+void gtk_button_box_set_child_size (GtkButtonBox *widget, gint width, gint height)
+{
+  widget->child_min_width = width;
+  widget->child_min_height = height;
+}
+
+void gtk_button_box_set_child_ipadding (GtkButtonBox *widget,
+                                       gint ipad_x, gint ipad_y)
+{
+  widget->child_ipad_x = ipad_x;
+  widget->child_ipad_y = ipad_y;
+}
+
+void gtk_button_box_set_layout (GtkButtonBox *widget, gint layout_style)
+{
+  widget->layout_style = layout_style;
+}
+
+
+/* get per widget values for spacing, child size and child internal padding */
+
+gint gtk_button_box_get_spacing (GtkButtonBox *widget)
+{
+  return widget->spacing;
+}
+
+void gtk_button_box_get_child_size (GtkButtonBox *widget,
+                                    gint *width, gint *height)
+{
+  *width  = widget->child_min_width;
+  *height = widget->child_min_height;
+}
+
+void gtk_button_box_get_child_ipadding (GtkButtonBox *widget,
+                                        gint* ipad_x, gint *ipad_y)
+{
+  *ipad_x = widget->child_ipad_x;
+  *ipad_y = widget->child_ipad_y;
+}
+
+gint gtk_button_box_get_layout (GtkButtonBox *widget)
+{
+  return widget->layout_style;
+}
+
+
+
+/* Ask children how much space they require and round up 
+   to match minimum size and internal padding.
+   Returns the size each single child should have. */
+void
+gtk_button_box_child_requisition (GtkWidget *widget,
+                                 int *nvis_children,
+                                 int *width,
+                                 int *height)
+{
+  GtkButtonBox *bbox;
+  GtkBoxChild *child;
+  GList *children;
+  gint nchildren;
+  gint needed_width;
+  gint needed_height;
+  GtkRequisition child_requisition;
+  gint ipad_w;
+  gint ipad_h;
+  gint width_default;
+  gint height_default;
+  gint ipad_x_default;
+  gint ipad_y_default;
+  
+  gint child_min_width;
+  gint child_min_height;
+  gint ipad_x;
+  gint ipad_y;
+  
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_BUTTON_BOX (widget));
+
+  bbox = GTK_BUTTON_BOX (widget);
+
+  gtk_button_box_get_child_size_default (&width_default, &height_default);
+  gtk_button_box_get_child_ipadding_default (&ipad_x_default, &ipad_y_default);
+  
+  child_min_width = bbox->child_min_width   != GTK_BUTTONBOX_DEFAULT
+         ? bbox->child_min_width : width_default;
+  child_min_height = bbox->child_min_height !=GTK_BUTTONBOX_DEFAULT
+         ? bbox->child_min_height : height_default;
+  ipad_x = bbox->child_ipad_x != GTK_BUTTONBOX_DEFAULT
+         ? bbox->child_ipad_x : ipad_x_default;
+  ipad_y = bbox->child_ipad_y != GTK_BUTTONBOX_DEFAULT
+         ? bbox->child_ipad_y : ipad_y_default;
+
+  nchildren = 0;
+  children = GTK_BOX(bbox)->children;
+  needed_width = child_min_width;
+  needed_height = child_min_height;  
+  ipad_w = ipad_x * 2;
+  ipad_h = ipad_y * 2;
+  
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (child->widget))
+       {
+         nchildren += 1;
+         gtk_widget_size_request (child->widget, &child_requisition);
+         if (child_requisition.width + ipad_w > needed_width)
+                 needed_width = child_requisition.width + ipad_w;
+         if (child_requisition.height + ipad_h > needed_height)
+                 needed_height = child_requisition.height + ipad_h;
+       }
+    }
+  
+  *nvis_children = nchildren;
+  *width = needed_width;
+  *height = needed_height;
+}
diff --git a/gtk/gtkbbox.h b/gtk/gtkbbox.h
new file mode 100644 (file)
index 0000000..816f1f0
--- /dev/null
@@ -0,0 +1,93 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_BUTTON_BOX_H__
+#define __GTK_BUTTON_BOX_H__
+
+#include "gtkbox.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_BUTTON_BOX(obj)          GTK_CHECK_CAST (obj, gtk_button_box_get_type (), GtkButtonBox)
+#define GTK_BUTTON_BOX_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_button_box_get_type (), GtkButtonBoxClass)
+#define GTK_IS_BUTTON_BOX(obj)       GTK_CHECK_TYPE (obj, gtk_button_box_get_type ())
+
+#define GTK_BUTTONBOX_DEFAULT -1
+#define GTK_BUTTONBOX_SPREAD   1
+#define GTK_BUTTONBOX_EDGE     2
+#define GTK_BUTTONBOX_START    3
+#define GTK_BUTTONBOX_END      4
+
+typedef struct _GtkButtonBox       GtkButtonBox;
+typedef struct _GtkButtonBoxClass  GtkButtonBoxClass;
+
+struct _GtkButtonBox
+{
+  GtkBox box;
+  gint spacing;
+  gint child_min_width;
+  gint child_min_height;
+  gint child_ipad_x;
+  gint child_ipad_y;
+  gint layout_style;
+};
+
+struct _GtkButtonBoxClass
+{
+  GtkBoxClass parent_class;
+};
+
+
+guint gtk_button_box_get_type (void);
+
+void gtk_button_box_get_child_size_default (gint *min_width, gint *min_height);
+void gtk_button_box_get_child_ipadding_default (gint *ipad_x, gint *ipad_y);
+
+void gtk_button_box_set_child_size_default (gint min_width, gint min_height);
+void gtk_button_box_set_child_ipadding_default (gint ipad_x, gint ipad_y);
+
+gint gtk_button_box_get_spacing (GtkButtonBox *widget);
+gint gtk_button_box_get_layout (GtkButtonBox *widget);
+void gtk_button_box_get_child_size (GtkButtonBox *widget,
+                                   gint *min_width, gint *min_height);
+void gtk_button_box_get_child_ipadding (GtkButtonBox *widget, gint *ipad_x, gint *ipad_y);
+
+void gtk_button_box_set_spacing (GtkButtonBox *widget, gint spacing);
+void gtk_button_box_set_layout (GtkButtonBox *widget, gint layout_style);
+void gtk_button_box_set_child_size (GtkButtonBox *widget,
+                                   gint min_width, gint min_height);
+void gtk_button_box_set_child_ipadding (GtkButtonBox *widget, gint ipad_x, gint ipad_y);
+
+
+/* Internal method - do not use. */
+void gtk_button_box_child_requisition (GtkWidget *widget,
+                                      int *nvis_children,
+                                      int *width,
+                                      int *height);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_BUTTON_BOX_H__ */
+
+
diff --git a/gtk/gtkbin.c b/gtk/gtkbin.c
new file mode 100644 (file)
index 0000000..4cb7efc
--- /dev/null
@@ -0,0 +1,286 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkbin.h"
+
+
+static void gtk_bin_class_init (GtkBinClass    *klass);
+static void gtk_bin_init       (GtkBin         *bin);
+static void gtk_bin_destroy    (GtkObject      *object);
+static void gtk_bin_map        (GtkWidget      *widget);
+static void gtk_bin_unmap      (GtkWidget      *widget);
+static void gtk_bin_draw       (GtkWidget      *widget,
+                               GdkRectangle   *area);
+static gint gtk_bin_expose     (GtkWidget      *widget,
+                               GdkEventExpose *event);
+static void gtk_bin_add        (GtkContainer   *container,
+                               GtkWidget      *widget);
+static void gtk_bin_remove     (GtkContainer   *container,
+                               GtkWidget      *widget);
+static void gtk_bin_foreach    (GtkContainer   *container,
+                               GtkCallback     callback,
+                               gpointer        callback_data);
+
+
+static GtkContainerClass *parent_class = NULL;
+
+
+guint
+gtk_bin_get_type ()
+{
+  static guint bin_type = 0;
+
+  if (!bin_type)
+    {
+      GtkTypeInfo bin_info =
+      {
+       "GtkBin",
+       sizeof (GtkBin),
+       sizeof (GtkBinClass),
+       (GtkClassInitFunc) gtk_bin_class_init,
+       (GtkObjectInitFunc) gtk_bin_init,
+       (GtkArgFunc) NULL,
+      };
+
+      bin_type = gtk_type_unique (gtk_container_get_type (), &bin_info);
+    }
+
+  return bin_type;
+}
+
+static void
+gtk_bin_class_init (GtkBinClass *class)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+  GtkContainerClass *container_class;
+
+  object_class = (GtkObjectClass*) class;
+  widget_class = (GtkWidgetClass*) class;
+  container_class = (GtkContainerClass*) class;
+
+  parent_class = gtk_type_class (gtk_container_get_type ());
+
+  object_class->destroy = gtk_bin_destroy;
+
+  widget_class->map = gtk_bin_map;
+  widget_class->unmap = gtk_bin_unmap;
+  widget_class->draw = gtk_bin_draw;
+  widget_class->expose_event = gtk_bin_expose;
+
+  container_class->add = gtk_bin_add;
+  container_class->remove = gtk_bin_remove;
+  container_class->foreach = gtk_bin_foreach;
+}
+
+static void
+gtk_bin_init (GtkBin *bin)
+{
+  GTK_WIDGET_SET_FLAGS (bin, GTK_NO_WINDOW);
+
+  bin->child = NULL;
+}
+
+
+static void
+gtk_bin_destroy (GtkObject *object)
+{
+  GtkBin *bin;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_BIN (object));
+
+  bin = GTK_BIN (object);
+
+  if (bin->child)
+    {
+      bin->child->parent = NULL;
+      gtk_object_unref (GTK_OBJECT (bin->child));
+      gtk_widget_destroy (bin->child);
+    }
+
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+gtk_bin_map (GtkWidget *widget)
+{
+  GtkBin *bin;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_BIN (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
+  bin = GTK_BIN (widget);
+
+  if (!GTK_WIDGET_NO_WINDOW (widget))
+    gdk_window_show (widget->window);
+  else
+    gtk_widget_queue_draw (widget);
+
+  if (bin->child &&
+      GTK_WIDGET_VISIBLE (bin->child) &&
+      !GTK_WIDGET_MAPPED (bin->child))
+    gtk_widget_map (bin->child);
+}
+
+static void
+gtk_bin_unmap (GtkWidget *widget)
+{
+  GtkBin *bin;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_BIN (widget));
+
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
+  bin = GTK_BIN (widget);
+
+  if (GTK_WIDGET_NO_WINDOW (widget))
+    gdk_window_clear_area (widget->window,
+                          widget->allocation.x,
+                          widget->allocation.y,
+                          widget->allocation.width,
+                          widget->allocation.height);
+  else
+    gdk_window_hide (widget->window);
+
+  if (bin->child &&
+      GTK_WIDGET_VISIBLE (bin->child) &&
+      GTK_WIDGET_MAPPED (bin->child))
+    gtk_widget_unmap (bin->child);
+}
+
+static void
+gtk_bin_draw (GtkWidget    *widget,
+             GdkRectangle *area)
+{
+  GtkBin *bin;
+  GdkRectangle child_area;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_BIN (widget));
+
+  if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget))
+    {
+      bin = GTK_BIN (widget);
+
+      if (bin->child &&
+         gtk_widget_intersect (bin->child, area, &child_area))
+        gtk_widget_draw (bin->child, &child_area);
+    }
+}
+
+static gint
+gtk_bin_expose (GtkWidget      *widget,
+               GdkEventExpose *event)
+{
+  GtkBin *bin;
+  GdkEventExpose child_event;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_BIN (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      bin = GTK_BIN (widget);
+
+      child_event = *event;
+      if (bin->child &&
+         GTK_WIDGET_NO_WINDOW (bin->child) &&
+         gtk_widget_intersect (bin->child, &event->area, &child_event.area))
+       gtk_widget_event (bin->child, (GdkEvent*) &child_event);
+    }
+
+  return FALSE;
+}
+
+
+static void
+gtk_bin_add (GtkContainer *container,
+            GtkWidget    *widget)
+{
+  GtkBin *bin;
+
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_BIN (container));
+  g_return_if_fail (widget != NULL);
+
+  bin = GTK_BIN (container);
+
+  if (!bin->child)
+    {
+      gtk_widget_set_parent (widget, GTK_WIDGET (container));
+
+      if (GTK_WIDGET_VISIBLE (widget->parent))
+       {
+         if (GTK_WIDGET_REALIZED (widget->parent) &&
+             !GTK_WIDGET_REALIZED (widget))
+           gtk_widget_realize (widget);
+         
+         if (GTK_WIDGET_MAPPED (widget->parent) &&
+             !GTK_WIDGET_MAPPED (widget))
+           gtk_widget_map (widget);
+       }
+
+      bin->child = widget;
+
+      if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
+        gtk_widget_queue_resize (widget);
+    }
+}
+
+static void
+gtk_bin_remove (GtkContainer *container,
+               GtkWidget    *widget)
+{
+  GtkBin *bin;
+
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_BIN (container));
+  g_return_if_fail (widget != NULL);
+
+  bin = GTK_BIN (container);
+
+  if (bin->child == widget)
+    {
+      gtk_widget_unparent (widget);
+
+      bin->child = NULL;
+
+      if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
+        gtk_widget_queue_resize (GTK_WIDGET (container));
+    }
+}
+
+static void
+gtk_bin_foreach (GtkContainer *container,
+                GtkCallback   callback,
+                gpointer      callback_data)
+{
+  GtkBin *bin;
+
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_BIN (container));
+  g_return_if_fail (callback != NULL);
+
+  bin = GTK_BIN (container);
+
+  if (bin->child)
+    (* callback) (bin->child, callback_data);
+}
diff --git a/gtk/gtkbin.h b/gtk/gtkbin.h
new file mode 100644 (file)
index 0000000..c8676ab
--- /dev/null
@@ -0,0 +1,60 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_BIN_H__
+#define __GTK_BIN_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkcontainer.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_BIN(obj)          GTK_CHECK_CAST (obj, gtk_bin_get_type (), GtkBin)
+#define GTK_BIN_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_bin_get_type (), GtkBinClass)
+#define GTK_IS_BIN(obj)       GTK_CHECK_TYPE (obj, gtk_bin_get_type ())
+
+
+typedef struct _GtkBin       GtkBin;
+typedef struct _GtkBinClass  GtkBinClass;
+
+struct _GtkBin
+{
+  GtkContainer container;
+
+  GtkWidget *child;
+};
+
+struct _GtkBinClass
+{
+  GtkContainerClass parent_class;
+};
+
+
+guint  gtk_bin_get_type   (void);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_BIN_H__ */
diff --git a/gtk/gtkbox.c b/gtk/gtkbox.c
new file mode 100644 (file)
index 0000000..dfb2fed
--- /dev/null
@@ -0,0 +1,453 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkbox.h"
+
+
+static void gtk_box_class_init (GtkBoxClass    *klass);
+static void gtk_box_init       (GtkBox         *box);
+static void gtk_box_destroy    (GtkObject      *object);
+static void gtk_box_map        (GtkWidget      *widget);
+static void gtk_box_unmap      (GtkWidget      *widget);
+static void gtk_box_draw       (GtkWidget      *widget,
+                               GdkRectangle   *area);
+static gint gtk_box_expose     (GtkWidget      *widget,
+                               GdkEventExpose *event);
+static void gtk_box_add        (GtkContainer   *container,
+                               GtkWidget      *widget);
+static void gtk_box_remove     (GtkContainer   *container,
+                               GtkWidget      *widget);
+static void gtk_box_foreach    (GtkContainer   *container,
+                               GtkCallback     callback,
+                               gpointer        callback_data);
+
+
+static GtkContainerClass *parent_class = NULL;
+
+
+guint
+gtk_box_get_type ()
+{
+  static guint box_type = 0;
+
+  if (!box_type)
+    {
+      GtkTypeInfo box_info =
+      {
+       "GtkBox",
+       sizeof (GtkBox),
+       sizeof (GtkBoxClass),
+       (GtkClassInitFunc) gtk_box_class_init,
+       (GtkObjectInitFunc) gtk_box_init,
+       (GtkArgFunc) NULL,
+      };
+
+      box_type = gtk_type_unique (gtk_container_get_type (), &box_info);
+    }
+
+  return box_type;
+}
+
+static void
+gtk_box_class_init (GtkBoxClass *class)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+  GtkContainerClass *container_class;
+
+  object_class = (GtkObjectClass*) class;
+  widget_class = (GtkWidgetClass*) class;
+  container_class = (GtkContainerClass*) class;
+
+  parent_class = gtk_type_class (gtk_container_get_type ());
+
+  object_class->destroy = gtk_box_destroy;
+
+  widget_class->map = gtk_box_map;
+  widget_class->unmap = gtk_box_unmap;
+  widget_class->draw = gtk_box_draw;
+  widget_class->expose_event = gtk_box_expose;
+
+  container_class->add = gtk_box_add;
+  container_class->remove = gtk_box_remove;
+  container_class->foreach = gtk_box_foreach;
+}
+
+static void
+gtk_box_init (GtkBox *box)
+{
+  GTK_WIDGET_SET_FLAGS (box, GTK_NO_WINDOW | GTK_BASIC);
+
+  box->children = NULL;
+  box->spacing = 0;
+  box->homogeneous = FALSE;
+}
+
+void
+gtk_box_pack_start (GtkBox    *box,
+                   GtkWidget *child,
+                   gint       expand,
+                   gint       fill,
+                   gint       padding)
+{
+  GtkBoxChild *child_info;
+
+  g_return_if_fail (box != NULL);
+  g_return_if_fail (GTK_IS_BOX (box));
+  g_return_if_fail (child != NULL);
+
+  child_info = g_new (GtkBoxChild, 1);
+  child_info->widget = child;
+  child_info->padding = padding;
+  child_info->expand = expand ? TRUE : FALSE;
+  child_info->fill = fill ? TRUE : FALSE;
+  child_info->pack = GTK_PACK_START;
+
+  box->children = g_list_append (box->children, child_info);
+
+  gtk_widget_set_parent (child, GTK_WIDGET (box));
+
+  if (GTK_WIDGET_VISIBLE (GTK_WIDGET (box)))
+    {
+      if (GTK_WIDGET_REALIZED (GTK_WIDGET (box)) &&
+         !GTK_WIDGET_REALIZED (child))
+       gtk_widget_realize (child);
+      
+      if (GTK_WIDGET_MAPPED (GTK_WIDGET (box)) &&
+         !GTK_WIDGET_MAPPED (child))
+       gtk_widget_map (child);
+    }
+
+  if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (box))
+    gtk_widget_queue_resize (child);
+}
+
+void
+gtk_box_pack_end (GtkBox    *box,
+                 GtkWidget *child,
+                 gint       expand,
+                 gint       fill,
+                 gint       padding)
+{
+  GtkBoxChild *child_info;
+
+  g_return_if_fail (box != NULL);
+  g_return_if_fail (GTK_IS_BOX (box));
+  g_return_if_fail (child != NULL);
+
+  child_info = g_new (GtkBoxChild, 1);
+  child_info->widget = child;
+  child_info->padding = padding;
+  child_info->expand = expand ? TRUE : FALSE;
+  child_info->fill = fill ? TRUE : FALSE;
+  child_info->pack = GTK_PACK_END;
+
+  box->children = g_list_append (box->children, child_info);
+
+  gtk_widget_set_parent (child, GTK_WIDGET (box));
+
+  if (GTK_WIDGET_VISIBLE (GTK_WIDGET (box)))
+    {
+      if (GTK_WIDGET_REALIZED (GTK_WIDGET (box)) &&
+         !GTK_WIDGET_REALIZED (child))
+       gtk_widget_realize (child);
+      
+      if (GTK_WIDGET_MAPPED (GTK_WIDGET (box)) &&
+         !GTK_WIDGET_MAPPED (child))
+       gtk_widget_map (child);
+    }
+  
+  if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (box))
+    gtk_widget_queue_resize (child);
+}
+
+void
+gtk_box_pack_start_defaults (GtkBox    *box,
+                            GtkWidget *child)
+{
+  g_return_if_fail (box != NULL);
+  g_return_if_fail (GTK_IS_BOX (box));
+  g_return_if_fail (child != NULL);
+
+  gtk_box_pack_start (box, child, TRUE, TRUE, 0);
+}
+
+void
+gtk_box_pack_end_defaults (GtkBox    *box,
+                          GtkWidget *child)
+{
+  g_return_if_fail (box != NULL);
+  g_return_if_fail (GTK_IS_BOX (box));
+  g_return_if_fail (child != NULL);
+
+  gtk_box_pack_end (box, child, TRUE, TRUE, 0);
+}
+
+void
+gtk_box_set_homogeneous (GtkBox *box,
+                        gint    homogeneous)
+{
+  g_return_if_fail (box != NULL);
+  g_return_if_fail (GTK_IS_BOX (box));
+
+  if ((homogeneous ? TRUE : FALSE) != box->homogeneous)
+    {
+      box->homogeneous = homogeneous ? TRUE : FALSE;
+      gtk_widget_queue_resize (GTK_WIDGET (box));
+    }
+}
+
+void
+gtk_box_set_spacing (GtkBox *box,
+                    gint    spacing)
+{
+  g_return_if_fail (box != NULL);
+  g_return_if_fail (GTK_IS_BOX (box));
+
+  if (spacing != box->spacing)
+    {
+      box->spacing = spacing;
+      gtk_widget_queue_resize (GTK_WIDGET (box));
+    }
+}
+
+
+static void
+gtk_box_destroy (GtkObject *object)
+{
+  GtkBox *box;
+  GtkBoxChild *child;
+  GList *children;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_BOX (object));
+
+  box = GTK_BOX (object);
+
+  children = box->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      child->widget->parent = NULL;
+      gtk_object_unref (GTK_OBJECT (child->widget));
+      gtk_widget_destroy (child->widget);
+      g_free (child);
+    }
+
+  g_list_free (box->children);
+
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+gtk_box_map (GtkWidget *widget)
+{
+  GtkBox *box;
+  GtkBoxChild *child;
+  GList *children;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_BOX (widget));
+
+  box = GTK_BOX (widget);
+  GTK_WIDGET_SET_FLAGS (box, GTK_MAPPED);
+
+  children = box->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (child->widget) &&
+         !GTK_WIDGET_MAPPED (child->widget))
+       gtk_widget_map (child->widget);
+    }
+}
+
+static void
+gtk_box_unmap (GtkWidget *widget)
+{
+  GtkBox *box;
+  GtkBoxChild *child;
+  GList *children;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_BOX (widget));
+
+  box = GTK_BOX (widget);
+  GTK_WIDGET_UNSET_FLAGS (box, GTK_MAPPED);
+
+  children = box->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (child->widget) &&
+         GTK_WIDGET_MAPPED (child->widget))
+       gtk_widget_unmap (child->widget);
+    }
+}
+
+static void
+gtk_box_draw (GtkWidget    *widget,
+             GdkRectangle *area)
+{
+  GtkBox *box;
+  GtkBoxChild *child;
+  GdkRectangle child_area;
+  GList *children;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_BOX (widget));
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      box = GTK_BOX (widget);
+
+      children = box->children;
+      while (children)
+       {
+         child = children->data;
+         children = children->next;
+
+         if (gtk_widget_intersect (child->widget, area, &child_area))
+           gtk_widget_draw (child->widget, &child_area);
+       }
+    }
+}
+
+static gint
+gtk_box_expose (GtkWidget      *widget,
+               GdkEventExpose *event)
+{
+  GtkBox *box;
+  GtkBoxChild *child;
+  GdkEventExpose child_event;
+  GList *children;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_BOX (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      box = GTK_BOX (widget);
+
+      child_event = *event;
+
+      children = box->children;
+      while (children)
+       {
+         child = children->data;
+         children = children->next;
+
+         if (GTK_WIDGET_NO_WINDOW (child->widget) &&
+             gtk_widget_intersect (child->widget, &event->area, &child_event.area))
+           gtk_widget_event (child->widget, (GdkEvent*) &child_event);
+       }
+    }
+
+  return FALSE;
+}
+
+static void
+gtk_box_add (GtkContainer *container,
+            GtkWidget    *widget)
+{
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_BOX (container));
+  g_return_if_fail (widget != NULL);
+
+  gtk_box_pack_start_defaults (GTK_BOX (container), widget);
+}
+
+static void
+gtk_box_remove (GtkContainer *container,
+               GtkWidget    *widget)
+{
+  GtkBox *box;
+  GtkBoxChild *child;
+  GList *children;
+
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_BOX (container));
+  g_return_if_fail (widget != NULL);
+
+  box = GTK_BOX (container);
+
+  children = box->children;
+  while (children)
+    {
+      child = children->data;
+
+      if (child->widget == widget)
+       {
+         gtk_widget_unparent (widget);
+
+         box->children = g_list_remove_link (box->children, children);
+         g_list_free (children);
+         g_free (child);
+
+         if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
+           gtk_widget_queue_resize (GTK_WIDGET (container));
+
+         break;
+       }
+
+      children = children->next;
+    }
+}
+
+static void
+gtk_box_foreach (GtkContainer *container,
+                GtkCallback   callback,
+                gpointer      callback_data)
+{
+  GtkBox *box;
+  GtkBoxChild *child;
+  GList *children;
+
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_BOX (container));
+  g_return_if_fail (callback != NULL);
+
+  box = GTK_BOX (container);
+
+  children = box->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (child->pack == GTK_PACK_START)
+       (* callback) (child->widget, callback_data);
+    }
+
+  children = g_list_last (box->children);
+  while (children)
+    {
+      child = children->data;
+      children = children->prev;
+
+      if (child->pack == GTK_PACK_END)
+       (* callback) (child->widget, callback_data);
+    }
+}
diff --git a/gtk/gtkbox.h b/gtk/gtkbox.h
new file mode 100644 (file)
index 0000000..5ff0dd2
--- /dev/null
@@ -0,0 +1,90 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_BOX_H__
+#define __GTK_BOX_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkcontainer.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_BOX(obj)          GTK_CHECK_CAST (obj, gtk_box_get_type (), GtkBox)
+#define GTK_BOX_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_box_get_type (), GtkBoxClass)
+#define GTK_IS_BOX(obj)       GTK_CHECK_TYPE (obj, gtk_box_get_type ())
+
+
+typedef struct _GtkBox        GtkBox;
+typedef struct _GtkBoxClass   GtkBoxClass;
+typedef struct _GtkBoxChild   GtkBoxChild;
+
+struct _GtkBox
+{
+  GtkContainer container;
+
+  GList *children;
+  gint16 spacing;
+  guint homogeneous : 1;
+};
+
+struct _GtkBoxClass
+{
+  GtkContainerClass parent_class;
+};
+
+struct _GtkBoxChild
+{
+  GtkWidget *widget;
+  guint16 padding;
+  guint expand : 1;
+  guint fill : 1;
+  guint pack : 1;
+};
+
+
+guint      gtk_box_get_type            (void);
+void       gtk_box_pack_start          (GtkBox       *box,
+                                       GtkWidget    *child,
+                                       gint          expand,
+                                       gint          fill,
+                                       gint          padding);
+void       gtk_box_pack_end            (GtkBox       *box,
+                                       GtkWidget    *child,
+                                       gint          expand,
+                                       gint          fill,
+                                       gint          padding);
+void       gtk_box_pack_start_defaults (GtkBox       *box,
+                                       GtkWidget    *widget);
+void       gtk_box_pack_end_defaults   (GtkBox       *box,
+                                       GtkWidget    *widget);
+void       gtk_box_set_homogeneous     (GtkBox       *box,
+                                       gint          homogeneous);
+void       gtk_box_set_spacing         (GtkBox       *box,
+                                       gint          spacing);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_BOX_H__ */
diff --git a/gtk/gtkbutton.c b/gtk/gtkbutton.c
new file mode 100644 (file)
index 0000000..18afb17
--- /dev/null
@@ -0,0 +1,915 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkbutton.h"
+#include "gtklabel.h"
+#include "gtkmain.h"
+#include "gtksignal.h"
+
+
+#define CHILD_SPACING     1
+#define DEFAULT_LEFT_POS  4
+#define DEFAULT_TOP_POS   4
+#define DEFAULT_SPACING   7
+
+
+enum {
+  PRESSED,
+  RELEASED,
+  CLICKED,
+  ENTER,
+  LEAVE,
+  LAST_SIGNAL
+};
+
+
+static void gtk_button_class_init     (GtkButtonClass   *klass);
+static void gtk_button_init           (GtkButton        *button);
+static void gtk_button_arg            (GtkButton        *button,
+                                      GtkArg           *arg);
+static void gtk_button_destroy        (GtkObject        *object);
+static void gtk_button_map            (GtkWidget        *widget);
+static void gtk_button_unmap          (GtkWidget        *widget);
+static void gtk_button_realize        (GtkWidget        *widget);
+static void gtk_button_size_request   (GtkWidget        *widget,
+                                      GtkRequisition   *requisition);
+static void gtk_button_size_allocate  (GtkWidget        *widget,
+                                      GtkAllocation    *allocation);
+static void gtk_button_paint          (GtkWidget        *widget,
+                                      GdkRectangle     *area);
+static void gtk_button_draw           (GtkWidget        *widget,
+                                      GdkRectangle     *area);
+static void gtk_button_draw_focus     (GtkWidget        *widget);
+static void gtk_button_draw_default   (GtkWidget        *widget);
+static gint gtk_button_expose         (GtkWidget        *widget,
+                                      GdkEventExpose   *event);
+static gint gtk_button_button_press   (GtkWidget        *widget,
+                                      GdkEventButton   *event);
+static gint gtk_button_button_release (GtkWidget        *widget,
+                                      GdkEventButton   *event);
+static gint gtk_button_enter_notify   (GtkWidget        *widget,
+                                      GdkEventCrossing *event);
+static gint gtk_button_leave_notify   (GtkWidget        *widget,
+                                      GdkEventCrossing *event);
+static gint gtk_button_focus_in       (GtkWidget        *widget,
+                                      GdkEventFocus    *event);
+static gint gtk_button_focus_out      (GtkWidget        *widget,
+                                      GdkEventFocus    *event);
+static void gtk_button_add            (GtkContainer     *container,
+                                      GtkWidget        *widget);
+static void gtk_button_remove         (GtkContainer     *container,
+                                      GtkWidget        *widget);
+static void gtk_button_foreach        (GtkContainer     *container,
+                                      GtkCallback       callback,
+                                      gpointer          callback_data);
+static void gtk_real_button_pressed   (GtkButton        *button);
+static void gtk_real_button_released  (GtkButton        *button);
+static void gtk_real_button_enter     (GtkButton        *button);
+static void gtk_real_button_leave     (GtkButton        *button);
+
+
+static GtkContainerClass *parent_class;
+static gint button_signals[LAST_SIGNAL] = { 0 };
+
+
+guint
+gtk_button_get_type ()
+{
+  static guint button_type = 0;
+
+  if (!button_type)
+    {
+      GtkTypeInfo button_info =
+      {
+       "GtkButton",
+       sizeof (GtkButton),
+       sizeof (GtkButtonClass),
+       (GtkClassInitFunc) gtk_button_class_init,
+       (GtkObjectInitFunc) gtk_button_init,
+       (GtkArgFunc) gtk_button_arg,
+      };
+
+      button_type = gtk_type_unique (gtk_container_get_type (), &button_info);
+    }
+
+  return button_type;
+}
+
+static void
+gtk_button_class_init (GtkButtonClass *klass)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+  GtkContainerClass *container_class;
+
+  object_class = (GtkObjectClass*) klass;
+  widget_class = (GtkWidgetClass*) klass;
+  container_class = (GtkContainerClass*) klass;
+
+  parent_class = gtk_type_class (gtk_container_get_type ());
+
+  gtk_object_add_arg_type ("GtkButton::label", GTK_TYPE_STRING);
+
+  button_signals[PRESSED] =
+    gtk_signal_new ("pressed",
+                    GTK_RUN_FIRST,
+                    object_class->type,
+                    GTK_SIGNAL_OFFSET (GtkButtonClass, pressed),
+                    gtk_signal_default_marshaller,
+                   GTK_TYPE_NONE, 0);
+  button_signals[RELEASED] =
+    gtk_signal_new ("released",
+                    GTK_RUN_FIRST,
+                    object_class->type,
+                    GTK_SIGNAL_OFFSET (GtkButtonClass, released),
+                    gtk_signal_default_marshaller,
+                   GTK_TYPE_NONE, 0);
+  button_signals[CLICKED] =
+    gtk_signal_new ("clicked",
+                    GTK_RUN_FIRST,
+                    object_class->type,
+                    GTK_SIGNAL_OFFSET (GtkButtonClass, clicked),
+                    gtk_signal_default_marshaller,
+                   GTK_TYPE_NONE, 0);
+  button_signals[ENTER] =
+    gtk_signal_new ("enter",
+                    GTK_RUN_FIRST,
+                    object_class->type,
+                    GTK_SIGNAL_OFFSET (GtkButtonClass, enter),
+                    gtk_signal_default_marshaller,
+                   GTK_TYPE_NONE, 0);
+  button_signals[LEAVE] =
+    gtk_signal_new ("leave",
+                    GTK_RUN_FIRST,
+                    object_class->type,
+                    GTK_SIGNAL_OFFSET (GtkButtonClass, leave),
+                    gtk_signal_default_marshaller,
+                   GTK_TYPE_NONE, 0);
+
+  gtk_object_class_add_signals (object_class, button_signals, LAST_SIGNAL);
+
+  object_class->destroy = gtk_button_destroy;
+
+  widget_class->activate_signal = button_signals[CLICKED];
+  widget_class->map = gtk_button_map;
+  widget_class->unmap = gtk_button_unmap;
+  widget_class->realize = gtk_button_realize;
+  widget_class->draw = gtk_button_draw;
+  widget_class->draw_focus = gtk_button_draw_focus;
+  widget_class->draw_default = gtk_button_draw_default;
+  widget_class->size_request = gtk_button_size_request;
+  widget_class->size_allocate = gtk_button_size_allocate;
+  widget_class->expose_event = gtk_button_expose;
+  widget_class->button_press_event = gtk_button_button_press;
+  widget_class->button_release_event = gtk_button_button_release;
+  widget_class->enter_notify_event = gtk_button_enter_notify;
+  widget_class->leave_notify_event = gtk_button_leave_notify;
+  widget_class->focus_in_event = gtk_button_focus_in;
+  widget_class->focus_out_event = gtk_button_focus_out;
+
+  container_class->add = gtk_button_add;
+  container_class->remove = gtk_button_remove;
+  container_class->foreach = gtk_button_foreach;
+
+  klass->pressed = gtk_real_button_pressed;
+  klass->released = gtk_real_button_released;
+  klass->clicked = NULL;
+  klass->enter = gtk_real_button_enter;
+  klass->leave = gtk_real_button_leave;
+}
+
+static void
+gtk_button_init (GtkButton *button)
+{
+  GTK_WIDGET_SET_FLAGS (button, GTK_CAN_FOCUS);
+
+  button->child = NULL;
+  button->in_button = FALSE;
+  button->button_down = FALSE;
+}
+
+static void
+gtk_button_arg (GtkButton *button,
+               GtkArg    *arg)
+{
+  if (strcmp (arg->name, "label") == 0)
+    {
+      GtkWidget *label;
+
+      gtk_container_disable_resize (GTK_CONTAINER (button));
+
+      if (button->child)
+       gtk_widget_destroy (button->child);
+
+      label = gtk_label_new (GTK_VALUE_STRING(*arg));
+      gtk_widget_show (label);
+
+      gtk_container_add (GTK_CONTAINER (button), label);
+      gtk_container_enable_resize (GTK_CONTAINER (button));
+    }
+}
+
+GtkWidget*
+gtk_button_new ()
+{
+  return GTK_WIDGET (gtk_type_new (gtk_button_get_type ()));
+}
+
+GtkWidget*
+gtk_button_new_with_label (const gchar *label)
+{
+  GtkWidget *button;
+  GtkWidget *label_widget;
+
+  button = gtk_button_new ();
+  label_widget = gtk_label_new (label);
+  gtk_misc_set_alignment (GTK_MISC (label_widget), 0.5, 0.5);
+
+  gtk_container_add (GTK_CONTAINER (button), label_widget);
+  gtk_widget_show (label_widget);
+
+  return button;
+}
+
+void
+gtk_button_pressed (GtkButton *button)
+{
+  gtk_signal_emit (GTK_OBJECT (button), button_signals[PRESSED]);
+}
+
+void
+gtk_button_released (GtkButton *button)
+{
+  gtk_signal_emit (GTK_OBJECT (button), button_signals[RELEASED]);
+}
+
+void
+gtk_button_clicked (GtkButton *button)
+{
+  gtk_signal_emit (GTK_OBJECT (button), button_signals[CLICKED]);
+}
+
+void
+gtk_button_enter (GtkButton *button)
+{
+  gtk_signal_emit (GTK_OBJECT (button), button_signals[ENTER]);
+}
+
+void
+gtk_button_leave (GtkButton *button)
+{
+  gtk_signal_emit (GTK_OBJECT (button), button_signals[LEAVE]);
+}
+
+static void
+gtk_button_destroy (GtkObject *object)
+{
+  GtkButton *button;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_BUTTON (object));
+
+  button = GTK_BUTTON (object);
+
+  if (button->child)
+    {
+      button->child->parent = NULL;
+      gtk_object_unref (GTK_OBJECT (button->child));
+      gtk_widget_destroy (button->child);
+    }
+
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+gtk_button_map (GtkWidget *widget)
+{
+  GtkButton *button;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_BUTTON (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
+  gdk_window_show (widget->window);
+
+  button = GTK_BUTTON (widget);
+
+  if (button->child &&
+      GTK_WIDGET_VISIBLE (button->child) &&
+      !GTK_WIDGET_MAPPED (button->child))
+    gtk_widget_map (button->child);
+}
+
+static void
+gtk_button_unmap (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_BUTTON (widget));
+
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
+  gdk_window_hide (widget->window);
+}
+
+static void
+gtk_button_realize (GtkWidget *widget)
+{
+  GtkButton *button;
+  GdkWindowAttr attributes;
+  gint attributes_mask;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_BUTTON (widget));
+
+  button = GTK_BUTTON (widget);
+  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+
+  attributes.window_type = GDK_WINDOW_CHILD;
+  attributes.x = widget->allocation.x;
+  attributes.y = widget->allocation.y;
+  attributes.width = widget->allocation.width;
+  attributes.height = widget->allocation.height;
+  attributes.wclass = GDK_INPUT_OUTPUT;
+  attributes.visual = gtk_widget_get_visual (widget);
+  attributes.colormap = gtk_widget_get_colormap (widget);
+  attributes.event_mask = gtk_widget_get_events (widget);
+  attributes.event_mask |= (GDK_EXPOSURE_MASK |
+                           GDK_BUTTON_PRESS_MASK |
+                           GDK_BUTTON_RELEASE_MASK |
+                           GDK_ENTER_NOTIFY_MASK |
+                           GDK_LEAVE_NOTIFY_MASK);
+
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+
+  widget->window = gdk_window_new (widget->parent->window, &attributes, attributes_mask);
+  gdk_window_set_user_data (widget->window, button);
+
+  widget->style = gtk_style_attach (widget->style, widget->window);
+  gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
+}
+
+static void
+gtk_button_size_request (GtkWidget      *widget,
+                        GtkRequisition *requisition)
+{
+  GtkButton *button;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_BUTTON (widget));
+  g_return_if_fail (requisition != NULL);
+
+  button = GTK_BUTTON (widget);
+
+  requisition->width = (GTK_CONTAINER (widget)->border_width + CHILD_SPACING +
+                       GTK_WIDGET (widget)->style->klass->xthickness) * 2;
+  requisition->height = (GTK_CONTAINER (widget)->border_width + CHILD_SPACING +
+                        GTK_WIDGET (widget)->style->klass->ythickness) * 2;
+
+  if (GTK_WIDGET_CAN_DEFAULT (widget))
+    {
+      requisition->width += (GTK_WIDGET (widget)->style->klass->xthickness * 2 +
+                            DEFAULT_SPACING);
+      requisition->height += (GTK_WIDGET (widget)->style->klass->ythickness * 2 +
+                             DEFAULT_SPACING);
+    }
+
+  if (button->child && GTK_WIDGET_VISIBLE (button->child))
+    {
+      gtk_widget_size_request (button->child, &button->child->requisition);
+
+      requisition->width += button->child->requisition.width;
+      requisition->height += button->child->requisition.height;
+    }
+}
+
+static void
+gtk_button_size_allocate (GtkWidget     *widget,
+                         GtkAllocation *allocation)
+{
+  GtkButton *button;
+  GtkAllocation child_allocation;
+  gint border_width;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_BUTTON (widget));
+  g_return_if_fail (allocation != NULL);
+
+  widget->allocation = *allocation;
+  border_width = GTK_CONTAINER (widget)->border_width;
+
+  if (GTK_WIDGET_REALIZED (widget))
+    gdk_window_move_resize (widget->window,
+                           widget->allocation.x + border_width,
+                           widget->allocation.y + border_width,
+                           widget->allocation.width - border_width * 2,
+                           widget->allocation.height - border_width * 2);
+
+  button = GTK_BUTTON (widget);
+
+  if (button->child && GTK_WIDGET_VISIBLE (button->child))
+    {
+      child_allocation.x = (CHILD_SPACING + GTK_WIDGET (widget)->style->klass->xthickness);
+      child_allocation.y = (CHILD_SPACING + GTK_WIDGET (widget)->style->klass->ythickness);
+
+      child_allocation.width = widget->allocation.width - child_allocation.x * 2 -
+                                border_width * 2;
+      child_allocation.height = widget->allocation.height - child_allocation.y * 2 -
+                                 border_width * 2;
+
+      if (GTK_WIDGET_CAN_DEFAULT (button))
+       {
+         child_allocation.x += (GTK_WIDGET (widget)->style->klass->xthickness +
+                                DEFAULT_LEFT_POS);
+         child_allocation.y += (GTK_WIDGET (widget)->style->klass->ythickness +
+                                DEFAULT_TOP_POS);
+         child_allocation.width -= (GTK_WIDGET (widget)->style->klass->xthickness * 2 +
+                                    DEFAULT_SPACING);
+         child_allocation.height -= (GTK_WIDGET (widget)->style->klass->xthickness * 2 +
+                                     DEFAULT_SPACING);
+       }
+
+      gtk_widget_size_allocate (button->child, &child_allocation);
+    }
+}
+
+static void
+gtk_button_paint (GtkWidget    *widget,
+                 GdkRectangle *area)
+{
+  GdkRectangle restrict_area;
+  GdkRectangle new_area;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_BUTTON (widget));
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      restrict_area.x = GTK_WIDGET (widget)->style->klass->xthickness;
+      restrict_area.y = GTK_WIDGET (widget)->style->klass->ythickness;
+      restrict_area.width = (GTK_WIDGET (widget)->allocation.width - restrict_area.x * 2 -
+                             GTK_CONTAINER (widget)->border_width * 2);
+      restrict_area.height = (GTK_WIDGET (widget)->allocation.height - restrict_area.y * 2 -
+                              GTK_CONTAINER (widget)->border_width * 2);
+
+      if (GTK_WIDGET_CAN_DEFAULT (widget))
+       {
+         restrict_area.x += DEFAULT_LEFT_POS;
+         restrict_area.y += DEFAULT_TOP_POS;
+         restrict_area.width -= DEFAULT_SPACING;
+         restrict_area.height -= DEFAULT_SPACING;
+       }
+
+      if (gdk_rectangle_intersect (area, &restrict_area, &new_area))
+       {
+         gtk_style_set_background (widget->style, widget->window, GTK_WIDGET_STATE (widget));
+         gdk_window_clear_area (widget->window,
+                                new_area.x, new_area.y,
+                                new_area.width, new_area.height);
+       }
+    }
+}
+
+static void
+gtk_button_draw (GtkWidget    *widget,
+                GdkRectangle *area)
+{
+  GtkButton *button;
+  GdkRectangle child_area;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_BUTTON (widget));
+  g_return_if_fail (area != NULL);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      button = GTK_BUTTON (widget);
+
+      gtk_button_paint (widget, area);
+
+      if (button->child && gtk_widget_intersect (button->child, area, &child_area))
+       gtk_widget_draw (button->child, &child_area);
+
+      gtk_widget_draw_default (widget);
+      gtk_widget_draw_focus (widget);
+    }
+}
+
+static void
+gtk_button_draw_focus (GtkWidget *widget)
+{
+  GtkButton *button;
+  GtkShadowType shadow_type;
+  gint width, height;
+  gint x, y;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_BUTTON (widget));
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      button = GTK_BUTTON (widget);
+
+      x = 0;
+      y = 0;
+      width = widget->allocation.width - GTK_CONTAINER (widget)->border_width * 2;
+      height = widget->allocation.height - GTK_CONTAINER (widget)->border_width * 2;
+
+      if (GTK_WIDGET_CAN_DEFAULT (widget))
+       {
+         x += widget->style->klass->xthickness;
+         y += widget->style->klass->ythickness;
+         width -= 2 * x + DEFAULT_SPACING;
+         height -= 2 * y + DEFAULT_SPACING;
+         x += DEFAULT_LEFT_POS;
+         y += DEFAULT_TOP_POS;
+       }
+
+      if (GTK_WIDGET_HAS_FOCUS (widget))
+       {
+         x += 1;
+         y += 1;
+         width -= 2;
+         height -= 2;
+       }
+      else
+       {
+         if (GTK_WIDGET_STATE (widget) == GTK_STATE_ACTIVE)
+           gdk_draw_rectangle (widget->window,
+                               widget->style->bg_gc[GTK_WIDGET_STATE (widget)], FALSE,
+                               x + 1, y + 1, width - 4, height - 4);
+         else
+           gdk_draw_rectangle (widget->window,
+                               widget->style->bg_gc[GTK_WIDGET_STATE (widget)], FALSE,
+                               x + 2, y + 2, width - 5, height - 5);
+       }
+
+      if (GTK_WIDGET_STATE (widget) == GTK_STATE_ACTIVE)
+       shadow_type = GTK_SHADOW_IN;
+      else
+       shadow_type = GTK_SHADOW_OUT;
+
+      gtk_draw_shadow (widget->style, widget->window,
+                      GTK_WIDGET_STATE (widget), shadow_type,
+                      x, y, width, height);
+
+      if (GTK_WIDGET_HAS_FOCUS (widget))
+       {
+         x -= 1;
+         y -= 1;
+         width += 2;
+         height += 2;
+
+         gdk_draw_rectangle (widget->window,
+                             widget->style->black_gc, FALSE,
+                             x, y, width - 1, height - 1);
+       }
+    }
+}
+
+static void
+gtk_button_draw_default (GtkWidget *widget)
+{
+  gint width, height;
+  gint x, y;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_BUTTON (widget));
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      x = 0;
+      y = 0;
+      width = widget->allocation.width - GTK_CONTAINER (widget)->border_width * 2;
+      height = widget->allocation.height - GTK_CONTAINER (widget)->border_width * 2;
+
+      if (GTK_WIDGET_HAS_DEFAULT (widget))
+       {
+         gtk_draw_shadow (widget->style, widget->window,
+                          GTK_STATE_NORMAL, GTK_SHADOW_IN,
+                          x, y, width, height);
+       }
+      else
+       {
+         gdk_draw_rectangle (widget->window, widget->style->bg_gc[GTK_STATE_NORMAL],
+                             FALSE, x, y, width - 1, height - 1);
+         gdk_draw_rectangle (widget->window, widget->style->bg_gc[GTK_STATE_NORMAL],
+                             FALSE, x + 1, y + 1, width - 3, height - 3);
+       }
+    }
+}
+
+static gint
+gtk_button_expose (GtkWidget      *widget,
+                  GdkEventExpose *event)
+{
+  GtkButton *button;
+  GdkEventExpose child_event;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_BUTTON (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      button = GTK_BUTTON (widget);
+
+      gtk_button_paint (widget, &event->area);
+
+      child_event = *event;
+      if (button->child && GTK_WIDGET_NO_WINDOW (button->child) &&
+         gtk_widget_intersect (button->child, &event->area, &child_event.area))
+       gtk_widget_event (button->child, (GdkEvent*) &child_event);
+
+      gtk_widget_draw_default (widget);
+      gtk_widget_draw_focus (widget);
+    }
+
+  return FALSE;
+}
+
+static gint
+gtk_button_button_press (GtkWidget      *widget,
+                        GdkEventButton *event)
+{
+  GtkButton *button;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_BUTTON (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (event->type == GDK_BUTTON_PRESS)
+    {
+      button = GTK_BUTTON (widget);
+
+      if (GTK_WIDGET_CAN_DEFAULT (widget) && (event->button == 1))
+       gtk_widget_grab_default (widget);
+      if (!GTK_WIDGET_HAS_FOCUS (widget))
+       gtk_widget_grab_focus (widget);
+
+      if (event->button == 1)
+       {
+         gtk_grab_add (GTK_WIDGET (button));
+         gtk_button_pressed (button);
+       }
+    }
+
+  return TRUE;
+}
+
+static gint
+gtk_button_button_release (GtkWidget      *widget,
+                          GdkEventButton *event)
+{
+  GtkButton *button;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_BUTTON (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (event->button == 1)
+    {
+      button = GTK_BUTTON (widget);
+      gtk_grab_remove (GTK_WIDGET (button));
+      gtk_button_released (button);
+    }
+
+  return TRUE;
+}
+
+static gint
+gtk_button_enter_notify (GtkWidget        *widget,
+                        GdkEventCrossing *event)
+{
+  GtkButton *button;
+  GtkWidget *event_widget;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_BUTTON (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  button = GTK_BUTTON (widget);
+  event_widget = gtk_get_event_widget ((GdkEvent*) event);
+
+  if ((event_widget == widget) &&
+      (event->detail != GDK_NOTIFY_INFERIOR))
+    {
+      button->in_button = TRUE;
+      gtk_button_enter (button);
+    }
+
+  return FALSE;
+}
+
+static gint
+gtk_button_leave_notify (GtkWidget        *widget,
+                        GdkEventCrossing *event)
+{
+  GtkButton *button;
+  GtkWidget *event_widget;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_BUTTON (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  button = GTK_BUTTON (widget);
+  event_widget = gtk_get_event_widget ((GdkEvent*) event);
+
+  if ((event_widget == widget) &&
+      (event->detail != GDK_NOTIFY_INFERIOR))
+    {
+      button->in_button = FALSE;
+      gtk_button_leave (button);
+    }
+
+  return FALSE;
+}
+
+static gint
+gtk_button_focus_in (GtkWidget     *widget,
+                    GdkEventFocus *event)
+{
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_BUTTON (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
+  gtk_widget_draw_focus (widget);
+
+  return FALSE;
+}
+
+static gint
+gtk_button_focus_out (GtkWidget     *widget,
+                     GdkEventFocus *event)
+{
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_BUTTON (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
+  gtk_widget_draw_focus (widget);
+
+  return FALSE;
+}
+
+static void
+gtk_button_add (GtkContainer *container,
+               GtkWidget    *widget)
+{
+  GtkButton *button;
+
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_BUTTON (container));
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (gtk_widget_basic (widget));
+
+  button = GTK_BUTTON (container);
+
+  if (!button->child)
+    {
+      gtk_widget_set_parent (widget, GTK_WIDGET (container));
+
+      if (GTK_WIDGET_VISIBLE (widget->parent))
+       {
+         if (GTK_WIDGET_REALIZED (widget->parent) &&
+             !GTK_WIDGET_REALIZED (widget))
+           gtk_widget_realize (widget);
+         
+         if (GTK_WIDGET_MAPPED (widget->parent) &&
+             !GTK_WIDGET_MAPPED (widget))
+           gtk_widget_map (widget);
+       }
+      
+      button->child = widget;
+
+      if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
+       gtk_widget_queue_resize (widget);
+    }
+}
+
+static void
+gtk_button_remove (GtkContainer *container,
+                  GtkWidget    *widget)
+{
+  GtkButton *button;
+
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_BUTTON (container));
+
+  button = GTK_BUTTON (container);
+
+  if (button->child == widget)
+    {
+      gtk_widget_unparent (widget);
+
+      button->child = NULL;
+
+      if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
+       gtk_widget_queue_resize (GTK_WIDGET (container));
+    }
+}
+
+static void
+gtk_button_foreach (GtkContainer *container,
+                   GtkCallback   callback,
+                   gpointer      callback_data)
+{
+  GtkButton *button;
+
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_BUTTON (container));
+  g_return_if_fail (callback != NULL);
+
+  button = GTK_BUTTON (container);
+
+  if (button->child)
+    (* callback) (button->child, callback_data);
+}
+
+static void
+gtk_real_button_pressed (GtkButton *button)
+{
+  GtkStateType new_state;
+
+  g_return_if_fail (button != NULL);
+  g_return_if_fail (GTK_IS_BUTTON (button));
+
+  button->button_down = TRUE;
+
+  new_state = (button->in_button ? GTK_STATE_ACTIVE : GTK_STATE_NORMAL);
+
+  if (GTK_WIDGET_STATE (button) != new_state)
+    {
+      gtk_widget_set_state (GTK_WIDGET (button), new_state);
+      gtk_widget_queue_draw (GTK_WIDGET (button));
+    }
+}
+
+static void
+gtk_real_button_released (GtkButton *button)
+{
+  GtkStateType new_state;
+
+  g_return_if_fail (button != NULL);
+  g_return_if_fail (GTK_IS_BUTTON (button));
+
+  if (button->button_down)
+    {
+      button->button_down = FALSE;
+
+      if (button->in_button)
+       gtk_button_clicked (button);
+
+      new_state = (button->in_button ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL);
+
+      if (GTK_WIDGET_STATE (button) != new_state)
+       {
+         gtk_widget_set_state (GTK_WIDGET (button), new_state);
+         gtk_widget_queue_draw (GTK_WIDGET (button));
+       }
+    }
+}
+
+static void
+gtk_real_button_enter (GtkButton *button)
+{
+  GtkStateType new_state;
+
+  g_return_if_fail (button != NULL);
+  g_return_if_fail (GTK_IS_BUTTON (button));
+
+  new_state = (button->button_down ? GTK_STATE_ACTIVE : GTK_STATE_PRELIGHT);
+
+  if (GTK_WIDGET_STATE (button) != new_state)
+    {
+      gtk_widget_set_state (GTK_WIDGET (button), new_state);
+      gtk_widget_queue_draw (GTK_WIDGET (button));
+    }
+}
+
+static void
+gtk_real_button_leave (GtkButton *button)
+{
+  g_return_if_fail (button != NULL);
+  g_return_if_fail (GTK_IS_BUTTON (button));
+
+  if (GTK_WIDGET_STATE (button) != GTK_STATE_NORMAL)
+    {
+      gtk_widget_set_state (GTK_WIDGET (button), GTK_STATE_NORMAL);
+      gtk_widget_queue_draw (GTK_WIDGET (button));
+    }
+}
diff --git a/gtk/gtkbutton.h b/gtk/gtkbutton.h
new file mode 100644 (file)
index 0000000..ec72c99
--- /dev/null
@@ -0,0 +1,76 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_BUTTON_H__
+#define __GTK_BUTTON_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkcontainer.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_BUTTON(obj)          GTK_CHECK_CAST (obj, gtk_button_get_type (), GtkButton)
+#define GTK_BUTTON_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_button_get_type (), GtkButtonClass)
+#define GTK_IS_BUTTON(obj)       GTK_CHECK_TYPE (obj, gtk_button_get_type ())
+
+
+typedef struct _GtkButton       GtkButton;
+typedef struct _GtkButtonClass  GtkButtonClass;
+
+struct _GtkButton
+{
+  GtkContainer container;
+
+  GtkWidget *child;
+
+  guint in_button : 1;
+  guint button_down : 1;
+};
+
+struct _GtkButtonClass
+{
+  GtkContainerClass parent_class;
+
+  void (* pressed)  (GtkButton *button);
+  void (* released) (GtkButton *button);
+  void (* clicked)  (GtkButton *button);
+  void (* enter)    (GtkButton *button);
+  void (* leave)    (GtkButton *button);
+};
+
+
+guint      gtk_button_get_type       (void);
+GtkWidget* gtk_button_new            (void);
+GtkWidget* gtk_button_new_with_label (const gchar *label);
+void       gtk_button_pressed        (GtkButton *button);
+void       gtk_button_released       (GtkButton *button);
+void       gtk_button_clicked        (GtkButton *button);
+void       gtk_button_enter          (GtkButton *button);
+void       gtk_button_leave          (GtkButton *button);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_BUTTON_H__ */
diff --git a/gtk/gtkcheckbutton.c b/gtk/gtkcheckbutton.c
new file mode 100644 (file)
index 0000000..d7f72ce
--- /dev/null
@@ -0,0 +1,362 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkcheckbutton.h"
+#include "gtklabel.h"
+
+
+#define INDICATOR_SIZE     10
+#define INDICATOR_SPACING  2
+
+#define CHECK_BUTTON_CLASS(w)  GTK_CHECK_BUTTON_CLASS (GTK_OBJECT (w)->klass)
+
+
+static void gtk_check_button_class_init          (GtkCheckButtonClass *klass);
+static void gtk_check_button_init                (GtkCheckButton      *check_button);
+static void gtk_check_button_draw                (GtkWidget           *widget,
+                                                 GdkRectangle        *area);
+static void gtk_check_button_draw_focus          (GtkWidget           *widget);
+static void gtk_check_button_size_request        (GtkWidget           *widget,
+                                                 GtkRequisition      *requisition);
+static void gtk_check_button_size_allocate       (GtkWidget           *widget,
+                                                 GtkAllocation       *allocation);
+static gint gtk_check_button_expose              (GtkWidget           *widget,
+                                                 GdkEventExpose      *event);
+static void gtk_check_button_draw_indicator      (GtkCheckButton      *check_button,
+                                                 GdkRectangle        *area);
+static void gtk_real_check_button_draw_indicator (GtkCheckButton      *check_button,
+                                                 GdkRectangle        *area);
+
+
+static GtkToggleButtonClass *parent_class = NULL;
+
+
+guint
+gtk_check_button_get_type ()
+{
+  static guint check_button_type = 0;
+
+  if (!check_button_type)
+    {
+      GtkTypeInfo check_button_info =
+      {
+       "GtkCheckButton",
+       sizeof (GtkCheckButton),
+       sizeof (GtkCheckButtonClass),
+       (GtkClassInitFunc) gtk_check_button_class_init,
+       (GtkObjectInitFunc) gtk_check_button_init,
+       (GtkArgFunc) NULL,
+      };
+
+      check_button_type = gtk_type_unique (gtk_toggle_button_get_type (), &check_button_info);
+    }
+
+  return check_button_type;
+}
+
+static void
+gtk_check_button_class_init (GtkCheckButtonClass *class)
+{
+  GtkWidgetClass *widget_class;
+
+  widget_class = (GtkWidgetClass*) class;
+  parent_class = gtk_type_class (gtk_toggle_button_get_type ());
+
+  widget_class->draw = gtk_check_button_draw;
+  widget_class->draw_focus = gtk_check_button_draw_focus;
+  widget_class->size_request = gtk_check_button_size_request;
+  widget_class->size_allocate = gtk_check_button_size_allocate;
+  widget_class->expose_event = gtk_check_button_expose;
+
+  class->indicator_size = INDICATOR_SIZE;
+  class->indicator_spacing = INDICATOR_SPACING;
+  class->draw_indicator = gtk_real_check_button_draw_indicator;
+}
+
+static void
+gtk_check_button_init (GtkCheckButton *check_button)
+{
+  check_button->toggle_button.draw_indicator = TRUE;
+}
+
+GtkWidget*
+gtk_check_button_new ()
+{
+  return GTK_WIDGET (gtk_type_new (gtk_check_button_get_type ()));
+}
+
+
+GtkWidget*
+gtk_check_button_new_with_label (const gchar *label)
+{
+  GtkWidget *check_button;
+  GtkWidget *label_widget;
+
+  check_button = gtk_check_button_new ();
+  label_widget = gtk_label_new (label);
+  gtk_misc_set_alignment (GTK_MISC (label_widget), 0.0, 0.5);
+
+  gtk_container_add (GTK_CONTAINER (check_button), label_widget);
+  gtk_widget_show (label_widget);
+
+  return check_button;
+}
+
+static void
+gtk_check_button_draw (GtkWidget    *widget,
+                      GdkRectangle *area)
+{
+  GtkButton *button;
+  GtkCheckButton *check_button;
+  GdkRectangle child_area;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_CHECK_BUTTON (widget));
+  g_return_if_fail (area != NULL);
+
+  if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget))
+    {
+      check_button = GTK_CHECK_BUTTON (widget);
+
+      if (check_button->toggle_button.draw_indicator)
+       {
+         button = GTK_BUTTON (widget);
+
+         gtk_check_button_draw_indicator (check_button, area);
+
+         if (button->child && GTK_WIDGET_NO_WINDOW (button->child) &&
+             gtk_widget_intersect (button->child, area, &child_area))
+           gtk_widget_draw (button->child, &child_area);
+
+         gtk_widget_draw_focus (widget);
+       }
+      else
+       {
+         if (GTK_WIDGET_CLASS (parent_class)->draw)
+           (* GTK_WIDGET_CLASS (parent_class)->draw) (widget, area);
+       }
+    }
+}
+
+static void
+gtk_check_button_draw_focus (GtkWidget *widget)
+{
+  GtkCheckButton *check_button;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_CHECK_BUTTON (widget));
+
+  if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget))
+    {
+      check_button = GTK_CHECK_BUTTON (widget);
+      if (check_button->toggle_button.draw_indicator)
+       {
+         if (GTK_WIDGET_HAS_FOCUS (widget))
+           gdk_draw_rectangle (widget->window,
+                               widget->style->black_gc, FALSE, 0, 0,
+                               widget->allocation.width - 1,
+                               widget->allocation.height - 1);
+         else
+           gdk_draw_rectangle (widget->window,
+                               widget->style->bg_gc[GTK_STATE_NORMAL], FALSE, 0, 0,
+                               widget->allocation.width - 1,
+                               widget->allocation.height - 1);
+       }
+      else
+       {
+         if (GTK_WIDGET_CLASS (parent_class)->draw_focus)
+           (* GTK_WIDGET_CLASS (parent_class)->draw_focus) (widget);
+       }
+    }
+}
+
+static void
+gtk_check_button_size_request (GtkWidget      *widget,
+                              GtkRequisition *requisition)
+{
+  GtkCheckButton *check_button;
+  GtkButton *button;
+  gint temp;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_CHECK_BUTTON (widget));
+  g_return_if_fail (requisition != NULL);
+
+  check_button = GTK_CHECK_BUTTON (widget);
+
+  if (GTK_WIDGET_CLASS (parent_class)->size_request)
+    (* GTK_WIDGET_CLASS (parent_class)->size_request) (widget, requisition);
+
+  if (check_button->toggle_button.draw_indicator)
+    {
+      button = GTK_BUTTON (widget);
+
+      requisition->width += (CHECK_BUTTON_CLASS (widget)->indicator_size +
+                            CHECK_BUTTON_CLASS (widget)->indicator_spacing * 3 + 2);
+
+      temp = (CHECK_BUTTON_CLASS (widget)->indicator_size +
+             CHECK_BUTTON_CLASS (widget)->indicator_spacing * 2);
+      requisition->height = MAX (requisition->height, temp) + 2;
+    }
+}
+
+static void
+gtk_check_button_size_allocate (GtkWidget     *widget,
+                               GtkAllocation *allocation)
+{
+  GtkCheckButton *check_button;
+  GtkButton *button;
+  GtkAllocation child_allocation;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_CHECK_BUTTON (widget));
+  g_return_if_fail (allocation != NULL);
+
+  check_button = GTK_CHECK_BUTTON (widget);
+  if (check_button->toggle_button.draw_indicator)
+    {
+      widget->allocation = *allocation;
+      if (GTK_WIDGET_REALIZED (widget))
+       gdk_window_move_resize (widget->window,
+                               allocation->x, allocation->y,
+                               allocation->width, allocation->height);
+
+      button = GTK_BUTTON (widget);
+
+      if (button->child && GTK_WIDGET_VISIBLE (button->child))
+       {
+         child_allocation.x = (GTK_CONTAINER (widget)->border_width +
+                               CHECK_BUTTON_CLASS (widget)->indicator_size +
+                               CHECK_BUTTON_CLASS (widget)->indicator_spacing * 3 + 1);
+         child_allocation.y = GTK_CONTAINER (widget)->border_width + 1;
+         child_allocation.width = (allocation->width - child_allocation.x  -
+                                   GTK_CONTAINER (widget)->border_width - 1);
+         child_allocation.height = allocation->height - child_allocation.y * 2;
+
+         gtk_widget_size_allocate (button->child, &child_allocation);
+       }
+    }
+  else
+    {
+      if (GTK_WIDGET_CLASS (parent_class)->size_allocate)
+       (* GTK_WIDGET_CLASS (parent_class)->size_allocate) (widget, allocation);
+    }
+}
+
+static gint
+gtk_check_button_expose (GtkWidget      *widget,
+                        GdkEventExpose *event)
+{
+  GtkButton *button;
+  GtkCheckButton *check_button;
+  GdkEventExpose child_event;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_CHECK_BUTTON (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget))
+    {
+      check_button = GTK_CHECK_BUTTON (widget);
+
+      if (check_button->toggle_button.draw_indicator)
+       {
+         button = GTK_BUTTON (widget);
+
+         gtk_check_button_draw_indicator (check_button, &event->area);
+
+         child_event = *event;
+         if (button->child && GTK_WIDGET_NO_WINDOW (button->child) &&
+             gtk_widget_intersect (button->child, &event->area, &child_event.area))
+           gtk_widget_event (button->child, (GdkEvent*) &child_event);
+
+         gtk_widget_draw_focus (widget);
+       }
+      else
+       {
+         if (GTK_WIDGET_CLASS (parent_class)->expose_event)
+           (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
+       }
+    }
+
+  return FALSE;
+}
+
+
+static void
+gtk_check_button_draw_indicator (GtkCheckButton *check_button,
+                                GdkRectangle   *area)
+{
+  GtkCheckButtonClass *class;
+
+  g_return_if_fail (check_button != NULL);
+  g_return_if_fail (GTK_IS_CHECK_BUTTON (check_button));
+  g_return_if_fail (CHECK_BUTTON_CLASS (check_button) != NULL);
+
+  class = CHECK_BUTTON_CLASS (check_button);
+
+  if (class->draw_indicator)
+    (* class->draw_indicator) (check_button, area);
+}
+
+static void
+gtk_real_check_button_draw_indicator (GtkCheckButton *check_button,
+                                     GdkRectangle    *area)
+{
+  GtkWidget *widget;
+  GtkToggleButton *toggle_button;
+  GtkStateType state_type;
+  GtkShadowType shadow_type;
+  gint width, height;
+  gint x, y;
+
+  g_return_if_fail (check_button != NULL);
+  g_return_if_fail (GTK_IS_CHECK_BUTTON (check_button));
+
+  if (GTK_WIDGET_DRAWABLE (check_button))
+    {
+      widget = GTK_WIDGET (check_button);
+      toggle_button = GTK_TOGGLE_BUTTON (check_button);
+
+      state_type = GTK_WIDGET_STATE (widget);
+      if ((state_type != GTK_STATE_NORMAL) &&
+         (state_type != GTK_STATE_PRELIGHT))
+       state_type = GTK_STATE_NORMAL;
+
+      gtk_style_set_background (widget->style, widget->window, state_type);
+      gdk_window_clear_area (widget->window, area->x, area->y, area->width, area->height);
+
+      x = CHECK_BUTTON_CLASS (widget)->indicator_spacing + GTK_CONTAINER (widget)->border_width;
+      y = (widget->allocation.height - CHECK_BUTTON_CLASS (widget)->indicator_size) / 2;
+      width = CHECK_BUTTON_CLASS (widget)->indicator_size;
+      height = CHECK_BUTTON_CLASS (widget)->indicator_size;
+
+      if (GTK_WIDGET_STATE (widget) == GTK_STATE_ACTIVE)
+       shadow_type = GTK_SHADOW_IN;
+      else if ((GTK_WIDGET_STATE (widget) == GTK_STATE_PRELIGHT) && toggle_button->active)
+       shadow_type = GTK_SHADOW_IN;
+      else
+       shadow_type = GTK_SHADOW_OUT;
+
+      gdk_draw_rectangle (widget->window,
+                         widget->style->bg_gc[GTK_WIDGET_STATE (widget)],
+                         TRUE, x + 1, y + 1, width, height);
+      gtk_draw_shadow (widget->style, widget->window,
+                      GTK_WIDGET_STATE (widget), shadow_type,
+                      x + 1, y + 1, width, height);
+    }
+}
diff --git a/gtk/gtkcheckbutton.h b/gtk/gtkcheckbutton.h
new file mode 100644 (file)
index 0000000..8994db5
--- /dev/null
@@ -0,0 +1,66 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_CHECK_BUTTON_H__
+#define __GTK_CHECK_BUTTON_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtktogglebutton.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_CHECK_BUTTON(obj)          GTK_CHECK_CAST (obj, gtk_check_button_get_type (), GtkCheckButton)
+#define GTK_CHECK_BUTTON_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_check_button_get_type (), GtkCheckButtonClass)
+#define GTK_IS_CHECK_BUTTON(obj)       GTK_CHECK_TYPE (obj, gtk_check_button_get_type ())
+
+
+typedef struct _GtkCheckButton       GtkCheckButton;
+typedef struct _GtkCheckButtonClass  GtkCheckButtonClass;
+
+struct _GtkCheckButton
+{
+  GtkToggleButton toggle_button;
+};
+
+struct _GtkCheckButtonClass
+{
+  GtkToggleButtonClass parent_class;
+
+  guint16 indicator_size;
+  guint16 indicator_spacing;
+
+  void (* draw_indicator) (GtkCheckButton *check_button,
+                          GdkRectangle   *area);
+};
+
+
+guint      gtk_check_button_get_type       (void);
+GtkWidget* gtk_check_button_new            (void);
+GtkWidget* gtk_check_button_new_with_label (const gchar *label);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_CHECK_BUTTON_H__ */
diff --git a/gtk/gtkcheckmenuitem.c b/gtk/gtkcheckmenuitem.c
new file mode 100644 (file)
index 0000000..a36dfa7
--- /dev/null
@@ -0,0 +1,250 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkcheckmenuitem.h"
+#include "gtklabel.h"
+#include "gtksignal.h"
+
+
+#define CHECK_MENU_ITEM_CLASS(w)  GTK_CHECK_MENU_ITEM_CLASS (GTK_OBJECT (w)->klass)
+
+
+enum {
+  TOGGLED,
+  LAST_SIGNAL
+};
+
+
+static void gtk_check_menu_item_class_init          (GtkCheckMenuItemClass *klass);
+static void gtk_check_menu_item_init                (GtkCheckMenuItem      *check_menu_item);
+static void gtk_check_menu_item_draw                (GtkWidget             *widget,
+                                                    GdkRectangle          *area);
+static gint gtk_check_menu_item_expose              (GtkWidget             *widget,
+                                                    GdkEventExpose        *event);
+static void gtk_check_menu_item_activate            (GtkMenuItem           *menu_item);
+static void gtk_check_menu_item_draw_indicator      (GtkCheckMenuItem      *check_menu_item,
+                                                    GdkRectangle          *area);
+static void gtk_real_check_menu_item_draw_indicator (GtkCheckMenuItem      *check_menu_item,
+                                                    GdkRectangle          *area);
+
+
+static GtkMenuItemClass *parent_class = NULL;
+static gint check_menu_item_signals[LAST_SIGNAL] = { 0 };
+
+
+guint
+gtk_check_menu_item_get_type ()
+{
+  static guint check_menu_item_type = 0;
+
+  if (!check_menu_item_type)
+    {
+      GtkTypeInfo check_menu_item_info =
+      {
+        "GtkCheckMenuItem",
+        sizeof (GtkCheckMenuItem),
+        sizeof (GtkCheckMenuItemClass),
+        (GtkClassInitFunc) gtk_check_menu_item_class_init,
+        (GtkObjectInitFunc) gtk_check_menu_item_init,
+        (GtkArgFunc) NULL,
+      };
+
+      check_menu_item_type = gtk_type_unique (gtk_menu_item_get_type (), &check_menu_item_info);
+    }
+
+  return check_menu_item_type;
+}
+
+GtkWidget*
+gtk_check_menu_item_new ()
+{
+  return GTK_WIDGET (gtk_type_new (gtk_check_menu_item_get_type ()));
+}
+
+GtkWidget*
+gtk_check_menu_item_new_with_label (const gchar *label)
+{
+  GtkWidget *check_menu_item;
+  GtkWidget *label_widget;
+
+  check_menu_item = gtk_check_menu_item_new ();
+  label_widget = gtk_label_new (label);
+  gtk_misc_set_alignment (GTK_MISC (label_widget), 0.0, 0.5);
+
+  gtk_container_add (GTK_CONTAINER (check_menu_item), label_widget);
+  gtk_widget_show (label_widget);
+
+  return check_menu_item;
+}
+
+void
+gtk_check_menu_item_set_state (GtkCheckMenuItem *check_menu_item,
+                              gint              state)
+{
+  g_return_if_fail (check_menu_item != NULL);
+  g_return_if_fail (GTK_IS_CHECK_MENU_ITEM (check_menu_item));
+
+  if (check_menu_item->active != state)
+    gtk_menu_item_activate (GTK_MENU_ITEM (check_menu_item));
+}
+
+void
+gtk_check_menu_item_toggled (GtkCheckMenuItem *check_menu_item)
+{
+  gtk_signal_emit (GTK_OBJECT (check_menu_item), check_menu_item_signals[TOGGLED]);
+}
+
+
+static void
+gtk_check_menu_item_class_init (GtkCheckMenuItemClass *klass)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+  GtkMenuItemClass *menu_item_class;
+
+  object_class = (GtkObjectClass*) klass;
+  widget_class = (GtkWidgetClass*) klass;
+  menu_item_class = (GtkMenuItemClass*) klass;
+
+  parent_class = gtk_type_class (gtk_menu_item_get_type ());
+
+  check_menu_item_signals[TOGGLED] =
+    gtk_signal_new ("toggled",
+                    GTK_RUN_FIRST,
+                    object_class->type,
+                    GTK_SIGNAL_OFFSET (GtkCheckMenuItemClass, toggled),
+                    gtk_signal_default_marshaller,
+                   GTK_TYPE_NONE, 0);
+
+  gtk_object_class_add_signals (object_class, check_menu_item_signals, LAST_SIGNAL);
+
+  widget_class->draw = gtk_check_menu_item_draw;
+  widget_class->expose_event = gtk_check_menu_item_expose;
+
+  menu_item_class->activate = gtk_check_menu_item_activate;
+  menu_item_class->toggle_size = 12;
+
+  klass->toggled = NULL;
+  klass->draw_indicator = gtk_real_check_menu_item_draw_indicator;
+}
+
+static void
+gtk_check_menu_item_init (GtkCheckMenuItem *check_menu_item)
+{
+  check_menu_item->active = FALSE;
+}
+
+static void
+gtk_check_menu_item_draw (GtkWidget    *widget,
+                         GdkRectangle *area)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_CHECK_MENU_ITEM (widget));
+  g_return_if_fail (area != NULL);
+
+  if (GTK_WIDGET_CLASS (parent_class)->draw)
+    (* GTK_WIDGET_CLASS (parent_class)->draw) (widget, area);
+
+  gtk_check_menu_item_draw_indicator (GTK_CHECK_MENU_ITEM (widget), area);
+}
+
+static gint
+gtk_check_menu_item_expose (GtkWidget      *widget,
+                           GdkEventExpose *event)
+{
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_CHECK_MENU_ITEM (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (GTK_WIDGET_CLASS (parent_class)->expose_event)
+    (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
+
+  gtk_check_menu_item_draw_indicator (GTK_CHECK_MENU_ITEM (widget), &event->area);
+
+  return FALSE;
+}
+
+static void
+gtk_check_menu_item_activate (GtkMenuItem *menu_item)
+{
+  GtkCheckMenuItem *check_menu_item;
+
+  g_return_if_fail (menu_item != NULL);
+  g_return_if_fail (GTK_IS_CHECK_MENU_ITEM (menu_item));
+
+  check_menu_item = GTK_CHECK_MENU_ITEM (menu_item);
+  check_menu_item->active = !check_menu_item->active;
+
+  gtk_check_menu_item_toggled (check_menu_item);
+  gtk_widget_queue_draw (GTK_WIDGET (check_menu_item));
+}
+
+static void
+gtk_check_menu_item_draw_indicator (GtkCheckMenuItem *check_menu_item,
+                                   GdkRectangle     *area)
+{
+  g_return_if_fail (check_menu_item != NULL);
+  g_return_if_fail (GTK_IS_CHECK_MENU_ITEM (check_menu_item));
+  g_return_if_fail (CHECK_MENU_ITEM_CLASS (check_menu_item) != NULL);
+
+  if (CHECK_MENU_ITEM_CLASS (check_menu_item)->draw_indicator)
+    (* CHECK_MENU_ITEM_CLASS (check_menu_item)->draw_indicator) (check_menu_item, area);
+}
+
+static void
+gtk_real_check_menu_item_draw_indicator (GtkCheckMenuItem *check_menu_item,
+                                        GdkRectangle     *area)
+{
+  GtkWidget *widget;
+  GtkStateType state_type;
+  GtkShadowType shadow_type;
+  gint width, height;
+  gint x, y;
+
+  g_return_if_fail (check_menu_item != NULL);
+  g_return_if_fail (GTK_IS_CHECK_MENU_ITEM (check_menu_item));
+
+  if (GTK_WIDGET_DRAWABLE (check_menu_item))
+    {
+      widget = GTK_WIDGET (check_menu_item);
+
+      width = 8;
+      height = 8;
+      x = (GTK_CONTAINER (check_menu_item)->border_width +
+          widget->style->klass->xthickness + 2);
+      y = (widget->allocation.height - height) / 2;
+
+      gdk_window_clear_area (widget->window, x, y, width, height);
+
+      if (check_menu_item->active ||
+         (GTK_WIDGET_STATE (check_menu_item) == GTK_STATE_PRELIGHT))
+       {
+         state_type = GTK_WIDGET_STATE (widget);
+
+         shadow_type = GTK_SHADOW_IN;
+         if (check_menu_item->active && (state_type == GTK_STATE_PRELIGHT))
+           shadow_type = GTK_SHADOW_OUT;
+
+         gdk_draw_rectangle (widget->window,
+                             widget->style->bg_gc[state_type],
+                             TRUE, x, y, width, height);
+         gtk_draw_shadow (widget->style, widget->window,
+                          state_type, shadow_type,
+                          x, y, width, height);
+       }
+    }
+}
diff --git a/gtk/gtkcheckmenuitem.h b/gtk/gtkcheckmenuitem.h
new file mode 100644 (file)
index 0000000..1dc816c
--- /dev/null
@@ -0,0 +1,69 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_MENU_CHECK_ITEM_H__
+#define __GTK_MENU_CHECK_ITEM_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkmenuitem.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_CHECK_MENU_ITEM(obj)        ((GtkCheckMenuItem*) obj)
+#define GTK_CHECK_MENU_ITEM_CLASS(obj)  ((GtkCheckMenuItemClass*) GTK_OBJECT_CLASS (obj))
+#define GTK_IS_CHECK_MENU_ITEM(obj)     (gtk_type_is_a (GTK_WIDGET_TYPE (obj), gtk_check_menu_item_get_type ()))
+
+
+typedef struct _GtkCheckMenuItem       GtkCheckMenuItem;
+typedef struct _GtkCheckMenuItemClass  GtkCheckMenuItemClass;
+
+struct _GtkCheckMenuItem
+{
+  GtkMenuItem menu_item;
+
+  guint active : 1;
+};
+
+struct _GtkCheckMenuItemClass
+{
+  GtkMenuItemClass parent_class;
+
+  void (* toggled)        (GtkCheckMenuItem *check_menu_item);
+  void (* draw_indicator) (GtkCheckMenuItem *check_menu_item,
+                          GdkRectangle     *area);
+};
+
+
+guint      gtk_check_menu_item_get_type       (void);
+GtkWidget* gtk_check_menu_item_new            (void);
+GtkWidget* gtk_check_menu_item_new_with_label (const gchar      *label);
+void       gtk_check_menu_item_set_state      (GtkCheckMenuItem *check_menu_item,
+                                              gint              state);
+void       gtk_check_menu_item_toggled        (GtkCheckMenuItem *check_menu_item);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_CHECK_MENU_ITEM_H__ */
diff --git a/gtk/gtkcolorsel.c b/gtk/gtkcolorsel.c
new file mode 100644 (file)
index 0000000..78780b2
--- /dev/null
@@ -0,0 +1,1463 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <math.h>
+#include "gtkcolorsel.h"
+
+
+#define DEGTORAD(a) (2.0*M_PI*a/360.0)
+#define SQR(a) (a*a)
+
+#define TIMER_DELAY 300
+
+#define CIRCLE_RADIUS 65
+
+#define WHEEL_WIDTH   2*CIRCLE_RADIUS+2
+#define WHEEL_HEIGHT  2*CIRCLE_RADIUS+2
+
+#define VALUE_WIDTH   32
+#define VALUE_HEIGHT  WHEEL_HEIGHT
+
+#define SAMPLE_WIDTH  WHEEL_WIDTH+VALUE_WIDTH+5
+#define SAMPLE_HEIGHT 28
+
+
+enum
+{
+  COLOR_CHANGED,
+  LAST_SIGNAL
+};
+
+enum
+{
+  RGB_INPUTS     = 1 << 0,
+  HSV_INPUTS     = 1 << 1,
+  OPACITY_INPUTS = 1 << 2
+};
+
+enum
+{
+  SCALE,
+  ENTRY,
+  BOTH
+};
+
+enum
+{
+  HUE,
+  SATURATION,
+  VALUE,
+  RED,
+  GREEN,
+  BLUE,
+  OPACITY,
+  NUM_CHANNELS
+};
+
+typedef struct
+{
+  gchar *label;
+  gfloat lower, upper, step_inc, page_inc;
+  GtkSignalFunc updater;
+} scale_val_type;
+
+
+#define HSV_TO_RGB()  gtk_color_selection_hsv_to_rgb( \
+                        colorsel->values[HUE], \
+                        colorsel->values[SATURATION], \
+                        colorsel->values[VALUE], \
+                        &colorsel->values[RED], \
+                        &colorsel->values[GREEN], \
+                        &colorsel->values[BLUE])
+
+#define RGB_TO_HSV()  gtk_color_selection_rgb_to_hsv( \
+                        colorsel->values[RED], \
+                        colorsel->values[GREEN], \
+                        colorsel->values[BLUE], \
+                        &colorsel->values[HUE], \
+                        &colorsel->values[SATURATION], \
+                        &colorsel->values[VALUE])
+
+
+static void gtk_color_selection_hsv_updater       (GtkWidget         *widget,
+                                                   gpointer           data);
+static void gtk_color_selection_rgb_updater       (GtkWidget         *widget,
+                                                   gpointer           data);
+static void gtk_color_selection_opacity_updater   (GtkWidget         *widget,
+                                                   gpointer           data);
+static void gtk_color_selection_realize           (GtkWidget         *widget);
+static void gtk_color_selection_destroy           (GtkObject         *object);
+static void gtk_color_selection_color_changed     (GtkColorSelection *colorsel);
+static void gtk_color_selection_update_input      (GtkWidget         *scale,
+                                                   GtkWidget         *entry,
+                                                   gdouble            value);
+static void gtk_color_selection_update_inputs     (GtkColorSelection *colorsel,
+                                                   gint               inputs,
+                                                   gint               which);
+static void gtk_color_selection_update_value      (GtkColorSelection *colorsel,
+                                                   gint               y);
+static void gtk_color_selection_update_wheel      (GtkColorSelection *colorsel,
+                                                   gint               x,
+                                                   gint               y);
+static void gtk_color_selection_value_resize      (GtkWidget          *widget,
+                                                   gpointer            data);
+static gint gtk_color_selection_value_events      (GtkWidget          *area,
+                                                   GdkEvent           *event);
+static gint gtk_color_selection_value_timeout     (GtkColorSelection  *colorsel);
+static void gtk_color_selection_wheel_resize      (GtkWidget          *widget,
+                                                   gpointer            data);
+static gint gtk_color_selection_wheel_events      (GtkWidget          *area,
+                                                   GdkEvent           *event);
+static gint gtk_color_selection_wheel_timeout     (GtkColorSelection  *colorsel);
+static void gtk_color_selection_sample_resize     (GtkWidget          *widget,
+                                                   gpointer            data);
+static void gtk_color_selection_drop_handle       (GtkWidget          *widget,
+                                                  GdkEvent           *event);
+static void gtk_color_selection_drag_handle       (GtkWidget          *widget,
+                                                  GdkEvent           *event);
+static void gtk_color_selection_draw_wheel_marker (GtkColorSelection  *colorsel);
+static void gtk_color_selection_draw_wheel_frame  (GtkColorSelection  *colorsel);
+static void gtk_color_selection_draw_value_marker (GtkColorSelection  *colorsel);
+static void gtk_color_selection_draw_value_bar    (GtkColorSelection  *colorsel,
+                                                   gint                resize);
+static void gtk_color_selection_draw_wheel        (GtkColorSelection  *colorsel,
+                                                   gint                resize);
+static void gtk_color_selection_draw_sample       (GtkColorSelection  *colorsel,
+                                                   gint                resize);
+
+static gint gtk_color_selection_eval_wheel        (gint     x, gint     y,
+                                                  gdouble cx, gdouble cy,
+                                                  gdouble *h, gdouble *s);
+
+static void gtk_color_selection_hsv_to_rgb        (gdouble  h, gdouble  s, gdouble  v,
+                                                  gdouble *r, gdouble *g, gdouble *b);
+static void gtk_color_selection_rgb_to_hsv        (gdouble  r, gdouble  g, gdouble  b,
+                                                  gdouble *h, gdouble *s, gdouble *v);
+
+static void gtk_color_selection_dialog_destroy    (GtkObject *object);
+
+
+static GtkVBoxClass *color_selection_parent_class = NULL;
+static GtkWindowClass *color_selection_dialog_parent_class = NULL;
+
+
+static gint color_selection_signals[LAST_SIGNAL] = {0};
+
+
+#define SF GtkSignalFunc
+
+
+scale_val_type scale_vals[NUM_CHANNELS] =
+{
+  {"Hue:",        0.0, 360.0, 1.00, 10.00, (SF) gtk_color_selection_hsv_updater},
+  {"Saturation:", 0.0,   1.0, 0.01,  0.01, (SF) gtk_color_selection_hsv_updater},
+  {"Value:",      0.0,   1.0, 0.01,  0.01, (SF) gtk_color_selection_hsv_updater},
+  {"Red:",        0.0,   1.0, 0.01,  0.01, (SF) gtk_color_selection_rgb_updater},
+  {"Green:",      0.0,   1.0, 0.01,  0.01, (SF) gtk_color_selection_rgb_updater},
+  {"Blue:",       0.0,   1.0, 0.01,  0.01, (SF) gtk_color_selection_rgb_updater},
+  {"Opacity:",    0.0,   1.0, 0.01,  0.01, (SF) gtk_color_selection_opacity_updater}
+};
+
+guint
+gtk_color_selection_get_type ()
+{
+  static guint color_selection_type = 0;
+
+  if (!color_selection_type)
+    {
+      GtkTypeInfo colorsel_info =
+      {
+       "color selection widget",
+       sizeof (GtkColorSelection),
+       sizeof (GtkColorSelectionClass),
+       (GtkClassInitFunc) gtk_color_selection_class_init,
+       (GtkObjectInitFunc) gtk_color_selection_init,
+      };
+
+      color_selection_type = gtk_type_unique (gtk_vbox_get_type (), &colorsel_info);
+    }
+
+  return color_selection_type;
+}
+
+void
+gtk_color_selection_class_init (GtkColorSelectionClass *klass)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+  GtkContainerClass *container_class;
+
+  object_class = (GtkObjectClass*) klass;
+  widget_class = (GtkWidgetClass*) klass;
+  container_class = (GtkContainerClass*) klass;
+
+  color_selection_parent_class = gtk_type_class (gtk_vbox_get_type ());
+
+  color_selection_signals[COLOR_CHANGED] =
+     gtk_signal_new ("color_changed",
+                    GTK_RUN_FIRST,
+                     object_class->type,
+                    GTK_SIGNAL_OFFSET (GtkColorSelectionClass, color_changed),
+                     gtk_signal_default_marshaller, GTK_TYPE_NONE, 0);
+
+  gtk_object_class_add_signals (object_class, color_selection_signals, LAST_SIGNAL);
+
+  object_class->destroy = gtk_color_selection_destroy;
+
+  widget_class->realize = gtk_color_selection_realize;
+}
+
+void
+gtk_color_selection_init (GtkColorSelection *colorsel)
+{
+  GtkWidget *frame, *hbox, *vbox, *hbox2, *label, *table;
+  GtkObject *adj;
+  gint old_mask, n;
+  gchar txt[32];
+
+  for (n = RED; n <= OPACITY; n++)
+    colorsel->values[n] = 1.0;
+
+  RGB_TO_HSV ();
+
+  for (n = HUE; n <= OPACITY; n++)
+    colorsel->old_values[n] = colorsel->values[n];
+
+  colorsel->wheel_gc = NULL;
+  colorsel->value_gc = NULL;
+  colorsel->sample_gc = NULL;
+  colorsel->wheel_buf = NULL;
+  colorsel->value_buf = NULL;
+  colorsel->sample_buf = NULL;
+
+  colorsel->use_opacity = FALSE;
+  colorsel->timer_active = FALSE;
+  colorsel->policy = GTK_UPDATE_CONTINUOUS;
+
+  hbox = gtk_hbox_new (FALSE, 5);
+  gtk_container_border_width (GTK_CONTAINER (hbox), 5);
+  gtk_container_add (GTK_CONTAINER (colorsel), hbox);
+
+  vbox = gtk_vbox_new (FALSE, 5);
+  gtk_container_add (GTK_CONTAINER (hbox), vbox);
+  gtk_widget_show (vbox);
+
+  hbox2 = gtk_hbox_new (FALSE, 5);
+  gtk_container_add (GTK_CONTAINER (vbox), hbox2);
+  gtk_widget_show (hbox2);
+
+  colorsel->wheel_area = gtk_preview_new (GTK_PREVIEW_COLOR);
+  gtk_widget_set_events (colorsel->wheel_area,
+                        old_mask |
+                        GDK_BUTTON_PRESS_MASK |
+                        GDK_BUTTON_RELEASE_MASK |
+                        GDK_BUTTON_MOTION_MASK |
+                        GDK_POINTER_MOTION_HINT_MASK);
+  gtk_preview_size (GTK_PREVIEW (colorsel->wheel_area), WHEEL_WIDTH, WHEEL_HEIGHT);
+  gtk_preview_set_expand (GTK_PREVIEW (colorsel->wheel_area), TRUE);
+  gtk_container_add (GTK_CONTAINER (hbox2), colorsel->wheel_area);
+  gtk_widget_show (colorsel->wheel_area);
+
+  old_mask = gtk_widget_get_events (colorsel->wheel_area);
+
+  gtk_signal_connect (GTK_OBJECT (colorsel->wheel_area), "event",
+    (SF) gtk_color_selection_wheel_events, (gpointer) colorsel->wheel_area);
+  gtk_signal_connect_after (GTK_OBJECT (colorsel->wheel_area), "expose_event",
+    (SF) gtk_color_selection_wheel_events, (gpointer) colorsel->wheel_area);
+  gtk_signal_connect_after (GTK_OBJECT (colorsel->wheel_area), "size_allocate",
+    (SF) gtk_color_selection_wheel_resize, (gpointer) colorsel->wheel_area);
+  gtk_object_set_data (GTK_OBJECT (colorsel->wheel_area), "_GtkColorSelection", (gpointer) colorsel);
+
+  frame = gtk_frame_new (NULL);
+  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
+  gtk_container_border_width (GTK_CONTAINER (frame), 0);
+  gtk_box_pack_start (GTK_BOX (hbox2), frame, FALSE, TRUE, 0);
+  gtk_widget_show (frame);
+
+  colorsel->value_area = gtk_preview_new (GTK_PREVIEW_COLOR);
+  gtk_preview_size (GTK_PREVIEW (colorsel->value_area), VALUE_WIDTH, VALUE_HEIGHT);
+  gtk_preview_set_expand (GTK_PREVIEW (colorsel->value_area), TRUE);
+  gtk_container_add (GTK_CONTAINER (frame), colorsel->value_area);
+  gtk_widget_show (colorsel->value_area);
+
+  old_mask = gtk_widget_get_events (colorsel->value_area);
+  gtk_widget_set_events (colorsel->value_area,
+                        old_mask |
+                        GDK_BUTTON_PRESS_MASK |
+                        GDK_BUTTON_RELEASE_MASK |
+                        GDK_BUTTON_MOTION_MASK |
+                        GDK_POINTER_MOTION_HINT_MASK);
+
+  gtk_signal_connect_after (GTK_OBJECT (colorsel->value_area), "expose_event",
+    (SF) gtk_color_selection_value_events, (gpointer) colorsel->value_area);
+  gtk_signal_connect_after (GTK_OBJECT (colorsel->value_area), "size_allocate",
+    (SF) gtk_color_selection_value_resize, (gpointer) colorsel->value_area);
+  gtk_signal_connect (GTK_OBJECT (colorsel->value_area), "event",
+    (SF) gtk_color_selection_value_events, (gpointer) colorsel->value_area);
+  gtk_object_set_data (GTK_OBJECT (colorsel->value_area), "_GtkColorSelection", (gpointer) colorsel);
+
+  /* New/old color samples */
+  /* ===================== */
+
+  frame = gtk_frame_new (NULL);
+  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
+  gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
+  gtk_widget_show (frame);
+
+/*  colorsel->sample_area_eb = gtk_button_new ();
+  gtk_container_add (GTK_CONTAINER (frame), colorsel->sample_area_eb);
+  gtk_widget_show (colorsel->sample_area_eb); */
+
+  colorsel->sample_area = gtk_preview_new (GTK_PREVIEW_COLOR);
+  gtk_preview_size (GTK_PREVIEW (colorsel->sample_area), SAMPLE_WIDTH, SAMPLE_HEIGHT);
+  gtk_preview_set_expand (GTK_PREVIEW (colorsel->sample_area), TRUE);
+  gtk_container_add (GTK_CONTAINER (frame),
+                    colorsel->sample_area);
+  gtk_widget_set_events(colorsel->sample_area,
+               gtk_widget_get_events(colorsel->sample_area)
+               | GDK_BUTTON_MOTION_MASK
+               | GDK_BUTTON_PRESS_MASK
+               | GDK_BUTTON_RELEASE_MASK
+               | GDK_ENTER_NOTIFY_MASK
+               | GDK_LEAVE_NOTIFY_MASK);
+  gtk_widget_show (colorsel->sample_area);
+
+  gtk_signal_connect_after (GTK_OBJECT (colorsel->sample_area),
+                           "size_allocate",
+                           GTK_SIGNAL_FUNC (gtk_color_selection_sample_resize),
+                           colorsel->sample_area);
+  gtk_object_set_data (GTK_OBJECT (colorsel->sample_area), "_GtkColorSelection", (gpointer) colorsel);
+
+  table = gtk_table_new (NUM_CHANNELS, 3, FALSE);
+  gtk_table_set_col_spacings (GTK_TABLE (table), 3);
+  gtk_box_pack_start (GTK_BOX (hbox), table, FALSE, TRUE, 0);
+
+  for (n = HUE; n <= OPACITY; n++)
+    {
+      label = gtk_label_new (scale_vals[n].label);
+      gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
+      gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, n, n + 1);
+
+      adj = gtk_adjustment_new (colorsel->values[n], scale_vals[n].lower,
+                               scale_vals[n].upper, scale_vals[n].step_inc,
+                                scale_vals[n].page_inc, 0.0);
+      colorsel->scales[n] = gtk_hscale_new (GTK_ADJUSTMENT (adj));
+      gtk_widget_set_usize (colorsel->scales[n], 128, 0);
+      gtk_scale_set_value_pos (GTK_SCALE (colorsel->scales[n]), GTK_POS_TOP);
+
+      gtk_range_set_update_policy (GTK_RANGE (colorsel->scales[n]), colorsel->policy);
+      gtk_scale_set_draw_value (GTK_SCALE (colorsel->scales[n]), FALSE);
+      gtk_scale_set_digits (GTK_SCALE (colorsel->scales[n]), 2);
+      gtk_table_attach_defaults (GTK_TABLE (table), colorsel->scales[n], 1, 2, n, n + 1);
+
+      colorsel->entries[n] = gtk_entry_new ();
+      gtk_widget_set_usize (colorsel->entries[n], 40, 0);
+      sprintf (txt, "%.2f", colorsel->values[n]);
+      gtk_entry_set_text (GTK_ENTRY (colorsel->entries[n]), txt);
+      gtk_table_attach_defaults (GTK_TABLE (table), colorsel->entries[n], 2, 3, n, n + 1);
+
+      if (n != OPACITY)
+       {
+         gtk_widget_show (label);
+         gtk_widget_show (colorsel->scales[n]);
+         gtk_widget_show (colorsel->entries[n]);
+       }
+
+      gtk_signal_connect_object (GTK_OBJECT (adj), "value_changed",
+                                 scale_vals[n].updater, (gpointer) colorsel->scales[n]);
+      gtk_object_set_data (GTK_OBJECT (colorsel->scales[n]), "_GtkColorSelection", (gpointer) colorsel);
+      gtk_object_set_data (GTK_OBJECT (colorsel->scales[n]), "_ValueIndex", (gpointer) n);
+      gtk_signal_connect_object (GTK_OBJECT (colorsel->entries[n]), "changed",
+                                 scale_vals[n].updater, (gpointer) colorsel->entries[n]);
+      gtk_object_set_data (GTK_OBJECT (colorsel->entries[n]), "_GtkColorSelection", (gpointer) colorsel);
+      gtk_object_set_data (GTK_OBJECT (colorsel->entries[n]), "_ValueIndex", (gpointer) n);
+    }
+
+  colorsel->opacity_label = label;
+
+  gtk_widget_show (table);
+  gtk_widget_show (hbox);
+}
+
+GtkWidget *
+gtk_color_selection_new (void)
+{
+  GtkColorSelection *colorsel;
+
+  colorsel = gtk_type_new (gtk_color_selection_get_type ());
+
+  return GTK_WIDGET (colorsel);
+}
+
+void
+gtk_color_selection_set_update_policy (GtkColorSelection *colorsel,
+                                      GtkUpdateType      policy)
+{
+  gint n;
+
+  g_return_if_fail (colorsel != NULL);
+
+  if (policy != colorsel->policy)
+    {
+      colorsel->policy = policy;
+
+      for (n = 0; n < NUM_CHANNELS; n++)
+       gtk_range_set_update_policy (GTK_RANGE (colorsel->scales[n]), policy);
+    }
+}
+
+
+void
+gtk_color_selection_set_color (GtkColorSelection *colorsel,
+                              gdouble           *color)
+{
+  gint n, i = 0;
+
+  g_return_if_fail (colorsel != NULL);
+  g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
+
+  if (GTK_WIDGET_DRAWABLE (GTK_WIDGET (colorsel)))
+    gtk_color_selection_draw_wheel_marker (colorsel);
+
+  for (n = RED; n <= BLUE; n++)
+    {
+      colorsel->old_values[n] = colorsel->values[n];
+      colorsel->values[n] = color[i++];
+    }
+
+  if (colorsel->use_opacity == TRUE)
+    {
+      colorsel->old_values[OPACITY] = colorsel->values[OPACITY];
+      colorsel->values[OPACITY] = color[i];
+    }
+
+  RGB_TO_HSV ();
+
+  gtk_color_selection_update_inputs (colorsel, RGB_INPUTS | HSV_INPUTS | OPACITY_INPUTS, BOTH);
+
+  if (GTK_WIDGET_DRAWABLE (GTK_WIDGET (colorsel)))
+    {
+      gtk_color_selection_draw_value_bar (colorsel, FALSE);
+      gtk_color_selection_draw_sample (colorsel, FALSE);
+      gtk_color_selection_draw_wheel_marker (colorsel);
+    }
+}
+
+void
+gtk_color_selection_get_color (GtkColorSelection *colorsel,
+                              gdouble           *color)
+{
+  gint n, i = 0;
+
+  g_return_if_fail (colorsel != NULL);
+  g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
+
+  for (n = RED; n <= BLUE; n++)
+    color[i++] = colorsel->values[n];
+  if (colorsel->use_opacity == TRUE)
+    color[i] = colorsel->values[OPACITY];
+}
+
+static void
+gtk_color_selection_realize (GtkWidget         *widget)
+{
+  GtkColorSelection *colorsel;
+  gchar *type_accept_list[] = {"application/x-color"};
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_COLOR_SELECTION (widget));
+
+  colorsel = GTK_COLOR_SELECTION (widget);
+
+  if (GTK_WIDGET_CLASS (color_selection_parent_class)->realize)
+    (*GTK_WIDGET_CLASS (color_selection_parent_class)->realize) (widget);
+
+  gtk_widget_dnd_drag_set (colorsel->sample_area,
+                          1, type_accept_list, 1);
+  gtk_widget_dnd_drop_set (colorsel->sample_area,
+                          1, type_accept_list, 1, 0);
+  gtk_signal_connect_after (GTK_OBJECT (colorsel->sample_area),
+                           "drop_data_available_event",
+                           GTK_SIGNAL_FUNC (gtk_color_selection_drop_handle),
+                           NULL);
+  gtk_signal_connect_after (GTK_OBJECT (colorsel->sample_area),
+                           "drag_request_event",
+                           GTK_SIGNAL_FUNC (gtk_color_selection_drag_handle),
+                           NULL);
+}
+
+static void
+gtk_color_selection_destroy (GtkObject *object)
+{
+  GtkColorSelection *colorsel;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_COLOR_SELECTION (object));
+
+  colorsel = GTK_COLOR_SELECTION (object);
+
+  if (colorsel->wheel_buf != NULL)
+    g_free (colorsel->wheel_buf);
+  if (colorsel->value_buf != NULL)
+    g_free (colorsel->value_buf);
+  if (colorsel->sample_buf != NULL)
+    g_free (colorsel->sample_buf);
+
+  if (GTK_OBJECT_CLASS (color_selection_parent_class)->destroy)
+    (*GTK_OBJECT_CLASS (color_selection_parent_class)->destroy) (object);
+}
+
+static void
+gtk_color_selection_color_changed (GtkColorSelection *colorsel)
+{
+  gtk_signal_emit (GTK_OBJECT (colorsel), color_selection_signals[COLOR_CHANGED]);
+}
+
+static void
+gtk_color_selection_update_input (GtkWidget *scale,
+                                  GtkWidget *entry,
+                                  gdouble    value)
+{
+  GtkAdjustment *adj;
+  gchar txt[32];
+
+  if (scale != NULL)
+    {
+      adj = gtk_range_get_adjustment (GTK_RANGE (scale));
+      adj->value = (gfloat) value;
+      gtk_signal_handler_block_by_data (GTK_OBJECT (adj), (gpointer) scale);
+      gtk_signal_emit_by_name (GTK_OBJECT (adj), "value_changed");
+      gtk_range_slider_update (GTK_RANGE (scale));
+      gtk_signal_handler_unblock_by_data (GTK_OBJECT (adj), (gpointer) scale);
+    }
+
+  if (entry != NULL)
+    {
+      gtk_signal_handler_block_by_data (GTK_OBJECT (entry), (gpointer) entry);
+      sprintf (txt, "%.2f", value);
+      gtk_entry_set_text (GTK_ENTRY (entry), txt);
+      gtk_signal_handler_unblock_by_data (GTK_OBJECT (entry), (gpointer) entry);
+    }
+}
+
+static void
+gtk_color_selection_update_inputs (GtkColorSelection *colorsel,
+                                   gint               inputs,
+                                   gint               which)
+{
+  gint n;
+
+  switch (which)
+    {
+    case SCALE:
+      if ((inputs & RGB_INPUTS) != 0)
+       for (n = RED; n <= BLUE; n++)
+         gtk_color_selection_update_input (colorsel->scales[n], NULL,
+                                           colorsel->values[n]);
+      if ((inputs & HSV_INPUTS) != 0)
+       for (n = HUE; n <= VALUE; n++)
+         gtk_color_selection_update_input (colorsel->scales[n], NULL,
+                                           colorsel->values[n]);
+      if ((inputs & OPACITY_INPUTS) != 0)
+       gtk_color_selection_update_input(colorsel->scales[OPACITY], NULL,
+                                        colorsel->values[OPACITY]);
+      break;
+    case ENTRY:
+      if ((inputs & RGB_INPUTS) != 0)
+       for (n = RED; n <= BLUE; n++)
+         gtk_color_selection_update_input (NULL, colorsel->entries[n], colorsel->values[n]);
+      if ((inputs & HSV_INPUTS) != 0)
+       for (n = HUE; n <= VALUE; n++)
+         gtk_color_selection_update_input (NULL, colorsel->entries[n], colorsel->values[n]);
+      if ((inputs & OPACITY_INPUTS) != 0)
+       gtk_color_selection_update_input(NULL, colorsel->entries[OPACITY], colorsel->values[OPACITY]);
+      break;
+    default:
+      if ((inputs & RGB_INPUTS) != 0)
+       for (n = RED; n <= BLUE; n++)
+         gtk_color_selection_update_input (colorsel->scales[n], colorsel->entries[n],
+                                            colorsel->values[n]);
+      if ((inputs & HSV_INPUTS) != 0)
+       for (n = HUE; n <= VALUE; n++)
+         gtk_color_selection_update_input (colorsel->scales[n], colorsel->entries[n],
+                                            colorsel->values[n]);
+      if ((inputs & OPACITY_INPUTS) != 0)
+       gtk_color_selection_update_input(colorsel->scales[OPACITY], colorsel->entries[OPACITY],
+                                        colorsel->values[OPACITY]);
+      break;
+    }
+}
+
+static void
+gtk_color_selection_hsv_updater (GtkWidget *widget,
+                                 gpointer   data)
+{
+  GtkColorSelection *colorsel;
+  GtkAdjustment *adj;
+  gdouble newvalue;
+  gint i, which = SCALE;
+
+  if (GTK_WIDGET_DRAWABLE (GTK_WIDGET (widget)))
+    {
+      colorsel = (GtkColorSelection*) gtk_object_get_data (GTK_OBJECT (widget), "_GtkColorSelection");
+      i = (gint) gtk_object_get_data (GTK_OBJECT (widget), "_ValueIndex");
+
+      if (GTK_IS_SCALE (widget))
+       {
+         adj = gtk_range_get_adjustment (GTK_RANGE (GTK_SCALE (widget)));
+         newvalue = (gdouble) adj->value;
+         which = ENTRY;
+       }
+      else
+       newvalue = (gdouble) atof (gtk_entry_get_text (GTK_ENTRY (widget)));
+
+      if (i == VALUE)
+       {
+         gtk_color_selection_draw_value_marker (colorsel);
+         colorsel->values[i] = newvalue;
+
+         HSV_TO_RGB ();
+
+         gtk_color_selection_draw_value_marker (colorsel);
+       }
+      else
+       {
+         gtk_color_selection_draw_wheel_marker (colorsel);
+         colorsel->values[i] = newvalue;
+
+         HSV_TO_RGB ();
+
+         gtk_color_selection_draw_wheel_marker (colorsel);
+         gtk_color_selection_draw_value_bar (colorsel, FALSE);
+       }
+
+      gtk_color_selection_draw_sample (colorsel, FALSE);
+      gtk_color_selection_color_changed (colorsel);
+      gtk_color_selection_update_inputs (colorsel, HSV_INPUTS, which);
+      gtk_color_selection_update_inputs (colorsel, RGB_INPUTS, BOTH);
+    }
+}
+
+static void
+gtk_color_selection_rgb_updater (GtkWidget *widget,
+                                 gpointer   data)
+{
+  GtkColorSelection *colorsel;
+  GtkAdjustment *adj;
+  gdouble newvalue;
+  gint i, which = SCALE;
+
+  if (GTK_WIDGET_DRAWABLE (GTK_WIDGET (widget)))
+    {
+      colorsel = (GtkColorSelection*) gtk_object_get_data (GTK_OBJECT (widget), "_GtkColorSelection");
+      i = (gint) gtk_object_get_data (GTK_OBJECT (widget), "_ValueIndex");
+
+      if (GTK_IS_SCALE (widget))
+       {
+         adj = gtk_range_get_adjustment (GTK_RANGE (GTK_SCALE (widget)));
+         newvalue = (gdouble) adj->value;
+         which = ENTRY;
+       }
+      else
+       newvalue = (gdouble) atof (gtk_entry_get_text (GTK_ENTRY (widget)));
+
+      gtk_color_selection_draw_wheel_marker (colorsel);
+
+      colorsel->values[i] = newvalue;
+      RGB_TO_HSV ();
+
+      gtk_color_selection_draw_wheel_marker (colorsel);
+      gtk_color_selection_draw_value_bar (colorsel, FALSE);
+      gtk_color_selection_draw_sample (colorsel, FALSE);
+      gtk_color_selection_color_changed (colorsel);
+      gtk_color_selection_update_inputs (colorsel, RGB_INPUTS, which);
+      gtk_color_selection_update_inputs (colorsel, HSV_INPUTS, BOTH);
+    }
+}
+
+static void
+gtk_color_selection_opacity_updater (GtkWidget *widget,
+                                     gpointer   data)
+{
+  GtkColorSelection *colorsel;
+  GtkAdjustment *adj;
+
+  colorsel = (GtkColorSelection*) gtk_object_get_data (GTK_OBJECT (widget), "_GtkColorSelection");
+
+  if (GTK_IS_SCALE (widget))
+    {
+      adj = gtk_range_get_adjustment (GTK_RANGE (widget));
+      colorsel->values[OPACITY] = (gdouble) adj->value;
+      gtk_color_selection_update_input (NULL, colorsel->entries[OPACITY], colorsel->values[OPACITY]);
+    }
+  else
+    {
+      colorsel->values[OPACITY] = (gdouble) atof (gtk_entry_get_text (GTK_ENTRY (widget)));
+      gtk_color_selection_update_input (colorsel->scales[OPACITY], NULL, colorsel->values[OPACITY]);
+    }
+
+  gtk_color_selection_draw_sample (colorsel, FALSE);
+  gtk_color_selection_color_changed (colorsel);
+}
+
+void
+gtk_color_selection_set_opacity (GtkColorSelection *colorsel,
+                                 gint               use_opacity)
+{
+  g_return_if_fail (colorsel != NULL);
+
+  colorsel->use_opacity = use_opacity;
+
+  if (use_opacity == FALSE && GTK_WIDGET_VISIBLE (colorsel->scales[OPACITY]))
+    {
+      gtk_widget_hide (colorsel->opacity_label);
+      gtk_widget_hide (colorsel->scales[OPACITY]);
+      gtk_widget_hide (colorsel->entries[OPACITY]);
+    }
+  else if (use_opacity == TRUE && !GTK_WIDGET_VISIBLE (colorsel->scales[OPACITY]))
+    {
+      gtk_widget_show (colorsel->opacity_label);
+      gtk_widget_show (colorsel->scales[OPACITY]);
+      gtk_widget_show (colorsel->entries[OPACITY]);
+    }
+
+  if (GTK_WIDGET_DRAWABLE (colorsel->sample_area))
+    gtk_color_selection_draw_sample (colorsel, FALSE);
+}
+
+static void
+gtk_color_selection_value_resize (GtkWidget *widget,
+                                  gpointer   data)
+{
+  GtkColorSelection *colorsel;
+
+  colorsel = (GtkColorSelection*) gtk_object_get_data (GTK_OBJECT (widget), "_GtkColorSelection");
+  gtk_color_selection_draw_value_bar (colorsel, TRUE);
+}
+
+static void
+gtk_color_selection_wheel_resize (GtkWidget *widget,
+                                  gpointer   data)
+{
+  GtkColorSelection *colorsel;
+
+  colorsel = (GtkColorSelection*) gtk_object_get_data (GTK_OBJECT (widget), "_GtkColorSelection");
+  gtk_color_selection_draw_wheel (colorsel, TRUE);
+}
+
+static void
+gtk_color_selection_sample_resize (GtkWidget *widget,
+                                   gpointer   data)
+{
+  GtkColorSelection *colorsel;
+
+  colorsel = (GtkColorSelection*) gtk_object_get_data (GTK_OBJECT (widget), "_GtkColorSelection");
+  gtk_color_selection_draw_sample (colorsel, TRUE);
+}
+
+static void
+gtk_color_selection_drop_handle (GtkWidget *widget, GdkEvent *event)
+{
+  int i;
+  GtkColorSelection *w;
+  gdouble *newbuf;
+  g_print("Handling drop in color selection\n");
+  gtk_color_selection_set_color(GTK_COLOR_SELECTION(widget),
+                               event->dropdataavailable.data);
+  g_free(event->dropdataavailable.data);
+  g_free(event->dropdataavailable.data_type);
+}
+
+static void
+gtk_color_selection_drag_handle (GtkWidget *widget, GdkEvent *event)
+{
+  g_print("Handling drag in color selector\n");
+  gtk_widget_dnd_data_set(widget, event, GTK_COLOR_SELECTION(widget)->values,
+                         sizeof(GTK_COLOR_SELECTION(widget)->values));
+}
+
+static void
+gtk_color_selection_draw_wheel_marker (GtkColorSelection *colorsel)
+{
+  gint xpos, ypos;
+
+  gdk_gc_set_function (colorsel->wheel_gc, GDK_INVERT);
+
+  xpos = (gint) ((-(gdouble) (colorsel->wheel_area->allocation.width) / 2.0) *
+                colorsel->values[SATURATION] * cos (DEGTORAD ((colorsel->values[HUE] - 90)))) +
+                 (colorsel->wheel_area->allocation.width >> 1) - 4;
+  ypos = (gint) (((gdouble) (colorsel->wheel_area->allocation.height) / 2.0) *
+                colorsel->values[SATURATION] * sin (DEGTORAD ((colorsel->values[HUE] - 90)))) +
+                 (colorsel->wheel_area->allocation.height >> 1) - 4;
+
+  gdk_draw_arc (colorsel->wheel_area->window, colorsel->wheel_gc, FALSE, xpos, ypos, 8, 8, 0, 360 * 64);
+}
+
+static void
+gtk_color_selection_draw_value_marker (GtkColorSelection *colorsel)
+{
+  gint y;
+
+  gdk_gc_set_function (colorsel->value_gc, GDK_INVERT);
+
+  y = (gint) ((gdouble) (colorsel->value_area->allocation.height) * (1.0 - colorsel->values[VALUE]));
+  gdk_draw_line (colorsel->value_area->window, colorsel->value_gc,
+                 0, y, colorsel->value_area->allocation.width, y);
+}
+
+static void
+gtk_color_selection_update_value (GtkColorSelection *colorsel,
+                                  gint               y)
+{
+  gtk_color_selection_draw_value_marker (colorsel);
+
+  if (y < 0)
+    y = 0;
+  else if (y > colorsel->value_area->allocation.height - 1)
+    y = colorsel->value_area->allocation.height - 1;
+
+  colorsel->values[VALUE] = 1.0 - (gdouble) y / (gdouble) (colorsel->value_area->allocation.height);
+
+  HSV_TO_RGB ();
+
+  gtk_color_selection_draw_value_marker (colorsel);
+  gtk_color_selection_draw_sample (colorsel, FALSE);
+  gtk_color_selection_update_input (colorsel->scales[VALUE], colorsel->entries[VALUE],
+                                   colorsel->values[VALUE]);
+  gtk_color_selection_update_inputs (colorsel, RGB_INPUTS, BOTH);
+}
+
+static void
+gtk_color_selection_update_wheel (GtkColorSelection *colorsel,
+                                  gint               x,
+                                  gint               y)
+{
+  gdouble wid, heig;
+  gint res;
+
+  gtk_color_selection_draw_wheel_marker (colorsel);
+
+  wid = (gdouble) (colorsel->wheel_area->allocation.width) / 2.0;
+  heig = (gdouble) (colorsel->wheel_area->allocation.height) / 2.0;
+
+  res = gtk_color_selection_eval_wheel (x, y, wid, heig, &colorsel->values[HUE],
+                                        &colorsel->values[SATURATION]);
+
+  HSV_TO_RGB ();
+
+  gtk_color_selection_draw_wheel_marker (colorsel);
+  gtk_color_selection_draw_value_bar (colorsel, FALSE);
+  gtk_color_selection_draw_sample (colorsel, FALSE);
+  gtk_color_selection_update_inputs (colorsel, RGB_INPUTS | HSV_INPUTS, BOTH);
+}
+
+static gint
+gtk_color_selection_value_timeout (GtkColorSelection *colorsel)
+{
+  gint x, y;
+
+  gdk_window_get_pointer (colorsel->value_area->window, &x, &y, NULL);
+  gtk_color_selection_update_value (colorsel, y);
+  gtk_color_selection_color_changed (colorsel);
+
+  return (TRUE);
+}
+
+static gint
+gtk_color_selection_value_events (GtkWidget *area,
+                                  GdkEvent  *event)
+{
+  GtkColorSelection *colorsel;
+  gint y;
+
+  colorsel = (GtkColorSelection*) gtk_object_get_data (GTK_OBJECT (area), "_GtkColorSelection");
+
+  switch (event->type)
+    {
+    case GDK_MAP:
+      gtk_color_selection_draw_value_marker (colorsel);
+      break;
+    case GDK_EXPOSE:
+      if (colorsel->value_gc == NULL)
+       colorsel->value_gc = gdk_gc_new (colorsel->value_area->window);
+      gtk_color_selection_draw_value_marker (colorsel);
+      break;
+    case GDK_BUTTON_PRESS:
+      gtk_grab_add (area);
+      gtk_color_selection_update_value (colorsel, event->button.y);
+      gtk_color_selection_color_changed (colorsel);
+      break;
+    case GDK_BUTTON_RELEASE:
+      gtk_grab_remove (area);
+      if (colorsel->timer_active == TRUE)
+       gtk_timeout_remove (colorsel->timer_tag);
+      colorsel->timer_active = FALSE;
+
+      y = event->button.y;
+      if (event->button.window != area->window)
+       gdk_window_get_pointer (area->window, NULL, &y, NULL);
+
+      gtk_color_selection_update_value (colorsel, y);
+      gtk_color_selection_color_changed (colorsel);
+      break;
+    case GDK_MOTION_NOTIFY:
+      y = event->motion.y;
+
+      if (event->motion.is_hint || (event->motion.window != area->window))
+       gdk_window_get_pointer (area->window, NULL, &y, NULL);
+
+      switch (colorsel->policy)
+       {
+       case GTK_UPDATE_CONTINUOUS:
+         gtk_color_selection_update_value (colorsel, y);
+         gtk_color_selection_color_changed (colorsel);
+         break;
+       case GTK_UPDATE_DELAYED:
+         if (colorsel->timer_active == TRUE)
+           gtk_timeout_remove (colorsel->timer_tag);
+
+         colorsel->timer_tag = gtk_timeout_add (TIMER_DELAY,
+                                                (GtkFunction) gtk_color_selection_value_timeout,
+                                                (gpointer) colorsel);
+         colorsel->timer_active = TRUE;
+         break;
+       default:
+         break;
+       }
+      break;
+    default:
+      break;
+    }
+
+  return (FALSE);
+}
+
+static gint
+gtk_color_selection_wheel_timeout (GtkColorSelection *colorsel)
+{
+  gint x, y;
+
+  gdk_window_get_pointer (colorsel->wheel_area->window, &x, &y, NULL);
+  gtk_color_selection_update_wheel (colorsel, x, y);
+  gtk_color_selection_color_changed (colorsel);
+
+  return (TRUE);
+}
+
+static gint
+gtk_color_selection_wheel_events (GtkWidget *area,
+                                  GdkEvent  *event)
+{
+  GtkColorSelection *colorsel;
+  gint x, y;
+
+  colorsel = (GtkColorSelection*) gtk_object_get_data (GTK_OBJECT (area), "_GtkColorSelection");
+
+  switch (event->type)
+    {
+    case GDK_MAP:
+      gtk_color_selection_draw_wheel (colorsel, TRUE);
+      gtk_color_selection_draw_wheel_marker (colorsel);
+      gtk_color_selection_draw_sample (colorsel, TRUE);
+      break;
+    case GDK_EXPOSE:
+      if (colorsel->wheel_gc == NULL)
+       colorsel->wheel_gc = gdk_gc_new (colorsel->wheel_area->window);
+      if (colorsel->sample_gc == NULL)
+       colorsel->sample_gc = gdk_gc_new (colorsel->sample_area->window);
+      if (colorsel->value_gc == NULL)
+       colorsel->value_gc = gdk_gc_new (colorsel->value_area->window);
+      gtk_color_selection_draw_wheel_marker (colorsel);
+      gtk_color_selection_draw_wheel_frame (colorsel);
+      break;
+    case GDK_BUTTON_PRESS:
+      gtk_grab_add (area);
+      gtk_color_selection_update_wheel (colorsel, event->button.x, event->button.y);
+      gtk_color_selection_color_changed (colorsel);
+      break;
+    case GDK_BUTTON_RELEASE:
+      gtk_grab_remove (area);
+      if (colorsel->timer_active == TRUE)
+       gtk_timeout_remove (colorsel->timer_tag);
+      colorsel->timer_active = FALSE;
+
+      x = event->button.x;
+      y = event->button.y;
+
+      if (event->button.window != area->window)
+       gdk_window_get_pointer (area->window, &x, &y, NULL);
+
+      gtk_color_selection_update_wheel (colorsel, x, y);
+      gtk_color_selection_color_changed (colorsel);
+      break;
+    case GDK_MOTION_NOTIFY:
+      x = event->motion.x;
+      y = event->motion.y;
+
+      if (event->motion.is_hint || (event->motion.window != area->window))
+       gdk_window_get_pointer (area->window, &x, &y, NULL);
+
+      switch (colorsel->policy)
+       {
+       case GTK_UPDATE_CONTINUOUS:
+         gtk_color_selection_update_wheel (colorsel, x, y);
+         gtk_color_selection_color_changed (colorsel);
+         break;
+       case GTK_UPDATE_DELAYED:
+         if (colorsel->timer_active == TRUE)
+           gtk_timeout_remove (colorsel->timer_tag);
+         colorsel->timer_tag = gtk_timeout_add (TIMER_DELAY,
+                                                (GtkFunction) gtk_color_selection_wheel_timeout,
+                                                (gpointer) colorsel);
+         colorsel->timer_active = TRUE;
+         break;
+       default:
+         break;
+       }
+      break;
+    default:
+      break;
+    }
+
+  return (FALSE);
+}
+
+static void
+gtk_color_selection_draw_value_bar (GtkColorSelection *colorsel,
+                                    gint               resize)
+{
+  gint x, y, i, wid, heig, n;
+  gdouble sv, v, c[3];
+  guchar rc[3];
+
+  wid = colorsel->value_area->allocation.width;
+  heig = colorsel->value_area->allocation.height;
+
+  if (resize)
+    {
+      if (colorsel->value_buf != NULL)
+       g_free (colorsel->value_buf);
+
+      colorsel->value_buf = g_new(guchar, 3 * wid);
+    }
+
+  v = 1.0;
+  sv = 1.0 / (gdouble) (heig - 1);
+
+  for (y = 0; y < heig; y++)
+    {
+      i = 0;
+
+      gtk_color_selection_hsv_to_rgb (colorsel->values[HUE],colorsel->values[SATURATION],v,
+                                      &c[0], &c[1], &c[2]);
+
+      for (n = 0; n < 3; n++)
+       rc[n] = (guchar) (255.0 * c[n]);
+
+      for (x = 0; x < wid; x++)
+       {
+         for (n = 0; n < 3; n++)
+           colorsel->value_buf[i++] = rc[n];
+       }
+
+      gtk_preview_draw_row (GTK_PREVIEW (colorsel->value_area), colorsel->value_buf, 0, y, wid);
+      v -= sv;
+    }
+
+  gtk_widget_draw (colorsel->value_area, NULL);
+}
+
+static void
+gtk_color_selection_draw_wheel_frame (GtkColorSelection *colorsel)
+{
+  GtkStyle *style;
+  gint w, h;
+
+  style = gtk_widget_get_style (GTK_WIDGET (colorsel));
+
+  w = colorsel->wheel_area->allocation.width;
+  h = colorsel->wheel_area->allocation.height;
+
+  gdk_draw_arc (colorsel->wheel_area->window, style->black_gc,
+               FALSE, 1, 1, w - 1, h - 1, 30 * 64, 180 * 64);
+  gdk_draw_arc (colorsel->wheel_area->window, style->mid_gc[GTK_STATE_NORMAL],
+               FALSE, 0, 0, w, h, 30 * 64, 180 * 64);
+
+  gdk_draw_arc (colorsel->wheel_area->window, style->bg_gc[GTK_STATE_NORMAL],
+               FALSE, 1, 1, w - 1, h - 1, 210 * 64, 180 * 64);
+  gdk_draw_arc (colorsel->wheel_area->window, style->light_gc[GTK_STATE_NORMAL],
+               FALSE, 0, 0, w, h, 210 * 64, 180 * 64);
+}
+
+static void
+gtk_color_selection_draw_wheel (GtkColorSelection *colorsel,
+                                gint               resize)
+{
+  gint x, y, i, wid, heig, n;
+  gdouble cx, cy, h, s, c[3];
+  guchar bg[3];
+  GtkStyle *style = gtk_widget_get_style (GTK_WIDGET (colorsel));
+
+  wid = colorsel->wheel_area->allocation.width;
+  heig = colorsel->wheel_area->allocation.height;
+
+  if (resize)
+    {
+      if (colorsel->wheel_buf != NULL)
+       g_free (colorsel->wheel_buf);
+
+      colorsel->wheel_buf = g_new(guchar, 3 * wid);
+    }
+
+  cx = (gdouble) (wid) / 2.0;
+  cy = (gdouble) (heig) / 2.0;
+
+  bg[0] = style->bg[GTK_STATE_NORMAL].red >> 8;
+  bg[1] = style->bg[GTK_STATE_NORMAL].green >> 8;
+  bg[2] = style->bg[GTK_STATE_NORMAL].blue >> 8;
+
+  for (y = 0; y < heig; y++)
+    {
+      i = 0;
+      for (x = 0; x < wid; x++)
+       {
+         if (gtk_color_selection_eval_wheel (x, y, cx, cy, &h, &s) == TRUE)
+           {
+             for (n = 0; n < 3; n++)
+               colorsel->wheel_buf[i++] = bg[n];
+           }
+         else
+           {
+             gtk_color_selection_hsv_to_rgb (h, s, 1.0, &c[0], &c[1], &c[2]);
+             for (n = 0; n < 3; n++)
+               colorsel->wheel_buf[i++] = (guchar) (255.0 * c[n]);
+           }
+       }
+
+      gtk_preview_draw_row (GTK_PREVIEW (colorsel->wheel_area), colorsel->wheel_buf, 0, y, wid);
+    }
+
+  gtk_widget_draw (colorsel->wheel_area, NULL);
+}
+
+static void
+gtk_color_selection_draw_sample (GtkColorSelection *colorsel,
+                                 gint               resize)
+{
+  gint x, y, i, wid, heig, f, half, n;
+  guchar c[3 * 2], cc[3 * 4], *cp = c;
+  gdouble o, oldo;
+
+  wid = colorsel->sample_area->allocation.width;
+  heig = colorsel->sample_area->allocation.height;
+  half = wid >> 1;
+
+  if (resize)
+    {
+      if (colorsel->sample_buf != NULL)
+       g_free (colorsel->sample_buf);
+
+      colorsel->sample_buf = g_new(guchar, 3 * wid);
+    }
+
+  i = RED;
+  for (n = 0; n < 3; n++)
+    {
+      c[n] = (guchar) (255.0 * colorsel->old_values[i]);
+      c[n + 3] = (guchar) (255.0 * colorsel->values[i++]);
+    }
+
+  if (colorsel->use_opacity == TRUE)
+    {
+      o = colorsel->values[OPACITY];
+      oldo = colorsel->old_values[OPACITY];
+
+      for (n = 0; n < 3; n++)
+       {
+         cc[n] = (guchar) ((1.0 - oldo) * 192 + (oldo * (gdouble) c[n]));
+         cc[n + 3] = (guchar) ((1.0 - oldo) * 128 + (oldo * (gdouble) c[n]));
+         cc[n + 6] = (guchar) ((1.0 - o) * 192 + (o * (gdouble) c[n + 3]));
+         cc[n + 9] = (guchar) ((1.0 - o) * 128 + (o * (gdouble) c[n + 3]));
+       }
+      cp = cc;
+    }
+
+  for (y = 0; y < heig; y++)
+    {
+      i = 0;
+      for (x = 0; x < wid; x++)
+       {
+         if (colorsel->use_opacity)
+           {
+             f = 3 * (((x % 32) < 16) ^ ((y % 32) < 16));
+             f += (x > half) * 6;
+           }
+         else
+           f = (x > half) * 3;
+
+         for (n = 0; n < 3; n++)
+           colorsel->sample_buf[i++] = cp[n + f];
+       }
+
+      gtk_preview_draw_row (GTK_PREVIEW (colorsel->sample_area), colorsel->sample_buf, 0, y, wid);
+    }
+
+  gtk_widget_draw (colorsel->sample_area, NULL);
+}
+
+static gint
+gtk_color_selection_eval_wheel (gint     x,  gint     y,
+                               gdouble  cx, gdouble  cy,
+                               gdouble *h,  gdouble *s)
+{
+  gdouble d, r, rx, ry, l;
+
+  rx = (gdouble) x - cx;
+  ry = (gdouble) y - cy;
+
+  d = (SQR (cy) * SQR (rx) + SQR (cx) * SQR (ry) - SQR (cx) * SQR (cy));
+
+  r = sqrt (SQR (rx) + SQR (ry));
+
+  if (r != 0.0)
+    *h = atan2 (rx / r, ry / r);
+  else
+    *h = 0.0;
+
+  l = sqrt (SQR ((cx * cos (*h + 0.5 * M_PI))) + SQR ((cy * sin (*h + 0.5 * M_PI))));
+  *s = r / l;
+  *h = 360.0 * (*h) / (2.0 * M_PI) + 180;
+
+  if (*s == 0.0)
+    *s = 0.00001;
+  else if (*s > 1.0)
+    *s = 1.0;
+
+  return ((d > 0.0));
+}
+
+static void
+gtk_color_selection_hsv_to_rgb (gdouble  h, gdouble  s, gdouble  v,
+                               gdouble *r, gdouble *g, gdouble *b)
+{
+  gint i;
+  gdouble f, w, q, t;
+
+  if (s == 0.0)
+    s = 0.000001;
+
+  if (h == -1.0)
+    {
+      *r = v;
+      *g = v;
+      *b = v;
+    }
+  else
+    {
+      if (h == 360.0)
+       h = 0.0;
+      h = h / 60.0;
+      i = (gint) h;
+      f = h - i;
+      w = v * (1.0 - s);
+      q = v * (1.0 - (s * f));
+      t = v * (1.0 - (s * (1.0 - f)));
+
+      switch (i)
+       {
+       case 0:
+         *r = v;
+         *g = t;
+         *b = w;
+         break;
+       case 1:
+         *r = q;
+         *g = v;
+         *b = w;
+         break;
+       case 2:
+         *r = w;
+         *g = v;
+         *b = t;
+         break;
+       case 3:
+         *r = w;
+         *g = q;
+         *b = v;
+         break;
+       case 4:
+         *r = t;
+         *g = w;
+         *b = v;
+         break;
+       case 5:
+         *r = v;
+         *g = w;
+         *b = q;
+         break;
+       }
+    }
+}
+
+static void
+gtk_color_selection_rgb_to_hsv (gdouble  r, gdouble  g, gdouble  b,
+                               gdouble *h, gdouble *s, gdouble *v)
+{
+  double max, min, delta;
+
+  max = r;
+  if (g > max)
+    max = g;
+  if (b > max)
+    max = b;
+
+  min = r;
+  if (g < min)
+    min = g;
+  if (b < min)
+    min = b;
+
+  *v = max;
+
+  if (max != 0.0)
+    *s = (max - min) / max;
+  else
+    *s = 0.0;
+
+  if (*s == 0.0)
+    *h = -1.0;
+  else
+    {
+      delta = max - min;
+
+      if (r == max)
+       *h = (g - b) / delta;
+      else if (g == max)
+       *h = 2.0 + (b - r) / delta;
+      else if (b == max)
+       *h = 4.0 + (r - g) / delta;
+
+      *h = *h * 60.0;
+
+      if (*h < 0.0)
+       *h = *h + 360;
+    }
+}
+
+/***************************/
+/* GtkColorSelectionDialog */
+/***************************/
+
+guint
+gtk_color_selection_dialog_get_type ()
+{
+  static guint color_selection_dialog_type = 0;
+
+  if (!color_selection_dialog_type)
+    {
+      GtkTypeInfo colorsel_diag_info =
+      {
+       "color selection dialog",
+       sizeof (GtkColorSelectionDialog),
+       sizeof (GtkColorSelectionDialogClass),
+       (GtkClassInitFunc) gtk_color_selection_dialog_class_init,
+       (GtkObjectInitFunc) gtk_color_selection_dialog_init,
+      };
+
+      color_selection_dialog_type = gtk_type_unique (gtk_window_get_type (), &colorsel_diag_info);
+    }
+
+  return color_selection_dialog_type;
+}
+
+void
+gtk_color_selection_dialog_class_init (GtkColorSelectionDialogClass *class)
+{
+  GtkObjectClass *object_class;
+
+  object_class = (GtkObjectClass*) class;
+
+  color_selection_dialog_parent_class = gtk_type_class (gtk_window_get_type ());
+
+  object_class->destroy = gtk_color_selection_dialog_destroy;
+}
+
+void
+gtk_color_selection_dialog_init (GtkColorSelectionDialog *colorseldiag)
+{
+  GtkWidget *action_area, *frame;
+
+  colorseldiag->main_vbox = gtk_vbox_new (FALSE, 10);
+  gtk_container_border_width (GTK_CONTAINER (colorseldiag), 10);
+  gtk_container_add (GTK_CONTAINER (colorseldiag), colorseldiag->main_vbox);
+  gtk_widget_show (colorseldiag->main_vbox);
+
+  frame = gtk_frame_new (NULL);
+  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
+  gtk_container_add (GTK_CONTAINER (colorseldiag->main_vbox), frame);
+  gtk_widget_show (frame);
+
+  colorseldiag->colorsel = gtk_color_selection_new ();
+  gtk_container_add (GTK_CONTAINER (frame), colorseldiag->colorsel);
+  gtk_widget_show (colorseldiag->colorsel);
+
+  action_area = gtk_hbox_new (TRUE, 10);
+  gtk_box_pack_end (GTK_BOX (colorseldiag->main_vbox), action_area, FALSE, FALSE, 0);
+  gtk_widget_show (action_area);
+
+  colorseldiag->ok_button = gtk_button_new_with_label ("OK");
+  GTK_WIDGET_SET_FLAGS (colorseldiag->ok_button, GTK_CAN_DEFAULT);
+  gtk_box_pack_start (GTK_BOX (action_area), colorseldiag->ok_button, TRUE, TRUE, 0);
+  gtk_widget_grab_default (colorseldiag->ok_button);
+  gtk_widget_show (colorseldiag->ok_button);
+
+  colorseldiag->cancel_button = gtk_button_new_with_label ("Cancel");
+  GTK_WIDGET_SET_FLAGS (colorseldiag->cancel_button, GTK_CAN_DEFAULT);
+  gtk_box_pack_start (GTK_BOX (action_area), colorseldiag->cancel_button, TRUE, TRUE, 0);
+  gtk_widget_show (colorseldiag->cancel_button);
+
+  colorseldiag->help_button = gtk_button_new_with_label ("Help");
+  GTK_WIDGET_SET_FLAGS (colorseldiag->help_button, GTK_CAN_DEFAULT);
+  gtk_box_pack_start (GTK_BOX (action_area), colorseldiag->help_button, TRUE, TRUE, 0);
+  gtk_widget_show (colorseldiag->help_button);
+}
+
+GtkWidget *
+gtk_color_selection_dialog_new (const gchar *title)
+{
+  GtkColorSelectionDialog *colorseldiag;
+
+  colorseldiag = gtk_type_new (gtk_color_selection_dialog_get_type ());
+  gtk_window_set_title (GTK_WINDOW (colorseldiag), title);
+
+  return GTK_WIDGET (colorseldiag);
+}
+
+static void
+gtk_color_selection_dialog_destroy (GtkObject *object)
+{
+  GtkColorSelectionDialog *colorseldiag;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_COLOR_SELECTION_DIALOG (object));
+
+  colorseldiag = GTK_COLOR_SELECTION_DIALOG (object);
+
+
+  if (GTK_OBJECT_CLASS (color_selection_dialog_parent_class)->destroy)
+    (*GTK_OBJECT_CLASS (color_selection_dialog_parent_class)->destroy) (object);
+}
diff --git a/gtk/gtkcolorsel.h b/gtk/gtkcolorsel.h
new file mode 100644 (file)
index 0000000..c29ea64
--- /dev/null
@@ -0,0 +1,152 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_COLORSEL_H__
+#define __GTK_COLORSEL_H__
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <gdk/gdk.h>
+
+#include "gtkwindow.h"
+#include "gtkvbox.h"
+#include "gtkframe.h"
+#include "gtkpreview.h"
+#include "gtkbutton.h"
+#include "gtkentry.h"
+#include "gtkhbox.h"
+#include "gtklabel.h"
+#include "gtkmain.h"
+#include "gtksignal.h"
+#include "gtkmisc.h"
+#include "gtkrange.h"
+#include "gtkscale.h"
+#include "gtkhscale.h"
+#include "gtktable.h"
+#include "gtkeventbox.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_COLOR_SELECTION(obj)          GTK_CHECK_CAST (obj, gtk_color_selection_get_type (), GtkColorSelection)
+#define GTK_COLOR_SELECTION_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_color_selection_get_type (), GtkColorSelectionClass)
+#define GTK_IS_COLOR_SELECTION(obj)       GTK_CHECK_TYPE (obj, gtk_color_selection_get_type ())
+
+#define GTK_COLOR_SELECTION_DIALOG(obj)          GTK_CHECK_CAST (obj, gtk_color_selection_dialog_get_type (), GtkColorSelectionDialog)
+#define GTK_COLOR_SELECTION_DIALOG_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_color_selection_dialog_get_type (), GtkColorSelectionDialogClass)
+#define GTK_IS_COLOR_SELECTION_DIALOG(obj)       GTK_CHECK_TYPE (obj, gtk_color_selection_dialog_get_type ())
+
+
+typedef struct _GtkColorSelection             GtkColorSelection;
+typedef struct _GtkColorSelectionClass        GtkColorSelectionClass;
+
+typedef struct _GtkColorSelectionDialog       GtkColorSelectionDialog;
+typedef struct _GtkColorSelectionDialogClass  GtkColorSelectionDialogClass;
+
+
+struct _GtkColorSelection
+{
+  GtkVBox vbox;
+
+  GtkWidget *wheel_area;
+  GtkWidget *value_area;
+  GtkWidget *sample_area, *sample_area_eb;
+
+  GtkWidget *scales[8];
+  GtkWidget *entries[8];
+  GtkWidget *opacity_label;
+
+  GdkGC *wheel_gc;
+  GdkGC *value_gc;
+  GdkGC *sample_gc;
+
+  GtkUpdateType policy;
+  gint use_opacity;
+  gint timer_active;
+  gint timer_tag;
+  gdouble values[8];
+  gdouble old_values[8];
+
+  guchar *wheel_buf;
+  guchar *value_buf;
+  guchar *sample_buf;
+};
+
+struct _GtkColorSelectionClass
+{
+  GtkVBoxClass parent_class;
+
+  void (* color_changed) (GtkColorSelection *colorsel);
+};
+
+struct _GtkColorSelectionDialog
+{
+  GtkWindow window;
+
+  GtkWidget *colorsel;
+  GtkWidget *main_vbox;
+  GtkWidget *ok_button;
+  GtkWidget *reset_button;
+  GtkWidget *cancel_button;
+  GtkWidget *help_button;
+};
+
+struct _GtkColorSelectionDialogClass
+{
+  GtkWindowClass parent_class;
+};
+
+
+/* ColorSelection */
+
+guint      gtk_color_selection_get_type          (void);
+void       gtk_color_selection_class_init        (GtkColorSelectionClass *klass);
+void       gtk_color_selection_init              (GtkColorSelection      *colorsel);
+
+GtkWidget* gtk_color_selection_new               (void);
+
+void       gtk_color_selection_set_update_policy (GtkColorSelection     *colorsel,
+                                                  GtkUpdateType          policy);
+
+void       gtk_color_selection_set_opacity       (GtkColorSelection     *colorsel,
+                                                  gint                   use_opacity);
+
+void       gtk_color_selection_set_color         (GtkColorSelection     *colorsel,
+                                                 gdouble               *color);
+
+void       gtk_color_selection_get_color         (GtkColorSelection     *colorsel,
+                                                  gdouble               *color);
+
+/* ColorSelectionDialog */
+
+guint      gtk_color_selection_dialog_get_type   (void);
+void       gtk_color_selection_dialog_class_init (GtkColorSelectionDialogClass *klass);
+void       gtk_color_selection_dialog_init       (GtkColorSelectionDialog      *colorseldiag);
+
+GtkWidget* gtk_color_selection_dialog_new        (const gchar *title);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_COLORSEL_H__ */
diff --git a/gtk/gtkcontainer.c b/gtk/gtkcontainer.c
new file mode 100644 (file)
index 0000000..977fabc
--- /dev/null
@@ -0,0 +1,844 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <string.h>
+#include "gtkcontainer.h"
+#include "gtksignal.h"
+
+
+enum {
+  ADD,
+  REMOVE,
+  NEED_RESIZE,
+  FOREACH,
+  FOCUS,
+  LAST_SIGNAL
+};
+
+
+typedef void (*GtkContainerSignal1) (GtkObject *object,
+                                    gpointer   arg1,
+                                    gpointer   data);
+typedef void (*GtkContainerSignal2) (GtkObject *object,
+                                    gpointer   arg1,
+                                    gpointer   arg2,
+                                    gpointer   data);
+typedef gint (*GtkContainerSignal3) (GtkObject *object,
+                                    gint       arg1,
+                                    gpointer   data);
+typedef gint (*GtkContainerSignal4) (GtkObject *object,
+                                    gpointer   data);
+
+
+static void gtk_container_marshal_signal_1 (GtkObject      *object,
+                                           GtkSignalFunc   func,
+                                           gpointer        func_data,
+                                           GtkArg         *args);
+static void gtk_container_marshal_signal_2 (GtkObject      *object,
+                                           GtkSignalFunc   func,
+                                           gpointer        func_data,
+                                           GtkArg         *args);
+static void gtk_container_marshal_signal_3 (GtkObject      *object,
+                                           GtkSignalFunc   func,
+                                           gpointer        func_data,
+                                           GtkArg         *args);
+static void gtk_container_marshal_signal_4 (GtkObject      *object,
+                                           GtkSignalFunc   func,
+                                           gpointer        func_data,
+                                           GtkArg         *args);
+
+
+static void gtk_container_class_init        (GtkContainerClass *klass);
+static void gtk_container_init              (GtkContainer      *container);
+static void gtk_container_arg               (GtkContainer      *container,
+                                            GtkArg            *arg);
+static gint gtk_real_container_need_resize  (GtkContainer      *container);
+static gint gtk_real_container_focus        (GtkContainer      *container,
+                                            GtkDirectionType   direction);
+static gint gtk_container_focus_tab         (GtkContainer      *container,
+                                            GList             *children,
+                                            GtkDirectionType   direction);
+static gint gtk_container_focus_up_down     (GtkContainer      *container,
+                                            GList             *children,
+                                            GtkDirectionType   direction);
+static gint gtk_container_focus_left_right  (GtkContainer      *container,
+                                            GList             *children,
+                                            GtkDirectionType   direction);
+static gint gtk_container_focus_move        (GtkContainer      *container,
+                                            GList             *children,
+                                            GtkDirectionType   direction);
+static void gtk_container_children_callback (GtkWidget         *widget,
+                                             gpointer           client_data);
+
+
+static gint container_signals[LAST_SIGNAL] = { 0 };
+
+
+guint
+gtk_container_get_type ()
+{
+  static guint container_type = 0;
+
+  if (!container_type)
+    {
+      GtkTypeInfo container_info =
+      {
+       "GtkContainer",
+       sizeof (GtkContainer),
+       sizeof (GtkContainerClass),
+       (GtkClassInitFunc) gtk_container_class_init,
+       (GtkObjectInitFunc) gtk_container_init,
+       (GtkArgFunc) gtk_container_arg,
+      };
+
+      container_type = gtk_type_unique (gtk_widget_get_type (), &container_info);
+    }
+
+  return container_type;
+}
+
+static void
+gtk_container_class_init (GtkContainerClass *class)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+
+  object_class = (GtkObjectClass*) class;
+  widget_class = (GtkWidgetClass*) class;
+
+  gtk_object_add_arg_type ("GtkContainer::border_width", GTK_TYPE_LONG);
+  gtk_object_add_arg_type ("GtkContainer::auto_resize", GTK_TYPE_BOOL);
+  gtk_object_add_arg_type ("GtkContainer::block_resize", GTK_TYPE_BOOL);
+  gtk_object_add_arg_type ("GtkContainer::child", GTK_TYPE_WIDGET);
+
+  container_signals[ADD] =
+    gtk_signal_new ("add",
+                    GTK_RUN_FIRST,
+                    object_class->type,
+                    GTK_SIGNAL_OFFSET (GtkContainerClass, add),
+                    gtk_container_marshal_signal_1,
+                   GTK_TYPE_NONE, 1,
+                    GTK_TYPE_WIDGET);
+  container_signals[REMOVE] =
+    gtk_signal_new ("remove",
+                    GTK_RUN_FIRST,
+                    object_class->type,
+                    GTK_SIGNAL_OFFSET (GtkContainerClass, remove),
+                    gtk_container_marshal_signal_1,
+                   GTK_TYPE_NONE, 1,
+                    GTK_TYPE_WIDGET);
+  container_signals[NEED_RESIZE] =
+    gtk_signal_new ("need_resize",
+                    GTK_RUN_FIRST,
+                    object_class->type,
+                    GTK_SIGNAL_OFFSET (GtkContainerClass, need_resize),
+                    gtk_container_marshal_signal_4,
+                   GTK_TYPE_BOOL, 0,
+                    GTK_TYPE_WIDGET);
+  container_signals[FOREACH] =
+    gtk_signal_new ("foreach",
+                    GTK_RUN_FIRST,
+                    object_class->type,
+                    GTK_SIGNAL_OFFSET (GtkContainerClass, foreach),
+                    gtk_container_marshal_signal_2,
+                   GTK_TYPE_NONE, 1,
+                    GTK_TYPE_C_CALLBACK);
+  container_signals[FOCUS] =
+    gtk_signal_new ("focus",
+                    GTK_RUN_FIRST,
+                    object_class->type,
+                    GTK_SIGNAL_OFFSET (GtkContainerClass, focus),
+                    gtk_container_marshal_signal_3,
+                   GTK_TYPE_DIRECTION_TYPE, 1,
+                    GTK_TYPE_DIRECTION_TYPE);
+
+  gtk_object_class_add_signals (object_class, container_signals, LAST_SIGNAL);
+
+  class->need_resize = gtk_real_container_need_resize;
+  class->focus = gtk_real_container_focus;
+}
+
+static void
+gtk_container_init (GtkContainer *container)
+{
+  container->focus_child = NULL;
+  container->border_width = 0;
+  container->auto_resize = TRUE;
+  container->need_resize = FALSE;
+  container->block_resize = FALSE;
+}
+
+static void
+gtk_container_arg (GtkContainer *container,
+                  GtkArg       *arg)
+{
+  if (strcmp (arg->name, "border_width") == 0)
+    {
+      gtk_container_border_width (container, GTK_VALUE_LONG (*arg));
+    }
+  else if (strcmp (arg->name, "auto_resize") == 0)
+    {
+      if (GTK_VALUE_BOOL (*arg))
+       gtk_container_enable_resize (container);
+      else
+       gtk_container_disable_resize (container);
+    }
+  else if (strcmp (arg->name, "block_resize") == 0)
+    {
+      if (GTK_VALUE_BOOL (*arg))
+       gtk_container_block_resize (container);
+      else
+       gtk_container_unblock_resize (container);
+    }
+  else if (strcmp (arg->name, "child") == 0)
+    {
+      gtk_container_add (container, GTK_WIDGET (GTK_VALUE_OBJECT (*arg)));
+    }
+}
+
+void
+gtk_container_border_width (GtkContainer *container,
+                           gint          border_width)
+{
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_CONTAINER (container));
+
+  if (container->border_width != border_width)
+    {
+      container->border_width = border_width;
+
+      if (container->widget.parent && GTK_WIDGET_VISIBLE (container))
+       gtk_container_need_resize (GTK_CONTAINER (container->widget.parent));
+    }
+}
+
+void
+gtk_container_add (GtkContainer *container,
+                  GtkWidget    *widget)
+{
+  gtk_signal_emit (GTK_OBJECT (container), container_signals[ADD], widget);
+}
+
+void
+gtk_container_remove (GtkContainer *container,
+                     GtkWidget    *widget)
+{
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_CONTAINER (container));
+
+  if (container->focus_child == widget)
+    container->focus_child = NULL;
+
+  gtk_signal_emit (GTK_OBJECT (container), container_signals[REMOVE], widget);
+}
+
+void
+gtk_container_disable_resize (GtkContainer *container)
+{
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_CONTAINER (container));
+
+  container->auto_resize = FALSE;
+}
+
+void
+gtk_container_enable_resize (GtkContainer *container)
+{
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_CONTAINER (container));
+
+  container->auto_resize = TRUE;
+  if (container->need_resize)
+    {
+      container->need_resize = FALSE;
+      gtk_widget_queue_resize (GTK_WIDGET (container));
+    }
+}
+
+void
+gtk_container_block_resize (GtkContainer *container)
+{
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_CONTAINER (container));
+
+  container->block_resize = TRUE;
+}
+
+void
+gtk_container_unblock_resize (GtkContainer *container)
+{
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_CONTAINER (container));
+
+  container->block_resize = FALSE;
+}
+
+gint
+gtk_container_need_resize (GtkContainer *container)
+{
+  gint return_val;
+
+  g_return_val_if_fail (container != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_CONTAINER (container), FALSE);
+
+  return_val = FALSE;
+
+  if (!container->block_resize)
+    {
+      if (container->auto_resize)
+       gtk_signal_emit (GTK_OBJECT (container),
+                         container_signals[NEED_RESIZE],
+                         &return_val);
+      else
+       container->need_resize = TRUE;
+    }
+
+  return return_val;
+}
+
+void
+gtk_container_foreach (GtkContainer *container,
+                      GtkCallback   callback,
+                      gpointer      callback_data)
+{
+  gtk_signal_emit (GTK_OBJECT (container),
+                   container_signals[FOREACH],
+                   callback, callback_data);
+}
+
+gint
+gtk_container_focus (GtkContainer     *container,
+                    GtkDirectionType  direction)
+{
+  gint return_val;
+
+  gtk_signal_emit (GTK_OBJECT (container),
+                   container_signals[FOCUS],
+                   direction, &return_val);
+
+  return return_val;
+}
+
+GList*
+gtk_container_children (GtkContainer *container)
+{
+  GList *children;
+
+  children = NULL;
+
+  gtk_container_foreach (container,
+                        gtk_container_children_callback,
+                        &children);
+
+  return g_list_reverse (children);
+}
+
+
+static void
+gtk_container_marshal_signal_1 (GtkObject      *object,
+                               GtkSignalFunc   func,
+                               gpointer        func_data,
+                               GtkArg         *args)
+{
+  GtkContainerSignal1 rfunc;
+
+  rfunc = (GtkContainerSignal1) func;
+
+  (* rfunc) (object, GTK_VALUE_OBJECT (args[0]), func_data);
+}
+
+static void
+gtk_container_marshal_signal_2 (GtkObject      *object,
+                               GtkSignalFunc   func,
+                               gpointer        func_data,
+                               GtkArg         *args)
+{
+  GtkContainerSignal2 rfunc;
+
+  rfunc = (GtkContainerSignal2) func;
+
+  (* rfunc) (object,
+            GTK_VALUE_C_CALLBACK(args[0]).func,
+            GTK_VALUE_C_CALLBACK(args[0]).func_data,
+            func_data);
+}
+
+static void
+gtk_container_marshal_signal_3 (GtkObject      *object,
+                               GtkSignalFunc   func,
+                               gpointer        func_data,
+                               GtkArg         *args)
+{
+  GtkContainerSignal3 rfunc;
+  gint *return_val;
+
+  rfunc = (GtkContainerSignal3) func;
+  return_val = GTK_RETLOC_ENUM (args[1]);
+
+  *return_val = (* rfunc) (object, GTK_VALUE_ENUM(args[0]), func_data);
+}
+
+static void
+gtk_container_marshal_signal_4 (GtkObject      *object,
+                               GtkSignalFunc   func,
+                               gpointer        func_data,
+                               GtkArg         *args)
+{
+  GtkContainerSignal4 rfunc;
+  gint *return_val;
+
+  rfunc = (GtkContainerSignal4) func;
+  return_val = GTK_RETLOC_BOOL (args[0]);
+
+  *return_val = (* rfunc) (object, func_data);
+}
+
+static gint
+gtk_real_container_need_resize (GtkContainer *container)
+{
+  g_return_val_if_fail (container != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_CONTAINER (container), FALSE);
+
+  if (GTK_WIDGET_VISIBLE (container) && container->widget.parent)
+    return gtk_container_need_resize (GTK_CONTAINER (container->widget.parent));
+
+  return FALSE;
+}
+
+static gint
+gtk_real_container_focus (GtkContainer     *container,
+                         GtkDirectionType  direction)
+{
+  GList *children;
+  GList *tmp_list;
+  GList *tmp_list2;
+  gint return_val;
+
+  g_return_val_if_fail (container != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_CONTAINER (container), FALSE);
+
+  /* Fail if the container is insensitive
+   */
+  if (!GTK_WIDGET_SENSITIVE (container))
+    return FALSE;
+
+  return_val = FALSE;
+
+  if (GTK_WIDGET_CAN_FOCUS (container))
+    {
+      gtk_widget_grab_focus (GTK_WIDGET (container));
+      return_val = TRUE;
+    }
+  else
+    {
+      /* Get a list of the containers children
+       */
+      children = gtk_container_children (container);
+
+      if (children)
+       {
+         /* Remove any children which are insensitive
+          */
+         tmp_list = children;
+         while (tmp_list)
+           {
+             if (!GTK_WIDGET_SENSITIVE (tmp_list->data))
+               {
+                 tmp_list2 = tmp_list;
+                 tmp_list = tmp_list->next;
+
+                 children = g_list_remove_link (children, tmp_list2);
+                 g_list_free_1 (tmp_list2);
+               }
+             else
+               tmp_list = tmp_list->next;
+           }
+
+         switch (direction)
+           {
+           case GTK_DIR_TAB_FORWARD:
+           case GTK_DIR_TAB_BACKWARD:
+             return_val = gtk_container_focus_tab (container, children, direction);
+             break;
+           case GTK_DIR_UP:
+           case GTK_DIR_DOWN:
+             return_val = gtk_container_focus_up_down (container, children, direction);
+             break;
+           case GTK_DIR_LEFT:
+           case GTK_DIR_RIGHT:
+             return_val = gtk_container_focus_left_right (container, children, direction);
+             break;
+           }
+
+         g_list_free (children);
+       }
+    }
+
+  return return_val;
+}
+
+static gint
+gtk_container_focus_tab (GtkContainer     *container,
+                        GList            *children,
+                        GtkDirectionType  direction)
+{
+  GtkWidget *child;
+  GtkWidget *child2;
+  GList *tmp_list;
+  gint length;
+  gint i, j;
+
+  length = g_list_length (children);
+
+  /* sort the children in the y direction */
+  for (i = 1; i < length; i++)
+    {
+      j = i;
+      tmp_list = g_list_nth (children, j);
+      child = tmp_list->data;
+
+      while (j > 0)
+       {
+         child2 = tmp_list->prev->data;
+         if (child->allocation.y < child2->allocation.y)
+           {
+             tmp_list->data = tmp_list->prev->data;
+             tmp_list = tmp_list->prev;
+             j--;
+           }
+         else
+           break;
+       }
+
+      tmp_list->data = child;
+    }
+
+  /* sort the children in the x direction while
+   *  maintaining the y direction sort.
+   */
+  for (i = 1; i < length; i++)
+    {
+      j = i;
+      tmp_list = g_list_nth (children, j);
+      child = tmp_list->data;
+
+      while (j > 0)
+       {
+         child2 = tmp_list->prev->data;
+         if ((child->allocation.x < child2->allocation.x) &&
+             (child->allocation.y >= child2->allocation.y))
+           {
+             tmp_list->data = tmp_list->prev->data;
+             tmp_list = tmp_list->prev;
+             j--;
+           }
+         else
+           break;
+       }
+
+      tmp_list->data = child;
+    }
+
+  /* if we are going backwards then reverse the order
+   *  of the children.
+   */
+  if (direction == GTK_DIR_TAB_BACKWARD)
+    children = g_list_reverse (children);
+
+  return gtk_container_focus_move (container, children, direction);
+}
+
+static gint
+gtk_container_focus_up_down (GtkContainer     *container,
+                            GList            *children,
+                            GtkDirectionType  direction)
+{
+  GtkWidget *child;
+  GtkWidget *child2;
+  GList *tmp_list;
+  gint dist1, dist2;
+  gint focus_x;
+  gint focus_width;
+  gint length;
+  gint i, j;
+
+  /* return failure if there isn't a focus child */
+  if (container->focus_child)
+    {
+      focus_width = container->focus_child->allocation.width / 2;
+      focus_x = container->focus_child->allocation.x + focus_width;
+    }
+  else
+    {
+      focus_width = GTK_WIDGET (container)->allocation.width;
+      if (GTK_WIDGET_NO_WINDOW (container))
+       focus_x = GTK_WIDGET (container)->allocation.x;
+      else
+       focus_x = 0;
+    }
+
+  length = g_list_length (children);
+
+  /* sort the children in the y direction */
+  for (i = 1; i < length; i++)
+    {
+      j = i;
+      tmp_list = g_list_nth (children, j);
+      child = tmp_list->data;
+
+      while (j > 0)
+       {
+         child2 = tmp_list->prev->data;
+         if (child->allocation.y < child2->allocation.y)
+           {
+             tmp_list->data = tmp_list->prev->data;
+             tmp_list = tmp_list->prev;
+             j--;
+           }
+         else
+           break;
+       }
+
+      tmp_list->data = child;
+    }
+
+  /* sort the children in distance in the x direction
+   *  in distance from the current focus child while maintaining the
+   *  sort in the y direction
+   */
+  for (i = 1; i < length; i++)
+    {
+      j = i;
+      tmp_list = g_list_nth (children, j);
+      child = tmp_list->data;
+      dist1 = (child->allocation.x + child->allocation.width / 2) - focus_x;
+
+      while (j > 0)
+       {
+         child2 = tmp_list->prev->data;
+         dist2 = (child2->allocation.x + child2->allocation.width / 2) - focus_x;
+
+         if ((dist1 < dist2) &&
+             (child->allocation.y >= child2->allocation.y))
+           {
+             tmp_list->data = tmp_list->prev->data;
+             tmp_list = tmp_list->prev;
+             j--;
+           }
+         else
+           break;
+       }
+
+      tmp_list->data = child;
+    }
+
+  /* go and invalidate any widget which is too
+   *  far from the focus widget.
+   */
+  if (!container->focus_child &&
+      (direction == GTK_DIR_UP))
+    focus_x += focus_width;
+
+  tmp_list = children;
+  while (tmp_list)
+    {
+      child = tmp_list->data;
+
+      dist1 = (child->allocation.x + child->allocation.width / 2) - focus_x;
+      if (((direction == GTK_DIR_DOWN) && (dist1 < 0)) ||
+         ((direction == GTK_DIR_UP) && (dist1 > 0)))
+       tmp_list->data = NULL;
+
+      tmp_list = tmp_list->next;
+    }
+
+  if (direction == GTK_DIR_UP)
+    children = g_list_reverse (children);
+
+  return gtk_container_focus_move (container, children, direction);
+}
+
+static gint
+gtk_container_focus_left_right (GtkContainer     *container,
+                               GList            *children,
+                               GtkDirectionType  direction)
+{
+  GtkWidget *child;
+  GtkWidget *child2;
+  GList *tmp_list;
+  gint dist1, dist2;
+  gint focus_y;
+  gint focus_height;
+  gint length;
+  gint i, j;
+
+  /* return failure if there isn't a focus child */
+  if (container->focus_child)
+    {
+      focus_height = container->focus_child->allocation.height / 2;
+      focus_y = container->focus_child->allocation.y + focus_height;
+    }
+  else
+    {
+      focus_height = GTK_WIDGET (container)->allocation.height;
+      if (GTK_WIDGET_NO_WINDOW (container))
+       focus_y = GTK_WIDGET (container)->allocation.y;
+      else
+       focus_y = 0;
+    }
+
+  length = g_list_length (children);
+
+  /* sort the children in the x direction */
+  for (i = 1; i < length; i++)
+    {
+      j = i;
+      tmp_list = g_list_nth (children, j);
+      child = tmp_list->data;
+
+      while (j > 0)
+       {
+         child2 = tmp_list->prev->data;
+         if (child->allocation.x < child2->allocation.x)
+           {
+             tmp_list->data = tmp_list->prev->data;
+             tmp_list = tmp_list->prev;
+             j--;
+           }
+         else
+           break;
+       }
+
+      tmp_list->data = child;
+    }
+
+  /* sort the children in distance in the y direction
+   *  in distance from the current focus child while maintaining the
+   *  sort in the x direction
+   */
+  for (i = 1; i < length; i++)
+    {
+      j = i;
+      tmp_list = g_list_nth (children, j);
+      child = tmp_list->data;
+      dist1 = (child->allocation.y + child->allocation.height / 2) - focus_y;
+
+      while (j > 0)
+       {
+         child2 = tmp_list->prev->data;
+         dist2 = (child2->allocation.y + child2->allocation.height / 2) - focus_y;
+
+         if ((dist1 < dist2) &&
+             (child->allocation.x >= child2->allocation.x))
+           {
+             tmp_list->data = tmp_list->prev->data;
+             tmp_list = tmp_list->prev;
+             j--;
+           }
+         else
+           break;
+       }
+
+      tmp_list->data = child;
+    }
+
+  /* go and invalidate any widget which is too
+   *  far from the focus widget.
+   */
+  if (!container->focus_child &&
+      (direction == GTK_DIR_LEFT))
+    focus_y += focus_height;
+
+  tmp_list = children;
+  while (tmp_list)
+    {
+      child = tmp_list->data;
+
+      dist1 = (child->allocation.y + child->allocation.height / 2) - focus_y;
+      if (((direction == GTK_DIR_RIGHT) && (dist1 < 0)) ||
+         ((direction == GTK_DIR_LEFT) && (dist1 > 0)))
+       tmp_list->data = NULL;
+
+      tmp_list = tmp_list->next;
+    }
+
+  if (direction == GTK_DIR_LEFT)
+    children = g_list_reverse (children);
+
+  return gtk_container_focus_move (container, children, direction);
+}
+
+static gint
+gtk_container_focus_move (GtkContainer     *container,
+                         GList            *children,
+                         GtkDirectionType  direction)
+{
+  GtkWidget *focus_child;
+  GtkWidget *child;
+
+  focus_child = container->focus_child;
+  container->focus_child = NULL;
+
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (!child)
+       continue;
+
+      if (focus_child)
+        {
+          if (focus_child == child)
+            {
+              focus_child = NULL;
+
+              if (GTK_WIDGET_VISIBLE (child) &&
+                 GTK_IS_CONTAINER (child) &&
+                 !GTK_WIDGET_HAS_FOCUS (child))
+               if (gtk_container_focus (GTK_CONTAINER (child), direction))
+                 return TRUE;
+            }
+        }
+      else if (GTK_WIDGET_VISIBLE (child))
+        {
+          if (GTK_WIDGET_CAN_FOCUS (child))
+            {
+              gtk_widget_grab_focus (child);
+              return TRUE;
+            }
+          else if (GTK_IS_CONTAINER (child))
+            {
+              if (gtk_container_focus (GTK_CONTAINER (child), direction))
+                return TRUE;
+            }
+        }
+    }
+
+  return FALSE;
+}
+
+
+static void
+gtk_container_children_callback (GtkWidget *widget,
+                                gpointer   client_data)
+{
+  GList **children;
+
+  children = (GList**) client_data;
+  *children = g_list_prepend (*children, widget);
+}
diff --git a/gtk/gtkcontainer.h b/gtk/gtkcontainer.h
new file mode 100644 (file)
index 0000000..80c1ce0
--- /dev/null
@@ -0,0 +1,95 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_CONTAINER_H__
+#define __GTK_CONTAINER_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkenums.h>
+#include <gtk/gtkwidget.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_CONTAINER(obj)          GTK_CHECK_CAST (obj, gtk_container_get_type (), GtkContainer)
+#define GTK_CONTAINER_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_container_get_type, GtkContainerClass)
+#define GTK_IS_CONTAINER(obj)       GTK_CHECK_TYPE (obj, gtk_container_get_type ())
+
+#define GTK_TYPE_CONTAINER          (gtk_container_get_type ())
+
+typedef struct _GtkContainer       GtkContainer;
+typedef struct _GtkContainerClass  GtkContainerClass;
+
+struct _GtkContainer
+{
+  GtkWidget widget;
+
+  GtkWidget *focus_child;
+  gint16 border_width;
+  guint auto_resize : 1;
+  guint need_resize : 1;
+  guint block_resize : 1;
+};
+
+struct _GtkContainerClass
+{
+  GtkWidgetClass parent_class;
+
+  void (* add)         (GtkContainer     *container,
+                       GtkWidget        *widget);
+  void (* remove)      (GtkContainer     *container,
+                       GtkWidget        *widget);
+  gint (* need_resize) (GtkContainer     *container);
+  void (* foreach)     (GtkContainer     *container,
+                       GtkCallback       callback,
+                       gpointer          callbabck_data);
+  gint (* focus)       (GtkContainer     *container,
+                       GtkDirectionType  direction);
+};
+
+
+
+guint  gtk_container_get_type       (void);
+void   gtk_container_border_width   (GtkContainer     *container,
+                                    gint              border_width);
+void   gtk_container_add            (GtkContainer     *container,
+                                    GtkWidget        *widget);
+void   gtk_container_remove         (GtkContainer     *container,
+                                    GtkWidget        *widget);
+void   gtk_container_disable_resize (GtkContainer     *container);
+void   gtk_container_enable_resize  (GtkContainer     *container);
+void   gtk_container_block_resize   (GtkContainer     *container);
+void   gtk_container_unblock_resize (GtkContainer     *container);
+gint   gtk_container_need_resize    (GtkContainer     *container);
+void   gtk_container_foreach        (GtkContainer     *container,
+                                    GtkCallback       callback,
+                                    gpointer          callback_data);
+gint   gtk_container_focus          (GtkContainer     *container,
+                                    GtkDirectionType  direction);
+GList* gtk_container_children       (GtkContainer     *container);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_CONTAINER_H__ */
diff --git a/gtk/gtkcurve.c b/gtk/gtkcurve.c
new file mode 100644 (file)
index 0000000..d2b6e08
--- /dev/null
@@ -0,0 +1,860 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1997 David Mosberger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <string.h>
+#include <math.h>
+
+#include "gtkcurve.h"
+#include "gtkdrawingarea.h"
+#include "gtkmain.h"
+#include "gtkradiobutton.h"
+#include "gtksignal.h"
+#include "gtktable.h"
+
+#define BOUNDS(a,x,y)  (((a) < (x)) ? (x) : (((a) > (y)) ? (y) : (a)))
+#define RADIUS         3       /* radius of the control points */
+#define MIN_DISTANCE   8       /* min distance between control points */
+
+#define GRAPH_MASK     (GDK_EXPOSURE_MASK |            \
+                        GDK_POINTER_MOTION_MASK |      \
+                        GDK_POINTER_MOTION_HINT_MASK | \
+                        GDK_ENTER_NOTIFY_MASK |        \
+                        GDK_BUTTON_PRESS_MASK |        \
+                        GDK_BUTTON_RELEASE_MASK |      \
+                        GDK_BUTTON1_MOTION_MASK)
+
+static GtkDrawingAreaClass *parent_class = NULL;
+static gint curve_type_changed_signal = 0;
+
+
+/* forward declarations: */
+static void gtk_curve_class_init (GtkCurveClass *class);
+static void gtk_curve_init (GtkCurve *curve);
+static void gtk_curve_destroy (GtkObject *object);
+
+
+guint
+gtk_curve_get_type (void)
+{
+  static guint curve_type = 0;
+
+  if (!curve_type)
+    {
+      GtkTypeInfo curve_info =
+      {
+       "GtkCurve",
+       sizeof (GtkCurve),
+       sizeof (GtkCurveClass),
+       (GtkClassInitFunc) gtk_curve_class_init,
+       (GtkObjectInitFunc) gtk_curve_init,
+       (GtkArgFunc) NULL,
+      };
+
+      curve_type = gtk_type_unique (gtk_drawing_area_get_type (), &curve_info);
+    }
+  return curve_type;
+}
+
+static void
+gtk_curve_class_init (GtkCurveClass *class)
+{
+  GtkObjectClass *object_class;
+
+  parent_class = gtk_type_class (gtk_drawing_area_get_type ());
+
+  object_class = (GtkObjectClass *) class;
+
+  curve_type_changed_signal =
+    gtk_signal_new ("curve_type_changed", GTK_RUN_FIRST, object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkCurveClass, curve_type_changed),
+                   gtk_signal_default_marshaller, GTK_TYPE_NONE, 0);
+  gtk_object_class_add_signals (object_class, &curve_type_changed_signal, 1);
+
+  object_class->destroy = gtk_curve_destroy;
+}
+
+static void
+gtk_curve_init (GtkCurve *curve)
+{
+  curve->cursor_type = GDK_TOP_LEFT_ARROW;
+  curve->pixmap = NULL;
+  curve->curve_type = GTK_CURVE_TYPE_SPLINE;
+  curve->height = 0;
+  curve->grab_point = -1;
+
+  curve->num_points = 0;
+  curve->point = 0;
+
+  curve->num_ctlpoints = 0;
+  curve->ctlpoint = NULL;
+}
+
+static int
+project (gfloat value, gfloat min, gfloat max, int norm)
+{
+  return (norm - 1) * ((value - min) / (max - min)) + 0.5;
+}
+
+static gfloat
+unproject (gint value, gfloat min, gfloat max, int norm)
+{
+  return value / (gfloat) (norm - 1) * (max - min) + min;
+}
+
+/* Solve the tridiagonal equation system that determines the second
+   derivatives for the interpolation points.  (Based on Numerical
+   Recipies 2nd Edition.) */
+static void
+spline_solve (int n, gfloat x[], gfloat y[], gfloat y2[])
+{
+  gfloat p, sig, *u;
+  gint i, k;
+
+  u = g_malloc ((n - 1) * sizeof (u[0]));
+
+  y2[0] = u[0] = 0.0;  /* set lower boundary condition to "natural" */
+
+  for (i = 1; i < n - 1; ++i)
+    {
+      sig = (x[i] - x[i - 1]) / (x[i + 1] - x[i - 1]);
+      p = sig * y2[i - 1] + 2.0;
+      y2[i] = (sig - 1.0) / p;
+      u[i] = ((y[i + 1] - y[i])
+             / (x[i + 1] - x[i]) - (y[i] - y[i - 1]) / (x[i] - x[i - 1]));
+      u[i] = (6.0 * u[i] / (x[i + 1] - x[i - 1]) - sig * u[i - 1]) / p;
+    }
+
+  y2[n - 1] = 0.0;
+  for (k = n - 2; k >= 0; --k)
+    y2[k] = y2[k] * y2[k + 1] + u[k];
+
+  g_free (u);
+}
+
+static gfloat
+spline_eval (int n, gfloat x[], gfloat y[], gfloat y2[], gfloat val)
+{
+  gint k_lo, k_hi, k;
+  gfloat h, b, a;
+
+  /* do a binary search for the right interval: */
+  k_lo = 0; k_hi = n - 1;
+  while (k_hi - k_lo > 1)
+    {
+      k = (k_hi + k_lo) / 2;
+      if (x[k] > val)
+       k_hi = k;
+      else
+       k_lo = k;
+    }
+
+  h = x[k_hi] - x[k_lo];
+  g_assert (h > 0.0);
+
+  a = (x[k_hi] - val) / h;
+  b = (val - x[k_lo]) / h;
+  return a*y[k_lo] + b*y[k_hi] +
+    ((a*a*a - a)*y2[k_lo] + (b*b*b - b)*y2[k_hi]) * (h*h)/6.0;
+}
+
+static void
+gtk_curve_interpolate (GtkCurve *c, gint width, gint height)
+{
+  gfloat *vector;
+  int i;
+
+  vector = g_malloc (width * sizeof (vector[0]));
+
+  gtk_curve_get_vector (c, width, vector);
+
+  c->height = height;
+  if (c->num_points != width)
+    {
+      c->num_points = width;
+      if (c->point)
+       g_free (c->point);
+      c->point = g_malloc (c->num_points * sizeof (c->point[0]));
+    }
+
+  for (i = 0; i < width; ++i)
+    {
+      c->point[i].x = RADIUS + i;
+      c->point[i].y = RADIUS + height
+       - project (vector[i], c->min_y, c->max_y, height);
+    }
+}
+
+static void
+gtk_curve_draw (GtkCurve *c, gint width, gint height)
+{
+  GtkStateType state;
+  GtkStyle *style;
+  gint i;
+
+  if (!c->pixmap)
+    return;
+
+  if (c->height != height || c->num_points != width)
+    gtk_curve_interpolate (c, width, height);
+
+  state = GTK_STATE_NORMAL;
+  if (!GTK_WIDGET_IS_SENSITIVE (GTK_WIDGET (c)))
+    state = GTK_STATE_INSENSITIVE;
+
+  style = GTK_WIDGET (c)->style;
+
+  /* clear the pixmap: */
+  gdk_draw_rectangle (c->pixmap, style->bg_gc[state], TRUE,
+                     0, 0, width + RADIUS * 2, height + RADIUS * 2);
+
+  /* draw the grid lines: (XXX make more meaningful) */
+  for (i = 0; i < 5; i++)
+    {
+      gdk_draw_line (c->pixmap, style->dark_gc[state],
+                    RADIUS, i * (height / 4.0) + RADIUS,
+                    width + RADIUS, i * (height / 4.0) + RADIUS);
+      gdk_draw_line (c->pixmap, style->dark_gc[state],
+                    i * (width / 4.0) + RADIUS, RADIUS,
+                    i * (width / 4.0) + RADIUS, height + RADIUS);
+    }
+
+  gdk_draw_points (c->pixmap, style->fg_gc[state], c->point, c->num_points);
+  if (c->curve_type != GTK_CURVE_TYPE_FREE)
+    for (i = 0; i < c->num_ctlpoints; ++i)
+      {
+       gint x, y;
+
+       if (c->ctlpoint[i][0] < c->min_x)
+         continue;
+
+       x = project (c->ctlpoint[i][0], c->min_x, c->max_x,
+                    width);
+       y = height -
+         project (c->ctlpoint[i][1], c->min_y, c->max_y,
+                  height);
+
+       /* draw a bullet: */
+       gdk_draw_arc (c->pixmap, style->fg_gc[state], TRUE, x, y,
+                     RADIUS * 2, RADIUS*2, 0, 360*64);
+      }
+  gdk_draw_pixmap (GTK_WIDGET (c)->window, style->fg_gc[state], c->pixmap,
+                  0, 0, 0, 0, width + RADIUS * 2, height + RADIUS * 2);
+}
+
+static gint
+gtk_curve_graph_events (GtkWidget *widget, GdkEvent *event, GtkCurve *c)
+{
+  GdkCursorType new_type = c->cursor_type;
+  gint i, src, dst, leftbound, rightbound;
+  GdkEventButton *bevent;
+  GdkEventMotion *mevent;
+  GtkWidget *w;
+  gint tx, ty;
+  gint cx, x, y, width, height;
+  gint closest_point = 0;
+  gfloat rx, ry, min_x;
+  guint distance;
+  gint x1, x2, y1, y2;
+
+  w = GTK_WIDGET (c);
+  width = w->allocation.width - RADIUS * 2;
+  height = w->allocation.height - RADIUS * 2;
+
+  /*  get the pointer position  */
+  gdk_window_get_pointer (w->window, &tx, &ty, NULL);
+  x = BOUNDS ((tx - RADIUS), 0, width);
+  y = BOUNDS ((ty - RADIUS), 0, height);
+
+  min_x = c->min_x;
+
+  distance = ~0U;
+  for (i = 0; i < c->num_ctlpoints; ++i)
+    {
+      cx = project (c->ctlpoint[i][0], min_x, c->max_x, width);
+      if ((guint) abs (x - cx) < distance)
+       {
+         distance = abs (x - cx);
+         closest_point = i;
+       }
+    }
+
+  switch (event->type)
+    {
+    case GDK_CONFIGURE:
+      if (c->pixmap)
+       gdk_pixmap_destroy (c->pixmap);
+      c->pixmap = 0;
+      /* fall through */
+    case GDK_EXPOSE:
+      if (!c->pixmap)
+       c->pixmap = gdk_pixmap_new (w->window,
+                                   w->allocation.width,
+                                   w->allocation.height, -1);
+      gtk_curve_draw (c, width, height);
+      break;
+
+    case GDK_BUTTON_PRESS:
+      gtk_grab_add (widget);
+
+      bevent = (GdkEventButton *) event;
+      new_type = GDK_TCROSS;
+
+      switch (c->curve_type)
+       {
+       case GTK_CURVE_TYPE_LINEAR:
+       case GTK_CURVE_TYPE_SPLINE:
+         if (distance > MIN_DISTANCE)
+           {
+             /* insert a new control point */
+             if (c->num_ctlpoints > 0)
+               {
+                 cx = project (c->ctlpoint[closest_point][0], min_x,
+                               c->max_x, width);
+                 if (x > cx)
+                   ++closest_point;
+               }
+             ++c->num_ctlpoints;
+             c->ctlpoint =
+               g_realloc (c->ctlpoint,
+                          c->num_ctlpoints * sizeof (*c->ctlpoint));
+             for (i = c->num_ctlpoints - 1; i > closest_point; --i)
+               memcpy (c->ctlpoint + i, c->ctlpoint + i - 1,
+                       sizeof (*c->ctlpoint));
+           }
+         c->grab_point = closest_point;
+         c->ctlpoint[c->grab_point][0] =
+           unproject (x, min_x, c->max_x, width);
+         c->ctlpoint[c->grab_point][1] =
+           unproject (height - y, c->min_y, c->max_y, height);
+
+         gtk_curve_interpolate (c, width, height);
+         break;
+
+       case GTK_CURVE_TYPE_FREE:
+         c->point[x].x = RADIUS + x;
+         c->point[x].y = RADIUS + y;
+         c->grab_point = x;
+         c->last = y;
+         break;
+       }
+      gtk_curve_draw (c, width, height);
+      break;
+
+    case GDK_BUTTON_RELEASE:
+      gtk_grab_remove (widget);
+
+      /* delete inactive points: */
+      if (c->curve_type != GTK_CURVE_TYPE_FREE)
+       {
+         for (src = dst = 0; src < c->num_ctlpoints; ++src)
+           {
+             if (c->ctlpoint[src][0] >= min_x)
+               {
+                 memcpy (c->ctlpoint + dst, c->ctlpoint + src,
+                         sizeof (*c->ctlpoint));
+                 ++dst;
+               }
+           }
+         if (dst < src)
+           {
+             c->num_ctlpoints -= (src - dst);
+             if (c->num_ctlpoints <= 0)
+               {
+                 c->num_ctlpoints = 1;
+                 c->ctlpoint[0][0] = min_x;
+                 c->ctlpoint[0][1] = c->min_y;
+                 gtk_curve_interpolate (c, width, height);
+                 gtk_curve_draw (c, width, height);
+               }
+             c->ctlpoint =
+               g_realloc (c->ctlpoint,
+                          c->num_ctlpoints * sizeof (*c->ctlpoint));
+           }
+       }
+      new_type = GDK_FLEUR;
+      c->grab_point = -1;
+      break;
+
+    case GDK_MOTION_NOTIFY:
+      mevent = (GdkEventMotion *) event;
+      if (mevent->is_hint)
+       {
+         mevent->x = tx;
+         mevent->y = ty;
+       }
+      switch (c->curve_type)
+       {
+       case GTK_CURVE_TYPE_LINEAR:
+       case GTK_CURVE_TYPE_SPLINE:
+         if (c->grab_point == -1)
+           {
+             /* if no point is grabbed...  */
+             if (distance <= MIN_DISTANCE)
+               new_type = GDK_FLEUR;
+             else
+               new_type = GDK_TCROSS;
+           }
+         else
+           {
+             /* drag the grabbed point  */
+             new_type = GDK_TCROSS;
+
+             leftbound = -MIN_DISTANCE;
+             if (c->grab_point > 0)
+               leftbound = project (c->ctlpoint[c->grab_point - 1][0],
+                                    min_x, c->max_x, width);
+
+             rightbound = width + RADIUS * 2 + MIN_DISTANCE;
+             if (c->grab_point + 1 < c->num_ctlpoints)
+               rightbound = project (c->ctlpoint[c->grab_point + 1][0],
+                                     min_x, c->max_x, width);
+
+             if (tx <= leftbound || tx >= rightbound
+                 || ty > height + RADIUS * 2 + MIN_DISTANCE
+                 || ty < -MIN_DISTANCE)
+               c->ctlpoint[c->grab_point][0] = min_x - 1.0;
+             else
+               {
+                 rx = unproject (x, min_x, c->max_x, width);
+                 ry = unproject (height - y, c->min_y, c->max_y, height);
+                 c->ctlpoint[c->grab_point][0] = rx;
+                 c->ctlpoint[c->grab_point][1] = ry;
+               }
+             gtk_curve_interpolate (c, width, height);
+             gtk_curve_draw (c, width, height);
+           }
+         break;
+
+       case GTK_CURVE_TYPE_FREE:
+         if (c->grab_point != -1)
+           {
+             if (c->grab_point > x)
+               {
+                 x1 = x;
+                 x2 = c->grab_point;
+                 y1 = y;
+                 y2 = c->last;
+               }
+             else
+               {
+                 x1 = c->grab_point;
+                 x2 = x;
+                 y1 = c->last;
+                 y2 = y;
+               }
+
+             if (x2 != x1)
+               for (i = x1; i <= x2; i++)
+                 {
+                   c->point[i].x = RADIUS + i;
+                   c->point[i].y = RADIUS +
+                     (y1 + ((y2 - y1) * (i - x1)) / (x2 - x1));
+                 }
+             else
+               {
+                 c->point[x].x = RADIUS + x;
+                 c->point[x].y = RADIUS + y;
+               }
+             c->grab_point = x;
+             c->last = y;
+             gtk_curve_draw (c, width, height);
+           }
+         if (mevent->state & GDK_BUTTON1_MASK)
+           new_type = GDK_TCROSS;
+         else
+           new_type = GDK_PENCIL;
+         break;
+       }
+      if (new_type != (GdkCursorType) c->cursor_type)
+       {
+         GdkCursor *cursor;
+
+         c->cursor_type = new_type;
+
+         cursor = gdk_cursor_new (c->cursor_type);
+         gdk_window_set_cursor (w->window, cursor);
+         gdk_cursor_destroy (cursor);
+       }
+      break;
+
+    default:
+      break;
+    }
+  return FALSE;
+}
+
+void
+gtk_curve_set_curve_type (GtkCurve *c, GtkCurveType new_type)
+{
+  gfloat rx, dx;
+  gint x, i;
+
+  if (new_type != c->curve_type)
+    {
+      gint width, height;
+
+      width  = GTK_WIDGET(c)->allocation.width - RADIUS * 2;
+      height = GTK_WIDGET(c)->allocation.height - RADIUS * 2;
+
+      if (new_type == GTK_CURVE_TYPE_FREE)
+       {
+         gtk_curve_interpolate (c, width, height);
+         c->curve_type = new_type;
+       }
+      else if (c->curve_type == GTK_CURVE_TYPE_FREE)
+       {
+         if (c->ctlpoint)
+           g_free (c->ctlpoint);
+         c->num_ctlpoints = 9;
+         c->ctlpoint = g_malloc (c->num_ctlpoints * sizeof (*c->ctlpoint));
+
+         rx = 0.0;
+         dx = (width - 1) / (gfloat) (c->num_ctlpoints - 1);
+
+         for (i = 0; i < c->num_ctlpoints; ++i, rx += dx)
+           {
+             x = (int) (rx + 0.5);
+             c->ctlpoint[i][0] =
+               unproject (x, c->min_x, c->max_x, width);
+             c->ctlpoint[i][1] =
+               unproject (RADIUS + height - c->point[x].y,
+                          c->min_y, c->max_y, height);
+           }
+         c->curve_type = new_type;
+         gtk_curve_interpolate (c, width, height);
+       }
+      else
+       {
+         c->curve_type = new_type;
+         gtk_curve_interpolate (c, width, height);
+       }
+      gtk_signal_emit (GTK_OBJECT (c), curve_type_changed_signal);
+      gtk_curve_draw (c, width, height);
+    }
+}
+
+static void
+gtk_curve_size_graph (GtkCurve *curve)
+{
+  gint width, height;
+  gfloat aspect;
+
+  width  = (curve->max_x - curve->min_x) + 1;
+  height = (curve->max_y - curve->min_y) + 1;
+  aspect = width / (gfloat) height;
+  if (width > gdk_screen_width () / 4)
+    width  = gdk_screen_width () / 4;
+  if (height > gdk_screen_height () / 4)
+    height = gdk_screen_height () / 4;
+
+  if (aspect < 1.0)
+    width  = height * aspect;
+  else
+    height = width / aspect;
+
+  gtk_drawing_area_size (GTK_DRAWING_AREA (curve),
+                        width + RADIUS * 2, height + RADIUS * 2);
+}
+
+static void
+gtk_curve_reset_vector (GtkCurve *curve)
+{
+  if (curve->ctlpoint)
+    g_free (curve->ctlpoint);
+
+  curve->num_ctlpoints = 2;
+  curve->ctlpoint = g_malloc (2 * sizeof (curve->ctlpoint[0]));
+  curve->ctlpoint[0][0] = curve->min_x;
+  curve->ctlpoint[0][1] = curve->min_y;
+  curve->ctlpoint[1][0] = curve->max_x;
+  curve->ctlpoint[1][1] = curve->max_y;
+
+  if (curve->pixmap)
+    {
+      gint width, height;
+
+      width = GTK_WIDGET (curve)->allocation.width - RADIUS * 2;
+      height = GTK_WIDGET (curve)->allocation.height - RADIUS * 2;
+
+      if (curve->curve_type == GTK_CURVE_TYPE_FREE)
+       {
+         curve->curve_type = GTK_CURVE_TYPE_LINEAR;
+         gtk_curve_interpolate (curve, width, height);
+         curve->curve_type = GTK_CURVE_TYPE_FREE;
+       }
+      else
+       gtk_curve_interpolate (curve, width, height);
+      gtk_curve_draw (curve, width, height);
+    }
+}
+
+void
+gtk_curve_reset (GtkCurve *c)
+{
+  GtkCurveType old_type;
+
+  old_type = c->curve_type;
+  c->curve_type = GTK_CURVE_TYPE_SPLINE;
+  gtk_curve_reset_vector (c);
+
+  if (old_type != GTK_CURVE_TYPE_SPLINE)
+    gtk_signal_emit (GTK_OBJECT (c), curve_type_changed_signal);
+}
+
+void
+gtk_curve_set_gamma (GtkCurve *c, gfloat gamma)
+{
+  gfloat x, one_over_gamma, height, one_over_width;
+  GtkCurveType old_type;
+  gint i;
+
+  if (c->num_points < 2)
+    return;
+
+  old_type = c->curve_type;
+  c->curve_type = GTK_CURVE_TYPE_FREE;
+
+  if (gamma <= 0)
+    one_over_gamma = 1.0;
+  else
+    one_over_gamma = 1.0 / gamma;
+  one_over_width = 1.0 / (c->num_points - 1);
+  height = c->height;
+  for (i = 0; i < c->num_points; ++i)
+    {
+      x = (gfloat) i / (c->num_points - 1);
+      c->point[i].x = RADIUS + i;
+      c->point[i].y =
+       RADIUS + (height * (1.0 - pow (x, one_over_gamma)) + 0.5);
+    }
+
+  if (old_type != GTK_CURVE_TYPE_FREE)
+    gtk_signal_emit (GTK_OBJECT (c), curve_type_changed_signal);
+
+  gtk_curve_draw (c, c->num_points, c->height);
+}
+
+void
+gtk_curve_set_range (GtkCurve *curve,
+                    gfloat min_x, gfloat max_x, gfloat min_y, gfloat max_y)
+{
+  curve->min_x = min_x;
+  curve->max_x = max_x;
+  curve->min_y = min_y;
+  curve->max_y = max_y;
+
+  gtk_curve_size_graph (curve);
+  gtk_curve_reset_vector (curve);
+}
+
+void
+gtk_curve_set_vector (GtkCurve *c, int veclen, gfloat vector[])
+{
+  GtkCurveType old_type;
+  gfloat rx, dx, ry;
+  gint i, height;
+
+  old_type = c->curve_type;
+  c->curve_type = GTK_CURVE_TYPE_FREE;
+
+  if (c->point)
+    height = GTK_WIDGET (c)->allocation.height - RADIUS * 2;
+  else
+    {
+      height = (c->max_y - c->min_y);
+      if (height > gdk_screen_height () / 4)
+       height = gdk_screen_height () / 4;
+
+      c->height = height;
+      c->num_points = veclen;
+      c->point = g_malloc (c->num_points * sizeof (c->point[0]));
+    }
+  rx = 0;
+  dx = (veclen - 1.0) / (c->num_points - 1.0);
+
+  for (i = 0; i < c->num_points; ++i, rx += dx)
+    {
+      ry = vector[(int) (rx + 0.5)];
+      if (ry > c->max_y) ry = c->max_y;
+      if (ry < c->min_y) ry = c->min_y;
+      c->point[i].x = RADIUS + i;
+      c->point[i].y =
+       RADIUS + height - project (ry, c->min_y, c->max_y, height);
+    }
+  if (old_type != GTK_CURVE_TYPE_FREE)
+    gtk_signal_emit (GTK_OBJECT (c), curve_type_changed_signal);
+
+  gtk_curve_draw (c, c->num_points, height);
+}
+
+void
+gtk_curve_get_vector (GtkCurve *c, int veclen, gfloat vector[])
+{
+  gfloat rx, ry, dx, dy, min_x, delta_x, *mem, *xv, *yv, *y2v, prev;
+  gint dst, i, x, next, num_active_ctlpoints = 0, first_active = -1;
+
+  min_x = c->min_x;
+
+  if (c->curve_type != GTK_CURVE_TYPE_FREE)
+    {
+      /* count active points: */
+      prev = min_x - 1.0;
+      for (i = num_active_ctlpoints = 0; i < c->num_ctlpoints; ++i)
+       if (c->ctlpoint[i][0] > prev)
+         {
+           if (first_active < 0)
+             first_active = i;
+           prev = c->ctlpoint[i][0];
+           ++num_active_ctlpoints;
+         }
+
+      /* handle degenerate case: */
+      if (num_active_ctlpoints < 2)
+       {
+         if (num_active_ctlpoints > 0)
+           ry = c->ctlpoint[first_active][1];
+         else
+           ry = c->min_y;
+         if (ry < c->min_y) ry = c->min_y;
+         if (ry > c->max_y) ry = c->max_y;
+         for (x = 0; x < veclen; ++x)
+           vector[x] = ry;
+         return;
+       }
+    }
+
+  switch (c->curve_type)
+    {
+    case GTK_CURVE_TYPE_SPLINE:
+      mem = g_malloc (3 * num_active_ctlpoints * sizeof (gfloat));
+      xv  = mem;
+      yv  = mem + num_active_ctlpoints;
+      y2v = mem + 2*num_active_ctlpoints;
+
+      prev = min_x - 1.0;
+      for (i = dst = 0; i < c->num_ctlpoints; ++i)
+       if (c->ctlpoint[i][0] > prev)
+         {
+           prev    = c->ctlpoint[i][0];
+           xv[dst] = c->ctlpoint[i][0];
+           yv[dst] = c->ctlpoint[i][1];
+           ++dst;
+         }
+
+      spline_solve (num_active_ctlpoints, xv, yv, y2v);
+
+      rx = min_x;
+      dx = (c->max_x - min_x) / (veclen - 1);
+      for (x = 0; x < veclen; ++x, rx += dx)
+       {
+         ry = spline_eval (num_active_ctlpoints, xv, yv, y2v, rx);
+         if (ry < c->min_y) ry = c->min_y;
+         if (ry > c->max_y) ry = c->max_y;
+         vector[x] = ry;
+       }
+
+      g_free (mem);
+      break;
+
+    case GTK_CURVE_TYPE_LINEAR:
+      dx = (c->max_x - min_x) / (veclen - 1);
+      rx = min_x;
+      ry = c->min_y;
+      dy = 0.0;
+      i  = first_active;
+      for (x = 0; x < veclen; ++x, rx += dx)
+       {
+         if (rx >= c->ctlpoint[i][0])
+           {
+             if (rx > c->ctlpoint[i][0])
+               ry = c->min_y;
+             dy = 0.0;
+             next = i + 1;
+             while (next < c->num_ctlpoints
+                    && c->ctlpoint[next][0] <= c->ctlpoint[i][0])
+               ++next;
+             if (next < c->num_ctlpoints)
+               {
+                 delta_x = c->ctlpoint[next][0] - c->ctlpoint[i][0];
+                 dy = ((c->ctlpoint[next][1] - c->ctlpoint[i][1])
+                       / delta_x);
+                 dy *= dx;
+                 ry = c->ctlpoint[i][1];
+                 i = next;
+               }
+           }
+         vector[x] = ry;
+         ry += dy;
+       }
+      break;
+
+    case GTK_CURVE_TYPE_FREE:
+      if (c->point)
+       {
+         rx = 0.0;
+         dx = c->num_points / (double) veclen;
+         for (x = 0; x < veclen; ++x, rx += dx)
+           vector[x] = unproject (RADIUS + c->height - c->point[(int) rx].y,
+                                  c->min_y, c->max_y,
+                                  c->height);
+       }
+      else
+       memset (vector, 0, veclen * sizeof (vector[0]));
+      break;
+    }
+}
+
+GtkWidget*
+gtk_curve_new (void)
+{
+  GtkCurve *curve;
+  gint old_mask;
+
+  curve = gtk_type_new (gtk_curve_get_type ());
+  curve->min_x = 0.0;
+  curve->max_x = 1.0;
+  curve->min_y = 0.0;
+  curve->max_y = 1.0;
+
+  old_mask = gtk_widget_get_events (GTK_WIDGET (curve));
+  gtk_widget_set_events (GTK_WIDGET (curve), old_mask | GRAPH_MASK);
+  gtk_signal_connect (GTK_OBJECT (curve), "event",
+                     (GtkSignalFunc) gtk_curve_graph_events, curve);
+  gtk_curve_size_graph (curve);
+
+  return GTK_WIDGET (curve);
+}
+
+static void
+gtk_curve_destroy (GtkObject *object)
+{
+  GtkCurve *curve;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_CURVE (object));
+
+  curve = GTK_CURVE (object);
+  if (curve->pixmap)
+    gdk_pixmap_destroy (curve->pixmap);
+  if (curve->point)
+    g_free (curve->point);
+  if (curve->ctlpoint)
+    g_free (curve->ctlpoint);
+
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (*GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
diff --git a/gtk/gtkcurve.h b/gtk/gtkcurve.h
new file mode 100644 (file)
index 0000000..0e1568b
--- /dev/null
@@ -0,0 +1,96 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_CURVE_H__
+#define __GTK_CURVE_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkdrawingarea.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_CURVE(obj)        GTK_CHECK_CAST (obj, gtk_curve_get_type (), GtkCurve)
+#define GTK_CURVE_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gtk_curve_get_type, GtkCurveClass)
+#define GTK_IS_CURVE(obj)     GTK_CHECK_TYPE (obj, gtk_curve_get_type ())
+
+
+typedef struct _GtkCurve       GtkCurve;
+typedef struct _GtkCurveClass  GtkCurveClass;
+
+typedef enum
+{
+  GTK_CURVE_TYPE_LINEAR,       /* linear interpolation */
+  GTK_CURVE_TYPE_SPLINE,       /* spline interpolation */
+  GTK_CURVE_TYPE_FREE          /* free form curve */
+} GtkCurveType;
+
+struct _GtkCurve
+{
+  GtkDrawingArea graph;
+
+  gint cursor_type;
+  gfloat min_x;
+  gfloat max_x;
+  gfloat min_y;
+  gfloat max_y;
+  GdkPixmap *pixmap;
+  GtkCurveType curve_type;
+  gint height;                  /* (cached) graph height in pixels */
+  gint grab_point;              /* point currently grabbed */
+  gint last;
+
+  /* (cached) curve points: */
+  gint num_points;
+  GdkPoint *point;
+
+  /* control points: */
+  gint num_ctlpoints;           /* number of control points */
+  gfloat (*ctlpoint)[2];        /* array of control points */
+};
+
+struct _GtkCurveClass
+{
+  GtkDrawingAreaClass parent_class;
+
+  void (* curve_type_changed) (GtkCurve *curve);
+};
+
+
+guint          gtk_curve_get_type      (void);
+GtkWidget*     gtk_curve_new           (void);
+void           gtk_curve_reset         (GtkCurve *curve);
+void           gtk_curve_set_gamma     (GtkCurve *curve, gfloat gamma);
+void           gtk_curve_set_range     (GtkCurve *curve,
+                                        gfloat min_x, gfloat max_x,
+                                        gfloat min_y, gfloat max_y);
+void           gtk_curve_get_vector    (GtkCurve *curve,
+                                        int veclen, gfloat vector[]);
+void           gtk_curve_set_vector    (GtkCurve *curve,
+                                        int veclen, gfloat vector[]);
+void           gtk_curve_set_curve_type (GtkCurve *curve, GtkCurveType type);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_CURVE_H__ */
diff --git a/gtk/gtkdata.c b/gtk/gtkdata.c
new file mode 100644 (file)
index 0000000..63add29
--- /dev/null
@@ -0,0 +1,73 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkdata.h"
+#include "gtksignal.h"
+
+
+enum {
+  DISCONNECT,
+  LAST_SIGNAL
+};
+
+
+static void gtk_data_class_init (GtkDataClass *klass);
+
+
+static gint data_signals[LAST_SIGNAL] = { 0 };
+
+
+guint
+gtk_data_get_type ()
+{
+  static guint data_type = 0;
+
+  if (!data_type)
+    {
+      GtkTypeInfo data_info =
+      {
+       "GtkData",
+       sizeof (GtkData),
+       sizeof (GtkDataClass),
+       (GtkClassInitFunc) gtk_data_class_init,
+       (GtkObjectInitFunc) NULL,
+       (GtkArgFunc) NULL,
+      };
+
+      data_type = gtk_type_unique (gtk_object_get_type (), &data_info);
+    }
+
+  return data_type;
+}
+
+static void
+gtk_data_class_init (GtkDataClass *class)
+{
+  GtkObjectClass *object_class;
+
+  object_class = (GtkObjectClass*) class;
+
+  data_signals[DISCONNECT] =
+    gtk_signal_new ("disconnect",
+                    GTK_RUN_FIRST,
+                    object_class->type,
+                    GTK_SIGNAL_OFFSET (GtkDataClass, disconnect),
+                    gtk_signal_default_marshaller,
+                   GTK_TYPE_NONE, 0);
+
+  gtk_object_class_add_signals (object_class, data_signals, LAST_SIGNAL);
+}
diff --git a/gtk/gtkdata.h b/gtk/gtkdata.h
new file mode 100644 (file)
index 0000000..2e9d30b
--- /dev/null
@@ -0,0 +1,60 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_DATA_H__
+#define __GTK_DATA_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkobject.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_DATA(obj)          GTK_CHECK_CAST (obj, gtk_data_get_type (), GtkData)
+#define GTK_DATA_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_data_get_type (), GtkDataClass)
+#define GTK_IS_DATA(obj)       GTK_CHECK_TYPE (obj, gtk_data_get_type ())
+
+
+typedef struct _GtkData       GtkData;
+typedef struct _GtkDataClass  GtkDataClass;
+
+struct _GtkData
+{
+  GtkObject object;
+};
+
+struct _GtkDataClass
+{
+  GtkObjectClass parent_class;
+
+  void (* disconnect) (GtkData *data);
+};
+
+
+guint gtk_data_get_type (void);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_DATA_H__ */
diff --git a/gtk/gtkdialog.c b/gtk/gtkdialog.c
new file mode 100644 (file)
index 0000000..55da2d1
--- /dev/null
@@ -0,0 +1,80 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkbutton.h"
+#include "gtkdialog.h"
+#include "gtkhbox.h"
+#include "gtkhseparator.h"
+#include "gtkvbox.h"
+
+
+static void gtk_dialog_class_init (GtkDialogClass *klass);
+static void gtk_dialog_init       (GtkDialog      *dialog);
+
+
+guint
+gtk_dialog_get_type ()
+{
+  static guint dialog_type = 0;
+
+  if (!dialog_type)
+    {
+      GtkTypeInfo dialog_info =
+      {
+       "GtkDialog",
+       sizeof (GtkDialog),
+       sizeof (GtkDialogClass),
+       (GtkClassInitFunc) gtk_dialog_class_init,
+       (GtkObjectInitFunc) gtk_dialog_init,
+       (GtkArgFunc) NULL,
+      };
+
+      dialog_type = gtk_type_unique (gtk_window_get_type (), &dialog_info);
+    }
+
+  return dialog_type;
+}
+
+static void
+gtk_dialog_class_init (GtkDialogClass *class)
+{
+}
+
+static void
+gtk_dialog_init (GtkDialog *dialog)
+{
+  GtkWidget *separator;
+
+  dialog->vbox = gtk_vbox_new (FALSE, 0);
+  gtk_container_add (GTK_CONTAINER (dialog), dialog->vbox);
+  gtk_widget_show (dialog->vbox);
+
+  dialog->action_area = gtk_hbox_new (TRUE, 5);
+  gtk_container_border_width (GTK_CONTAINER (dialog->action_area), 10);
+  gtk_box_pack_end (GTK_BOX (dialog->vbox), dialog->action_area, FALSE, TRUE, 0);
+  gtk_widget_show (dialog->action_area);
+
+  separator = gtk_hseparator_new ();
+  gtk_box_pack_end (GTK_BOX (dialog->vbox), separator, FALSE, TRUE, 0);
+  gtk_widget_show (separator);
+}
+
+GtkWidget*
+gtk_dialog_new ()
+{
+  return GTK_WIDGET (gtk_type_new (gtk_dialog_get_type ()));
+}
diff --git a/gtk/gtkdialog.h b/gtk/gtkdialog.h
new file mode 100644 (file)
index 0000000..1396996
--- /dev/null
@@ -0,0 +1,64 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_DIALOG_H__
+#define __GTK_DIALOG_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkwindow.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_DIALOG(obj)          GTK_CHECK_CAST (obj, gtk_dialog_get_type (), GtkDialog)
+#define GTK_DIALOG_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_dialog_get_type (), GtkDialogClass)
+#define GTK_IS_DIALOG(obj)       GTK_CHECK_TYPE (obj, gtk_dialog_get_type ())
+
+
+typedef struct _GtkDialog        GtkDialog;
+typedef struct _GtkDialogClass   GtkDialogClass;
+typedef struct _GtkDialogButton  GtkDialogButton;
+
+
+struct _GtkDialog
+{
+  GtkWindow window;
+
+  GtkWidget *vbox;
+  GtkWidget *action_area;
+};
+
+struct _GtkDialogClass
+{
+  GtkWindowClass parent_class;
+};
+
+
+guint      gtk_dialog_get_type (void);
+GtkWidget* gtk_dialog_new      (void);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_DIALOG_H__ */
diff --git a/gtk/gtkdrawingarea.c b/gtk/gtkdrawingarea.c
new file mode 100644 (file)
index 0000000..3220446
--- /dev/null
@@ -0,0 +1,146 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkdrawingarea.h"
+
+
+static void gtk_drawing_area_class_init    (GtkDrawingAreaClass *klass);
+static void gtk_drawing_area_init          (GtkDrawingArea      *darea);
+static void gtk_drawing_area_realize       (GtkWidget           *widget);
+static void gtk_drawing_area_size_allocate (GtkWidget           *widget,
+                                           GtkAllocation       *allocation);
+
+
+guint
+gtk_drawing_area_get_type ()
+{
+  static guint drawing_area_type = 0;
+
+  if (!drawing_area_type)
+    {
+      GtkTypeInfo drawing_area_info =
+      {
+       "GtkDrawingArea",
+       sizeof (GtkDrawingArea),
+       sizeof (GtkDrawingAreaClass),
+       (GtkClassInitFunc) gtk_drawing_area_class_init,
+       (GtkObjectInitFunc) gtk_drawing_area_init,
+       (GtkArgFunc) NULL,
+      };
+
+      drawing_area_type = gtk_type_unique (gtk_widget_get_type (), &drawing_area_info);
+    }
+
+  return drawing_area_type;
+}
+
+static void
+gtk_drawing_area_class_init (GtkDrawingAreaClass *class)
+{
+  GtkWidgetClass *widget_class;
+
+  widget_class = (GtkWidgetClass*) class;
+
+  widget_class->realize = gtk_drawing_area_realize;
+  widget_class->size_allocate = gtk_drawing_area_size_allocate;
+}
+
+static void
+gtk_drawing_area_init (GtkDrawingArea *darea)
+{
+  GTK_WIDGET_SET_FLAGS (darea, GTK_BASIC);
+}
+
+
+GtkWidget*
+gtk_drawing_area_new ()
+{
+  return GTK_WIDGET (gtk_type_new (gtk_drawing_area_get_type ()));
+}
+
+void
+gtk_drawing_area_size (GtkDrawingArea *darea,
+                      gint            width,
+                      gint            height)
+{
+  g_return_if_fail (darea != NULL);
+  g_return_if_fail (GTK_IS_DRAWING_AREA (darea));
+
+  GTK_WIDGET (darea)->requisition.width = width;
+  GTK_WIDGET (darea)->requisition.height = height;
+}
+
+static void
+gtk_drawing_area_realize (GtkWidget *widget)
+{
+  GtkDrawingArea *darea;
+  GdkWindowAttr attributes;
+  gint attributes_mask;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_DRAWING_AREA (widget));
+
+  darea = GTK_DRAWING_AREA (widget);
+  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+
+  attributes.window_type = GDK_WINDOW_CHILD;
+  attributes.x = widget->allocation.x;
+  attributes.y = widget->allocation.y;
+  attributes.width = widget->allocation.width;
+  attributes.height = widget->allocation.height;
+  attributes.wclass = GDK_INPUT_OUTPUT;
+  attributes.visual = gtk_widget_get_visual (widget);
+  attributes.colormap = gtk_widget_get_colormap (widget);
+  attributes.event_mask = gtk_widget_get_events (widget);
+
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+
+  widget->window = gdk_window_new (widget->parent->window, &attributes, attributes_mask);
+  gdk_window_set_user_data (widget->window, darea);
+
+  widget->style = gtk_style_attach (widget->style, widget->window);
+  gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
+}
+
+static void
+gtk_drawing_area_size_allocate (GtkWidget     *widget,
+                               GtkAllocation *allocation)
+{
+  GdkEventConfigure event;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_DRAWING_AREA (widget));
+  g_return_if_fail (allocation != NULL);
+
+  widget->allocation = *allocation;
+
+  if (GTK_WIDGET_REALIZED (widget))
+    {
+      gdk_window_move_resize (widget->window,
+                             allocation->x, allocation->y,
+                             allocation->width, allocation->height);
+
+      event.type = GDK_CONFIGURE;
+      event.window = widget->window;
+      event.x = allocation->x;
+      event.y = allocation->y;
+      event.width = allocation->width;
+      event.height = allocation->height;
+
+      gtk_widget_event (widget, (GdkEvent*) &event);
+    }
+}
diff --git a/gtk/gtkdrawingarea.h b/gtk/gtkdrawingarea.h
new file mode 100644 (file)
index 0000000..d11445b
--- /dev/null
@@ -0,0 +1,62 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_DRAWING_AREA_H__
+#define __GTK_DRAWING_AREA_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkwidget.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_DRAWING_AREA(obj)          GTK_CHECK_CAST (obj, gtk_drawing_area_get_type (), GtkDrawingArea)
+#define GTK_DRAWING_AREA_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_drawing_area_get_type (), GtkDrawingAreaClass)
+#define GTK_IS_DRAWING_AREA(obj)       GTK_CHECK_TYPE (obj, gtk_drawing_area_get_type ())
+
+
+typedef struct _GtkDrawingArea       GtkDrawingArea;
+typedef struct _GtkDrawingAreaClass  GtkDrawingAreaClass;
+
+struct _GtkDrawingArea
+{
+  GtkWidget widget;
+};
+
+struct _GtkDrawingAreaClass
+{
+  GtkWidgetClass parent_class;
+};
+
+
+guint      gtk_drawing_area_get_type   (void);
+GtkWidget* gtk_drawing_area_new        (void);
+void       gtk_drawing_area_size       (GtkDrawingArea      *darea,
+                                       gint                 width,
+                                       gint                 height);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_DRAWING_AREA_H__ */
diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c
new file mode 100644 (file)
index 0000000..b9c25f6
--- /dev/null
@@ -0,0 +1,1678 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <ctype.h>
+#include <string.h>
+#include "gdk/gdkkeysyms.h"
+#include "gtkentry.h"
+#include "gtkmain.h"
+#include "gtkselection.h"
+#include "gtksignal.h"
+
+#define MIN_ENTRY_WIDTH  150
+#define DRAW_TIMEOUT     20
+#define INNER_BORDER     2
+
+
+enum {
+  INSERT_TEXT,
+  DELETE_TEXT,
+  CHANGED,
+  SET_TEXT,
+  ACTIVATE,
+  LAST_SIGNAL
+};
+
+
+typedef void (*GtkTextFunction) (GtkEntry  *entry);
+typedef void (*GtkEntrySignal1) (GtkObject *object,
+                                gpointer   arg1,
+                                gint       arg2,
+                                gpointer   arg3,
+                                gpointer   data);
+typedef void (*GtkEntrySignal2) (GtkObject *object,
+                                gint       arg1,
+                                gint       arg2,
+                                gpointer   data);
+
+
+static void gtk_entry_marshal_signal_1     (GtkObject         *object,
+                                           GtkSignalFunc      func,
+                                           gpointer           func_data,
+                                           GtkArg            *args);
+static void gtk_entry_marshal_signal_2     (GtkObject         *object,
+                                           GtkSignalFunc      func,
+                                           gpointer           func_data,
+                                           GtkArg            *args);
+
+static void gtk_entry_class_init          (GtkEntryClass     *klass);
+static void gtk_entry_init                (GtkEntry          *entry);
+static void gtk_entry_destroy             (GtkObject         *object);
+static void gtk_entry_realize             (GtkWidget         *widget);
+static void gtk_entry_unrealize           (GtkWidget         *widget);
+static void gtk_entry_draw_focus          (GtkWidget         *widget);
+static void gtk_entry_size_request        (GtkWidget         *widget,
+                                          GtkRequisition    *requisition);
+static void gtk_entry_size_allocate       (GtkWidget         *widget,
+                                          GtkAllocation     *allocation);
+static void gtk_entry_draw                (GtkWidget         *widget,
+                                          GdkRectangle      *area);
+static gint gtk_entry_expose              (GtkWidget         *widget,
+                                          GdkEventExpose    *event);
+static gint gtk_entry_button_press        (GtkWidget         *widget,
+                                          GdkEventButton    *event);
+static gint gtk_entry_button_release      (GtkWidget         *widget,
+                                          GdkEventButton    *event);
+static gint gtk_entry_motion_notify       (GtkWidget         *widget,
+                                          GdkEventMotion    *event);
+static gint gtk_entry_key_press           (GtkWidget         *widget,
+                                          GdkEventKey       *event);
+static gint gtk_entry_focus_in            (GtkWidget         *widget,
+                                          GdkEventFocus     *event);
+static gint gtk_entry_focus_out           (GtkWidget         *widget,
+                                          GdkEventFocus     *event);
+static gint gtk_entry_selection_clear     (GtkWidget         *widget,
+                                          GdkEventSelection *event);
+static void gtk_entry_selection_handler   (GtkWidget    *widget,
+                                          GtkSelectionData  *selection_data,
+                                          gpointer      data);
+static void gtk_entry_selection_received  (GtkWidget         *widget,
+                                          GtkSelectionData  *selection_data);
+static void gtk_entry_draw_text           (GtkEntry          *entry);
+static void gtk_entry_draw_cursor         (GtkEntry          *entry);
+static void gtk_entry_queue_draw          (GtkEntry          *entry);
+static gint gtk_entry_timer               (gpointer           data);
+static gint gtk_entry_position            (GtkEntry          *entry,
+                                          gint               x);
+       void gtk_entry_adjust_scroll       (GtkEntry          *entry);
+static void gtk_entry_grow_text           (GtkEntry          *entry);
+static void gtk_entry_insert_text         (GtkEntry          *entry,
+                                          const gchar       *new_text,
+                                          gint               new_text_length,
+                                          gint              *position);
+static void gtk_entry_delete_text         (GtkEntry          *entry,
+                                          gint               start_pos,
+                                          gint               end_pos);
+static void gtk_real_entry_insert_text    (GtkEntry          *entry,
+                                          const gchar       *new_text,
+                                          gint               new_text_length,
+                                          gint              *position);
+static void gtk_real_entry_delete_text    (GtkEntry          *entry,
+                                          gint               start_pos,
+                                          gint               end_pos);
+
+static void gtk_move_forward_character    (GtkEntry          *entry);
+static void gtk_move_backward_character   (GtkEntry          *entry);
+static void gtk_move_forward_word         (GtkEntry          *entry);
+static void gtk_move_backward_word        (GtkEntry          *entry);
+static void gtk_move_beginning_of_line    (GtkEntry          *entry);
+static void gtk_move_end_of_line          (GtkEntry          *entry);
+static void gtk_delete_forward_character  (GtkEntry          *entry);
+static void gtk_delete_backward_character (GtkEntry          *entry);
+static void gtk_delete_forward_word       (GtkEntry          *entry);
+static void gtk_delete_backward_word      (GtkEntry          *entry);
+static void gtk_delete_line               (GtkEntry          *entry);
+static void gtk_delete_to_line_end        (GtkEntry          *entry);
+static void gtk_delete_selection          (GtkEntry          *entry);
+static void gtk_select_word               (GtkEntry          *entry);
+static void gtk_select_line               (GtkEntry          *entry);
+static void gtk_select_region             (GtkEntry          *entry,
+                                          gint               start,
+                                          gint               end);
+
+
+static GtkWidgetClass *parent_class = NULL;
+static gint entry_signals[LAST_SIGNAL] = { 0 };
+
+static GtkTextFunction control_keys[26] =
+{
+  gtk_move_beginning_of_line,    /* a */
+  gtk_move_backward_character,   /* b */
+  NULL,                          /* c */
+  gtk_delete_forward_character,  /* d */
+  gtk_move_end_of_line,          /* e */
+  gtk_move_forward_character,    /* f */
+  NULL,                          /* g */
+  NULL,                          /* h */
+  NULL,                          /* i */
+  NULL,                          /* j */
+  gtk_delete_to_line_end,        /* k */
+  NULL,                          /* l */
+  NULL,                          /* m */
+  NULL,                          /* n */
+  NULL,                          /* o */
+  NULL,                          /* p */
+  NULL,                          /* q */
+  NULL,                          /* r */
+  NULL,                          /* s */
+  NULL,                          /* t */
+  gtk_delete_line,               /* u */
+  NULL,                          /* v */
+  gtk_delete_backward_word,      /* w */
+  NULL,                          /* x */
+  NULL,                          /* y */
+  NULL,                          /* z */
+};
+
+static GtkTextFunction alt_keys[26] =
+{
+  NULL,                          /* a */
+  gtk_move_backward_word,        /* b */
+  NULL,                          /* c */
+  gtk_delete_forward_word,       /* d */
+  NULL,                          /* e */
+  gtk_move_forward_word,         /* f */
+  NULL,                          /* g */
+  NULL,                          /* h */
+  NULL,                          /* i */
+  NULL,                          /* j */
+  NULL,                          /* k */
+  NULL,                          /* l */
+  NULL,                          /* m */
+  NULL,                          /* n */
+  NULL,                          /* o */
+  NULL,                          /* p */
+  NULL,                          /* q */
+  NULL,                          /* r */
+  NULL,                          /* s */
+  NULL,                          /* t */
+  NULL,                          /* u */
+  NULL,                          /* v */
+  NULL,                          /* w */
+  NULL,                          /* x */
+  NULL,                          /* y */
+  NULL,                          /* z */
+};
+
+
+guint
+gtk_entry_get_type ()
+{
+  static guint entry_type = 0;
+
+  if (!entry_type)
+    {
+      GtkTypeInfo entry_info =
+      {
+       "GtkEntry",
+       sizeof (GtkEntry),
+       sizeof (GtkEntryClass),
+       (GtkClassInitFunc) gtk_entry_class_init,
+       (GtkObjectInitFunc) gtk_entry_init,
+       (GtkArgFunc) NULL,
+      };
+
+      entry_type = gtk_type_unique (gtk_widget_get_type (), &entry_info);
+    }
+
+  return entry_type;
+}
+
+static void
+gtk_entry_class_init (GtkEntryClass *class)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+
+  object_class = (GtkObjectClass*) class;
+  widget_class = (GtkWidgetClass*) class;
+
+  parent_class = gtk_type_class (gtk_widget_get_type ());
+
+  entry_signals[INSERT_TEXT] =
+    gtk_signal_new ("insert_text",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkEntryClass, insert_text),
+                   gtk_entry_marshal_signal_1,
+                   GTK_TYPE_NONE, 3,
+                   GTK_TYPE_STRING, GTK_TYPE_INT,
+                   GTK_TYPE_POINTER);
+  entry_signals[DELETE_TEXT] =
+    gtk_signal_new ("delete_text",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkEntryClass, delete_text),
+                   gtk_entry_marshal_signal_2,
+                   GTK_TYPE_NONE, 2,
+                   GTK_TYPE_INT, GTK_TYPE_INT);
+  entry_signals[CHANGED] =
+    gtk_signal_new ("changed",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkEntryClass, changed),
+                   gtk_signal_default_marshaller,
+                   GTK_TYPE_NONE, 0);
+  entry_signals[SET_TEXT] =
+    gtk_signal_new ("set_text",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkEntryClass, set_text),
+                   gtk_signal_default_marshaller,
+                   GTK_TYPE_NONE, 0);
+  entry_signals[ACTIVATE] =
+    gtk_signal_new ("activate",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkEntryClass, activate),
+                   gtk_signal_default_marshaller,
+                   GTK_TYPE_NONE, 0);
+
+  gtk_object_class_add_signals (object_class, entry_signals, LAST_SIGNAL);
+
+  object_class->destroy = gtk_entry_destroy;
+
+  widget_class->realize = gtk_entry_realize;
+  widget_class->unrealize = gtk_entry_unrealize;
+  widget_class->draw_focus = gtk_entry_draw_focus;
+  widget_class->size_request = gtk_entry_size_request;
+  widget_class->size_allocate = gtk_entry_size_allocate;
+  widget_class->draw = gtk_entry_draw;
+  widget_class->expose_event = gtk_entry_expose;
+  widget_class->button_press_event = gtk_entry_button_press;
+  widget_class->button_release_event = gtk_entry_button_release;
+  widget_class->motion_notify_event = gtk_entry_motion_notify;
+  widget_class->key_press_event = gtk_entry_key_press;
+  widget_class->focus_in_event = gtk_entry_focus_in;
+  widget_class->focus_out_event = gtk_entry_focus_out;
+  widget_class->selection_clear_event = gtk_entry_selection_clear;
+  widget_class->selection_received = gtk_entry_selection_received;
+
+  class->insert_text = gtk_real_entry_insert_text;
+  class->delete_text = gtk_real_entry_delete_text;
+  class->changed = gtk_entry_adjust_scroll;
+  class->set_text = NULL;        /* user defined handling */
+  class->activate = NULL;        /* user defined handling */
+}
+
+static void
+gtk_entry_init (GtkEntry *entry)
+{
+  static GdkAtom text_atom = GDK_NONE;
+
+  GTK_WIDGET_SET_FLAGS (entry, GTK_CAN_FOCUS);
+
+  entry->text_area = NULL;
+  entry->text = NULL;
+  entry->text_size = 0;
+  entry->text_length = 0;
+  entry->current_pos = 0;
+  entry->selection_start_pos = 0;
+  entry->selection_end_pos = 0;
+  entry->scroll_offset = 0;
+  entry->have_selection = FALSE;
+  entry->timer = 0;
+  entry->visible = 1;
+
+  gtk_selection_add_handler (GTK_WIDGET(entry), GDK_SELECTION_PRIMARY,
+                            GDK_TARGET_STRING, gtk_entry_selection_handler,
+                            NULL, NULL);
+
+  if (!text_atom)
+    text_atom = gdk_atom_intern ("TEXT", FALSE);
+
+  gtk_selection_add_handler (GTK_WIDGET(entry), GDK_SELECTION_PRIMARY,
+                            text_atom,
+                            gtk_entry_selection_handler,
+                            NULL, NULL);
+}
+
+GtkWidget*
+gtk_entry_new ()
+{
+  return GTK_WIDGET (gtk_type_new (gtk_entry_get_type ()));
+}
+
+void
+gtk_entry_set_text (GtkEntry *entry,
+                   const gchar *text)
+{
+  gint tmp_pos;
+
+  g_return_if_fail (entry != NULL);
+  g_return_if_fail (GTK_IS_ENTRY (entry));
+
+  gtk_real_entry_delete_text (entry, 0, entry->text_length);
+
+  tmp_pos = 0;
+  gtk_entry_insert_text (entry, text, strlen (text), &tmp_pos);
+  entry->current_pos = tmp_pos;
+
+  entry->selection_start_pos = 0;
+  entry->selection_end_pos = 0;
+
+  if (GTK_WIDGET_DRAWABLE (entry))
+    gtk_entry_draw_text (entry);
+
+  gtk_signal_emit (GTK_OBJECT (entry), entry_signals[SET_TEXT]);
+}
+
+void
+gtk_entry_append_text (GtkEntry *entry,
+                      const gchar *text)
+{
+  gint tmp_pos;
+
+  g_return_if_fail (entry != NULL);
+  g_return_if_fail (GTK_IS_ENTRY (entry));
+
+  tmp_pos = entry->text_length;
+  gtk_entry_insert_text (entry, text, strlen (text), &tmp_pos);
+  entry->current_pos = tmp_pos;
+
+  gtk_signal_emit (GTK_OBJECT (entry), entry_signals[SET_TEXT]);
+}
+
+void
+gtk_entry_prepend_text (GtkEntry *entry,
+                       const gchar *text)
+{
+  gint tmp_pos;
+
+  g_return_if_fail (entry != NULL);
+  g_return_if_fail (GTK_IS_ENTRY (entry));
+
+  tmp_pos = 0;
+  gtk_entry_insert_text (entry, text, strlen (text), &tmp_pos);
+  entry->current_pos = tmp_pos;
+
+  gtk_signal_emit (GTK_OBJECT (entry), entry_signals[SET_TEXT]);
+}
+
+void
+gtk_entry_set_position (GtkEntry *entry,
+                       gint      position)
+{
+  g_return_if_fail (entry != NULL);
+  g_return_if_fail (GTK_IS_ENTRY (entry));
+
+  if ((position == -1) || (position > entry->text_length))
+    entry->current_pos = entry->text_length;
+  else
+    entry->current_pos = position;
+}
+
+void
+gtk_entry_set_visibility (GtkEntry *entry,
+        gint      visible)
+{
+  g_return_if_fail (entry != NULL);
+  g_return_if_fail (GTK_IS_ENTRY (entry));
+
+  entry->visible = visible;
+}
+
+gchar*
+gtk_entry_get_text (GtkEntry *entry)
+{
+  static char empty_str[2] = "";
+
+  g_return_val_if_fail (entry != NULL, NULL);
+  g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
+
+  if (!entry->text)
+    return empty_str;
+  return entry->text;
+}
+
+
+static void
+gtk_entry_marshal_signal_1 (GtkObject      *object,
+                           GtkSignalFunc   func,
+                           gpointer        func_data,
+                           GtkArg         *args)
+{
+  GtkEntrySignal1 rfunc;
+
+  rfunc = (GtkEntrySignal1) func;
+
+  (* rfunc) (object, GTK_VALUE_STRING (args[0]), GTK_VALUE_INT (args[1]),
+            GTK_VALUE_POINTER (args[2]), func_data);
+}
+
+static void
+gtk_entry_marshal_signal_2 (GtkObject      *object,
+                           GtkSignalFunc   func,
+                           gpointer        func_data,
+                           GtkArg         *args)
+{
+  GtkEntrySignal2 rfunc;
+
+  rfunc = (GtkEntrySignal2) func;
+
+  (* rfunc) (object, GTK_VALUE_INT (args[0]), GTK_VALUE_INT (args[1]),
+            func_data);
+}
+
+static void
+gtk_entry_destroy (GtkObject *object)
+{
+  GtkEntry *entry;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_ENTRY (object));
+
+  entry = GTK_ENTRY (object);
+
+  if (entry->have_selection)
+    gtk_selection_owner_set (NULL, GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME);
+
+  if (entry->timer)
+    gtk_timeout_remove (entry->timer);
+
+  if (entry->text)
+    g_free (entry->text);
+  entry->text = NULL;
+
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+gtk_entry_realize (GtkWidget *widget)
+{
+  GtkEntry *entry;
+  GdkWindowAttr attributes;
+  gint attributes_mask;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_ENTRY (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+  entry = GTK_ENTRY (widget);
+
+  attributes.window_type = GDK_WINDOW_CHILD;
+  attributes.x = widget->allocation.x;
+  attributes.y = widget->allocation.y;
+  attributes.width = widget->allocation.width;
+  attributes.height = widget->allocation.height;
+  attributes.wclass = GDK_INPUT_OUTPUT;
+  attributes.visual = gtk_widget_get_visual (widget);
+  attributes.colormap = gtk_widget_get_colormap (widget);
+  attributes.event_mask = gtk_widget_get_events (widget);
+  attributes.event_mask |= (GDK_EXPOSURE_MASK |
+                           GDK_BUTTON_PRESS_MASK |
+                           GDK_BUTTON_RELEASE_MASK |
+                           GDK_BUTTON1_MOTION_MASK |
+                           GDK_BUTTON3_MOTION_MASK |
+                           GDK_POINTER_MOTION_HINT_MASK |
+                           GDK_ENTER_NOTIFY_MASK |
+                           GDK_LEAVE_NOTIFY_MASK |
+                           GDK_KEY_PRESS_MASK);
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+
+  widget->window = gdk_window_new (widget->parent->window, &attributes, attributes_mask);
+  gdk_window_set_user_data (widget->window, entry);
+
+  attributes.x = widget->style->klass->xthickness + INNER_BORDER;
+  attributes.y = widget->style->klass->ythickness + INNER_BORDER;
+  attributes.width = widget->allocation.width - attributes.x * 2;
+  attributes.height = widget->allocation.height - attributes.y * 2;
+
+  entry->text_area = gdk_window_new (widget->window, &attributes, attributes_mask);
+  gdk_window_set_user_data (entry->text_area, entry);
+
+  widget->style = gtk_style_attach (widget->style, widget->window);
+
+  gdk_window_set_background (widget->window, &widget->style->white);
+  gdk_window_set_background (entry->text_area, &widget->style->white);
+
+  gdk_window_show (entry->text_area);
+}
+
+static void
+gtk_entry_unrealize (GtkWidget *widget)
+{
+  GtkEntry *entry;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_ENTRY (widget));
+
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED);
+  entry = GTK_ENTRY (widget);
+
+  gtk_style_detach (widget->style);
+
+  if (entry->text_area)
+    {
+      gdk_window_set_user_data (entry->text_area, NULL);
+      gdk_window_destroy (entry->text_area);
+    }
+  if (widget->window)
+    {
+      gdk_window_set_user_data (widget->window, NULL);
+      gdk_window_destroy (widget->window);
+    }
+
+  entry->text_area = NULL;
+  widget->window = NULL;
+}
+
+static void
+gtk_entry_draw_focus (GtkWidget *widget)
+{
+  gint width, height;
+  gint x, y;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_ENTRY (widget));
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      x = 0;
+      y = 0;
+      gdk_window_get_size (widget->window, &width, &height);
+
+      if (GTK_WIDGET_HAS_FOCUS (widget))
+       {
+         x += 1;
+         y += 1;
+         width -= 2;
+         height -= 2;
+       }
+      else
+       {
+         gdk_draw_rectangle (widget->window, widget->style->white_gc, FALSE,
+                             x + 2, y + 2, width - 5, height - 5);
+       }
+
+      gtk_draw_shadow (widget->style, widget->window,
+                      GTK_STATE_NORMAL, GTK_SHADOW_IN,
+                      x, y, width, height);
+
+      if (GTK_WIDGET_HAS_FOCUS (widget))
+       {
+         gdk_window_get_size (widget->window, &width, &height);
+         gdk_draw_rectangle (widget->window, widget->style->fg_gc[GTK_STATE_NORMAL],
+                             FALSE, 0, 0, width - 1, height - 1);
+       }
+
+      gtk_entry_draw_cursor (GTK_ENTRY (widget));
+    }
+}
+
+static void
+gtk_entry_size_request (GtkWidget      *widget,
+                       GtkRequisition *requisition)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_ENTRY (widget));
+  g_return_if_fail (requisition != NULL);
+
+  requisition->width = MIN_ENTRY_WIDTH + (widget->style->klass->xthickness + INNER_BORDER) * 2;
+  requisition->height = (widget->style->font->ascent +
+                        widget->style->font->descent +
+                        (widget->style->klass->ythickness + INNER_BORDER) * 2);
+}
+
+static void
+gtk_entry_size_allocate (GtkWidget     *widget,
+                        GtkAllocation *allocation)
+{
+  GtkEntry *entry;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_ENTRY (widget));
+  g_return_if_fail (allocation != NULL);
+
+  widget->allocation = *allocation;
+  entry = GTK_ENTRY (widget);
+
+  if (GTK_WIDGET_REALIZED (widget))
+    {
+      gdk_window_move_resize (widget->window,
+                             allocation->x,
+                             allocation->y + (allocation->height - widget->requisition.height) / 2,
+                             allocation->width, widget->requisition.height);
+      gdk_window_move_resize (entry->text_area,
+                             widget->style->klass->xthickness + INNER_BORDER,
+                             widget->style->klass->ythickness + INNER_BORDER,
+                             allocation->width - (widget->style->klass->xthickness + INNER_BORDER) * 2,
+                             widget->requisition.height - (widget->style->klass->ythickness + INNER_BORDER) * 2);
+
+      entry->scroll_offset = 0;
+      gtk_entry_adjust_scroll (entry);
+    }
+}
+
+static void
+gtk_entry_draw (GtkWidget    *widget,
+               GdkRectangle *area)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_ENTRY (widget));
+  g_return_if_fail (area != NULL);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      gtk_widget_draw_focus (widget);
+      gtk_entry_draw_text (GTK_ENTRY (widget));
+    }
+}
+
+static gint
+gtk_entry_expose (GtkWidget      *widget,
+                 GdkEventExpose *event)
+{
+  GtkEntry *entry;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_ENTRY (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  entry = GTK_ENTRY (widget);
+
+  if (widget->window == event->window)
+    gtk_widget_draw_focus (widget);
+  else if (entry->text_area == event->window)
+    gtk_entry_draw_text (GTK_ENTRY (widget));
+
+  return FALSE;
+}
+
+static gint
+gtk_entry_button_press (GtkWidget      *widget,
+                       GdkEventButton *event)
+{
+  GtkEntry *entry;
+  gint tmp_pos;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_ENTRY (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  entry = GTK_ENTRY (widget);
+  if (!GTK_WIDGET_HAS_FOCUS (widget))
+    gtk_widget_grab_focus (widget);
+
+  if (event->button == 1)
+    {
+      switch (event->type)
+       {
+       case GDK_BUTTON_PRESS:
+         gtk_grab_add (widget);
+
+         tmp_pos = gtk_entry_position (entry, event->x + entry->scroll_offset);
+         gtk_select_region (entry, tmp_pos, tmp_pos);
+         entry->current_pos = entry->selection_start_pos;
+         gtk_entry_queue_draw (entry);
+         break;
+
+       case GDK_2BUTTON_PRESS:
+         gtk_select_word (entry);
+         gtk_entry_queue_draw (entry);
+         break;
+
+       case GDK_3BUTTON_PRESS:
+         gtk_select_line (entry);
+         gtk_entry_queue_draw (entry);
+         break;
+
+       default:
+         break;
+       }
+    }
+  else if (event->type == GDK_BUTTON_PRESS)
+    {
+      if (event->button == 2)
+       {
+         if (entry->selection_start_pos == entry->selection_end_pos)
+           entry->current_pos = gtk_entry_position (entry, event->x + entry->scroll_offset);
+         gtk_selection_convert (widget, GDK_SELECTION_PRIMARY,
+                                GDK_TARGET_STRING, event->time);
+       }
+      else
+       {
+         gtk_grab_add (widget);
+
+         tmp_pos = gtk_entry_position (entry, event->x + entry->scroll_offset);
+         gtk_select_region (entry, tmp_pos, tmp_pos);
+         entry->have_selection = FALSE;
+         entry->current_pos = entry->selection_start_pos;
+         gtk_entry_queue_draw (entry);
+       }
+    }
+
+  return FALSE;
+}
+
+static gint
+gtk_entry_button_release (GtkWidget      *widget,
+                         GdkEventButton *event)
+{
+  GtkEntry *entry;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_ENTRY (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (event->button == 1)
+    {
+      entry = GTK_ENTRY (widget);
+      gtk_grab_remove (widget);
+
+      entry->have_selection = FALSE;
+      if (entry->selection_start_pos != entry->selection_end_pos)
+       {
+         if (gtk_selection_owner_set (widget,
+                                      GDK_SELECTION_PRIMARY,
+                                      event->time))
+           {
+             entry->have_selection = TRUE;
+             gtk_entry_queue_draw (entry);
+           }
+       }
+      else
+       {
+         if (gdk_selection_owner_get (GDK_SELECTION_PRIMARY) == widget->window)
+           gtk_selection_owner_set (NULL, GDK_SELECTION_PRIMARY, event->time);
+       }
+    }
+  else if (event->button == 3)
+    {
+      gtk_grab_remove (widget);
+      if (gdk_selection_owner_get (GDK_SELECTION_PRIMARY) == widget->window)
+       gtk_selection_owner_set (NULL, GDK_SELECTION_PRIMARY, event->time);
+    }
+
+  return FALSE;
+}
+
+static gint
+gtk_entry_motion_notify (GtkWidget      *widget,
+                        GdkEventMotion *event)
+{
+  GtkEntry *entry;
+  gint x;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_ENTRY (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  entry = GTK_ENTRY (widget);
+
+  x = event->x;
+  if (event->is_hint || (entry->text_area != event->window))
+    gdk_window_get_pointer (entry->text_area, &x, NULL, NULL);
+
+  entry->selection_end_pos = gtk_entry_position (entry, event->x + entry->scroll_offset);
+  entry->current_pos = entry->selection_end_pos;
+  gtk_entry_adjust_scroll (entry);
+  gtk_entry_queue_draw (entry);
+
+  return FALSE;
+}
+
+static gint
+gtk_entry_key_press (GtkWidget   *widget,
+                    GdkEventKey *event)
+{
+  GtkEntry *entry;
+  gint return_val;
+  gint key;
+  gint tmp_pos;
+  gchar tmp;
+  gint extend_selection;
+  gint selection_pos;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_ENTRY (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  entry = GTK_ENTRY (widget);
+  return_val = FALSE;
+  extend_selection = FALSE;
+
+  if (entry->selection_start_pos == entry->selection_end_pos)
+    selection_pos = entry->current_pos;
+  else if (entry->selection_start_pos == entry->current_pos)
+    selection_pos = entry->selection_end_pos;
+  else
+    selection_pos = entry->selection_start_pos;
+
+  switch (event->keyval)
+    {
+    case GDK_BackSpace:
+      return_val = TRUE;
+      if (entry->selection_start_pos != entry->selection_end_pos)
+       gtk_delete_selection (entry);
+      else if (event->state & GDK_CONTROL_MASK)
+       gtk_delete_backward_word (entry);
+      else
+       gtk_delete_backward_character (entry);
+      break;
+    case GDK_Clear:
+      return_val = TRUE;
+      gtk_delete_line (entry);
+      break;
+     case GDK_Insert:
+       return_val = TRUE;
+       if (event->state & GDK_SHIFT_MASK)
+        {
+          /* gtk_paste_clipboard(entry) -- NEEDS CLIPBOARD */
+        }
+       else if (event->state & GDK_CONTROL_MASK)
+        {
+          /* gtk_copy_clipboard(entry) -- NEEDS CLIPBOARD */
+        }
+       else
+        {
+          /* gtk_toggle_insert(entry) -- IMPLEMENT */
+        }
+       break;
+    case GDK_Delete:
+      return_val = TRUE;
+      if (entry->selection_start_pos != entry->selection_end_pos)
+       gtk_delete_selection (entry);
+      else
+       {
+         if (event->state & GDK_CONTROL_MASK)
+           gtk_delete_line (entry);
+         else if (event->state & GDK_SHIFT_MASK)
+           /* gtk_cut_clipboard(entry) -- NEEDS CLIPBOARD */ ;
+         else
+           gtk_delete_forward_character (entry);
+       }
+      break;
+    case GDK_Home:
+      return_val = TRUE;
+      if (event->state & GDK_SHIFT_MASK)
+       {
+         if (entry->selection_start_pos == entry->selection_end_pos)
+           entry->selection_start_pos = entry->current_pos;
+         entry->current_pos = entry->selection_end_pos = 0;
+       }
+      else
+        gtk_move_beginning_of_line (entry);
+      break;
+    case GDK_End:
+     return_val = TRUE;
+     if (event->state & GDK_SHIFT_MASK)
+       {
+        if (entry->selection_start_pos == entry->selection_end_pos)
+          entry->selection_start_pos = entry->current_pos;
+        entry->current_pos = entry->selection_end_pos = entry->text_length;
+       }
+     else
+       gtk_move_end_of_line (entry);
+     break;
+    case GDK_Left:
+     return_val = TRUE;
+     if (event->state & GDK_SHIFT_MASK)
+       {
+        if (entry->selection_start_pos == entry->selection_end_pos)
+          entry->selection_start_pos = entry->selection_end_pos = entry->current_pos;
+        if (entry->selection_end_pos > 0)
+          entry->current_pos = --entry->selection_end_pos;
+       }
+      else
+        gtk_move_backward_character (entry);
+     break;
+    case GDK_Right:
+      return_val = TRUE;
+      if (event->state & GDK_SHIFT_MASK)
+       {
+         if (entry->selection_start_pos == entry->selection_end_pos)
+           entry->selection_start_pos = entry->selection_end_pos = entry->current_pos;
+         if (entry->selection_end_pos < entry->text_length)
+           entry->current_pos = ++entry->selection_end_pos;
+       }
+      else
+        gtk_move_forward_character (entry);
+      break;
+    case GDK_Return:
+      return_val = TRUE;
+      gtk_signal_emit (GTK_OBJECT (entry), entry_signals[ACTIVATE]);
+      break;
+    default:
+      if ((event->keyval >= 0x20) && (event->keyval <= 0xFF))
+       {
+         return_val = TRUE;
+         key = event->keyval;
+
+         if (event->state & GDK_CONTROL_MASK)
+           {
+             if ((key >= 'A') && (key <= 'Z'))
+               key -= 'A' - 'a';
+
+             if ((key >= 'a') && (key <= 'z') && control_keys[key - 'a'])
+               (* control_keys[key - 'a']) (entry);
+           }
+         else if (event->state & GDK_MOD1_MASK)
+           {
+             if ((key >= 'A') && (key <= 'Z'))
+               key -= 'A' - 'a';
+
+             if ((key >= 'a') && (key <= 'z') && alt_keys[key - 'a'])
+               (* alt_keys[key - 'a']) (entry);
+           }
+         else
+           {
+             tmp = (gchar) key;
+             gtk_delete_selection (entry);
+
+             tmp_pos = entry->current_pos;
+             gtk_entry_insert_text (entry, &tmp, 1, &tmp_pos);
+             entry->current_pos = tmp_pos;
+           }
+       }
+      break;
+    }
+
+  /* alex stuff */
+  if (entry->selection_start_pos != entry->selection_end_pos)
+   {
+    if (gtk_selection_owner_set (widget, GDK_SELECTION_PRIMARY, event->time))
+     {
+      entry->have_selection = TRUE;
+      gtk_entry_queue_draw (entry);
+     }
+   }
+  else
+   {
+    if (gdk_selection_owner_get (GDK_SELECTION_PRIMARY) == widget->window)
+      gtk_selection_owner_set (NULL, GDK_SELECTION_PRIMARY, event->time);
+   }
+  /* end of alex stuff */
+
+  if (return_val)
+    {
+      gtk_entry_adjust_scroll (entry);
+      gtk_entry_queue_draw (entry);
+    }
+
+  return return_val;
+}
+
+static gint
+gtk_entry_focus_in (GtkWidget     *widget,
+                   GdkEventFocus *event)
+{
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_ENTRY (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
+  gtk_widget_draw_focus (widget);
+
+  return FALSE;
+}
+
+static gint
+gtk_entry_focus_out (GtkWidget     *widget,
+                    GdkEventFocus *event)
+{
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_ENTRY (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
+  gtk_widget_draw_focus (widget);
+
+  return FALSE;
+}
+
+static gint
+gtk_entry_selection_clear (GtkWidget         *widget,
+                          GdkEventSelection *event)
+{
+  GtkEntry *entry;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_ENTRY (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  entry = GTK_ENTRY (widget);
+
+  if (entry->have_selection)
+    {
+      entry->have_selection = FALSE;
+      gtk_entry_queue_draw (entry);
+    }
+
+  return FALSE;
+}
+
+static void
+gtk_entry_selection_handler (GtkWidget        *widget,
+                            GtkSelectionData *selection_data,
+                            gpointer          data)
+{
+  GtkEntry *entry;
+  gint selection_start_pos;
+  gint selection_end_pos;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_ENTRY (widget));
+
+  entry = GTK_ENTRY (widget);
+
+  selection_start_pos = MIN (entry->selection_start_pos, entry->selection_end_pos);
+  selection_end_pos = MAX (entry->selection_start_pos, entry->selection_end_pos);
+
+  gtk_selection_data_set (selection_data,
+                         GDK_SELECTION_TYPE_STRING,
+                         8*sizeof(gchar),
+                         &entry->text[selection_start_pos],
+                         selection_end_pos - selection_start_pos);
+}
+
+static void
+gtk_entry_selection_received  (GtkWidget         *widget,
+                              GtkSelectionData  *selection_data)
+{
+  GtkEntry *entry;
+  gint reselect;
+  gint tmp_pos;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_ENTRY (widget));
+
+  entry = GTK_ENTRY (widget);
+
+  if (selection_data->length < 0)
+    return ;
+
+  if (selection_data->target == GDK_TARGET_STRING)
+    {
+      reselect = FALSE;
+      if (entry->selection_start_pos != entry->selection_end_pos)
+       {
+         reselect = TRUE;
+         gtk_delete_selection (entry);
+       }
+
+      tmp_pos = entry->current_pos;
+
+      selection_data->data[selection_data->length] = 0;
+      gtk_entry_insert_text (entry, selection_data->data,
+                            strlen (selection_data->data), &tmp_pos);
+
+      if (reselect)
+       {
+         reselect = entry->have_selection;
+         gtk_select_region (entry, entry->current_pos, tmp_pos);
+         entry->have_selection = reselect;
+       }
+
+      entry->current_pos = tmp_pos;
+
+      gtk_entry_queue_draw (entry);
+    }
+}
+
+static void
+gtk_entry_draw_text (GtkEntry *entry)
+{
+  GtkWidget *widget;
+  GtkStateType selected_state;
+  gint selection_start_pos;
+  gint selection_end_pos;
+  gint selection_start_xoffset;
+  gint selection_end_xoffset;
+  gint width, height;
+  gint y;
+
+  g_return_if_fail (entry != NULL);
+  g_return_if_fail (GTK_IS_ENTRY (entry));
+
+  if (entry->timer)
+    {
+      gtk_timeout_remove (entry->timer);
+      entry->timer = 0;
+    }
+
+  if (!entry->visible)
+    {
+      gtk_entry_draw_cursor (entry);
+      return;
+    }
+
+  if (GTK_WIDGET_DRAWABLE (entry))
+    {
+      widget = GTK_WIDGET (entry);
+
+      gdk_window_clear (entry->text_area);
+
+      if (entry->text)
+       {
+         gdk_window_get_size (entry->text_area, &width, &height);
+         y = (height - (widget->style->font->ascent + widget->style->font->descent)) / 2;
+         y += widget->style->font->ascent;
+
+          if (entry->selection_start_pos != entry->selection_end_pos)
+            {
+             selected_state = GTK_STATE_SELECTED;
+             if (!entry->have_selection)
+               selected_state = GTK_STATE_ACTIVE;
+
+              selection_start_pos = MIN (entry->selection_start_pos, entry->selection_end_pos);
+              selection_end_pos = MAX (entry->selection_start_pos, entry->selection_end_pos);
+
+              selection_start_xoffset = gdk_text_width (widget->style->font,
+                                                       entry->text,
+                                                       selection_start_pos);
+              selection_end_xoffset = gdk_text_width (widget->style->font,
+                                                     entry->text,
+                                                     selection_end_pos);
+
+              if (selection_start_pos > 0)
+                gdk_draw_text (entry->text_area, widget->style->font,
+                               widget->style->fg_gc[GTK_STATE_NORMAL],
+                               -entry->scroll_offset, y,
+                               entry->text, selection_start_pos);
+
+              gdk_draw_rectangle (entry->text_area,
+                                  widget->style->bg_gc[selected_state],
+                                  TRUE,
+                                  -entry->scroll_offset + selection_start_xoffset,
+                                  0,
+                                  selection_end_xoffset - selection_start_xoffset,
+                                  -1);
+
+              gdk_draw_text (entry->text_area, widget->style->font,
+                             widget->style->fg_gc[selected_state],
+                             -entry->scroll_offset + selection_start_xoffset, y,
+                             entry->text + selection_start_pos,
+                             selection_end_pos - selection_start_pos);
+
+              if (selection_end_pos < entry->text_length)
+                gdk_draw_string (entry->text_area, widget->style->font,
+                                 widget->style->fg_gc[GTK_STATE_NORMAL],
+                                 -entry->scroll_offset + selection_end_xoffset, y,
+                                 entry->text + selection_end_pos);
+           }
+          else
+            {
+             GdkGCValues values;
+
+             gdk_gc_get_values (widget->style->fg_gc[GTK_STATE_NORMAL], &values);
+              gdk_draw_string (entry->text_area, widget->style->font,
+                               widget->style->fg_gc[GTK_STATE_NORMAL],
+                               -entry->scroll_offset, y,
+                               entry->text);
+            }
+       }
+
+      gtk_entry_draw_cursor (entry);
+    }
+}
+
+static void
+gtk_entry_draw_cursor (GtkEntry *entry)
+{
+  GtkWidget *widget;
+  GdkGC *gc;
+  gint xoffset;
+  gint text_area_height;
+
+  g_return_if_fail (entry != NULL);
+  g_return_if_fail (GTK_IS_ENTRY (entry));
+
+  if (GTK_WIDGET_DRAWABLE (entry))
+    {
+      widget = GTK_WIDGET (entry);
+
+      if (entry->current_pos > 0 && entry->visible)
+       xoffset = gdk_text_width (widget->style->font, entry->text, entry->current_pos);
+      else
+       xoffset = 0;
+      xoffset -= entry->scroll_offset;
+
+      if (GTK_WIDGET_HAS_FOCUS (widget) &&
+         (entry->selection_start_pos == entry->selection_end_pos))
+       gc = widget->style->fg_gc[GTK_STATE_NORMAL];
+      else
+       gc = widget->style->white_gc;
+
+      gdk_window_get_size (entry->text_area, &text_area_height, NULL);
+      gdk_draw_line (entry->text_area, gc, xoffset, 0, xoffset, text_area_height);
+    }
+}
+
+static void
+gtk_entry_queue_draw (GtkEntry *entry)
+{
+  g_return_if_fail (entry != NULL);
+  g_return_if_fail (GTK_IS_ENTRY (entry));
+
+  if (!entry->timer)
+    entry->timer = gtk_timeout_add (DRAW_TIMEOUT, gtk_entry_timer, entry);
+}
+
+static gint
+gtk_entry_timer (gpointer data)
+{
+  GtkEntry *entry;
+
+  g_return_val_if_fail (data != NULL, FALSE);
+
+  entry = GTK_ENTRY (data);
+  entry->timer = 0;
+  gtk_entry_draw_text (entry);
+
+  return FALSE;
+}
+
+static gint
+gtk_entry_position (GtkEntry *entry,
+                   gint      x)
+{
+  gint return_val;
+  gint char_width;
+  gint sum;
+  gint i;
+
+  g_return_val_if_fail (entry != NULL, 0);
+  g_return_val_if_fail (GTK_IS_ENTRY (entry), 0);
+
+  i = 0;
+  sum = 0;
+
+  if (x > sum)
+    {
+      for (; i < entry->text_length; i++)
+       {
+         char_width = gdk_char_width (GTK_WIDGET (entry)->style->font, entry->text[i]);
+
+         if (x < (sum + char_width / 2))
+           break;
+         sum += char_width;
+       }
+    }
+
+  return_val = i;
+
+  return return_val;
+}
+
+void
+gtk_entry_adjust_scroll (GtkEntry *entry)
+{
+  gint xoffset;
+  gint text_area_width;
+
+  g_return_if_fail (entry != NULL);
+  g_return_if_fail (GTK_IS_ENTRY (entry));
+
+  if (!entry->text_area)
+    return;
+
+  gdk_window_get_size (entry->text_area, &text_area_width, NULL);
+
+  if (entry->current_pos > 0)
+    xoffset = gdk_text_width (GTK_WIDGET (entry)->style->font, entry->text, entry->current_pos);
+  else
+    xoffset = 0;
+  xoffset -= entry->scroll_offset;
+
+  if (xoffset < 0)
+    entry->scroll_offset += xoffset;
+  else if (xoffset > text_area_width)
+    entry->scroll_offset += (xoffset - text_area_width) + 1;
+}
+
+static void
+gtk_entry_grow_text (GtkEntry *entry)
+{
+  gint previous_size;
+  gint i;
+
+  g_return_if_fail (entry != NULL);
+  g_return_if_fail (GTK_IS_ENTRY (entry));
+
+  previous_size = entry->text_size;
+  if (!entry->text_size)
+    entry->text_size = 128;
+  else
+    entry->text_size *= 2;
+  entry->text = g_realloc (entry->text, entry->text_size);
+
+  for (i = previous_size; i < entry->text_size; i++)
+    entry->text[i] = '\0';
+}
+
+static void
+gtk_entry_insert_text (GtkEntry *entry,
+                      const gchar *new_text,
+                      gint      new_text_length,
+                      gint     *position)
+{
+  gchar buf[64];
+  gchar *text;
+
+  g_return_if_fail (entry != NULL);
+  g_return_if_fail (GTK_IS_ENTRY (entry));
+
+  if (new_text_length <= 64)
+    text = buf;
+  else
+    text = g_new (gchar, new_text_length);
+
+  strncpy (text, new_text, new_text_length);
+
+  gtk_signal_emit (GTK_OBJECT (entry), entry_signals[INSERT_TEXT],
+                  text, new_text_length, position);
+  gtk_signal_emit (GTK_OBJECT (entry), entry_signals[CHANGED]);
+
+  if (new_text_length > 64)
+    g_free (text);
+}
+
+static void
+gtk_entry_delete_text (GtkEntry *entry,
+                      gint      start_pos,
+                      gint      end_pos)
+{
+  g_return_if_fail (entry != NULL);
+  g_return_if_fail (GTK_IS_ENTRY (entry));
+
+  gtk_signal_emit (GTK_OBJECT (entry), entry_signals[DELETE_TEXT],
+                  start_pos, end_pos);
+  gtk_signal_emit (GTK_OBJECT (entry), entry_signals[CHANGED]);
+}
+
+static void
+gtk_real_entry_insert_text (GtkEntry *entry,
+                           const gchar *new_text,
+                           gint      new_text_length,
+                           gint     *position)
+{
+  gchar *text;
+  gint start_pos;
+  gint end_pos;
+  gint last_pos;
+  gint i;
+
+  g_return_if_fail (entry != NULL);
+  g_return_if_fail (GTK_IS_ENTRY (entry));
+
+  start_pos = *position;
+  end_pos = start_pos + new_text_length;
+  last_pos = new_text_length + entry->text_length;
+
+  while (last_pos >= entry->text_size)
+    gtk_entry_grow_text (entry);
+
+  text = entry->text;
+  for (i = last_pos - 1; i >= end_pos; i--)
+    text[i] = text[i- (end_pos - start_pos)];
+  for (i = start_pos; i < end_pos; i++)
+    text[i] = new_text[i - start_pos];
+
+  entry->text_length += new_text_length;
+  *position = end_pos;
+}
+
+static void
+gtk_real_entry_delete_text (GtkEntry *entry,
+                           gint      start_pos,
+                           gint      end_pos)
+{
+  gchar *text;
+  gint deletion_length;
+  gint i;
+
+  g_return_if_fail (entry != NULL);
+  g_return_if_fail (GTK_IS_ENTRY (entry));
+
+  if ((start_pos < end_pos) &&
+      (start_pos >= 0) &&
+      (end_pos <= entry->text_length))
+    {
+      text = entry->text;
+      deletion_length = end_pos - start_pos;
+
+      for (i = end_pos; i < entry->text_length; i++)
+        text[i - deletion_length] = text[i];
+
+      for (i = entry->text_length - deletion_length; i < entry->text_length; i++)
+        text[i] = '\0';
+
+      entry->text_length -= deletion_length;
+      entry->current_pos = start_pos;
+    }
+}
+
+
+static void
+gtk_move_forward_character (GtkEntry *entry)
+{
+  entry->current_pos += 1;
+  if (entry->current_pos > entry->text_length)
+    entry->current_pos = entry->text_length;
+
+  entry->selection_start_pos = 0;
+  entry->selection_end_pos = 0;
+}
+
+static void
+gtk_move_backward_character (GtkEntry *entry)
+{
+  entry->current_pos -= 1;
+  if (entry->current_pos < 0)
+    entry->current_pos = 0;
+
+  entry->selection_start_pos = 0;
+  entry->selection_end_pos = 0;
+}
+
+static void
+gtk_move_forward_word (GtkEntry *entry)
+{
+  gchar *text;
+  gint i;
+
+  if (entry->text)
+    {
+      text = entry->text;
+      i = entry->current_pos;
+
+      if (!((text[i] == '_') || isalnum (text[i])))
+        for (; i < entry->text_length; i++)
+          if ((text[i] == '_') || isalnum (text[i]))
+            break;
+
+      for (; i < entry->text_length; i++)
+        if (!((text[i] == '_') || isalnum (text[i])))
+         break;
+
+      entry->current_pos = i;
+      if (entry->current_pos > entry->text_length)
+       entry->current_pos = entry->text_length;
+    }
+
+  entry->selection_start_pos = 0;
+  entry->selection_end_pos = 0;
+}
+
+static void
+gtk_move_backward_word (GtkEntry *entry)
+{
+  gchar *text;
+  gint i;
+
+  if (entry->text)
+    {
+      text = entry->text;
+      i = entry->current_pos - 1;
+      if (i < 0) /* Per */
+       {
+         entry->selection_start_pos = 0;
+         entry->selection_end_pos = 0;
+         return;
+       }
+
+      if (!((text[i] == '_') || isalnum (text[i])))
+        for (; i >= 0; i--)
+          if ((text[i] == '_') || isalnum (text[i]))
+            break;
+
+      for (; i >= 0; i--)
+        if (!((text[i] == '_') || isalnum (text[i])))
+          {
+            i += 1;
+            break;
+          }
+
+      entry->current_pos = i;
+      if (entry->current_pos < 0)
+        entry->current_pos = 0;
+
+      if (text[entry->current_pos] == ' ')
+        entry->current_pos += 1;
+    }
+
+  entry->selection_start_pos = 0;
+  entry->selection_end_pos = 0;
+}
+
+static void
+gtk_move_beginning_of_line (GtkEntry *entry)
+{
+  entry->current_pos = 0;
+  entry->selection_start_pos = 0;
+  entry->selection_end_pos = 0;
+}
+
+static void
+gtk_move_end_of_line (GtkEntry *entry)
+{
+  entry->current_pos = entry->text_length;
+  entry->selection_start_pos = 0;
+  entry->selection_end_pos = 0;
+}
+
+static void
+gtk_delete_forward_character (GtkEntry *entry)
+{
+  gint old_pos;
+
+  old_pos = entry->current_pos;
+  gtk_move_forward_character (entry);
+  gtk_entry_delete_text (entry, old_pos, entry->current_pos);
+
+  entry->selection_start_pos = 0;
+  entry->selection_end_pos = 0;
+}
+
+static void
+gtk_delete_backward_character (GtkEntry *entry)
+{
+  gint old_pos;
+
+  old_pos = entry->current_pos;
+  gtk_move_backward_character (entry);
+  gtk_entry_delete_text (entry, entry->current_pos, old_pos);
+
+  entry->selection_start_pos = 0;
+  entry->selection_end_pos = 0;
+}
+
+static void
+gtk_delete_forward_word (GtkEntry *entry)
+{
+  gint old_pos;
+
+  old_pos = entry->current_pos;
+  gtk_move_forward_word (entry);
+  gtk_entry_delete_text (entry, old_pos, entry->current_pos);
+
+  entry->selection_start_pos = 0;
+  entry->selection_end_pos = 0;
+}
+
+static void
+gtk_delete_backward_word (GtkEntry *entry)
+{
+  gint old_pos;
+
+  old_pos = entry->current_pos;
+  gtk_move_backward_word (entry);
+  gtk_entry_delete_text (entry, entry->current_pos, old_pos);
+
+  entry->selection_start_pos = 0;
+  entry->selection_end_pos = 0;
+}
+
+static void
+gtk_delete_line (GtkEntry *entry)
+{
+  gtk_entry_delete_text (entry, 0, entry->text_length);
+
+  entry->selection_start_pos = 0;
+  entry->selection_end_pos = 0;
+}
+
+static void
+gtk_delete_to_line_end (GtkEntry *entry)
+{
+  gtk_entry_delete_text (entry, entry->current_pos, entry->text_length);
+
+  entry->selection_start_pos = 0;
+  entry->selection_end_pos = 0;
+}
+
+static void
+gtk_delete_selection (GtkEntry *entry)
+{
+  if (entry->selection_start_pos != entry->selection_end_pos)
+    gtk_entry_delete_text (entry,
+                          MIN (entry->selection_start_pos, entry->selection_end_pos),
+                          MAX (entry->selection_start_pos, entry->selection_end_pos));
+
+  entry->selection_start_pos = 0;
+  entry->selection_end_pos = 0;
+
+  if (entry->have_selection)
+    {
+      entry->have_selection = FALSE;
+      gtk_selection_owner_set (NULL, GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME);
+    }
+}
+
+static void
+gtk_select_word (GtkEntry *entry)
+{
+  gint start_pos;
+  gint end_pos;
+
+  gtk_move_backward_word (entry);
+  start_pos = entry->current_pos;
+
+  gtk_move_forward_word (entry);
+  end_pos = entry->current_pos;
+
+  gtk_select_region (entry, start_pos, end_pos);
+}
+
+static void
+gtk_select_line (GtkEntry *entry)
+{
+  gtk_select_region (entry, 0, entry->text_length);
+  entry->current_pos = entry->selection_end_pos;
+}
+
+static void
+gtk_select_region (GtkEntry *entry,
+                  gint      start,
+                  gint      end)
+{
+  entry->have_selection = TRUE;
+  entry->selection_start_pos = start;
+  entry->selection_end_pos = end;
+}
diff --git a/gtk/gtkentry.h b/gtk/gtkentry.h
new file mode 100644 (file)
index 0000000..c24bee6
--- /dev/null
@@ -0,0 +1,94 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_ENTRY_H__
+#define __GTK_ENTRY_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkwidget.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_ENTRY(obj)          GTK_CHECK_CAST (obj, gtk_entry_get_type (), GtkEntry)
+#define GTK_ENTRY_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_entry_get_type (), GtkEntryClass)
+#define GTK_IS_ENTRY(obj)       GTK_CHECK_TYPE (obj, gtk_entry_get_type ())
+
+
+typedef struct _GtkEntry       GtkEntry;
+typedef struct _GtkEntryClass  GtkEntryClass;
+
+struct _GtkEntry
+{
+  GtkWidget widget;
+
+  GdkWindow *text_area;
+  gchar *text;
+
+  guint16 text_size;
+  guint16 text_length;
+  gint16  current_pos;
+  gint16  selection_start_pos;
+  gint16  selection_end_pos;
+  gint16  scroll_offset;
+  guint   have_selection : 1;
+  guint   visible : 1;
+  guint32 timer;
+};
+
+struct _GtkEntryClass
+{
+  GtkWidgetClass parent_class;
+
+  void (* insert_text)  (GtkEntry    *entry,
+                        const gchar *text,
+                        gint         length,
+                        gint        *position);
+  void (* delete_text)  (GtkEntry    *entry,
+                        gint         start_pos,
+                        gint         end_pos);
+  void (* changed)      (GtkEntry    *entry);
+  void (* set_text)     (GtkEntry    *entry);
+  void (* activate)     (GtkEntry    *entry);
+};
+
+
+guint      gtk_entry_get_type     (void);
+GtkWidget* gtk_entry_new          (void);
+void       gtk_entry_set_text     (GtkEntry      *entry,
+                                  const gchar   *text);
+void       gtk_entry_append_text  (GtkEntry      *entry,
+                                  const gchar   *text);
+void       gtk_entry_prepend_text (GtkEntry      *entry,
+                                  const gchar   *text);
+void       gtk_entry_set_position (GtkEntry      *entry,
+                                  gint           position);
+gchar*     gtk_entry_get_text     (GtkEntry      *entry);
+void       gtk_entry_set_visibility (GtkEntry    *entry,
+               gint           visible);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_ENTRY_H__ */
diff --git a/gtk/gtkenums.h b/gtk/gtkenums.h
new file mode 100644 (file)
index 0000000..b82d5e4
--- /dev/null
@@ -0,0 +1,191 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_ENUMS_H__
+#define __GTK_ENUMS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* Widget states */
+typedef enum
+{
+  GTK_STATE_NORMAL,
+  GTK_STATE_ACTIVE,
+  GTK_STATE_PRELIGHT,
+  GTK_STATE_SELECTED,
+  GTK_STATE_INSENSITIVE
+} GtkStateType;
+
+/* Window types */
+typedef enum
+{
+  GTK_WINDOW_TOPLEVEL,
+  GTK_WINDOW_DIALOG,
+  GTK_WINDOW_POPUP
+} GtkWindowType;
+
+/* Focus movement types */
+typedef enum
+{
+  GTK_DIR_TAB_FORWARD,
+  GTK_DIR_TAB_BACKWARD,
+  GTK_DIR_UP,
+  GTK_DIR_DOWN,
+  GTK_DIR_LEFT,
+  GTK_DIR_RIGHT
+} GtkDirectionType;
+
+/* Shadow types */
+typedef enum
+{
+  GTK_SHADOW_NONE,
+  GTK_SHADOW_IN,
+  GTK_SHADOW_OUT,
+  GTK_SHADOW_ETCHED_IN,
+  GTK_SHADOW_ETCHED_OUT
+} GtkShadowType;
+
+/* Arrow types */
+typedef enum
+{
+  GTK_ARROW_UP,
+  GTK_ARROW_DOWN,
+  GTK_ARROW_LEFT,
+  GTK_ARROW_RIGHT
+} GtkArrowType;
+
+/* Packing types (for boxes) */
+typedef enum
+{
+  GTK_PACK_START,
+  GTK_PACK_END
+} GtkPackType;
+
+/* Scrollbar policy types (for scrolled windows) */
+typedef enum
+{
+  GTK_POLICY_ALWAYS,
+  GTK_POLICY_AUTOMATIC
+} GtkPolicyType;
+
+/* Data update types (for ranges) */
+typedef enum
+{
+  GTK_UPDATE_CONTINUOUS,
+  GTK_UPDATE_DISCONTINUOUS,
+  GTK_UPDATE_DELAYED
+} GtkUpdateType;
+
+/* Attach options (for tables) */
+typedef enum
+{
+  GTK_EXPAND = 1 << 0,
+  GTK_SHRINK = 1 << 1,
+  GTK_FILL   = 1 << 2
+} GtkAttachOptions;
+
+typedef enum
+{
+  GTK_RUN_FIRST      = 0x1,
+  GTK_RUN_LAST       = 0x2,
+  GTK_RUN_BOTH       = 0x3,
+  GTK_RUN_MASK       = 0xF,
+  GTK_RUN_NO_RECURSE = 0x10
+} GtkSignalRunType;
+
+typedef enum
+{
+  GTK_WIN_POS_NONE,
+  GTK_WIN_POS_CENTER,
+  GTK_WIN_POS_MOUSE
+} GtkWindowPosition;
+
+typedef enum
+{
+  GTK_DIRECTION_LEFT,
+  GTK_DIRECTION_RIGHT
+} GtkSubmenuDirection;
+
+typedef enum
+{
+  GTK_TOP_BOTTOM,
+  GTK_LEFT_RIGHT
+} GtkSubmenuPlacement;
+
+typedef enum
+{
+  GTK_MENU_FACTORY_MENU,
+  GTK_MENU_FACTORY_MENU_BAR,
+  GTK_MENU_FACTORY_OPTION_MENU
+} GtkMenuFactoryType;
+
+typedef enum
+{
+  GTK_PIXELS,
+  GTK_INCHES,
+  GTK_CENTIMETERS
+} GtkMetricType;
+
+typedef enum
+{
+  GTK_SCROLL_NONE,
+  GTK_SCROLL_STEP_BACKWARD,
+  GTK_SCROLL_STEP_FORWARD,
+  GTK_SCROLL_PAGE_BACKWARD,
+  GTK_SCROLL_PAGE_FORWARD
+} GtkScrollType;
+
+typedef enum
+{
+  GTK_TROUGH_NONE,
+  GTK_TROUGH_START,
+  GTK_TROUGH_END
+} GtkTroughType;
+
+typedef enum
+{
+  GTK_POS_LEFT,
+  GTK_POS_RIGHT,
+  GTK_POS_TOP,
+  GTK_POS_BOTTOM
+} GtkPositionType;
+
+typedef enum
+{
+  GTK_PREVIEW_COLOR,
+  GTK_PREVIEW_GRAYSCALE
+} GtkPreviewType;
+
+/* justification for label and maybe other widgets (text?) */
+typedef enum
+{
+  GTK_JUSTIFY_LEFT,
+  GTK_JUSTIFY_RIGHT,
+  GTK_JUSTIFY_CENTER,
+  GTK_JUSTIFY_FILL
+} GtkJustification;
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_ENUMS_H__ */
diff --git a/gtk/gtkeventbox.c b/gtk/gtkeventbox.c
new file mode 100644 (file)
index 0000000..44a0d7a
--- /dev/null
@@ -0,0 +1,226 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtksignal.h"
+#include "gtkeventbox.h"
+
+
+static void gtk_event_box_class_init               (GtkEventBoxClass *klass);
+static void gtk_event_box_init                     (GtkEventBox      *event_box);
+static void gtk_event_box_realize                  (GtkWidget        *widget);
+static void gtk_event_box_size_request             (GtkWidget        *widget,
+                                                  GtkRequisition   *requisition);
+static void gtk_event_box_size_allocate            (GtkWidget        *widget,
+                                                  GtkAllocation    *allocation);
+static void gtk_event_box_draw                     (GtkWidget    *widget,
+                                                  GdkRectangle *area);
+static gint gtk_event_box_expose                   (GtkWidget      *widget,
+                                                  GdkEventExpose *event);
+
+
+guint
+gtk_event_box_get_type ()
+{
+  static guint event_box_type = 0;
+
+  if (!event_box_type)
+    {
+      GtkTypeInfo event_box_info =
+      {
+       "GtkEventBox",
+       sizeof (GtkEventBox),
+       sizeof (GtkEventBoxClass),
+       (GtkClassInitFunc) gtk_event_box_class_init,
+       (GtkObjectInitFunc) gtk_event_box_init,
+       (GtkArgFunc) NULL,
+      };
+
+      event_box_type = gtk_type_unique (gtk_bin_get_type (), &event_box_info);
+    }
+
+  return event_box_type;
+}
+
+static void
+gtk_event_box_class_init (GtkEventBoxClass *class)
+{
+  GtkWidgetClass *widget_class;
+
+  widget_class = (GtkWidgetClass*) class;
+
+  widget_class->realize = gtk_event_box_realize;
+  widget_class->size_request = gtk_event_box_size_request;
+  widget_class->size_allocate = gtk_event_box_size_allocate;
+  widget_class->draw = gtk_event_box_draw;
+  widget_class->expose_event = gtk_event_box_expose;
+}
+
+static void
+gtk_event_box_init (GtkEventBox *event_box)
+{
+  GTK_WIDGET_UNSET_FLAGS (event_box, GTK_NO_WINDOW);
+  GTK_WIDGET_SET_FLAGS (event_box, GTK_BASIC);
+}
+
+GtkWidget*
+gtk_event_box_new ()
+{
+  return GTK_WIDGET ( gtk_type_new (gtk_event_box_get_type ()));
+}
+
+static void
+gtk_event_box_realize (GtkWidget *widget)
+{
+  GdkWindowAttr attributes;
+  gint attributes_mask;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_EVENT_BOX (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+
+  attributes.x = widget->allocation.x;
+  attributes.y = widget->allocation.y;
+  attributes.width = widget->allocation.width;
+  attributes.height = widget->allocation.height;
+  attributes.window_type = GDK_WINDOW_CHILD;
+  attributes.wclass = GDK_INPUT_OUTPUT;
+  attributes.visual = gtk_widget_get_visual (widget);
+  attributes.colormap = gtk_widget_get_colormap (widget);
+  attributes.event_mask = gtk_widget_get_events (widget)
+                       | GDK_BUTTON_MOTION_MASK
+                       | GDK_BUTTON_PRESS_MASK
+                       | GDK_BUTTON_RELEASE_MASK
+                       | GDK_EXPOSURE_MASK
+                       | GDK_ENTER_NOTIFY_MASK
+                       | GDK_LEAVE_NOTIFY_MASK;
+
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+
+  widget->window = gdk_window_new (widget->parent->window, &attributes, attributes_mask);
+  gdk_window_set_user_data (widget->window, widget);
+
+  widget->style = gtk_style_attach (widget->style, widget->window);
+  gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
+}
+
+static void
+gtk_event_box_size_request (GtkWidget      *widget,
+                       GtkRequisition *requisition)
+{
+  GtkBin *bin;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_EVENT_BOX (widget));
+  g_return_if_fail (requisition != NULL);
+
+  bin = GTK_BIN (widget);
+
+  requisition->width = GTK_CONTAINER (widget)->border_width * 2;
+  requisition->height = GTK_CONTAINER (widget)->border_width * 2;
+
+  if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
+    {
+      gtk_widget_size_request (bin->child, &bin->child->requisition);
+
+      requisition->width += bin->child->requisition.width;
+      requisition->height += bin->child->requisition.height;
+    }
+}
+
+static void
+gtk_event_box_size_allocate (GtkWidget     *widget,
+                           GtkAllocation *allocation)
+{
+  GtkBin *bin;
+  GtkAllocation child_allocation;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_EVENT_BOX (widget));
+  g_return_if_fail (allocation != NULL);
+
+  widget->allocation = *allocation;
+  bin = GTK_BIN (widget);
+
+  child_allocation.x = 0;
+  child_allocation.y = 0;
+  child_allocation.width = allocation->width - GTK_CONTAINER (widget)->border_width * 2;
+  child_allocation.height = allocation->height - GTK_CONTAINER (widget)->border_width * 2;
+
+  if (GTK_WIDGET_REALIZED (widget))
+    {
+      gdk_window_move_resize (widget->window,
+                             allocation->x + GTK_CONTAINER (widget)->border_width,
+                             allocation->y + GTK_CONTAINER (widget)->border_width,
+                             child_allocation.width,
+                             child_allocation.height);
+    }
+  
+  if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
+    {
+      gtk_widget_size_allocate (bin->child, &child_allocation);
+    }
+}
+
+static void
+gtk_event_box_draw (GtkWidget    *widget,
+                  GdkRectangle *area)
+{
+  GtkBin *bin;
+  GdkRectangle child_area;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_EVENT_BOX (widget));
+  g_return_if_fail (area != NULL);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      bin = GTK_BIN (widget);
+
+      if (bin->child)
+       {
+         if (gtk_widget_intersect (bin->child, area, &child_area))
+           gtk_widget_draw (bin->child, &child_area);
+       }
+    }
+}
+
+static gint
+gtk_event_box_expose (GtkWidget      *widget,
+                    GdkEventExpose *event)
+{
+  GtkBin *bin;
+  GdkEventExpose child_event;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_EVENT_BOX (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      bin = GTK_BIN (widget);
+
+      child_event = *event;
+      if (bin->child &&
+         GTK_WIDGET_NO_WINDOW (bin->child) &&
+         gtk_widget_intersect (bin->child, &event->area, &child_event.area))
+       gtk_widget_event (bin->child, (GdkEvent*) &child_event);
+    }
+
+  return FALSE;
+}
+
diff --git a/gtk/gtkeventbox.h b/gtk/gtkeventbox.h
new file mode 100644 (file)
index 0000000..d90213d
--- /dev/null
@@ -0,0 +1,57 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_EVENT_BOX_H__
+#define __GTK_EVENT_BOX_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkbin.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_EVENT_BOX(obj)          GTK_CHECK_CAST (obj, gtk_event_box_get_type (), GtkEventBox)
+#define GTK_EVENT_BOX_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_event_box_get_type (), GtkEventBoxClass)
+#define GTK_IS_EVENT_BOX(obj)       GTK_CHECK_TYPE (obj, gtk_event_box_get_type ())
+
+
+typedef struct _GtkEventBox       GtkEventBox;
+typedef struct _GtkEventBoxClass  GtkEventBoxClass;
+
+struct _GtkEventBox
+{
+  GtkBin bin;
+};
+
+struct _GtkEventBoxClass
+{
+  GtkBinClass parent_class;
+};
+
+guint          gtk_event_box_get_type        (void);
+GtkWidget*     gtk_event_box_new             (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_EVENT_BOX_H__ */
diff --git a/gtk/gtkfilesel.c b/gtk/gtkfilesel.c
new file mode 100644 (file)
index 0000000..77f83a8
--- /dev/null
@@ -0,0 +1,2161 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <dirent.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <pwd.h>
+#include "fnmatch.h"
+
+#include "gdk/gdkkeysyms.h"
+#include "gtkbutton.h"
+#include "gtkentry.h"
+#include "gtkfilesel.h"
+#include "gtkhbox.h"
+#include "gtklabel.h"
+#include "gtklist.h"
+#include "gtklistitem.h"
+#include "gtkmain.h"
+#include "gtkscrolledwindow.h"
+#include "gtksignal.h"
+#include "gtkvbox.h"
+
+
+#define DIR_LIST_WIDTH   160
+#define DIR_LIST_HEIGHT  175
+#define FILE_LIST_WIDTH  160
+#define FILE_LIST_HEIGHT 175
+
+
+typedef struct _CompletionState    CompletionState;
+typedef struct _CompletionDir      CompletionDir;
+typedef struct _CompletionDirSent  CompletionDirSent;
+typedef struct _CompletionDirEntry CompletionDirEntry;
+typedef struct _CompletionUserDir  CompletionUserDir;
+typedef struct _PossibleCompletion PossibleCompletion;
+
+/* Non-external file completion decls and structures */
+
+/* A contant telling PRCS how many directories to cache.  Its actually
+ * kept in a list, so the geometry isn't important. */
+#define CMPL_DIRECTORY_CACHE_SIZE 10
+
+/* A constant used to determine whether a substring was an exact
+ * match by first_diff_index()
+ */
+#define PATTERN_MATCH -1
+/* The arguments used by all fnmatch() calls below
+ */
+#define FNMATCH_FLAGS (FNM_PATHNAME | FNM_PERIOD)
+
+#define CMPL_ERRNO_TOO_LONG ((1<<16)-1)
+
+/* This structure contains all the useful information about a directory
+ * for the purposes of filename completion.  These structures are cached
+ * in the CompletionState struct.  CompletionDir's are reference counted.
+ */
+struct _CompletionDirSent
+{
+  ino_t inode;
+  time_t mtime;
+
+  gint entry_count;
+  gchar *name_buffer; /* memory segment containing names of all entries */
+
+  struct _CompletionDirEntry *entries;
+};
+
+struct _CompletionDir
+{
+  CompletionDirSent *sent;
+
+  gchar *fullname;
+  gint fullname_len;
+
+  struct _CompletionDir *cmpl_parent;
+  gint cmpl_index;
+  gchar *cmpl_text;
+};
+
+/* This structure contains pairs of directory entry names with a flag saying
+ * whether or not they are a valid directory.  NOTE: This information is used
+ * to provide the caller with information about whether to update its completions
+ * or try to open a file.  Since directories are cached by the directory mtime,
+ * a symlink which points to an invalid file (which will not be a directory),
+ * will not be reevaluated if that file is created, unless the containing
+ * directory is touched.  I consider this case to be worth ignoring (josh).
+ */
+struct _CompletionDirEntry
+{
+  gint is_dir;
+  gchar *entry_name;
+};
+
+struct _CompletionUserDir
+{
+  gchar *login;
+  gchar *homedir;
+};
+
+struct _PossibleCompletion
+{
+  /* accessible fields, all are accessed externally by functions
+   * declared above
+   */
+  gchar *text;
+  gint is_a_completion;
+  gint is_directory;
+
+  /* Private fields
+   */
+  gint text_alloc;
+};
+
+struct _CompletionState
+{
+  gint last_valid_char;
+  gchar *updated_text;
+  gint updated_text_len;
+  gint updated_text_alloc;
+  gint re_complete;
+
+  gchar *user_dir_name_buffer;
+  gint user_directories_len;
+  gchar *user_home_dir;
+
+  gchar *last_completion_text;
+
+  gint user_completion_index; /* if >= 0, currently completing ~user */
+
+  struct _CompletionDir *completion_dir; /* directory completing from */
+  struct _CompletionDir *active_completion_dir;
+
+  struct _PossibleCompletion the_completion;
+
+  struct _CompletionDir *reference_dir; /* initial directory */
+
+  GList* directory_storage;
+  GList* directory_sent_storage;
+
+  struct _CompletionUserDir *user_directories;
+};
+
+
+/* File completion functions which would be external, were they used
+ * outside of this file.
+ */
+
+static CompletionState*    cmpl_init_state        (void);
+static void                cmpl_free_state        (CompletionState *cmpl_state);
+static gint                cmpl_state_okay        (CompletionState* cmpl_state);
+static gchar*              cmpl_strerror          (gint);
+
+static PossibleCompletion* cmpl_completion_matches(gchar           *text_to_complete,
+                                                  gchar          **remaining_text,
+                                                  CompletionState *cmpl_state);
+
+/* Returns a name for consideration, possibly a completion, this name
+ * will be invalid after the next call to cmpl_next_completion.
+ */
+static char*               cmpl_this_completion   (PossibleCompletion*);
+
+/* True if this completion matches the given text.  Otherwise, this
+ * output can be used to have a list of non-completions.
+ */
+static gint                cmpl_is_a_completion   (PossibleCompletion*);
+
+/* True if the completion is a directory
+ */
+static gint                cmpl_is_directory      (PossibleCompletion*);
+
+/* Obtains the next completion, or NULL
+ */
+static PossibleCompletion* cmpl_next_completion   (CompletionState*);
+
+/* Updating completions: the return value of cmpl_updated_text() will
+ * be text_to_complete completed as much as possible after the most
+ * recent call to cmpl_completion_matches.  For the present
+ * application, this is the suggested replacement for the user's input
+ * string.  You must CALL THIS AFTER ALL cmpl_text_completions have
+ * been received.
+ */
+static gchar*              cmpl_updated_text       (CompletionState* cmpl_state);
+
+/* After updating, to see if the completion was a directory, call
+ * this.  If it was, you should consider re-calling completion_matches.
+ */
+static gint                cmpl_updated_dir        (CompletionState* cmpl_state);
+
+/* Current location: if using file completion, return the current
+ * directory, from which file completion begins.  More specifically,
+ * the cwd concatenated with all exact completions up to the last
+ * directory delimiter('/').
+ */
+static gchar*              cmpl_reference_position (CompletionState* cmpl_state);
+
+/* backing up: if cmpl_completion_matches returns NULL, you may query
+ * the index of the last completable character into cmpl_updated_text.
+ */
+static gint                cmpl_last_valid_char    (CompletionState* cmpl_state);
+
+/* When the user selects a non-directory, call cmpl_completion_fullname
+ * to get the full name of the selected file.
+ */
+static gchar*              cmpl_completion_fullname (gchar*, CompletionState* cmpl_state);
+
+
+/* Directory operations. */
+static CompletionDir* open_ref_dir         (gchar* text_to_complete,
+                                           gchar** remaining_text,
+                                           CompletionState* cmpl_state);
+static CompletionDir* open_dir             (gchar* dir_name,
+                                           CompletionState* cmpl_state);
+static CompletionDir* open_user_dir        (gchar* text_to_complete,
+                                           CompletionState *cmpl_state);
+static CompletionDir* open_relative_dir    (gchar* dir_name, CompletionDir* dir,
+                                           CompletionState *cmpl_state);
+static CompletionDirSent* open_new_dir         (gchar* dir_name, struct stat* sbuf);
+static gint           correct_dir_fullname (CompletionDir* cmpl_dir);
+static gint           correct_parent       (CompletionDir* cmpl_dir,
+                                           struct stat *sbuf);
+static gchar*         find_parent_dir_fullname    (gchar* dirname);
+static CompletionDir* attach_dir           (CompletionDirSent* sent,
+                                           gchar* dir_name,
+                                           CompletionState *cmpl_state);
+static void           free_dir_sent (CompletionDirSent* sent);
+static void           free_dir      (CompletionDir  *dir);
+static void           prune_memory_usage(CompletionState *cmpl_state);
+
+/* Completion operations */
+static PossibleCompletion* attempt_homedir_completion(gchar* text_to_complete,
+                                                     CompletionState *cmpl_state);
+static PossibleCompletion* attempt_file_completion(CompletionState *cmpl_state);
+static CompletionDir* find_completion_dir(gchar* text_to_complete,
+                                         gchar** remaining_text,
+                                         CompletionState* cmpl_state);
+static PossibleCompletion* append_completion_text(gchar* text,
+                                                 CompletionState* cmpl_state);
+static gint get_pwdb(CompletionState* cmpl_state);
+static gint first_diff_index(gchar* pat, gchar* text);
+static gint compare_user_dir(const void* a, const void* b);
+static gint compare_cmpl_dir(const void* a, const void* b);
+static void update_cmpl(PossibleCompletion* poss,
+                       CompletionState* cmpl_state);
+
+static void gtk_file_selection_class_init    (GtkFileSelectionClass *klass);
+static void gtk_file_selection_init          (GtkFileSelection      *filesel);
+static void gtk_file_selection_destroy       (GtkObject             *object);
+static gint gtk_file_selection_key_press     (GtkWidget             *widget,
+                                             GdkEventKey           *event,
+                                             gpointer               user_data);
+static gint gtk_file_selection_file_button   (GtkWidget             *widget,
+                                             GdkEventButton        *event,
+                                             gpointer               user_data);
+static gint gtk_file_selection_dir_button    (GtkWidget             *widget,
+                                             GdkEventButton        *event,
+                                             gpointer               user_data);
+static void gtk_file_selection_file_list_changed  (GtkList          *gtklist,
+                                                  gpointer          func_data);
+static void gtk_file_selection_dir_list_changed   (GtkList                 *gtklist,
+                                                  gpointer          func_data);
+static void gtk_file_selection_populate      (GtkFileSelection      *fs,
+                                             gchar                 *rel_path,
+                                             gint                   try_complete);
+static void gtk_file_selection_abort         (GtkFileSelection      *fs);
+static void gtk_file_selection_free_filename (GtkWidget             *widget,
+                                             gpointer               client_data);
+
+
+static GtkWindowClass *parent_class = NULL;
+
+static gchar *list_changed_key = "_gtk_selection_changed_handler_key";
+
+/* Saves errno when something cmpl does fails. */
+static gint cmpl_errno;
+
+
+guint
+gtk_file_selection_get_type ()
+{
+  static guint file_selection_type = 0;
+
+  if (!file_selection_type)
+    {
+      GtkTypeInfo filesel_info =
+      {
+       "GtkFileSelection",
+       sizeof (GtkFileSelection),
+       sizeof (GtkFileSelectionClass),
+       (GtkClassInitFunc) gtk_file_selection_class_init,
+       (GtkObjectInitFunc) gtk_file_selection_init,
+       (GtkArgFunc) NULL,
+      };
+
+      file_selection_type = gtk_type_unique (gtk_window_get_type (), &filesel_info);
+    }
+
+  return file_selection_type;
+}
+
+static void
+gtk_file_selection_class_init (GtkFileSelectionClass *class)
+{
+  GtkObjectClass *object_class;
+
+  object_class = (GtkObjectClass*) class;
+
+  parent_class = gtk_type_class (gtk_window_get_type ());
+
+  object_class->destroy = gtk_file_selection_destroy;
+}
+
+static void
+gtk_file_selection_init (GtkFileSelection *filesel)
+{
+  GtkWidget *dir_vbox;
+  GtkWidget *file_vbox;
+  GtkWidget *entry_vbox;
+  GtkWidget *listbox;
+  GtkWidget *label;
+  GtkWidget *list_hbox;
+  GtkWidget *action_area;
+  gint key;
+
+  filesel->cmpl_state = cmpl_init_state ();
+
+  /*  The dialog-sized vertical box  */
+  filesel->main_vbox = gtk_vbox_new (FALSE, 10);
+  gtk_container_border_width (GTK_CONTAINER (filesel), 10);
+  gtk_container_add (GTK_CONTAINER (filesel), filesel->main_vbox);
+  gtk_widget_show (filesel->main_vbox);
+
+  /*  The horizontal box containing the directory and file listboxes  */
+  list_hbox = gtk_hbox_new (TRUE, 5);
+  gtk_box_pack_start (GTK_BOX (filesel->main_vbox), list_hbox, TRUE, TRUE, 0);
+  gtk_widget_show (list_hbox);
+
+
+  /* The directories listbox  */
+  dir_vbox = gtk_vbox_new (FALSE, 2);
+  gtk_box_pack_start (GTK_BOX (list_hbox), dir_vbox, TRUE, TRUE, 0);
+  gtk_widget_show (dir_vbox);
+
+  label = gtk_label_new ("Directories");
+  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+  gtk_box_pack_start (GTK_BOX (dir_vbox), label, FALSE, FALSE, 0);
+  gtk_widget_show (label);
+
+  listbox = gtk_scrolled_window_new (NULL, NULL);
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (listbox),
+                                 GTK_POLICY_AUTOMATIC,
+                                 GTK_POLICY_ALWAYS);
+  gtk_box_pack_start (GTK_BOX (dir_vbox), listbox, TRUE, TRUE, 0);
+  gtk_widget_set_usize (listbox, DIR_LIST_WIDTH, DIR_LIST_HEIGHT);
+  gtk_widget_show (listbox);
+
+  filesel->dir_list = gtk_list_new ();
+  gtk_list_set_selection_mode (GTK_LIST (filesel->dir_list), GTK_SELECTION_BROWSE);
+  gtk_signal_connect (GTK_OBJECT (filesel->dir_list), "button_press_event",
+                     (GtkSignalFunc) gtk_file_selection_dir_button, filesel);
+  key = gtk_signal_connect (GTK_OBJECT (filesel->dir_list),
+                           "selection_changed",
+                           (GtkSignalFunc) gtk_file_selection_dir_list_changed,
+                           filesel);
+  gtk_object_set_data (GTK_OBJECT (filesel->dir_list), list_changed_key, (gpointer) key);
+  gtk_container_add (GTK_CONTAINER (listbox), filesel->dir_list);
+  gtk_widget_show (filesel->dir_list);
+
+
+  /* The files listbox  */
+  file_vbox = gtk_vbox_new (FALSE, 2);
+  gtk_box_pack_start (GTK_BOX (list_hbox), file_vbox, TRUE, TRUE, 0);
+  gtk_widget_show (file_vbox);
+
+  label = gtk_label_new ("Files");
+  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+  gtk_box_pack_start (GTK_BOX (file_vbox), label, FALSE, FALSE, 0);
+  gtk_widget_show (label);
+
+  listbox = gtk_scrolled_window_new (NULL, NULL);
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (listbox),
+                                 GTK_POLICY_AUTOMATIC,
+                                 GTK_POLICY_ALWAYS);
+  gtk_box_pack_start (GTK_BOX (file_vbox), listbox, TRUE, TRUE, 0);
+  gtk_widget_set_usize (listbox, FILE_LIST_WIDTH, FILE_LIST_HEIGHT);
+  gtk_widget_show (listbox);
+
+  filesel->file_list = gtk_list_new ();
+  gtk_list_set_selection_mode (GTK_LIST (filesel->file_list), GTK_SELECTION_BROWSE);
+  gtk_signal_connect (GTK_OBJECT (filesel->file_list), "button_press_event",
+                     (GtkSignalFunc) gtk_file_selection_file_button, filesel);
+  key = gtk_signal_connect (GTK_OBJECT (filesel->file_list),
+                           "selection_changed",
+                           (GtkSignalFunc) gtk_file_selection_file_list_changed,
+                           filesel);
+  gtk_object_set_data (GTK_OBJECT (filesel->file_list), list_changed_key, (gpointer) key);
+  gtk_container_add (GTK_CONTAINER (listbox), filesel->file_list);
+  gtk_widget_show (filesel->file_list);
+
+
+  /*  The action area  */
+  action_area = gtk_hbox_new (TRUE, 10);
+  gtk_box_pack_end (GTK_BOX (filesel->main_vbox), action_area, FALSE, FALSE, 0);
+  gtk_widget_show (action_area);
+
+  /*  The OK button  */
+  filesel->ok_button = gtk_button_new_with_label ("OK");
+  GTK_WIDGET_SET_FLAGS (filesel->ok_button, GTK_CAN_DEFAULT);
+  gtk_box_pack_start (GTK_BOX (action_area), filesel->ok_button, TRUE, TRUE, 0);
+  gtk_widget_grab_default (filesel->ok_button);
+  gtk_widget_show (filesel->ok_button);
+
+  /*  The Cancel button  */
+  filesel->cancel_button = gtk_button_new_with_label ("Cancel");
+  GTK_WIDGET_SET_FLAGS (filesel->cancel_button, GTK_CAN_DEFAULT);
+  gtk_box_pack_start (GTK_BOX (action_area), filesel->cancel_button, TRUE, TRUE, 0);
+  gtk_widget_show (filesel->cancel_button);
+
+  /*  The Help button  */
+  filesel->help_button = gtk_button_new_with_label ("Help");
+  GTK_WIDGET_SET_FLAGS (filesel->help_button, GTK_CAN_DEFAULT);
+  gtk_box_pack_start (GTK_BOX (action_area), filesel->help_button, TRUE, TRUE, 0);
+  gtk_widget_show (filesel->help_button);
+
+
+  /*  The selection entry widget  */
+  entry_vbox = gtk_vbox_new (FALSE, 2);
+  gtk_box_pack_end (GTK_BOX (filesel->main_vbox), entry_vbox, FALSE, FALSE, 0);
+  gtk_widget_show (entry_vbox);
+
+  filesel->selection_text = label = gtk_label_new ("");
+  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+  gtk_box_pack_start (GTK_BOX (entry_vbox), label, FALSE, FALSE, 0);
+  gtk_widget_show (label);
+
+  filesel->selection_entry = gtk_entry_new ();
+  gtk_signal_connect (GTK_OBJECT (filesel->selection_entry), "key_press_event",
+                     (GtkSignalFunc) gtk_file_selection_key_press, filesel);
+  gtk_signal_connect_object (GTK_OBJECT (filesel->selection_entry), "focus_in_event",
+                            (GtkSignalFunc) gtk_widget_grab_default,
+                            GTK_OBJECT (filesel->ok_button));
+  gtk_signal_connect_object (GTK_OBJECT (filesel->selection_entry), "activate",
+                             (GtkSignalFunc) gtk_button_clicked,
+                             GTK_OBJECT (filesel->ok_button));
+  gtk_box_pack_start (GTK_BOX (entry_vbox), filesel->selection_entry, TRUE, TRUE, 0);
+  gtk_widget_show (filesel->selection_entry);
+
+  if (!cmpl_state_okay (filesel->cmpl_state))
+    {
+      gchar err_buf[256];
+
+      sprintf (err_buf, "Directory unreadable: %s", cmpl_strerror (cmpl_errno));
+
+      gtk_label_set (GTK_LABEL (filesel->selection_text), err_buf);
+    }
+  else
+    {
+      gtk_file_selection_populate (filesel, "", FALSE);
+    }
+
+  gtk_widget_grab_focus (filesel->selection_entry);
+}
+
+GtkWidget*
+gtk_file_selection_new (const gchar *title)
+{
+  GtkFileSelection *filesel;
+
+  filesel = gtk_type_new (gtk_file_selection_get_type ());
+  gtk_window_set_title (GTK_WINDOW (filesel), title);
+
+  return GTK_WIDGET (filesel);
+}
+
+void
+gtk_file_selection_set_filename (GtkFileSelection *filesel,
+                                const gchar      *filename)
+{
+  char  buf[MAXPATHLEN];
+  const char *name, *last_slash;
+
+  g_return_if_fail (filesel != NULL);
+  g_return_if_fail (GTK_IS_FILE_SELECTION (filesel));
+  g_return_if_fail (filename != NULL);
+
+  last_slash = strrchr (filename, '/');
+
+  if (!last_slash)
+    {
+      buf[0] = 0;
+      name = filename;
+    }
+  else
+    {
+      gint len = MIN (MAXPATHLEN - 1, last_slash - filename + 1);
+
+      strncpy (buf, filename, len);
+      buf[len] = 0;
+
+      name = last_slash + 1;
+    }
+
+  gtk_file_selection_populate (filesel, buf, FALSE);
+
+  if (filesel->selection_entry)
+    gtk_entry_set_text (GTK_ENTRY (filesel->selection_entry), name);
+}
+
+gchar*
+gtk_file_selection_get_filename (GtkFileSelection *filesel)
+{
+  static char nothing[2] = "";
+  char *text;
+  char *filename;
+
+  g_return_val_if_fail (filesel != NULL, nothing);
+  g_return_val_if_fail (GTK_IS_FILE_SELECTION (filesel), nothing);
+
+  text = gtk_entry_get_text (GTK_ENTRY (filesel->selection_entry));
+  if (text)
+    {
+      filename = cmpl_completion_fullname (text, filesel->cmpl_state);
+      return filename;
+    }
+
+  return nothing;
+}
+
+static void
+gtk_file_selection_destroy (GtkObject *object)
+{
+  GtkFileSelection *filesel;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_FILE_SELECTION (object));
+
+  filesel = GTK_FILE_SELECTION (object);
+
+  cmpl_free_state (filesel->cmpl_state);
+
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static gint
+gtk_file_selection_key_press (GtkWidget   *widget,
+                             GdkEventKey *event,
+                             gpointer     user_data)
+{
+  GtkFileSelection *fs;
+  char *text;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (event->keyval == GDK_Tab)
+    {
+      gtk_signal_emit_stop_by_name (GTK_OBJECT (widget), "key_press_event");
+
+      fs = GTK_FILE_SELECTION (user_data);
+      text = gtk_entry_get_text (GTK_ENTRY (fs->selection_entry));
+      gtk_file_selection_populate (fs, text, TRUE);
+
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+static gint
+gtk_file_selection_file_button (GtkWidget      *widget,
+                               GdkEventButton *event,
+                               gpointer        user_data)
+{
+  GtkFileSelection *fs;
+  GtkWidget *event_widget;
+  gchar *filename;
+  gboolean handled;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  fs = GTK_FILE_SELECTION (user_data);
+  g_return_val_if_fail (fs != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_FILE_SELECTION (fs), FALSE);
+
+  event_widget = gtk_get_event_widget ((GdkEvent*) event);
+  handled = FALSE;
+  if (GTK_IS_LIST_ITEM (event_widget))
+    {
+      switch (event->type)
+       {
+       case GDK_BUTTON_PRESS:
+         filename = gtk_object_get_user_data (GTK_OBJECT (event_widget));
+         gtk_widget_grab_focus (fs->selection_entry);
+         gtk_entry_set_text (GTK_ENTRY (fs->selection_entry), filename);
+         handled = TRUE;
+         break;
+
+       case GDK_2BUTTON_PRESS:
+         gtk_button_clicked (GTK_BUTTON (fs->ok_button));
+         handled = TRUE;
+         break;
+
+       default:
+         break;
+       }
+    }
+
+  return handled;
+}
+
+static void
+gtk_file_selection_file_list_changed (GtkList          *list,
+                                     gpointer          func_data)
+{
+  GtkFileSelection *fs;
+
+  g_return_if_fail (func_data != NULL);
+  g_return_if_fail (GTK_IS_FILE_SELECTION (func_data));
+
+  fs = GTK_FILE_SELECTION (func_data);
+
+  /* only act on an appropriate selection
+   */
+  if (list->selection && list->selection->data)
+    {
+      GtkListItem *item;
+
+      item = list->selection->data;
+      
+      if (GTK_IS_LIST_ITEM (item))
+       {
+         gchar *filename;
+         
+         filename = gtk_object_get_user_data (GTK_OBJECT (item));
+         gtk_entry_set_text (GTK_ENTRY (fs->selection_entry), filename);
+       }
+    }
+}
+
+static gint
+gtk_file_selection_dir_button (GtkWidget      *widget,
+                              GdkEventButton *event,
+                              gpointer        user_data)
+{
+  GtkFileSelection *fs;
+  GtkWidget *event_widget;
+  gchar *filename;
+  gboolean handled;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_LIST (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  fs = GTK_FILE_SELECTION (user_data);
+  g_return_val_if_fail (fs != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_FILE_SELECTION (fs), FALSE);
+
+  event_widget = gtk_get_event_widget ((GdkEvent*) event);
+  handled = FALSE;
+  if (GTK_IS_LIST_ITEM (event_widget))
+    {
+      gint key;
+
+      filename = gtk_object_get_user_data (GTK_OBJECT (event_widget));
+
+      key = (gint) gtk_object_get_data (GTK_OBJECT (widget), list_changed_key);
+
+      switch (event->type)
+       {
+       case GDK_BUTTON_PRESS:
+
+         gtk_signal_handler_block (GTK_OBJECT (widget), key);
+         gtk_widget_activate (GTK_WIDGET (event_widget));
+         gtk_signal_handler_unblock (GTK_OBJECT (widget), key);
+
+         gtk_widget_grab_focus (fs->selection_entry);
+         gtk_entry_set_text (GTK_ENTRY (fs->selection_entry), filename);
+         handled = TRUE;
+         break;
+
+       case GDK_2BUTTON_PRESS:
+         gtk_file_selection_populate (fs, filename, FALSE);
+         handled = TRUE;
+         break;
+
+       default:
+         break;
+       }
+    }
+
+  return handled;
+}
+
+static void
+gtk_file_selection_dir_list_changed (GtkList          *list,
+                                    gpointer          func_data)
+{
+  GtkFileSelection *fs;
+  
+  g_return_if_fail (func_data != NULL);
+  g_return_if_fail (GTK_IS_FILE_SELECTION (func_data));
+  
+  fs = GTK_FILE_SELECTION (func_data);
+
+  /* only act on an appropriate selection
+   */
+  if (list->selection && list->selection->data)
+    {
+      GtkListItem *item;
+
+      item = list->selection->data;
+      
+      if (GTK_IS_LIST_ITEM (item))
+       {
+         gchar *filename;
+         
+         filename = gtk_object_get_user_data (GTK_OBJECT (item));
+
+         if (filename)
+           gtk_file_selection_populate (fs, filename, FALSE);
+       }
+    }
+}
+
+static void
+gtk_file_selection_populate (GtkFileSelection *fs,
+                            gchar            *rel_path,
+                            gint              try_complete)
+{
+  CompletionState *cmpl_state;
+  PossibleCompletion* poss;
+  GList *dir_list = NULL;
+  GList *file_list = NULL;
+  GtkWidget *label;
+  gchar* filename;
+  gchar* rem_path = rel_path;
+  gchar* sel_text;
+  gint did_recurse = FALSE;
+  gint possible_count = 0;
+  gint selection_index = -1;
+  gint dir_changed_key;
+  
+  g_return_if_fail (fs != NULL);
+  g_return_if_fail (GTK_IS_FILE_SELECTION (fs));
+  
+  dir_changed_key = (gint) gtk_object_get_data (GTK_OBJECT (fs->dir_list), list_changed_key);
+  gtk_signal_handler_block (GTK_OBJECT (fs->dir_list), dir_changed_key);
+  
+  cmpl_state = (CompletionState*) fs->cmpl_state;
+  poss = cmpl_completion_matches (rel_path, &rem_path, cmpl_state);
+
+  if (!cmpl_state_okay (cmpl_state))
+    {
+      /* Something went wrong. */
+      gtk_file_selection_abort (fs);
+      gtk_signal_handler_unblock (GTK_OBJECT (fs->dir_list), dir_changed_key);
+      return;
+    }
+
+  g_assert (cmpl_state->reference_dir);
+
+  /* Set the dir_list and file_list to be GLists of strdup'd
+   * filenames, including ./ and ../ */
+  dir_list = g_list_prepend (dir_list, g_strdup("./"));
+  dir_list = g_list_prepend (dir_list, g_strdup("../"));
+
+  while (poss)
+    {
+      if (cmpl_is_a_completion (poss))
+        {
+          possible_count += 1;
+
+          filename = g_strdup (cmpl_this_completion (poss));
+
+          if (cmpl_is_directory (poss))
+            {
+              if (strcmp (filename, "./") != 0 &&
+                  strcmp (filename, "../") != 0)
+                dir_list = g_list_prepend (dir_list, filename);
+            }
+          else
+            file_list = g_list_prepend (file_list, filename);
+        }
+
+      poss = cmpl_next_completion (cmpl_state);
+    }
+
+  /* File lists are set. */
+
+  g_assert (cmpl_state->reference_dir);
+
+  if (try_complete)
+    {
+      /* User is trying to complete filenames, so advance the user's input
+       * string to the updated_text, which is the common leading substring
+       * of all possible completions, and if its a directory attempt
+       * attempt completions in it. */
+
+      if (cmpl_updated_text (cmpl_state)[0])
+        {
+          if (cmpl_updated_dir (cmpl_state))
+            {
+              gchar* dir_name = g_strdup (cmpl_updated_text (cmpl_state));
+
+              did_recurse = TRUE;
+
+              gtk_file_selection_populate (fs, dir_name, TRUE);
+
+              g_free (dir_name);
+            }
+          else
+            {
+             if (fs->selection_entry)
+               gtk_entry_set_text (GTK_ENTRY (fs->selection_entry),
+                                   cmpl_updated_text (cmpl_state));
+            }
+        }
+      else
+        {
+          selection_index = cmpl_last_valid_char (cmpl_state) -
+                            (strlen (rel_path) - strlen (rem_path));
+         if (fs->selection_entry)
+           gtk_entry_set_text (GTK_ENTRY (fs->selection_entry), rem_path);
+        }
+    }
+  else
+    {
+      if (fs->selection_entry)
+       gtk_entry_set_text (GTK_ENTRY (fs->selection_entry), "");
+    }
+
+  if (!did_recurse)
+    {
+      GList *file_label_list = NULL;
+      GList *dir_label_list = NULL;
+
+      /* This reverses the lists. */
+      while (file_list)
+        {
+          label = gtk_list_item_new_with_label (file_list->data);
+          gtk_object_set_user_data (GTK_OBJECT (label), file_list->data);
+          gtk_widget_show (label);
+
+          file_label_list = g_list_prepend (file_label_list, label);
+          file_list = file_list->next;
+        }
+
+      while (dir_list)
+        {
+          label = gtk_list_item_new_with_label (dir_list->data);
+          gtk_object_set_user_data (GTK_OBJECT (label), dir_list->data);
+          gtk_widget_show (label);
+
+          dir_label_list = g_list_prepend (dir_label_list, label);
+          dir_list = dir_list->next;
+        }
+
+      gtk_container_disable_resize (GTK_CONTAINER (fs));
+
+      if (fs->selection_entry)
+       gtk_entry_set_position (GTK_ENTRY (fs->selection_entry), selection_index);
+
+      if (fs->selection_entry)
+       {
+         sel_text = g_new (char, strlen (cmpl_reference_position (cmpl_state)) +
+                           sizeof ("Selection: "));
+         strcpy (sel_text, "Selection: ");
+         strcat (sel_text, cmpl_reference_position (cmpl_state));
+
+         gtk_label_set (GTK_LABEL (fs->selection_text), sel_text);
+         g_free (sel_text);
+       }
+
+      if (fs->dir_list)
+       {
+         gtk_container_foreach (GTK_CONTAINER (fs->dir_list),
+                                gtk_file_selection_free_filename, NULL);
+         gtk_list_clear_items (GTK_LIST (fs->dir_list), 0, -1);
+
+         if (dir_label_list)
+           gtk_list_append_items (GTK_LIST (fs->dir_list), dir_label_list);
+       }
+      if (fs->file_list)
+       {
+         gtk_container_foreach (GTK_CONTAINER (fs->file_list),
+                                gtk_file_selection_free_filename, NULL);
+         gtk_list_clear_items (GTK_LIST (fs->file_list), 0, -1);
+
+         if (file_label_list)
+           gtk_list_append_items (GTK_LIST (fs->file_list), file_label_list);
+       }
+
+      gtk_container_enable_resize (GTK_CONTAINER (fs));
+    }
+  else
+    {
+      GList *dir_list0 = dir_list;
+      GList *file_list0 = file_list;
+
+      while (dir_list)
+        {
+          GList *tmp = dir_list;
+          dir_list = dir_list->next;
+
+          if (tmp)
+            g_free (tmp->data);
+        }
+
+      while (file_list)
+        {
+          GList *tmp = file_list;
+          file_list = file_list->next;
+
+          if (tmp)
+            g_free (tmp->data);
+        }
+
+      g_list_free (dir_list0);
+      g_list_free (file_list0);
+    }
+
+  gtk_signal_handler_unblock (GTK_OBJECT (fs->dir_list), dir_changed_key);
+}
+
+static void
+gtk_file_selection_abort (GtkFileSelection *fs)
+{
+  gchar err_buf[256];
+
+  sprintf (err_buf, "Directory unreadable: %s", cmpl_strerror (cmpl_errno));
+
+  /*  BEEP gdk_beep();  */
+
+  if (fs->selection_entry)
+    gtk_label_set (GTK_LABEL (fs->selection_text), err_buf);
+}
+
+static void
+gtk_file_selection_free_filename (GtkWidget *widget,
+                                 gpointer   client_data)
+{
+  g_return_if_fail (widget != NULL);
+
+  g_free (gtk_object_get_user_data (GTK_OBJECT (widget)));
+  gtk_object_set_user_data (GTK_OBJECT (widget), NULL);
+}
+
+
+
+/**********************************************************************/
+/*                       External Interface                          */
+/**********************************************************************/
+
+/* The four completion state selectors
+ */
+static gchar*
+cmpl_updated_text (CompletionState* cmpl_state)
+{
+  return cmpl_state->updated_text;
+}
+
+static gint
+cmpl_updated_dir (CompletionState* cmpl_state)
+{
+  return cmpl_state->re_complete;
+}
+
+static gchar*
+cmpl_reference_position (CompletionState* cmpl_state)
+{
+  return cmpl_state->reference_dir->fullname;
+}
+
+static gint
+cmpl_last_valid_char (CompletionState* cmpl_state)
+{
+  return cmpl_state->last_valid_char;
+}
+
+static gchar*
+cmpl_completion_fullname (gchar* text, CompletionState* cmpl_state)
+{
+  if (text[0] == '/')
+    {
+      strcpy (cmpl_state->updated_text, text);
+    }
+  else if (text[0] == '~')
+    {
+      CompletionDir* dir;
+      char* slash;
+
+      dir = open_user_dir (text, cmpl_state);
+
+      if (!dir)
+       {
+         /* spencer says just return ~something, so
+          * for now just do it. */
+         strcpy (cmpl_state->updated_text, text);
+       }
+      else
+       {
+
+         strcpy (cmpl_state->updated_text, dir->fullname);
+
+         slash = strchr (text, '/');
+
+         if (slash)
+           strcat (cmpl_state->updated_text, slash);
+       }
+    }
+  else
+    {
+      strcpy (cmpl_state->updated_text, cmpl_state->reference_dir->fullname);
+      strcat (cmpl_state->updated_text, "/");
+      strcat (cmpl_state->updated_text, text);
+    }
+
+  return cmpl_state->updated_text;
+}
+
+/* The three completion selectors
+ */
+static gchar*
+cmpl_this_completion (PossibleCompletion* pc)
+{
+  return pc->text;
+}
+
+static gint
+cmpl_is_directory (PossibleCompletion* pc)
+{
+  return pc->is_directory;
+}
+
+static gint
+cmpl_is_a_completion (PossibleCompletion* pc)
+{
+  return pc->is_a_completion;
+}
+
+/**********************************************************************/
+/*                      Construction, deletion                       */
+/**********************************************************************/
+
+static CompletionState*
+cmpl_init_state (void)
+{
+  gchar getcwd_buf[2*MAXPATHLEN];
+  CompletionState *new_state;
+
+  new_state = g_new (CompletionState, 1);
+
+  if (!getcwd (getcwd_buf, MAXPATHLEN))
+    {
+      cmpl_errno = errno;
+      return NULL;
+    }
+
+  new_state->reference_dir = NULL;
+  new_state->completion_dir = NULL;
+  new_state->active_completion_dir = NULL;
+
+  if ((new_state->user_home_dir = getenv("HOME")) != NULL)
+    {
+      /* if this fails, get_pwdb will fill it in. */
+      new_state->user_home_dir = g_strdup(new_state->user_home_dir);
+    }
+
+  new_state->directory_storage = NULL;
+  new_state->directory_sent_storage = NULL;
+  new_state->last_valid_char = 0;
+  new_state->updated_text = g_new (gchar, MAXPATHLEN);
+  new_state->updated_text_alloc = MAXPATHLEN;
+  new_state->the_completion.text = g_new (gchar, MAXPATHLEN);
+  new_state->the_completion.text_alloc = MAXPATHLEN;
+  new_state->user_dir_name_buffer = NULL;
+  new_state->user_directories = NULL;
+
+  new_state->reference_dir =  open_dir (getcwd_buf, new_state);
+
+  if (!new_state->reference_dir)
+    return NULL;
+
+  return new_state;
+}
+
+static void
+cmpl_free_dir_list(GList* dp0)
+{
+  GList *dp = dp0;
+
+  while (dp) {
+    free_dir (dp->data);
+    dp = dp->next;
+  }
+
+  g_list_free(dp0);
+}
+
+static void
+cmpl_free_dir_sent_list(GList* dp0)
+{
+  GList *dp = dp0;
+
+  while (dp) {
+    free_dir_sent (dp->data);
+    dp = dp->next;
+  }
+
+  g_list_free(dp0);
+}
+
+static void
+cmpl_free_state (CompletionState* cmpl_state)
+{
+  cmpl_free_dir_list(cmpl_state->directory_storage);
+  cmpl_free_dir_sent_list(cmpl_state->directory_sent_storage);
+
+  if (cmpl_state->user_dir_name_buffer)
+    g_free (cmpl_state->user_dir_name_buffer);
+  if (cmpl_state->user_directories)
+    g_free (cmpl_state->user_directories);
+  if (cmpl_state->the_completion.text)
+    g_free (cmpl_state->the_completion.text);
+  if (cmpl_state->updated_text)
+    g_free (cmpl_state->updated_text);
+
+  g_free (cmpl_state);
+}
+
+static void
+free_dir(CompletionDir* dir)
+{
+  g_free(dir->fullname);
+  g_free(dir);
+}
+
+static void
+free_dir_sent(CompletionDirSent* sent)
+{
+  g_free(sent->name_buffer);
+  g_free(sent->entries);
+  g_free(sent);
+}
+
+static void
+prune_memory_usage(CompletionState *cmpl_state)
+{
+  GList* cdsl = cmpl_state->directory_sent_storage;
+  GList* cdl = cmpl_state->directory_storage;
+  GList* cdl0 = cdl;
+  gint len = 0;
+
+  for(; cdsl && len < CMPL_DIRECTORY_CACHE_SIZE; len += 1)
+    cdsl = cdsl->next;
+
+  if (cdsl) {
+    cmpl_free_dir_sent_list(cdsl->next);
+    cdsl->next = NULL;
+  }
+
+  while (cdl) {
+    if (cdl->data == cmpl_state->reference_dir)
+      cmpl_state->directory_storage = g_list_prepend(NULL, cdl->data);
+    else
+      free_dir (cdl->data);
+    cdl = cdl->next;
+  }
+
+  g_list_free(cdl0);
+}
+
+/**********************************************************************/
+/*                        The main entrances.                         */
+/**********************************************************************/
+
+static PossibleCompletion*
+cmpl_completion_matches (gchar* text_to_complete,
+                        gchar** remaining_text,
+                        CompletionState* cmpl_state)
+{
+  gchar* first_slash;
+  PossibleCompletion *poss;
+
+  prune_memory_usage(cmpl_state);
+
+  g_assert(text_to_complete);
+
+  cmpl_state->user_completion_index = -1;
+  cmpl_state->last_completion_text = text_to_complete;
+  cmpl_state->the_completion.text[0] = 0;
+  cmpl_state->last_valid_char = 0;
+  cmpl_state->updated_text_len = -1;
+  cmpl_state->updated_text[0] = 0;
+  cmpl_state->re_complete = FALSE;
+
+  first_slash = strchr(text_to_complete, '/');
+
+  if(text_to_complete[0] == '~' && !first_slash)
+    {
+      /* Text starts with ~ and there is no slash, show all the
+       * home directory completions.
+       */
+      poss = attempt_homedir_completion(text_to_complete, cmpl_state);
+
+      update_cmpl(poss, cmpl_state);
+
+      return poss;
+    }
+
+  cmpl_state->reference_dir =
+    open_ref_dir(text_to_complete, remaining_text, cmpl_state);
+
+  if(!cmpl_state->reference_dir)
+    return NULL;
+
+  cmpl_state->completion_dir =
+    find_completion_dir(*remaining_text, remaining_text, cmpl_state);
+
+  cmpl_state->last_valid_char = *remaining_text - text_to_complete;
+
+  if(!cmpl_state->completion_dir)
+    return NULL;
+
+  cmpl_state->completion_dir->cmpl_index = -1;
+  cmpl_state->completion_dir->cmpl_parent = NULL;
+  cmpl_state->completion_dir->cmpl_text = *remaining_text;
+
+  cmpl_state->active_completion_dir = cmpl_state->completion_dir;
+
+  cmpl_state->reference_dir = cmpl_state->completion_dir;
+
+  poss = attempt_file_completion(cmpl_state);
+
+  update_cmpl(poss, cmpl_state);
+
+  return poss;
+}
+
+static PossibleCompletion*
+cmpl_next_completion (CompletionState* cmpl_state)
+{
+  PossibleCompletion* poss = NULL;
+
+  cmpl_state->the_completion.text[0] = 0;
+
+  if(cmpl_state->user_completion_index >= 0)
+    poss = attempt_homedir_completion(cmpl_state->last_completion_text, cmpl_state);
+  else
+    poss = attempt_file_completion(cmpl_state);
+
+  update_cmpl(poss, cmpl_state);
+
+  return poss;
+}
+
+/**********************************************************************/
+/*                      Directory Operations                         */
+/**********************************************************************/
+
+/* Open the directory where completion will begin from, if possible. */
+static CompletionDir*
+open_ref_dir(gchar* text_to_complete,
+            gchar** remaining_text,
+            CompletionState* cmpl_state)
+{
+  gchar* first_slash;
+  CompletionDir *new_dir;
+
+  first_slash = strchr(text_to_complete, '/');
+
+  if (text_to_complete[0] == '/' || !cmpl_state->reference_dir)
+    {
+      new_dir = open_dir("/", cmpl_state);
+
+      if(new_dir)
+       *remaining_text = text_to_complete + 1;
+    }
+  else if (text_to_complete[0] == '~')
+    {
+      new_dir = open_user_dir(text_to_complete, cmpl_state);
+
+      if(new_dir)
+       {
+         if(first_slash)
+           *remaining_text = first_slash + 1;
+         else
+           *remaining_text = text_to_complete + strlen(text_to_complete);
+       }
+      else
+       {
+         return NULL;
+       }
+    }
+  else
+    {
+      *remaining_text = text_to_complete;
+
+      new_dir = open_dir(cmpl_state->reference_dir->fullname, cmpl_state);
+    }
+
+  if(new_dir)
+    {
+      new_dir->cmpl_index = -1;
+      new_dir->cmpl_parent = NULL;
+    }
+
+  return new_dir;
+}
+
+/* open a directory by user name */
+static CompletionDir*
+open_user_dir(gchar* text_to_complete,
+             CompletionState *cmpl_state)
+{
+  gchar *first_slash;
+  gint cmp_len;
+
+  g_assert(text_to_complete && text_to_complete[0] == '~');
+
+  first_slash = strchr(text_to_complete, '/');
+
+  if (first_slash)
+    cmp_len = first_slash - text_to_complete - 1;
+  else
+    cmp_len = strlen(text_to_complete + 1);
+
+  if(!cmp_len)
+    {
+      /* ~/ */
+      if (!cmpl_state->user_home_dir &&
+         !get_pwdb(cmpl_state))
+       return NULL;
+      return open_dir(cmpl_state->user_home_dir, cmpl_state);
+    }
+  else
+    {
+      /* ~user/ */
+      char* copy = g_new(char, cmp_len + 1);
+      struct passwd *pwd;
+      strncpy(copy, text_to_complete + 1, cmp_len);
+      copy[cmp_len] = 0;
+      pwd = getpwnam(copy);
+      g_free(copy);
+      if (!pwd)
+       {
+         cmpl_errno = errno;
+         return NULL;
+       }
+
+      return open_dir(pwd->pw_dir, cmpl_state);
+    }
+}
+
+/* open a directory relative the the current relative directory */
+static CompletionDir*
+open_relative_dir(gchar* dir_name,
+                 CompletionDir* dir,
+                 CompletionState *cmpl_state)
+{
+  gchar path_buf[2*MAXPATHLEN];
+
+  if(dir->fullname_len + strlen(dir_name) + 2 >= MAXPATHLEN)
+    {
+      cmpl_errno = CMPL_ERRNO_TOO_LONG;
+      return NULL;
+    }
+
+  strcpy(path_buf, dir->fullname);
+
+  if(dir->fullname_len > 1)
+    {
+      path_buf[dir->fullname_len] = '/';
+      strcpy(path_buf + dir->fullname_len + 1, dir_name);
+    }
+  else
+    {
+      strcpy(path_buf + dir->fullname_len, dir_name);
+    }
+
+  return open_dir(path_buf, cmpl_state);
+}
+
+/* after the cache lookup fails, really open a new directory */
+static CompletionDirSent*
+open_new_dir(gchar* dir_name, struct stat* sbuf)
+{
+  CompletionDirSent* sent;
+  DIR* directory;
+  gchar *buffer_ptr;
+  struct dirent *dirent_ptr;
+  gint buffer_size = 0;
+  gint entry_count = 0;
+  gint i;
+  struct stat ent_sbuf;
+  char path_buf[MAXPATHLEN*2];
+  gint path_buf_len;
+
+  sent = g_new(CompletionDirSent, 1);
+  sent->mtime = sbuf->st_mtime;
+  sent->inode = sbuf->st_ino;
+
+  path_buf_len = strlen(dir_name);
+
+  if (path_buf_len > MAXPATHLEN)
+    {
+      cmpl_errno = CMPL_ERRNO_TOO_LONG;
+      return NULL;
+    }
+
+  strcpy(path_buf, dir_name);
+
+  directory = opendir(dir_name);
+
+  if(!directory)
+    {
+      cmpl_errno = errno;
+      return NULL;
+    }
+
+  while((dirent_ptr = readdir(directory)) != NULL)
+    {
+      int entry_len = strlen(dirent_ptr->d_name);
+      buffer_size += entry_len + 1;
+      entry_count += 1;
+
+      if(path_buf_len + entry_len + 2 >= MAXPATHLEN)
+       {
+         cmpl_errno = CMPL_ERRNO_TOO_LONG;
+         closedir(directory);
+         return NULL;
+       }
+    }
+
+  sent->name_buffer = g_new(gchar, buffer_size);
+  sent->entries = g_new(CompletionDirEntry, entry_count);
+  sent->entry_count = entry_count;
+
+  buffer_ptr = sent->name_buffer;
+
+  rewinddir(directory);
+
+  for(i = 0; i < entry_count; i += 1)
+    {
+      dirent_ptr = readdir(directory);
+
+      if(!dirent_ptr)
+       {
+         cmpl_errno = errno;
+         closedir(directory);
+         return NULL;
+       }
+
+      strcpy(buffer_ptr, dirent_ptr->d_name);
+      sent->entries[i].entry_name = buffer_ptr;
+      buffer_ptr += strlen(dirent_ptr->d_name);
+      *buffer_ptr = 0;
+      buffer_ptr += 1;
+
+      path_buf[path_buf_len] = '/';
+      strcpy(path_buf + path_buf_len + 1, dirent_ptr->d_name);
+
+      if(stat(path_buf, &ent_sbuf) >= 0 && S_ISDIR(ent_sbuf.st_mode))
+       sent->entries[i].is_dir = 1;
+      else
+       /* stat may fail, and we don't mind, since it could be a
+        * dangling symlink. */
+       sent->entries[i].is_dir = 0;
+    }
+
+  qsort(sent->entries, sent->entry_count, sizeof(CompletionDirEntry), compare_cmpl_dir);
+
+  closedir(directory);
+
+  return sent;
+}
+
+/* open a directory by absolute pathname */
+static CompletionDir*
+open_dir(gchar* dir_name, CompletionState* cmpl_state)
+{
+  struct stat sbuf;
+  CompletionDirSent *sent;
+  GList* cdsl;
+
+  if(stat(dir_name, &sbuf) < 0)
+    {
+      cmpl_errno = errno;
+      return NULL;
+    }
+
+  cdsl = cmpl_state->directory_sent_storage;
+
+  while (cdsl)
+    {
+      sent = cdsl->data;
+
+      if(sent->inode == sbuf.st_ino &&
+        sent->mtime == sbuf.st_mtime)
+       return attach_dir(sent, dir_name, cmpl_state);
+
+      cdsl = cdsl->next;
+    }
+
+  sent = open_new_dir(dir_name, &sbuf);
+
+  if (sent) {
+    cmpl_state->directory_sent_storage =
+      g_list_prepend(cmpl_state->directory_sent_storage, sent);
+
+    return attach_dir(sent, dir_name, cmpl_state);
+  }
+
+  return NULL;
+}
+
+static CompletionDir*
+attach_dir(CompletionDirSent* sent, gchar* dir_name, CompletionState *cmpl_state)
+{
+  CompletionDir* new_dir;
+
+  new_dir = g_new(CompletionDir, 1);
+
+  cmpl_state->directory_storage =
+    g_list_prepend(cmpl_state->directory_storage, new_dir);
+
+  new_dir->sent = sent;
+  new_dir->fullname = g_strdup(dir_name);
+  new_dir->fullname_len = strlen(dir_name);
+
+  return new_dir;
+}
+
+static gint
+correct_dir_fullname(CompletionDir* cmpl_dir)
+{
+  gint length = strlen(cmpl_dir->fullname);
+  struct stat sbuf;
+
+  if (strcmp(cmpl_dir->fullname + length - 2, "/.") == 0)
+    cmpl_dir->fullname[length - 2] = 0;
+  else if (strcmp(cmpl_dir->fullname + length - 3, "/./") == 0)
+    cmpl_dir->fullname[length - 3] = 0;
+  else if (strcmp(cmpl_dir->fullname + length - 3, "/..") == 0)
+    {
+      if(length == 3)
+       {
+         strcpy(cmpl_dir->fullname, "/");
+         cmpl_dir->fullname_len = 1;
+         return TRUE;
+       }
+
+      if(stat(cmpl_dir->fullname, &sbuf) < 0)
+       {
+         cmpl_errno = errno;
+         return FALSE;
+       }
+
+      cmpl_dir->fullname[length - 3] = 0;
+
+      if(!correct_parent(cmpl_dir, &sbuf))
+       return FALSE;
+    }
+  else if (strcmp(cmpl_dir->fullname + length - 4, "/../") == 0)
+    {
+      if(length == 4)
+       {
+         strcpy(cmpl_dir->fullname, "/");
+         cmpl_dir->fullname_len = 1;
+         return TRUE;
+       }
+
+      if(stat(cmpl_dir->fullname, &sbuf) < 0)
+       {
+         cmpl_errno = errno;
+         return FALSE;
+       }
+
+      cmpl_dir->fullname[length - 4] = 0;
+
+      if(!correct_parent(cmpl_dir, &sbuf))
+       return FALSE;
+    }
+
+  cmpl_dir->fullname_len = strlen(cmpl_dir->fullname);
+
+  return TRUE;
+}
+
+static gint
+correct_parent(CompletionDir* cmpl_dir, struct stat *sbuf)
+{
+  struct stat parbuf;
+  gchar *last_slash;
+  gchar *new_name;
+  gchar c = 0;
+
+  last_slash = strrchr(cmpl_dir->fullname, '/');
+
+  g_assert(last_slash);
+
+  if(last_slash != cmpl_dir->fullname)
+    last_slash[0] = 0;
+  else
+    {
+      c = last_slash[1];
+      last_slash[1] = 0;
+    }
+
+  if (stat(cmpl_dir->fullname, &parbuf) < 0)
+    {
+      cmpl_errno = errno;
+      return FALSE;
+    }
+
+  if (parbuf.st_ino == sbuf->st_ino && parbuf.st_dev == sbuf->st_dev)
+    /* it wasn't a link */
+    return TRUE;
+
+  if(c)
+    last_slash[1] = c;
+  else
+    last_slash[0] = '/';
+
+  /* it was a link, have to figure it out the hard way */
+
+  new_name = find_parent_dir_fullname(cmpl_dir->fullname);
+
+  if (!new_name)
+    return FALSE;
+
+  g_free(cmpl_dir->fullname);
+
+  cmpl_dir->fullname = new_name;
+
+  return TRUE;
+}
+
+static gchar*
+find_parent_dir_fullname(gchar* dirname)
+{
+  gchar buffer[MAXPATHLEN];
+  gchar buffer2[MAXPATHLEN];
+
+  if(!getcwd(buffer, MAXPATHLEN))
+    {
+      cmpl_errno = errno;
+      return NULL;
+    }
+
+  if(chdir(dirname) != 0 || chdir("..") != 0)
+    {
+      cmpl_errno = errno;
+      return NULL;
+    }
+
+  if(!getcwd(buffer2, MAXPATHLEN))
+    {
+      chdir(buffer);
+      cmpl_errno = errno;
+
+      return NULL;
+    }
+
+  if(chdir(buffer) != 0)
+    {
+      cmpl_errno = errno;
+      return NULL;
+    }
+
+  return g_strdup(buffer2);
+}
+
+/**********************************************************************/
+/*                        Completion Operations                       */
+/**********************************************************************/
+
+static PossibleCompletion*
+attempt_homedir_completion(gchar* text_to_complete,
+                          CompletionState *cmpl_state)
+{
+  gint index, length;
+
+  if (!cmpl_state->user_dir_name_buffer &&
+      !get_pwdb(cmpl_state))
+    return NULL;
+  length = strlen(text_to_complete) - 1;
+
+  cmpl_state->user_completion_index += 1;
+
+  while(cmpl_state->user_completion_index < cmpl_state->user_directories_len)
+    {
+      index = first_diff_index(text_to_complete + 1,
+                              cmpl_state->user_directories
+                              [cmpl_state->user_completion_index].login);
+
+      switch(index)
+       {
+       case PATTERN_MATCH:
+         break;
+       default:
+         if(cmpl_state->last_valid_char < (index + 1))
+           cmpl_state->last_valid_char = index + 1;
+         cmpl_state->user_completion_index += 1;
+         continue;
+       }
+
+      cmpl_state->the_completion.is_a_completion = 1;
+      cmpl_state->the_completion.is_directory = 1;
+
+      append_completion_text("~", cmpl_state);
+
+      append_completion_text(cmpl_state->
+                             user_directories[cmpl_state->user_completion_index].login,
+                            cmpl_state);
+
+      return append_completion_text("/", cmpl_state);
+    }
+
+  if(text_to_complete[1] ||
+     cmpl_state->user_completion_index > cmpl_state->user_directories_len)
+    {
+      cmpl_state->user_completion_index = -1;
+      return NULL;
+    }
+  else
+    {
+      cmpl_state->user_completion_index += 1;
+      cmpl_state->the_completion.is_a_completion = 1;
+      cmpl_state->the_completion.is_directory = 1;
+
+      return append_completion_text("~/", cmpl_state);
+    }
+}
+
+/* returns the index (>= 0) of the first differing character,
+ * PATTERN_MATCH if the completion matches */
+static gint
+first_diff_index(gchar* pat, gchar* text)
+{
+  gint diff = 0;
+
+  while(*pat && *text && *text == *pat)
+    {
+      pat += 1;
+      text += 1;
+      diff += 1;
+    }
+
+  if(*pat)
+    return diff;
+
+  return PATTERN_MATCH;
+}
+
+static PossibleCompletion*
+append_completion_text(gchar* text, CompletionState* cmpl_state)
+{
+  gint len, i = 1;
+
+  if(!cmpl_state->the_completion.text)
+    return NULL;
+
+  len = strlen(text) + strlen(cmpl_state->the_completion.text) + 1;
+
+  if(cmpl_state->the_completion.text_alloc > len)
+    {
+      strcat(cmpl_state->the_completion.text, text);
+      return &cmpl_state->the_completion;
+    }
+
+  while(i < len) { i <<= 1; }
+
+  cmpl_state->the_completion.text_alloc = i;
+
+  cmpl_state->the_completion.text = (gchar*)g_realloc(cmpl_state->the_completion.text, i);
+
+  if(!cmpl_state->the_completion.text)
+    return NULL;
+  else
+    {
+      strcat(cmpl_state->the_completion.text, text);
+      return &cmpl_state->the_completion;
+    }
+}
+
+static CompletionDir*
+find_completion_dir(gchar* text_to_complete,
+                   gchar** remaining_text,
+                   CompletionState* cmpl_state)
+{
+  gchar* first_slash = strchr(text_to_complete, '/');
+  CompletionDir* dir = cmpl_state->reference_dir;
+  *remaining_text = text_to_complete;
+
+  while(first_slash)
+    {
+      gint len = first_slash - *remaining_text;
+      gint found = 0;
+      gint found_index = -1;
+      gint i;
+      gchar* pat_buf = g_new (gchar, len + 1);
+
+      strncpy(pat_buf, *remaining_text, len);
+      pat_buf[len] = 0;
+
+      for(i = 0; i < dir->sent->entry_count; i += 1)
+       {
+         if(dir->sent->entries[i].is_dir &&
+            fnmatch(pat_buf, dir->sent->entries[i].entry_name,
+                    FNMATCH_FLAGS)!= FNM_NOMATCH)
+           {
+             if(found)
+               {
+                 g_free (pat_buf);
+                 return dir;
+               }
+             else
+               {
+                 found = 1;
+                 found_index = i;
+               }
+           }
+       }
+
+      if(found)
+       {
+         CompletionDir* next = open_relative_dir(dir->sent->entries[found_index].entry_name,
+                                                 dir, cmpl_state);
+
+         if(!next)
+           {
+             g_free (pat_buf);
+             return NULL;
+           }
+
+         next->cmpl_parent = dir;
+
+         dir = next;
+
+         if(!correct_dir_fullname(dir))
+           {
+             g_free(pat_buf);
+             return NULL;
+           }
+
+         *remaining_text = first_slash + 1;
+         first_slash = strchr(*remaining_text, '/');
+       }
+      else
+       {
+         g_free (pat_buf);
+         return NULL;
+       }
+
+      g_free (pat_buf);
+    }
+
+  return dir;
+}
+
+static void
+update_cmpl(PossibleCompletion* poss, CompletionState* cmpl_state)
+{
+  gint cmpl_len;
+
+  if(!poss || !cmpl_is_a_completion(poss))
+    return;
+
+  cmpl_len = strlen(cmpl_this_completion(poss));
+
+  if(cmpl_state->updated_text_alloc < cmpl_len + 1)
+    {
+      cmpl_state->updated_text =
+       (gchar*)g_realloc(cmpl_state->updated_text,
+                         cmpl_state->updated_text_alloc);
+      cmpl_state->updated_text_alloc = 2*cmpl_len;
+    }
+
+  if(cmpl_state->updated_text_len < 0)
+    {
+      strcpy(cmpl_state->updated_text, cmpl_this_completion(poss));
+      cmpl_state->updated_text_len = cmpl_len;
+      cmpl_state->re_complete = cmpl_is_directory(poss);
+    }
+  else if(cmpl_state->updated_text_len == 0)
+    {
+      cmpl_state->re_complete = FALSE;
+    }
+  else
+    {
+      gint first_diff =
+       first_diff_index(cmpl_state->updated_text,
+                        cmpl_this_completion(poss));
+
+      cmpl_state->re_complete = FALSE;
+
+      if(first_diff == PATTERN_MATCH)
+       return;
+
+      if(first_diff > cmpl_state->updated_text_len)
+       strcpy(cmpl_state->updated_text, cmpl_this_completion(poss));
+
+      cmpl_state->updated_text_len = first_diff;
+      cmpl_state->updated_text[first_diff] = 0;
+    }
+}
+
+static PossibleCompletion*
+attempt_file_completion(CompletionState *cmpl_state)
+{
+  gchar *pat_buf, *first_slash;
+  CompletionDir *dir = cmpl_state->active_completion_dir;
+
+  dir->cmpl_index += 1;
+
+  if(dir->cmpl_index == dir->sent->entry_count)
+    {
+      if(dir->cmpl_parent == NULL)
+       {
+         cmpl_state->active_completion_dir = NULL;
+
+         return NULL;
+       }
+      else
+       {
+         cmpl_state->active_completion_dir = dir->cmpl_parent;
+
+         return attempt_file_completion(cmpl_state);
+       }
+    }
+
+  g_assert(dir->cmpl_text);
+
+  first_slash = strchr(dir->cmpl_text, '/');
+
+  if(first_slash)
+    {
+      gint len = first_slash - dir->cmpl_text;
+
+      pat_buf = g_new (gchar, len + 1);
+      strncpy(pat_buf, dir->cmpl_text, len);
+      pat_buf[len] = 0;
+    }
+  else
+    {
+      gint len = strlen(dir->cmpl_text);
+
+      pat_buf = g_new (gchar, len + 2);
+      strcpy(pat_buf, dir->cmpl_text);
+      strcpy(pat_buf + len, "*");
+    }
+
+  if(first_slash)
+    {
+      if(dir->sent->entries[dir->cmpl_index].is_dir)
+       {
+         if(fnmatch(pat_buf, dir->sent->entries[dir->cmpl_index].entry_name,
+                    FNMATCH_FLAGS) != FNM_NOMATCH)
+           {
+             CompletionDir* new_dir;
+
+             new_dir = open_relative_dir(dir->sent->entries[dir->cmpl_index].entry_name,
+                                         dir, cmpl_state);
+
+             if(!new_dir)
+               {
+                 g_free (pat_buf);
+                 return NULL;
+               }
+
+             new_dir->cmpl_parent = dir;
+
+             new_dir->cmpl_index = -1;
+             new_dir->cmpl_text = first_slash + 1;
+
+             cmpl_state->active_completion_dir = new_dir;
+
+             g_free (pat_buf);
+             return attempt_file_completion(cmpl_state);
+           }
+         else
+           {
+             g_free (pat_buf);
+             return attempt_file_completion(cmpl_state);
+           }
+       }
+      else
+       {
+         g_free (pat_buf);
+         return attempt_file_completion(cmpl_state);
+       }
+    }
+  else
+    {
+      if(dir->cmpl_parent != NULL)
+       {
+         append_completion_text(dir->fullname +
+                                strlen(cmpl_state->completion_dir->fullname) + 1,
+                                cmpl_state);
+         append_completion_text("/", cmpl_state);
+       }
+
+      append_completion_text(dir->sent->entries[dir->cmpl_index].entry_name, cmpl_state);
+
+      cmpl_state->the_completion.is_a_completion =
+       (fnmatch(pat_buf, dir->sent->entries[dir->cmpl_index].entry_name,
+                FNMATCH_FLAGS) != FNM_NOMATCH);
+
+      cmpl_state->the_completion.is_directory = dir->sent->entries[dir->cmpl_index].is_dir;
+      if(dir->sent->entries[dir->cmpl_index].is_dir)
+       append_completion_text("/", cmpl_state);
+
+      g_free (pat_buf);
+      return &cmpl_state->the_completion;
+    }
+}
+
+
+static gint
+get_pwdb(CompletionState* cmpl_state)
+{
+  struct passwd *pwd_ptr;
+  gchar* buf_ptr, *home_dir = NULL;
+  gint len = 0, i, count = 0;
+
+  if(cmpl_state->user_dir_name_buffer)
+    return TRUE;
+  setpwent ();
+
+  while ((pwd_ptr = getpwent()) != NULL)
+    {
+      len += strlen(pwd_ptr->pw_name);
+      len += strlen(pwd_ptr->pw_dir);
+      len += 2;
+      count += 1;
+    }
+
+  if (!cmpl_state->user_home_dir)
+    {
+      /* the loser doesn't have $HOME set */
+      setpwent ();
+
+      pwd_ptr = getpwuid(getuid());
+      if(!pwd_ptr)
+       {
+         cmpl_errno = errno;
+         goto error;
+       }
+      home_dir = pwd_ptr->pw_dir;
+
+      len += strlen(home_dir);
+      len += 1;
+    }
+
+  setpwent ();
+
+  cmpl_state->user_dir_name_buffer = g_new(gchar, len);
+  cmpl_state->user_directories = g_new(CompletionUserDir, count);
+  cmpl_state->user_directories_len = count;
+
+  buf_ptr = cmpl_state->user_dir_name_buffer;
+
+  if (!cmpl_state->user_home_dir)
+    {
+      strcpy(buf_ptr, home_dir);
+      cmpl_state->user_home_dir = buf_ptr;
+      buf_ptr += strlen(buf_ptr);
+      buf_ptr += 1;
+    }
+
+  for(i = 0; i < count; i += 1)
+    {
+      pwd_ptr = getpwent();
+      if(!pwd_ptr)
+       {
+         cmpl_errno = errno;
+         goto error;
+       }
+
+      strcpy(buf_ptr, pwd_ptr->pw_name);
+      cmpl_state->user_directories[i].login = buf_ptr;
+      buf_ptr += strlen(buf_ptr);
+      buf_ptr += 1;
+      strcpy(buf_ptr, pwd_ptr->pw_dir);
+      cmpl_state->user_directories[i].homedir = buf_ptr;
+      buf_ptr += strlen(buf_ptr);
+      buf_ptr += 1;
+    }
+
+  qsort(cmpl_state->user_directories,
+       cmpl_state->user_directories_len,
+       sizeof(CompletionUserDir),
+       compare_user_dir);
+
+  endpwent();
+
+  return TRUE;
+
+error:
+
+  if(cmpl_state->user_dir_name_buffer)
+    g_free(cmpl_state->user_dir_name_buffer);
+  if(cmpl_state->user_directories)
+    g_free(cmpl_state->user_directories);
+
+  cmpl_state->user_dir_name_buffer = NULL;
+  cmpl_state->user_directories = NULL;
+
+  return FALSE;
+}
+
+static gint
+compare_user_dir(const void* a, const void* b)
+{
+  return strcmp((((CompletionUserDir*)a))->login,
+               (((CompletionUserDir*)b))->login);
+}
+
+static gint
+compare_cmpl_dir(const void* a, const void* b)
+{
+  return strcmp((((CompletionDirEntry*)a))->entry_name,
+               (((CompletionDirEntry*)b))->entry_name);
+}
+
+static gint
+cmpl_state_okay(CompletionState* cmpl_state)
+{
+  return  cmpl_state && cmpl_state->reference_dir;
+}
+
+static gchar*
+cmpl_strerror(gint err)
+{
+  if(err == CMPL_ERRNO_TOO_LONG)
+    return "Name too long";
+  else
+    return g_strerror (err);
+}
diff --git a/gtk/gtkfilesel.h b/gtk/gtkfilesel.h
new file mode 100644 (file)
index 0000000..1248ac6
--- /dev/null
@@ -0,0 +1,73 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_FILESEL_H__
+#define __GTK_FILESEL_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkwindow.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_FILE_SELECTION(obj)          GTK_CHECK_CAST (obj, gtk_file_selection_get_type (), GtkFileSelection)
+#define GTK_FILE_SELECTION_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_file_selection_get_type (), GtkFileSelectionClass)
+#define GTK_IS_FILE_SELECTION(obj)       GTK_CHECK_TYPE (obj, gtk_file_selection_get_type ())
+
+
+typedef struct _GtkFileSelection       GtkFileSelection;
+typedef struct _GtkFileSelectionClass  GtkFileSelectionClass;
+
+struct _GtkFileSelection
+{
+  GtkWindow window;
+
+  GtkWidget *dir_list;
+  GtkWidget *file_list;
+  GtkWidget *selection_entry;
+  GtkWidget *selection_text;
+  GtkWidget *main_vbox;
+  GtkWidget *ok_button;
+  GtkWidget *cancel_button;
+  GtkWidget *help_button;
+
+  gpointer cmpl_state;
+};
+
+struct _GtkFileSelectionClass
+{
+  GtkWindowClass parent_class;
+};
+
+
+guint      gtk_file_selection_get_type     (void);
+GtkWidget* gtk_file_selection_new          (const gchar           *title);
+void       gtk_file_selection_set_filename (GtkFileSelection      *filesel,
+                                           const gchar           *filename);
+gchar*     gtk_file_selection_get_filename (GtkFileSelection      *filesel);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_FILESEL_H__ */
diff --git a/gtk/gtkfixed.c b/gtk/gtkfixed.c
new file mode 100644 (file)
index 0000000..59eba1f
--- /dev/null
@@ -0,0 +1,525 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkfixed.h"
+
+
+static void gtk_fixed_class_init    (GtkFixedClass    *klass);
+static void gtk_fixed_init          (GtkFixed         *fixed);
+static void gtk_fixed_destroy       (GtkObject        *object);
+static void gtk_fixed_map           (GtkWidget        *widget);
+static void gtk_fixed_unmap         (GtkWidget        *widget);
+static void gtk_fixed_realize       (GtkWidget        *widget);
+static void gtk_fixed_unrealize     (GtkWidget        *widget);
+static void gtk_fixed_size_request  (GtkWidget        *widget,
+                                    GtkRequisition   *requisition);
+static void gtk_fixed_size_allocate (GtkWidget        *widget,
+                                    GtkAllocation    *allocation);
+static void gtk_fixed_paint         (GtkWidget        *widget,
+                                    GdkRectangle     *area);
+static void gtk_fixed_draw          (GtkWidget        *widget,
+                                    GdkRectangle     *area);
+static gint gtk_fixed_expose        (GtkWidget        *widget,
+                                    GdkEventExpose   *event);
+static void gtk_fixed_add           (GtkContainer     *container,
+                                    GtkWidget        *widget);
+static void gtk_fixed_remove        (GtkContainer     *container,
+                                    GtkWidget        *widget);
+static void gtk_fixed_foreach       (GtkContainer     *container,
+                                    GtkCallback      callback,
+                                    gpointer         callback_data);
+
+
+static GtkContainerClass *parent_class = NULL;
+
+
+guint
+gtk_fixed_get_type ()
+{
+  static guint fixed_type = 0;
+
+  if (!fixed_type)
+    {
+      GtkTypeInfo fixed_info =
+      {
+       "GtkFixed",
+       sizeof (GtkFixed),
+       sizeof (GtkFixedClass),
+       (GtkClassInitFunc) gtk_fixed_class_init,
+       (GtkObjectInitFunc) gtk_fixed_init,
+       (GtkArgFunc) NULL,
+      };
+
+      fixed_type = gtk_type_unique (gtk_container_get_type (), &fixed_info);
+    }
+
+  return fixed_type;
+}
+
+static void
+gtk_fixed_class_init (GtkFixedClass *class)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+  GtkContainerClass *container_class;
+
+  object_class = (GtkObjectClass*) class;
+  widget_class = (GtkWidgetClass*) class;
+  container_class = (GtkContainerClass*) class;
+
+  parent_class = gtk_type_class (gtk_container_get_type ());
+
+  object_class->destroy = gtk_fixed_destroy;
+
+  widget_class->map = gtk_fixed_map;
+  widget_class->unmap = gtk_fixed_unmap;
+  widget_class->realize = gtk_fixed_realize;
+  widget_class->unrealize = gtk_fixed_unrealize;
+  widget_class->size_request = gtk_fixed_size_request;
+  widget_class->size_allocate = gtk_fixed_size_allocate;
+  widget_class->draw = gtk_fixed_draw;
+  widget_class->expose_event = gtk_fixed_expose;
+
+  container_class->add = gtk_fixed_add;
+  container_class->remove = gtk_fixed_remove;
+  container_class->foreach = gtk_fixed_foreach;
+}
+
+static void
+gtk_fixed_init (GtkFixed *fixed)
+{
+  GTK_WIDGET_UNSET_FLAGS (fixed, GTK_NO_WINDOW);
+  GTK_WIDGET_SET_FLAGS (fixed, GTK_BASIC);
+  fixed->children = NULL;
+}
+
+GtkWidget*
+gtk_fixed_new ()
+{
+  GtkFixed *fixed;
+
+  fixed = gtk_type_new (gtk_fixed_get_type ());
+  return GTK_WIDGET (fixed);
+}
+
+void
+gtk_fixed_put (GtkFixed       *fixed,
+               GtkWidget      *widget,
+               gint16         x,
+               gint16         y)
+{
+  GtkFixedChild *child_info;
+
+  g_return_if_fail (fixed != NULL);
+  g_return_if_fail (GTK_IS_FIXED (fixed));
+  g_return_if_fail (widget != NULL);
+
+  child_info = g_new (GtkFixedChild, 1);
+  child_info->widget = widget;
+  child_info->x = x;
+  child_info->y = y;
+
+  gtk_widget_set_parent (widget, GTK_WIDGET (fixed));
+
+  fixed->children = g_list_append (fixed->children, child_info); 
+
+  if (GTK_WIDGET_REALIZED (fixed) && !GTK_WIDGET_REALIZED (widget))
+    gtk_widget_realize (widget);
+
+  if (GTK_WIDGET_MAPPED (fixed) && !GTK_WIDGET_MAPPED (widget))
+    gtk_widget_map (widget);
+
+  if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (fixed))
+    gtk_widget_queue_resize (GTK_WIDGET (fixed));
+}
+
+void
+gtk_fixed_move (GtkFixed       *fixed,
+                GtkWidget      *widget,
+                gint16         x,
+                gint16         y)
+{
+  GtkFixedChild *child;
+  GList *children;
+
+  g_return_if_fail (fixed != NULL);
+  g_return_if_fail (GTK_IS_FIXED (fixed));
+  g_return_if_fail (widget != NULL);
+
+  children = fixed->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (child->widget == widget)
+        {
+          child->x = x;
+          child->y = y;
+
+          if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (fixed))
+            gtk_widget_queue_resize (GTK_WIDGET (fixed));
+
+          break;
+        }
+    }
+}
+
+static void
+gtk_fixed_destroy (GtkObject *object)
+{
+  GtkFixed *fixed;
+  GtkFixedChild *child;
+  GList *children;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_FIXED (object));
+
+  fixed = GTK_FIXED (object);
+
+  children = fixed->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      child->widget->parent = NULL;
+      gtk_object_unref (GTK_OBJECT (child->widget));
+      gtk_widget_destroy (child->widget);
+      g_free (child);
+    }
+
+  g_list_free (fixed->children);
+
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+gtk_fixed_map (GtkWidget *widget)
+{
+  GtkFixed *fixed;
+  GtkFixedChild *child;
+  GList *children;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_FIXED (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
+  fixed = GTK_FIXED (widget);
+
+  gdk_window_show (widget->window);
+
+  children = fixed->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (child->widget) &&
+         !GTK_WIDGET_MAPPED (child->widget))
+       gtk_widget_map (child->widget);
+    }
+}
+
+static void
+gtk_fixed_unmap (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_FIXED (widget));
+
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
+}
+
+static void
+gtk_fixed_realize (GtkWidget *widget)
+{
+  GdkWindowAttr attributes;
+  gint attributes_mask;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_FIXED (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+
+  attributes.window_type = GDK_WINDOW_CHILD;
+  attributes.x = widget->allocation.x;
+  attributes.y = widget->allocation.y;
+  attributes.width = widget->allocation.width;
+  attributes.height = widget->allocation.height;
+  attributes.wclass = GDK_INPUT_OUTPUT;
+  attributes.visual = gtk_widget_get_visual (widget);
+  attributes.colormap = gtk_widget_get_colormap (widget);
+  attributes.event_mask = gtk_widget_get_events (widget);
+  attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK;
+
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+
+  widget->window = gdk_window_new (widget->parent->window, &attributes, 
+                                  attributes_mask);
+  gdk_window_set_user_data (widget->window, widget);
+
+  widget->style = gtk_style_attach (widget->style, widget->window);
+  gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
+}
+
+static void
+gtk_fixed_unrealize (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_FIXED (widget));
+
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED | GTK_MAPPED);
+
+  gtk_style_detach (widget->style);
+  gdk_window_destroy (widget->window);
+  widget->window = NULL;
+}
+
+static void
+gtk_fixed_size_request (GtkWidget      *widget,
+                       GtkRequisition *requisition)
+{
+  GtkFixed *fixed;  
+  GtkFixedChild *child;
+  GList *children;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_FIXED (widget));
+  g_return_if_fail (requisition != NULL);
+
+  fixed = GTK_FIXED (widget);
+  requisition->width = 0;
+  requisition->height = 0;
+
+  children = fixed->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (child->widget))
+       {
+          gtk_widget_size_request (child->widget, &child->widget->requisition);
+
+          requisition->height = MAX (requisition->height,
+                                     child->y +
+                                     child->widget->requisition.height);
+          requisition->width = MAX (requisition->width,
+                                    child->x +
+                                    child->widget->requisition.width);
+       }
+    }
+
+  requisition->height += GTK_CONTAINER (fixed)->border_width * 2;
+  requisition->width += GTK_CONTAINER (fixed)->border_width * 2;
+}
+
+static void
+gtk_fixed_size_allocate (GtkWidget     *widget,
+                        GtkAllocation *allocation)
+{
+  GtkFixed *fixed;
+  GtkFixedChild *child;
+  GtkAllocation child_allocation;
+  GList *children;
+  guint16 border_width;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_FIXED(widget));
+  g_return_if_fail (allocation != NULL);
+
+  fixed = GTK_FIXED (widget);
+
+  widget->allocation = *allocation;
+  if (GTK_WIDGET_REALIZED (widget))
+    gdk_window_move_resize (widget->window,
+                           allocation->x, 
+                           allocation->y,
+                           allocation->width, 
+                           allocation->height);
+
+  border_width = GTK_CONTAINER (fixed)->border_width;
+  
+  children = fixed->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+      
+      if (GTK_WIDGET_VISIBLE (child->widget))
+       {
+         child_allocation.x = child->x + border_width;
+         child_allocation.y = child->y + border_width;
+         child_allocation.width = child->widget->requisition.width;
+         child_allocation.height = child->widget->requisition.height;
+         gtk_widget_size_allocate (child->widget, &child_allocation);
+       }
+    }
+}
+
+static void
+gtk_fixed_paint (GtkWidget    *widget,
+                GdkRectangle *area)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_FIXED (widget));
+  g_return_if_fail (area != NULL);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+      gdk_window_clear_area (widget->window,
+                            area->x, area->y,
+                            area->width, area->height);
+}
+
+static void
+gtk_fixed_draw (GtkWidget    *widget,
+               GdkRectangle *area)
+{
+  GtkFixed *fixed;
+  GtkFixedChild *child;
+  GdkRectangle child_area;
+  GList *children;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_FIXED (widget));
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      fixed = GTK_FIXED (widget);
+      gtk_fixed_paint (widget, area);
+
+      children = fixed->children;
+      while (children)
+       {
+         child = children->data;
+         children = children->next;
+
+         if (gtk_widget_intersect (child->widget, area, &child_area))
+           gtk_widget_draw (child->widget, &child_area);
+       }
+    }
+}
+
+static gint
+gtk_fixed_expose (GtkWidget      *widget,
+                 GdkEventExpose *event)
+{
+  GtkFixed *fixed;
+  GtkFixedChild *child;
+  GdkEventExpose child_event;
+  GList *children;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_FIXED (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      fixed = GTK_FIXED (widget);
+
+      child_event = *event;
+
+      children = fixed->children;
+      while (children)
+       {
+         child = children->data;
+         children = children->next;
+
+         if (GTK_WIDGET_NO_WINDOW (child->widget) &&
+             gtk_widget_intersect (child->widget, &event->area, 
+                                   &child_event.area))
+           gtk_widget_event (child->widget, (GdkEvent*) &child_event);
+       }
+    }
+
+  return FALSE;
+}
+
+static void
+gtk_fixed_add (GtkContainer *container,
+              GtkWidget    *widget)
+{
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_FIXED (container));
+  g_return_if_fail (widget != NULL);
+
+  gtk_fixed_put (GTK_FIXED (container), widget, 0, 0);
+}
+
+static void
+gtk_fixed_remove (GtkContainer *container,
+                 GtkWidget    *widget)
+{
+  GtkFixed *fixed;
+  GtkFixedChild *child;
+  GList *children;
+
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_FIXED (container));
+  g_return_if_fail (widget != NULL);
+
+  fixed = GTK_FIXED (container);
+
+  children = fixed->children;
+  while (children)
+    {
+      child = children->data;
+
+      if (child->widget == widget)
+       {
+         gtk_widget_unparent (widget);
+
+         fixed->children = g_list_remove_link (fixed->children, children);
+         g_list_free (children);
+         g_free (child);
+
+         if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
+           gtk_widget_queue_resize (GTK_WIDGET (container));
+
+         break;
+       }
+
+      children = children->next;
+    }
+}
+
+static void
+gtk_fixed_foreach (GtkContainer *container,
+                  GtkCallback   callback,
+                  gpointer      callback_data)
+{
+  GtkFixed *fixed;
+  GtkFixedChild *child;
+  GList *children;
+
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_FIXED (container));
+  g_return_if_fail (callback != NULL);
+
+  fixed = GTK_FIXED (container);
+
+  children = fixed->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      (* callback) (child->widget, callback_data);
+    }
+}
diff --git a/gtk/gtkfixed.h b/gtk/gtkfixed.h
new file mode 100644 (file)
index 0000000..ee9c131
--- /dev/null
@@ -0,0 +1,76 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_FIXED_H__
+#define __GTK_FIXED_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkcontainer.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_FIXED(obj)          GTK_CHECK_CAST (obj, gtk_fixed_get_type (), GtkFixed)
+#define GTK_FIXED_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_fixed_get_type (), GtkFixedClass)
+#define GTK_IS_FIXED(obj)       GTK_CHECK_TYPE (obj, gtk_fixed_get_type ())
+
+
+typedef struct _GtkFixed        GtkFixed;
+typedef struct _GtkFixedClass   GtkFixedClass;
+typedef struct _GtkFixedChild   GtkFixedChild;
+
+struct _GtkFixed
+{
+  GtkContainer container;
+
+  GList *children;
+};
+
+struct _GtkFixedClass
+{
+  GtkContainerClass parent_class;
+};
+
+struct _GtkFixedChild
+{
+  GtkWidget *widget;
+  gint16 x;
+  gint16 y;
+};
+
+
+guint      gtk_fixed_get_type          (void);
+GtkWidget* gtk_fixed_new               ();
+void       gtk_fixed_put               (GtkFixed       *fixed,
+                                        GtkWidget      *widget,
+                                        gint16         x,
+                                        gint16         y);
+void       gtk_fixed_move              (GtkFixed       *fixed,
+                                        GtkWidget      *widget,
+                                        gint16         x,
+                                        gint16         y);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_FIXED_H__ */
diff --git a/gtk/gtkframe.c b/gtk/gtkframe.c
new file mode 100644 (file)
index 0000000..fe78897
--- /dev/null
@@ -0,0 +1,419 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkframe.h"
+
+
+static void gtk_frame_class_init    (GtkFrameClass  *klass);
+static void gtk_frame_init          (GtkFrame       *frame);
+static void gtk_frame_destroy       (GtkObject      *object);
+static void gtk_frame_paint         (GtkWidget      *widget,
+                                    GdkRectangle   *area);
+static void gtk_frame_draw          (GtkWidget      *widget,
+                                    GdkRectangle   *area);
+static gint gtk_frame_expose        (GtkWidget      *widget,
+                                    GdkEventExpose *event);
+static void gtk_frame_size_request  (GtkWidget      *widget,
+                                    GtkRequisition *requisition);
+static void gtk_frame_size_allocate (GtkWidget      *widget,
+                                    GtkAllocation  *allocation);
+
+
+static GtkBinClass *parent_class = NULL;
+
+
+guint
+gtk_frame_get_type ()
+{
+  static guint frame_type = 0;
+
+  if (!frame_type)
+    {
+      GtkTypeInfo frame_info =
+      {
+       "GtkFrame",
+       sizeof (GtkFrame),
+       sizeof (GtkFrameClass),
+       (GtkClassInitFunc) gtk_frame_class_init,
+       (GtkObjectInitFunc) gtk_frame_init,
+       (GtkArgFunc) NULL,
+      };
+
+      frame_type = gtk_type_unique (gtk_bin_get_type (), &frame_info);
+    }
+
+  return frame_type;
+}
+
+static void
+gtk_frame_class_init (GtkFrameClass *class)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+
+  object_class = (GtkObjectClass*) class;
+  widget_class = (GtkWidgetClass*) class;
+
+  parent_class = gtk_type_class (gtk_bin_get_type ());
+
+  object_class->destroy = gtk_frame_destroy;
+
+  widget_class->draw = gtk_frame_draw;
+  widget_class->expose_event = gtk_frame_expose;
+  widget_class->size_request = gtk_frame_size_request;
+  widget_class->size_allocate = gtk_frame_size_allocate;
+}
+
+static void
+gtk_frame_init (GtkFrame *frame)
+{
+  GTK_WIDGET_SET_FLAGS (frame, GTK_BASIC);
+
+  frame->label = NULL;
+  frame->shadow_type = GTK_SHADOW_ETCHED_IN;
+  frame->label_width = 0;
+  frame->label_height = 0;
+  frame->label_xalign = 0.0;
+  frame->label_yalign = 0.5;
+}
+
+GtkWidget*
+gtk_frame_new (const gchar *label)
+{
+  GtkFrame *frame;
+
+  frame = gtk_type_new (gtk_frame_get_type ());
+
+  gtk_frame_set_label (frame, label);
+
+  return GTK_WIDGET (frame);
+}
+
+void
+gtk_frame_set_label (GtkFrame *frame,
+                    const gchar *label)
+{
+  g_return_if_fail (frame != NULL);
+  g_return_if_fail (GTK_IS_FRAME (frame));
+
+  if ((label && frame->label && (strcmp (frame->label, label) == 0)) ||
+      (!label && !frame->label))
+    return;
+
+  if (frame->label)
+    g_free (frame->label);
+  frame->label = NULL;
+
+  if (label)
+    {
+      frame->label = g_strdup (label);
+      frame->label_width = gdk_string_measure (GTK_WIDGET (frame)->style->font, frame->label) + 7;
+      frame->label_height = (GTK_WIDGET (frame)->style->font->ascent +
+                            GTK_WIDGET (frame)->style->font->descent + 1);
+    }
+  else
+    {
+      frame->label_width = 0;
+      frame->label_height = 0;
+    }
+
+  if (GTK_WIDGET_DRAWABLE (frame))
+    {
+      GtkWidget *widget;
+
+      /* clear the old label area
+      */
+      widget = GTK_WIDGET (frame);
+      gdk_window_clear_area (widget->window,
+                             widget->allocation.x + GTK_CONTAINER (frame)->border_width,
+                             widget->allocation.y + GTK_CONTAINER (frame)->border_width,
+                             widget->allocation.width - GTK_CONTAINER (frame)->border_width,
+                             widget->allocation.y + frame->label_height);
+
+      gtk_widget_queue_resize (GTK_WIDGET (frame));
+    }
+}
+
+void
+gtk_frame_set_label_align (GtkFrame *frame,
+                          gfloat    xalign,
+                          gfloat    yalign)
+{
+  g_return_if_fail (frame != NULL);
+  g_return_if_fail (GTK_IS_FRAME (frame));
+
+  xalign = CLAMP (xalign, 0.0, 1.0);
+  yalign = CLAMP (yalign, 0.0, 1.0);
+
+  if ((xalign != frame->label_xalign) || (yalign != frame->label_yalign))
+    {
+      frame->label_xalign = xalign;
+      frame->label_yalign = yalign;
+
+      if (GTK_WIDGET_VISIBLE (frame))
+       {
+          GtkWidget *widget;
+
+          /* clear the old label area
+          */
+          widget = GTK_WIDGET (frame);
+          gdk_window_clear_area (widget->window,
+                                 widget->allocation.x + GTK_CONTAINER (frame)->border_width,
+                                 widget->allocation.y + GTK_CONTAINER (frame)->border_width,
+                                 widget->allocation.width - GTK_CONTAINER (frame)->border_width,
+                                 widget->allocation.y + frame->label_height);
+
+         gtk_widget_size_allocate (GTK_WIDGET (frame), &(GTK_WIDGET (frame)->allocation));
+         gtk_widget_queue_draw (GTK_WIDGET (frame));
+       }
+    }
+}
+
+void
+gtk_frame_set_shadow_type (GtkFrame      *frame,
+                          GtkShadowType  type)
+{
+  g_return_if_fail (frame != NULL);
+  g_return_if_fail (GTK_IS_FRAME (frame));
+
+  if ((GtkShadowType) frame->shadow_type != type)
+    {
+      frame->shadow_type = type;
+
+      if (GTK_WIDGET_MAPPED (frame))
+       {
+         gdk_window_clear_area (GTK_WIDGET (frame)->window,
+                                GTK_WIDGET (frame)->allocation.x,
+                                GTK_WIDGET (frame)->allocation.y,
+                                GTK_WIDGET (frame)->allocation.width,
+                                GTK_WIDGET (frame)->allocation.height);
+         gtk_widget_size_allocate (GTK_WIDGET (frame), &(GTK_WIDGET (frame)->allocation));
+         gtk_widget_queue_draw (GTK_WIDGET (frame));
+       }
+    }
+}
+
+
+static void
+gtk_frame_destroy (GtkObject *object)
+{
+  GtkFrame *frame;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_FRAME (object));
+
+  frame = GTK_FRAME (object);
+
+  if (frame->label)
+    g_free (frame->label);
+
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+gtk_frame_paint (GtkWidget    *widget,
+                GdkRectangle *area)
+{
+  GtkFrame *frame;
+  GtkStateType state;
+  gint height_extra;
+  gint label_area_width;
+  gint x, y;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_FRAME (widget));
+  g_return_if_fail (area != NULL);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      frame = GTK_FRAME (widget);
+
+      state = widget->state;
+      if (!GTK_WIDGET_IS_SENSITIVE (widget))
+        state = GTK_STATE_INSENSITIVE;
+
+      height_extra = frame->label_height - widget->style->klass->xthickness;
+      height_extra = MAX (height_extra, 0);
+
+      x = GTK_CONTAINER (frame)->border_width;
+      y = GTK_CONTAINER (frame)->border_width;
+
+      gtk_draw_shadow (widget->style, widget->window,
+                      GTK_STATE_NORMAL, frame->shadow_type,
+                      widget->allocation.x + x,
+                      widget->allocation.y + y + height_extra / 2,
+                      widget->allocation.width - x * 2,
+                      widget->allocation.height - y * 2 - height_extra / 2);
+
+      if (frame->label)
+       {
+         label_area_width = (widget->allocation.width -
+                             GTK_CONTAINER (frame)->border_width * 2 -
+                             widget->style->klass->xthickness * 2);
+
+         x = ((label_area_width - frame->label_width) * frame->label_xalign +
+              GTK_CONTAINER (frame)->border_width + widget->style->klass->xthickness);
+         y = (GTK_CONTAINER (frame)->border_width + widget->style->font->ascent);
+
+         gdk_window_clear_area (widget->window,
+                                widget->allocation.x + x + 2,
+                                widget->allocation.y + GTK_CONTAINER (frame)->border_width,
+                                frame->label_width - 4,
+                                frame->label_height);
+         gtk_draw_string (widget->style, widget->window, state,
+                          widget->allocation.x + x + 3,
+                          widget->allocation.y + y,
+                          frame->label);
+       }
+    }
+}
+
+static void
+gtk_frame_draw (GtkWidget    *widget,
+               GdkRectangle *area)
+{
+  GtkBin *bin;
+  GdkRectangle child_area;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_FRAME (widget));
+  g_return_if_fail (area != NULL);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      bin = GTK_BIN (widget);
+
+      gtk_frame_paint (widget, area);
+
+      if (bin->child && gtk_widget_intersect (bin->child, area, &child_area))
+       gtk_widget_draw (bin->child, &child_area);
+    }
+}
+
+static gint
+gtk_frame_expose (GtkWidget      *widget,
+                 GdkEventExpose *event)
+{
+  GtkBin *bin;
+  GdkEventExpose child_event;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_FRAME (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      bin = GTK_BIN (widget);
+
+      gtk_frame_paint (widget, &event->area);
+
+      child_event = *event;
+      if (bin->child &&
+         GTK_WIDGET_NO_WINDOW (bin->child) &&
+         gtk_widget_intersect (bin->child, &event->area, &child_event.area))
+       gtk_widget_event (bin->child, (GdkEvent*) &child_event);
+    }
+
+  return FALSE;
+}
+
+static void
+gtk_frame_size_request (GtkWidget      *widget,
+                       GtkRequisition *requisition)
+{
+  GtkFrame *frame;
+  GtkBin *bin;
+  gint tmp_height;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_FRAME (widget));
+  g_return_if_fail (requisition != NULL);
+
+  frame = GTK_FRAME (widget);
+  bin = GTK_BIN (widget);
+
+  requisition->width = (GTK_CONTAINER (widget)->border_width +
+                       GTK_WIDGET (widget)->style->klass->xthickness) * 2;
+
+  tmp_height = frame->label_height - GTK_WIDGET (widget)->style->klass->ythickness;
+  tmp_height = MAX (tmp_height, 0);
+
+  requisition->height = tmp_height + (GTK_CONTAINER (widget)->border_width +
+                                     GTK_WIDGET (widget)->style->klass->ythickness) * 2;
+
+  if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
+    {
+      gtk_widget_size_request (bin->child, &bin->child->requisition);
+
+      requisition->width += MAX (bin->child->requisition.width, frame->label_width);
+      requisition->height += bin->child->requisition.height;
+    }
+  else
+    {
+      requisition->width += frame->label_width;
+    }
+}
+
+static void
+gtk_frame_size_allocate (GtkWidget     *widget,
+                        GtkAllocation *allocation)
+{
+  GtkFrame *frame;
+  GtkBin *bin;
+  GtkAllocation child_allocation;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_FRAME (widget));
+  g_return_if_fail (allocation != NULL);
+
+  frame = GTK_FRAME (widget);
+  bin = GTK_BIN (widget);
+
+  if (GTK_WIDGET_MAPPED (widget) &&
+      ((widget->allocation.x != allocation->x) ||
+       (widget->allocation.y != allocation->y) ||
+       (widget->allocation.width != allocation->width) ||
+       (widget->allocation.height != allocation->height)) &&
+      (widget->allocation.width != 0) &&
+      (widget->allocation.height != 0))
+    gdk_window_clear_area (widget->window,
+                          widget->allocation.x,
+                          widget->allocation.y,
+                          widget->allocation.width,
+                          widget->allocation.height);
+
+  widget->allocation = *allocation;
+
+  if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
+    {
+      child_allocation.x = (GTK_CONTAINER (frame)->border_width +
+                           GTK_WIDGET (frame)->style->klass->xthickness);
+      child_allocation.width = MAX(0, allocation->width - child_allocation.x * 2);
+
+      child_allocation.y = (GTK_CONTAINER (frame)->border_width +
+                           MAX (frame->label_height, GTK_WIDGET (frame)->style->klass->ythickness));
+      child_allocation.height = MAX (0, (allocation->height - child_allocation.y -
+                                        GTK_CONTAINER (frame)->border_width -
+                                        GTK_WIDGET (frame)->style->klass->ythickness));
+
+      child_allocation.x += allocation->x;
+      child_allocation.y += allocation->y;
+
+      gtk_widget_size_allocate (bin->child, &child_allocation);
+    }
+}
diff --git a/gtk/gtkframe.h b/gtk/gtkframe.h
new file mode 100644 (file)
index 0000000..3fe17a3
--- /dev/null
@@ -0,0 +1,73 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_FRAME_H__
+#define __GTK_FRAME_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkbin.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_FRAME(obj)          GTK_CHECK_CAST (obj, gtk_frame_get_type (), GtkFrame)
+#define GTK_FRAME_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_frame_get_type (), GtkFrameClass)
+#define GTK_IS_FRAME(obj)       GTK_CHECK_TYPE (obj, gtk_frame_get_type ())
+
+
+typedef struct _GtkFrame       GtkFrame;
+typedef struct _GtkFrameClass  GtkFrameClass;
+
+struct _GtkFrame
+{
+  GtkBin bin;
+
+  gchar *label;
+  gint16 shadow_type;
+  gint16 label_width;
+  gint16 label_height;
+  gfloat label_xalign;
+  gfloat label_yalign;
+};
+
+struct _GtkFrameClass
+{
+  GtkBinClass parent_class;
+};
+
+
+guint      gtk_frame_get_type        (void);
+GtkWidget* gtk_frame_new             (const gchar   *label);
+void       gtk_frame_set_label       (GtkFrame      *frame,
+                                     const gchar   *label);
+void       gtk_frame_set_label_align (GtkFrame      *frame,
+                                     gfloat         xalign,
+                                     gfloat         yalign);
+void       gtk_frame_set_shadow_type (GtkFrame      *frame,
+                                     GtkShadowType  type);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_FRAME_H__ */
diff --git a/gtk/gtkgamma.c b/gtk/gtkgamma.c
new file mode 100644 (file)
index 0000000..1d7abc6
--- /dev/null
@@ -0,0 +1,464 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1997 David Mosberger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "gtkgamma.h"
+#include "gtkcurve.h"
+#include "gtkdialog.h"
+#include "gtkdrawingarea.h"
+#include "gtkentry.h"
+#include "gtkhbox.h"
+#include "gtklabel.h"
+#include "gtkmain.h"
+#include "gtkpixmap.h"
+#include "gtkradiobutton.h"
+#include "gtksignal.h"
+#include "gtktable.h"
+#include "gtkvbox.h"
+#include "gtkwindow.h"
+
+static GtkVBoxClass *parent_class = NULL;
+
+
+/* forward declarations: */
+static void gtk_gamma_curve_class_init (GtkGammaCurveClass *class);
+static void gtk_gamma_curve_init (GtkGammaCurve *curve);
+static void gtk_gamma_curve_destroy (GtkObject *object);
+
+enum
+  {
+    LINEAR = 0,
+    SPLINE,
+    FREE,
+    GAMMA,
+    RESET,
+    NUM_XPMS
+  };
+
+static char *xpm[][27] =
+  {
+    /* spline: */
+    {
+      /* width height ncolors chars_per_pixel */
+      "16 16 4 1",
+      /* colors */
+      ". c None",
+      "B c #000000",
+      "+ c #BC2D2D",
+      "r c #FF0000",
+      /* pixels */
+      "..............BB",
+      ".........rrrrrrB",
+      ".......rr.......",
+      ".....B+.........",
+      "....BBB.........",
+      "....+B..........",
+      "....r...........",
+      "...r............",
+      "...r............",
+      "..r.............",
+      "..r.............",
+      ".r..............",
+      ".r..............",
+      ".r..............",
+      "B+..............",
+      "BB.............."
+    },
+    /* linear: */
+    {
+      /* width height ncolors chars_per_pixel */
+      "16 16 5 1",
+      /* colors */
+      ". c None", /* transparent */
+      "B c #000000",
+      "' c #7F7F7F",
+      "+ c #824141",
+      "r c #FF0000",
+      /* pixels */
+      "..............BB",
+      "..............+B",
+      "..............r.",
+      ".............r..",
+      ".............r..",
+      "....'B'.....r...",
+      "....BBB.....r...",
+      "....+B+....r....",
+      "....r.r....r....",
+      "...r...r..r.....",
+      "...r...r..r.....",
+      "..r.....rB+.....",
+      "..r.....BBB.....",
+      ".r......'B'.....",
+      "B+..............",
+      "BB.............."
+    },
+    /* free: */
+    {
+      /* width height ncolors chars_per_pixel */
+      "16 16 2 1",
+      /* colors */
+      ". c None",
+      "r c #FF0000",
+      /* pixels */
+      "................",
+      "................",
+      "......r.........",
+      "......r.........",
+      ".......r........",
+      ".......r........",
+      ".......r........",
+      "........r.......",
+      "........r.......",
+      "........r.......",
+      ".....r...r.rrrrr",
+      "....r....r......",
+      "...r.....r......",
+      "..r.......r.....",
+      ".r........r.....",
+      "r..............."
+    },
+    /* gamma: */
+    {
+      /* width height ncolors chars_per_pixel */
+      "16 16 10 1",
+      /* colors */
+      ". c None",
+      "B c #000000",
+      "& c #171717",
+      "# c #2F2F2F",
+      "X c #464646",
+      "= c #5E5E5E",
+      "/ c #757575",
+      "+ c #8C8C8C",
+      "- c #A4A4A4",
+      "` c #BBBBBB",
+      /* pixels */
+      "................",
+      "................",
+      "................",
+      "....B=..+B+.....",
+      "....X&`./&-.....",
+      "...../+.XX......",
+      "......B.B+......",
+      "......X.X.......",
+      "......X&+.......",
+      "......-B........",
+      "....../=........",
+      "......#B........",
+      "......BB........",
+      "......B#........",
+      "................",
+      "................"
+    },
+    /* reset: */
+    {
+      /* width height ncolors chars_per_pixel */
+      "16 16 4 1",
+      /* colors */
+      ". c None",
+      "B c #000000",
+      "+ c #824141",
+      "r c #FF0000",
+      /* pixels */
+      "..............BB",
+      "..............+B",
+      ".............r..",
+      "............r...",
+      "...........r....",
+      "..........r.....",
+      ".........r......",
+      "........r.......",
+      ".......r........",
+      "......r.........",
+      ".....r..........",
+      "....r...........",
+      "...r............",
+      "..r.............",
+      "B+..............",
+      "BB.............."
+    }
+  };
+
+guint
+gtk_gamma_curve_get_type (void)
+{
+  static guint gamma_curve_type = 0;
+
+  if (!gamma_curve_type)
+    {
+      GtkTypeInfo gamma_curve_info =
+      {
+       "GtkGammaCurve",
+       sizeof (GtkGammaCurve),
+       sizeof (GtkGammaCurveClass),
+       (GtkClassInitFunc) gtk_gamma_curve_class_init,
+       (GtkObjectInitFunc) gtk_gamma_curve_init,
+       (GtkArgFunc) NULL,
+      };
+
+      gamma_curve_type =
+       gtk_type_unique (gtk_vbox_get_type (), &gamma_curve_info);
+    }
+  return gamma_curve_type;
+}
+
+static void
+gtk_gamma_curve_class_init (GtkGammaCurveClass *class)
+{
+  GtkObjectClass *object_class;
+
+  parent_class = gtk_type_class (gtk_vbox_get_type ());
+
+  object_class = (GtkObjectClass *) class;
+  object_class->destroy = gtk_gamma_curve_destroy;
+}
+
+static void
+gtk_gamma_curve_init (GtkGammaCurve *curve)
+{
+  curve->gamma = 1.0;
+}
+
+static void
+button_realize_callback (GtkWidget *w)
+{
+  GtkWidget *pixmap;
+  GdkBitmap *mask;
+  GdkPixmap *pm;
+  int i;
+
+  i = (long) gtk_object_get_data (GTK_OBJECT (w), "_GtkGammaCurveIndex");
+  pm = gdk_pixmap_create_from_xpm_d (w->window, &mask,
+                                    &w->style->bg[GTK_STATE_NORMAL], xpm[i]);
+
+  pixmap = gtk_pixmap_new (pm, mask);
+  gtk_container_add (GTK_CONTAINER (w), pixmap);
+  gtk_widget_show (pixmap);
+
+  gdk_pixmap_destroy (pm);
+  gdk_pixmap_destroy (mask);   /* a bitmap is really just a special pixmap */
+}
+
+static void
+button_toggled_callback (GtkWidget *w, gpointer data)
+{
+  GtkGammaCurve *c = data;
+  GtkCurveType type;
+  int active, i;
+
+  if (!GTK_TOGGLE_BUTTON (w)->active)
+    return;
+
+  active = (long) gtk_object_get_data (GTK_OBJECT (w), "_GtkGammaCurveIndex");
+
+  for (i = 0; i < 3; ++i)
+    if ((i != active) && GTK_TOGGLE_BUTTON (c->button[i])->active)
+      break;
+
+  if (i < 3)
+    gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (c->button[i]), FALSE);
+
+  switch (active)
+    {
+    case 0:  type = GTK_CURVE_TYPE_SPLINE; break;
+    case 1:  type = GTK_CURVE_TYPE_LINEAR; break;
+    default: type = GTK_CURVE_TYPE_FREE; break;
+    }
+  gtk_curve_set_curve_type (GTK_CURVE (c->curve), type);
+}
+
+static void
+gamma_cancel_callback (GtkWidget *w, gpointer data)
+{
+  GtkGammaCurve *c = data;
+
+  gtk_widget_destroy (c->gamma_dialog);
+  c->gamma_dialog = 0;
+}
+
+static void
+gamma_ok_callback (GtkWidget *w, gpointer data)
+{
+  GtkGammaCurve *c = data;
+  gchar *start, *end;
+  gfloat v;
+
+  start = gtk_entry_get_text (GTK_ENTRY (c->gamma_text));
+  if (start)
+    {
+      v = strtod (start, &end);
+      if (end > start && v > 0.0)
+       c->gamma = v;
+    }
+  gtk_curve_set_gamma (GTK_CURVE (c->curve), c->gamma);
+  gamma_cancel_callback (w, data);
+}
+
+static void
+button_clicked_callback (GtkWidget *w, gpointer data)
+{
+  GtkGammaCurve *c = data;
+  int active;
+
+  active = (long) gtk_object_get_data (GTK_OBJECT (w), "_GtkGammaCurveIndex");
+  if (active == 3)
+    /* set gamma */
+    if (c->gamma_dialog)
+      return;
+    else
+      {
+       GtkWidget *vbox, *hbox, *label, *button;
+       gchar buf[64];
+
+       c->gamma_dialog = gtk_dialog_new ();
+       gtk_window_set_title (GTK_WINDOW (c->gamma_dialog), "Gamma");
+       vbox = GTK_DIALOG (c->gamma_dialog)->vbox;
+
+       hbox = gtk_hbox_new (/* homogeneous */ FALSE, 0);
+       gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 2);
+       gtk_widget_show (hbox);
+
+       label = gtk_label_new ("Gamma value");
+       gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 2);
+       gtk_widget_show (label);
+
+       sprintf (buf, "%g", c->gamma);
+       c->gamma_text = gtk_entry_new ();
+       gtk_entry_set_text (GTK_ENTRY (c->gamma_text), buf);
+       gtk_box_pack_start (GTK_BOX (hbox), c->gamma_text, TRUE, TRUE, 2);
+       gtk_widget_show (c->gamma_text);
+
+       /* fill in action area: */
+       hbox = GTK_DIALOG (c->gamma_dialog)->action_area;
+
+       button = gtk_button_new_with_label ("OK");
+       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+       gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                           (GtkSignalFunc) gamma_ok_callback, c);
+       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+       gtk_widget_grab_default (button);
+       gtk_widget_show (button);
+
+       button = gtk_button_new_with_label ("Cancel");
+       gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                           (GtkSignalFunc) gamma_cancel_callback, c);
+       gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+       gtk_widget_show (button);
+
+       gtk_widget_show (c->gamma_dialog);
+      }
+  else
+    /* reset */
+    gtk_curve_reset (GTK_CURVE (c->curve));
+}
+
+static void
+curve_type_changed_callback (GtkWidget *w, gpointer data)
+{
+  GtkGammaCurve *c = data;
+  GtkCurveType new_type;
+  int active;
+
+  new_type = GTK_CURVE (w)->curve_type;
+  switch (new_type)
+    {
+    case GTK_CURVE_TYPE_SPLINE: active = 0; break;
+    case GTK_CURVE_TYPE_LINEAR: active = 1; break;
+    default:                   active = 2; break;
+    }
+  if (!GTK_TOGGLE_BUTTON (c->button[active])->active)
+    gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (c->button[active]), TRUE);
+}
+
+GtkWidget*
+gtk_gamma_curve_new (void)
+{
+  GtkGammaCurve *c;
+  GtkWidget *vbox;
+  int i;
+
+  c = gtk_type_new (gtk_gamma_curve_get_type ());
+
+  c->table = gtk_table_new (1, 2, FALSE);
+  gtk_table_set_col_spacings (GTK_TABLE (c->table), 3);
+  gtk_container_add (GTK_CONTAINER (c), c->table);
+
+  c->curve = gtk_curve_new ();
+  gtk_signal_connect (GTK_OBJECT (c->curve), "curve_type_changed",
+                     (GtkSignalFunc) curve_type_changed_callback, c);
+  gtk_table_attach_defaults (GTK_TABLE (c->table), c->curve, 0, 1, 0, 1);
+
+  vbox = gtk_vbox_new (/* homogeneous */ FALSE, /* spacing */ 3);
+  gtk_table_attach (GTK_TABLE (c->table), vbox, 1, 2, 0, 1, 0, 0, 0, 0);
+
+  /* toggle buttons: */
+  for (i = 0; i < 3; ++i)
+    {
+      c->button[i] = gtk_toggle_button_new ();
+      gtk_object_set_data (GTK_OBJECT (c->button[i]), "_GtkGammaCurveIndex",
+                          (gpointer) (long) i);
+      gtk_container_add (GTK_CONTAINER (vbox), c->button[i]);
+      gtk_signal_connect (GTK_OBJECT (c->button[i]), "realize",
+                         (GtkSignalFunc) button_realize_callback, 0);
+      gtk_signal_connect (GTK_OBJECT (c->button[i]), "toggled",
+                         (GtkSignalFunc) button_toggled_callback, c);
+      gtk_widget_show (c->button[i]);
+    }
+
+  /* push buttons: */
+  for (i = 3; i < 5; ++i)
+    {
+      c->button[i] = gtk_button_new ();
+      gtk_object_set_data (GTK_OBJECT (c->button[i]), "_GtkGammaCurveIndex",
+                          (gpointer) (long) i);
+      gtk_container_add (GTK_CONTAINER (vbox), c->button[i]);
+      gtk_signal_connect (GTK_OBJECT (c->button[i]), "realize",
+                         (GtkSignalFunc) button_realize_callback, 0);
+      gtk_signal_connect (GTK_OBJECT (c->button[i]), "clicked",
+                         (GtkSignalFunc) button_clicked_callback, c);
+      gtk_widget_show (c->button[i]);
+    }
+
+  gtk_widget_show (vbox);
+  gtk_widget_show (c->table);
+  gtk_widget_show (c->curve);
+
+  return GTK_WIDGET (c);
+}
+
+static void
+gtk_gamma_curve_destroy (GtkObject *object)
+{
+  GtkGammaCurve *c;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_GAMMA_CURVE (object));
+
+  c = GTK_GAMMA_CURVE (object);
+
+  if (c->gamma_dialog)
+    {
+      gtk_widget_destroy (c->gamma_dialog);
+      c->gamma_dialog = 0;
+    }
+
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
diff --git a/gtk/gtkgamma.h b/gtk/gtkgamma.h
new file mode 100644 (file)
index 0000000..872a7bd
--- /dev/null
@@ -0,0 +1,71 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1997 David Mosberger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_GAMMA_CURVE_H__
+#define __GTK_GAMMA_CURVE_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkvbox.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_GAMMA_CURVE(obj) \
+   GTK_CHECK_CAST (obj, gtk_gamma_curve_get_type (), GtkGammaCurve)
+#define GTK_GAMMA_CURVE_CLASS(klass) \
+   GTK_CHECK_CLASS_CAST (klass, gtk_gamma_curve_get_type, GtkGammaCurveClass)
+#define GTK_IS_GAMMA_CURVE(obj) \
+   GTK_CHECK_TYPE (obj, gtk_gamma_curve_get_type ())
+
+
+typedef struct _GtkGammaCurve          GtkGammaCurve;
+typedef struct _GtkGammaCurveClass     GtkGammaCurveClass;
+
+
+struct _GtkGammaCurve
+{
+  GtkVBox vbox;
+
+  GtkWidget *table;
+  GtkWidget *curve;
+  GtkWidget *button[5];        /* spline, linear, free, gamma, reset */
+
+  gfloat gamma;
+  GtkWidget *gamma_dialog;
+  GtkWidget *gamma_text;
+};
+
+struct _GtkGammaCurveClass
+{
+  GtkVBoxClass parent_class;
+};
+
+
+guint      gtk_gamma_curve_get_type (void);
+GtkWidget* gtk_gamma_curve_new      (void);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_GAMMA_CURVE_H__ */
diff --git a/gtk/gtkgc.c b/gtk/gtkgc.c
new file mode 100644 (file)
index 0000000..c9da069
--- /dev/null
@@ -0,0 +1,382 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkgc.h"
+
+
+typedef struct _GtkGCKey       GtkGCKey;
+typedef struct _GtkGCDrawable  GtkGCDrawable;
+
+struct _GtkGCKey
+{
+  gint depth;
+  GdkColormap *colormap;
+  GdkGCValues values;
+  GdkGCValuesMask mask;
+};
+
+struct _GtkGCDrawable
+{
+  gint depth;
+  GdkPixmap *drawable;
+};
+
+
+static void      gtk_gc_init             (void);
+static GtkGCKey* gtk_gc_key_dup          (GtkGCKey      *key);
+static void      gtk_gc_key_destroy      (GtkGCKey      *key);
+static gpointer  gtk_gc_new              (gpointer       key);
+static void      gtk_gc_destroy          (gpointer       value);
+static guint     gtk_gc_key_hash         (gpointer       key);
+static guint     gtk_gc_value_hash       (gpointer       value);
+static gint      gtk_gc_key_compare      (gpointer       a,
+                                         gpointer       b);
+static guint     gtk_gc_drawable_hash    (GtkGCDrawable *d);
+static gint      gtk_gc_drawable_compare (GtkGCDrawable *a,
+                                         GtkGCDrawable *b);
+
+
+static gint initialize = TRUE;
+static GCache *gc_cache = NULL;
+static GHashTable *gc_drawable_ht = NULL;
+
+static GMemChunk *key_mem_chunk = NULL;
+
+
+GdkGC*
+gtk_gc_get (gint             depth,
+           GdkColormap     *colormap,
+           GdkGCValues     *values,
+           GdkGCValuesMask  values_mask)
+{
+  GtkGCKey key;
+  GdkGC *gc;
+
+  if (initialize)
+    gtk_gc_init ();
+
+  key.depth = depth;
+  key.colormap = colormap;
+  key.values = *values;
+  key.mask = values_mask;
+
+  gc = g_cache_insert (gc_cache, &key);
+
+  return gc;
+}
+
+void
+gtk_gc_release (GdkGC *gc)
+{
+  if (initialize)
+    gtk_gc_init ();
+
+  g_cache_remove (gc_cache, gc);
+}
+
+
+static void
+gtk_gc_init ()
+{
+  initialize = FALSE;
+
+  gc_cache = g_cache_new ((GCacheNewFunc) gtk_gc_new,
+                         (GCacheDestroyFunc) gtk_gc_destroy,
+                         (GCacheDupFunc) gtk_gc_key_dup,
+                         (GCacheDestroyFunc) gtk_gc_key_destroy,
+                         (GHashFunc) gtk_gc_key_hash,
+                         (GHashFunc) gtk_gc_value_hash,
+                         (GCompareFunc) gtk_gc_key_compare);
+
+  gc_drawable_ht = g_hash_table_new ((GHashFunc) gtk_gc_drawable_hash,
+                                    (GCompareFunc) gtk_gc_drawable_compare);
+}
+
+static GtkGCKey*
+gtk_gc_key_dup (GtkGCKey *key)
+{
+  GtkGCKey *new_key;
+
+  if (!key_mem_chunk)
+    key_mem_chunk = g_mem_chunk_new ("key mem chunk", sizeof (GtkGCKey),
+                                    1024, G_ALLOC_AND_FREE);
+
+  new_key = g_chunk_new (GtkGCKey, key_mem_chunk);
+
+  *new_key = *key;
+
+  return new_key;
+}
+
+static void
+gtk_gc_key_destroy (GtkGCKey *key)
+{
+  g_mem_chunk_free (key_mem_chunk, key);
+}
+
+static gpointer
+gtk_gc_new (gpointer key)
+{
+  GtkGCKey *keyval;
+  GtkGCDrawable *drawable;
+  GdkGC *gc;
+
+  keyval = key;
+
+  drawable = g_hash_table_lookup (gc_drawable_ht, &keyval->depth);
+  if (!drawable)
+    {
+      drawable = g_new (GtkGCDrawable, 1);
+      drawable->depth = keyval->depth;
+      drawable->drawable = gdk_pixmap_new (NULL, 1, 1, drawable->depth);
+
+      g_hash_table_insert (gc_drawable_ht, &drawable->depth, drawable);
+    }
+
+  gc = gdk_gc_new_with_values (drawable->drawable, &keyval->values, keyval->mask);
+
+  return (gpointer) gc;
+}
+
+static void
+gtk_gc_destroy (gpointer value)
+{
+  gdk_gc_destroy ((GdkGC*) value);
+}
+
+static guint
+gtk_gc_key_hash (gpointer key)
+{
+  GtkGCKey *keyval;
+  guint hash_val;
+
+  keyval = key;
+  hash_val = 0;
+
+  if (keyval->mask & GDK_GC_FOREGROUND)
+    {
+      hash_val += keyval->values.foreground.pixel;
+    }
+  if (keyval->mask & GDK_GC_BACKGROUND)
+    {
+      hash_val += keyval->values.background.pixel;
+    }
+  if (keyval->mask & GDK_GC_FONT)
+    {
+      hash_val += gdk_font_id (keyval->values.font);
+    }
+  if (keyval->mask & GDK_GC_FUNCTION)
+    {
+      hash_val += (gint) keyval->values.function;
+    }
+  if (keyval->mask & GDK_GC_FILL)
+    {
+      hash_val += (gint) keyval->values.fill;
+    }
+  if (keyval->mask & GDK_GC_TILE)
+    {
+      hash_val += (glong) keyval->values.tile;
+    }
+  if (keyval->mask & GDK_GC_STIPPLE)
+    {
+      hash_val += (glong) keyval->values.stipple;
+    }
+  if (keyval->mask & GDK_GC_CLIP_MASK)
+    {
+      hash_val += (glong) keyval->values.clip_mask;
+    }
+  if (keyval->mask & GDK_GC_SUBWINDOW)
+    {
+      hash_val += (gint) keyval->values.subwindow_mode;
+    }
+  if (keyval->mask & GDK_GC_TS_X_ORIGIN)
+    {
+      hash_val += (gint) keyval->values.ts_x_origin;
+    }
+  if (keyval->mask & GDK_GC_TS_Y_ORIGIN)
+    {
+      hash_val += (gint) keyval->values.ts_y_origin;
+    }
+  if (keyval->mask & GDK_GC_CLIP_X_ORIGIN)
+    {
+      hash_val += (gint) keyval->values.clip_x_origin;
+    }
+  if (keyval->mask & GDK_GC_CLIP_Y_ORIGIN)
+    {
+      hash_val += (gint) keyval->values.clip_y_origin;
+    }
+  if (keyval->mask & GDK_GC_EXPOSURES)
+    {
+      hash_val += (gint) keyval->values.graphics_exposures;
+    }
+  if (keyval->mask & GDK_GC_LINE_WIDTH)
+    {
+      hash_val += (gint) keyval->values.line_width;
+    }
+  if (keyval->mask & GDK_GC_LINE_STYLE)
+    {
+      hash_val += (gint) keyval->values.line_style;
+    }
+  if (keyval->mask & GDK_GC_CAP_STYLE)
+    {
+      hash_val += (gint) keyval->values.cap_style;
+    }
+  if (keyval->mask & GDK_GC_JOIN_STYLE)
+    {
+      hash_val += (gint) keyval->values.join_style;
+    }
+
+  return hash_val;
+}
+
+static guint
+gtk_gc_value_hash (gpointer value)
+{
+  return (gulong) value;
+}
+
+static gint
+gtk_gc_key_compare (gpointer a,
+                   gpointer b)
+{
+  GtkGCKey *akey;
+  GtkGCKey *bkey;
+  GdkGCValues *avalues;
+  GdkGCValues *bvalues;
+
+  akey = a;
+  bkey = b;
+
+  avalues = &akey->values;
+  bvalues = &bkey->values;
+
+  if (akey->mask != bkey->mask)
+    return FALSE;
+
+  if (akey->depth != bkey->depth)
+    return FALSE;
+
+  if (akey->colormap != bkey->colormap)
+    return FALSE;
+
+  if (akey->mask & GDK_GC_FOREGROUND)
+    {
+      if (avalues->foreground.pixel != bvalues->foreground.pixel)
+       return FALSE;
+    }
+  if (akey->mask & GDK_GC_BACKGROUND)
+    {
+      if (avalues->background.pixel != bvalues->background.pixel)
+       return FALSE;
+    }
+  if (akey->mask & GDK_GC_FONT)
+    {
+      if (!gdk_font_equal (avalues->font, bvalues->font))
+       return FALSE;
+    }
+  if (akey->mask & GDK_GC_FUNCTION)
+    {
+      if (avalues->function != bvalues->function)
+       return FALSE;
+    }
+  if (akey->mask & GDK_GC_FILL)
+    {
+      if (avalues->fill != bvalues->fill)
+       return FALSE;
+    }
+  if (akey->mask & GDK_GC_TILE)
+    {
+      if (avalues->tile != bvalues->tile)
+       return FALSE;
+    }
+  if (akey->mask & GDK_GC_STIPPLE)
+    {
+      if (avalues->stipple != bvalues->stipple)
+       return FALSE;
+    }
+  if (akey->mask & GDK_GC_CLIP_MASK)
+    {
+      if (avalues->clip_mask != bvalues->clip_mask)
+       return FALSE;
+    }
+  if (akey->mask & GDK_GC_SUBWINDOW)
+    {
+      if (avalues->subwindow_mode != bvalues->subwindow_mode)
+       return FALSE;
+    }
+  if (akey->mask & GDK_GC_TS_X_ORIGIN)
+    {
+      if (avalues->ts_x_origin != bvalues->ts_x_origin)
+       return FALSE;
+    }
+  if (akey->mask & GDK_GC_TS_Y_ORIGIN)
+    {
+      if (avalues->ts_y_origin != bvalues->ts_y_origin)
+       return FALSE;
+    }
+  if (akey->mask & GDK_GC_CLIP_X_ORIGIN)
+    {
+      if (avalues->clip_x_origin != bvalues->clip_x_origin)
+       return FALSE;
+    }
+  if (akey->mask & GDK_GC_CLIP_Y_ORIGIN)
+    {
+      if (avalues->clip_y_origin != bvalues->clip_y_origin)
+       return FALSE;
+    }
+  if (akey->mask & GDK_GC_EXPOSURES)
+    {
+      if (avalues->graphics_exposures != bvalues->graphics_exposures)
+       return FALSE;
+    }
+  if (akey->mask & GDK_GC_LINE_WIDTH)
+    {
+      if (avalues->line_width != bvalues->line_width)
+       return FALSE;
+    }
+  if (akey->mask & GDK_GC_LINE_STYLE)
+    {
+      if (avalues->line_style != bvalues->line_style)
+       return FALSE;
+    }
+  if (akey->mask & GDK_GC_CAP_STYLE)
+    {
+      if (avalues->cap_style != bvalues->cap_style)
+       return FALSE;
+    }
+  if (akey->mask & GDK_GC_JOIN_STYLE)
+    {
+      if (avalues->join_style != bvalues->join_style)
+       return FALSE;
+    }
+
+  return TRUE;
+}
+
+
+static guint
+gtk_gc_drawable_hash (GtkGCDrawable *d)
+{
+  return d->depth;
+}
+
+static gint
+gtk_gc_drawable_compare (GtkGCDrawable *a,
+                        GtkGCDrawable *b)
+{
+  return (a->depth == b->depth);
+}
diff --git a/gtk/gtkgc.h b/gtk/gtkgc.h
new file mode 100644 (file)
index 0000000..ff4ecc4
--- /dev/null
@@ -0,0 +1,42 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_GC_H__
+#define __GTK_GC_H__
+
+
+#include <gdk/gdk.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+GdkGC* gtk_gc_get     (gint             depth,
+                      GdkColormap     *colormap,
+                      GdkGCValues     *values,
+                      GdkGCValuesMask  values_mask);
+void   gtk_gc_release (GdkGC           *gc);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_GC_H__ */
diff --git a/gtk/gtkhbbox.c b/gtk/gtkhbbox.c
new file mode 100644 (file)
index 0000000..9d86c01
--- /dev/null
@@ -0,0 +1,269 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "gtkhbbox.h"
+
+
+static void gtk_hbutton_box_class_init    (GtkHButtonBoxClass   *klass);
+static void gtk_hbutton_box_init          (GtkHButtonBox        *box);
+static void gtk_hbutton_box_size_request  (GtkWidget      *widget,
+                                          GtkRequisition *requisition);
+static void gtk_hbutton_box_size_allocate (GtkWidget      *widget,
+                                          GtkAllocation  *allocation);
+
+static gint default_spacing = 30;
+static gint default_layout_style = GTK_BUTTONBOX_EDGE;
+
+guint
+gtk_hbutton_box_get_type ()
+{
+  static guint hbutton_box_type = 0;
+
+  if (!hbutton_box_type)
+    {
+      GtkTypeInfo hbutton_box_info =
+      {
+       "GtkHButtonBox",
+       sizeof (GtkHButtonBox),
+       sizeof (GtkHButtonBoxClass),
+       (GtkClassInitFunc) gtk_hbutton_box_class_init,
+       (GtkObjectInitFunc) gtk_hbutton_box_init,
+       (GtkArgFunc) NULL,
+      };
+
+      hbutton_box_type = gtk_type_unique (gtk_button_box_get_type (), &hbutton_box_info);
+    }
+
+  return hbutton_box_type;
+}
+
+static void
+gtk_hbutton_box_class_init (GtkHButtonBoxClass *class)
+{
+  GtkWidgetClass *widget_class;
+
+  widget_class = (GtkWidgetClass*) class;
+
+  widget_class->size_request = gtk_hbutton_box_size_request;
+  widget_class->size_allocate = gtk_hbutton_box_size_allocate;
+}
+
+static void
+gtk_hbutton_box_init (GtkHButtonBox *hbutton_box)
+{
+       /* button_box_init has done everything allready */
+}
+
+GtkWidget*
+gtk_hbutton_box_new ()
+{
+  GtkHButtonBox *hbutton_box;
+
+  hbutton_box = gtk_type_new (gtk_hbutton_box_get_type ());
+
+  return GTK_WIDGET (hbutton_box);
+}
+
+
+/* set default value for spacing */
+
+void gtk_hbutton_box_set_spacing_default (gint spacing)
+{
+  default_spacing = spacing;
+}
+
+
+/* set default value for layout style */
+
+void gtk_hbutton_box_set_layout_default (gint layout)
+{
+  default_layout_style = layout;
+}
+
+/* get default value for spacing */
+
+gint gtk_hbutton_box_get_spacing_default (void)
+{
+  return default_spacing;
+}
+
+
+/* get default value for layout style */
+
+gint gtk_hbutton_box_get_layout_default (void)
+{
+  return default_layout_style;
+}
+
+
+  
+static void
+gtk_hbutton_box_size_request (GtkWidget      *widget,
+                             GtkRequisition *requisition)
+{
+  GtkBox *box;
+  GtkButtonBox *bbox;
+  gint nvis_children;
+  gint child_width;
+  gint child_height;
+  gint spacing;
+  gint layout;
+  
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_HBUTTON_BOX (widget));
+  g_return_if_fail (requisition != NULL);
+
+  box = GTK_BOX (widget);
+  bbox = GTK_BUTTON_BOX (widget);
+
+  spacing = bbox->spacing != GTK_BUTTONBOX_DEFAULT
+         ? bbox->spacing : default_spacing;
+  layout = bbox->layout_style != GTK_BUTTONBOX_DEFAULT
+         ? bbox->layout_style : default_layout_style;
+  
+  gtk_button_box_child_requisition (widget,
+                                   &nvis_children,
+                                   &child_width,
+                                   &child_height);
+
+  if (nvis_children == 0)
+  {
+    requisition->width = 0; 
+    requisition->height = 0;
+  }
+  else
+  {
+    switch (layout)
+    {
+    case GTK_BUTTONBOX_SPREAD:
+      requisition->width =
+             nvis_children*child_width + ((nvis_children+1)*spacing);
+      break;
+    case GTK_BUTTONBOX_EDGE:
+    case GTK_BUTTONBOX_START:
+    case GTK_BUTTONBOX_END:
+      requisition->width = nvis_children*child_width + ((nvis_children-1)*spacing);
+      break;
+    default:
+      g_assert_not_reached();
+      break;
+    }
+         
+    requisition->height = child_height;
+  }
+         
+  requisition->width += GTK_CONTAINER (box)->border_width * 2;
+  requisition->height += GTK_CONTAINER (box)->border_width * 2;
+}
+
+
+
+static void
+gtk_hbutton_box_size_allocate (GtkWidget     *widget,
+                              GtkAllocation *allocation)
+{
+  GtkButtonBox *box;
+  GtkHButtonBox *hbox;
+  GtkBoxChild *child;
+  GList *children;
+  GtkAllocation child_allocation;
+  gint nvis_children;
+  gint child_width;
+  gint child_height;
+  gint x = 0;
+  gint y = 0;
+  gint width;
+  gint childspace;
+  gint childspacing = 0;
+  gint layout;
+  gint spacing;
+  
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_HBUTTON_BOX (widget));
+  g_return_if_fail (allocation != NULL);
+
+  box = GTK_BUTTON_BOX (widget);
+  hbox = GTK_HBUTTON_BOX (widget);
+  spacing = box->spacing != GTK_BUTTONBOX_DEFAULT
+         ? box->spacing : default_spacing;
+  layout = box->layout_style != GTK_BUTTONBOX_DEFAULT
+         ? box->layout_style : default_layout_style;
+  gtk_button_box_child_requisition (widget,
+                                   &nvis_children,
+                                   &child_width,
+                                   &child_height);
+  widget->allocation = *allocation;
+  width = allocation->width - GTK_CONTAINER (box)->border_width*2;
+  switch (layout)
+  {
+  case GTK_BUTTONBOX_SPREAD:
+    childspacing = (width - (nvis_children*child_width)) / (nvis_children+1);
+    x = allocation->x + GTK_CONTAINER (box)->border_width + childspacing;
+    break;
+  case GTK_BUTTONBOX_EDGE:
+    if (nvis_children >= 2)
+    {
+      childspacing =
+             (width - (nvis_children*child_width)) / (nvis_children-1);
+      x = allocation->x + GTK_CONTAINER (box)->border_width;
+    }
+    else
+      {
+                     /* one or zero children, just center */
+        childspacing = width;
+       x = allocation->x + (allocation->width - child_width) / 2;
+      }
+    break;
+  case GTK_BUTTONBOX_START:
+    childspacing = spacing;
+    x = allocation->x + GTK_CONTAINER (box)->border_width;
+    break;
+  case GTK_BUTTONBOX_END:
+    childspacing = spacing;
+    x = allocation->x + allocation->width - child_width * nvis_children
+           - spacing *(nvis_children-1)
+           - GTK_CONTAINER (box)->border_width;
+    break;
+  default:
+    g_assert_not_reached();
+    break;
+  }
+                 
+  
+  y = allocation->y + (allocation->height - child_height) / 2;
+  childspace = child_width + childspacing;
+
+  children = GTK_BOX (box)->children;
+         
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (child->widget))
+       {
+         child_allocation.width = child_width;
+         child_allocation.height = child_height;
+         child_allocation.x = x;
+         child_allocation.y = y;
+         gtk_widget_size_allocate (child->widget, &child_allocation);
+         x += childspace;
+       }
+    }
+}
+  
diff --git a/gtk/gtkhbbox.h b/gtk/gtkhbbox.h
new file mode 100644 (file)
index 0000000..c61c138
--- /dev/null
@@ -0,0 +1,66 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_HBUTTON_BOX_H__
+#define __GTK_HBUTTON_BOX_H__
+
+
+#include "gtk/gtkbbox.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_HBUTTON_BOX(obj)          GTK_CHECK_CAST (obj, gtk_hbutton_box_get_type (), GtkHButtonBox)
+#define GTK_HBUTTON_BOX_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_hbutton_box_get_type (), GtkHButtonBoxClass)
+#define GTK_IS_HBUTTON_BOX(obj)       GTK_CHECK_TYPE (obj, gtk_hbutton_box_get_type ())
+
+
+typedef struct _GtkHButtonBox       GtkHButtonBox;
+typedef struct _GtkHButtonBoxClass  GtkHButtonBoxClass;
+
+struct _GtkHButtonBox
+{
+  GtkButtonBox button_box;
+};
+
+struct _GtkHButtonBoxClass
+{
+  GtkButtonBoxClass parent_class;
+};
+
+
+guint      gtk_hbutton_box_get_type (void);
+GtkWidget *gtk_hbutton_box_new      (void);
+
+/* buttons can be added by gtk_container_add() */
+
+gint gtk_hbutton_box_get_spacing_default (void);
+gint gtk_hbutton_box_get_layout_default (void);
+
+void gtk_hbutton_box_set_spacing_default (gint spacing);
+void gtk_hbutton_box_set_layout_default (gint layout);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_HBUTTON_BOX_H__ */
diff --git a/gtk/gtkhbox.c b/gtk/gtkhbox.c
new file mode 100644 (file)
index 0000000..4cdc926
--- /dev/null
@@ -0,0 +1,306 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkhbox.h"
+
+
+static void gtk_hbox_class_init    (GtkHBoxClass   *klass);
+static void gtk_hbox_init          (GtkHBox        *box);
+static void gtk_hbox_size_request  (GtkWidget      *widget,
+                                   GtkRequisition *requisition);
+static void gtk_hbox_size_allocate (GtkWidget      *widget,
+                                   GtkAllocation  *allocation);
+
+
+guint
+gtk_hbox_get_type ()
+{
+  static guint hbox_type = 0;
+
+  if (!hbox_type)
+    {
+      GtkTypeInfo hbox_info =
+      {
+       "GtkHBox",
+       sizeof (GtkHBox),
+       sizeof (GtkHBoxClass),
+       (GtkClassInitFunc) gtk_hbox_class_init,
+       (GtkObjectInitFunc) gtk_hbox_init,
+       (GtkArgFunc) NULL,
+      };
+
+      hbox_type = gtk_type_unique (gtk_box_get_type (), &hbox_info);
+    }
+
+  return hbox_type;
+}
+
+static void
+gtk_hbox_class_init (GtkHBoxClass *class)
+{
+  GtkWidgetClass *widget_class;
+
+  widget_class = (GtkWidgetClass*) class;
+
+  widget_class->size_request = gtk_hbox_size_request;
+  widget_class->size_allocate = gtk_hbox_size_allocate;
+}
+
+static void
+gtk_hbox_init (GtkHBox *hbox)
+{
+}
+
+GtkWidget*
+gtk_hbox_new (gint homogeneous,
+             gint spacing)
+{
+  GtkHBox *hbox;
+
+  hbox = gtk_type_new (gtk_hbox_get_type ());
+
+  GTK_BOX (hbox)->spacing = spacing;
+  GTK_BOX (hbox)->homogeneous = homogeneous ? TRUE : FALSE;
+
+  return GTK_WIDGET (hbox);
+}
+
+
+static void
+gtk_hbox_size_request (GtkWidget      *widget,
+                      GtkRequisition *requisition)
+{
+  GtkBox *box;
+  GtkBoxChild *child;
+  GList *children;
+  gint nvis_children;
+  gint width;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_HBOX (widget));
+  g_return_if_fail (requisition != NULL);
+
+  box = GTK_BOX (widget);
+  requisition->width = 0;
+  requisition->height = 0;
+  nvis_children = 0;
+
+  children = box->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (child->widget))
+       {
+         gtk_widget_size_request (child->widget, &child->widget->requisition);
+
+         if (box->homogeneous)
+           {
+             width = child->widget->requisition.width + child->padding * 2;
+             requisition->width = MAX (requisition->width, width);
+           }
+         else
+           {
+             requisition->width += child->widget->requisition.width + child->padding * 2;
+           }
+
+         requisition->height = MAX (requisition->height, child->widget->requisition.height);
+
+         nvis_children += 1;
+       }
+    }
+
+  if (nvis_children > 0)
+    {
+      if (box->homogeneous)
+       requisition->width *= nvis_children;
+      requisition->width += (nvis_children - 1) * box->spacing;
+    }
+
+  requisition->width += GTK_CONTAINER (box)->border_width * 2;
+  requisition->height += GTK_CONTAINER (box)->border_width * 2;
+}
+
+static void
+gtk_hbox_size_allocate (GtkWidget     *widget,
+                       GtkAllocation *allocation)
+{
+  GtkBox *box;
+  GtkBoxChild *child;
+  GList *children;
+  GtkAllocation child_allocation;
+  gint nvis_children;
+  gint nexpand_children;
+  gint child_width;
+  gint width;
+  gint extra;
+  gint x;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_HBOX (widget));
+  g_return_if_fail (allocation != NULL);
+
+  box = GTK_BOX (widget);
+  widget->allocation = *allocation;
+
+  nvis_children = 0;
+  nexpand_children = 0;
+  children = box->children;
+
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (child->widget))
+       {
+         nvis_children += 1;
+         if (child->expand)
+           nexpand_children += 1;
+       }
+    }
+
+  if (nvis_children > 0)
+    {
+      if (box->homogeneous)
+       {
+         width = (allocation->width -
+                  GTK_CONTAINER (box)->border_width * 2 -
+                  (nvis_children - 1) * box->spacing);
+         extra = width / nvis_children;
+       }
+      else if (nexpand_children > 0)
+       {
+         width = allocation->width - widget->requisition.width;
+         extra = width / nexpand_children;
+       }
+      else
+       {
+         width = 0;
+         extra = 0;
+       }
+
+      x = allocation->x + GTK_CONTAINER (box)->border_width;
+      child_allocation.y = allocation->y + GTK_CONTAINER (box)->border_width;
+      child_allocation.height = allocation->height - GTK_CONTAINER (box)->border_width * 2;
+
+      children = box->children;
+      while (children)
+       {
+         child = children->data;
+         children = children->next;
+
+         if ((child->pack == GTK_PACK_START) && GTK_WIDGET_VISIBLE (child->widget))
+           {
+             if (box->homogeneous)
+               {
+                 if (nvis_children == 1)
+                   child_width = width;
+                 else
+                   child_width = extra;
+
+                 nvis_children -= 1;
+                 width -= extra;
+               }
+             else
+               {
+                 child_width = child->widget->requisition.width + child->padding * 2;
+
+                 if (child->expand)
+                   {
+                     if (nexpand_children == 1)
+                       child_width += width;
+                     else
+                       child_width += extra;
+
+                     nexpand_children -= 1;
+                     width -= extra;
+                   }
+               }
+
+             if (child->fill)
+               {
+                 child_allocation.width = child_width - child->padding * 2;
+                 child_allocation.x = x + child->padding;
+               }
+             else
+               {
+                 child_allocation.width = child->widget->requisition.width;
+                 child_allocation.x = x + (child_width - child_allocation.width) / 2;
+               }
+
+             gtk_widget_size_allocate (child->widget, &child_allocation);
+
+             x += child_width + box->spacing;
+           }
+       }
+
+      x = allocation->x + allocation->width - GTK_CONTAINER (box)->border_width;
+
+      children = box->children;
+      while (children)
+       {
+         child = children->data;
+         children = children->next;
+
+         if ((child->pack == GTK_PACK_END) && GTK_WIDGET_VISIBLE (child->widget))
+           {
+              if (box->homogeneous)
+                {
+                  if (nvis_children == 1)
+                    child_width = width;
+                  else
+                    child_width = extra;
+
+                  nvis_children -= 1;
+                  width -= extra;
+                }
+              else
+                {
+                 child_width = child->widget->requisition.width + child->padding * 2;
+
+                  if (child->expand)
+                    {
+                      if (nexpand_children == 1)
+                        child_width += width;
+                      else
+                        child_width += extra;
+
+                      nexpand_children -= 1;
+                      width -= extra;
+                    }
+                }
+
+              if (child->fill)
+                {
+                  child_allocation.width = child_width - child->padding * 2;
+                  child_allocation.x = x + child->padding - child_width;
+                }
+              else
+                {
+                  child_allocation.width = child->widget->requisition.width;
+                  child_allocation.x = x + (child_width - child_allocation.width) / 2 - child_width;
+                }
+
+              gtk_widget_size_allocate (child->widget, &child_allocation);
+
+              x -= (child_width + box->spacing);
+           }
+       }
+    }
+}
diff --git a/gtk/gtkhbox.h b/gtk/gtkhbox.h
new file mode 100644 (file)
index 0000000..7dfbb3d
--- /dev/null
@@ -0,0 +1,60 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_HBOX_H__
+#define __GTK_HBOX_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkbox.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_HBOX(obj)          GTK_CHECK_CAST (obj, gtk_hbox_get_type (), GtkHBox)
+#define GTK_HBOX_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_hbox_get_type (), GtkHBoxClass)
+#define GTK_IS_HBOX(obj)       GTK_CHECK_TYPE (obj, gtk_hbox_get_type ())
+
+
+typedef struct _GtkHBox       GtkHBox;
+typedef struct _GtkHBoxClass  GtkHBoxClass;
+
+struct _GtkHBox
+{
+  GtkBox box;
+};
+
+struct _GtkHBoxClass
+{
+  GtkBoxClass parent_class;
+};
+
+
+guint      gtk_hbox_get_type (void);
+GtkWidget* gtk_hbox_new      (gint homogeneous,
+                             gint spacing);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_HBOX_H__ */
diff --git a/gtk/gtkhpaned.c b/gtk/gtkhpaned.c
new file mode 100644 (file)
index 0000000..23c5096
--- /dev/null
@@ -0,0 +1,355 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkhpaned.h"
+#include "gtkmain.h"
+#include "gtksignal.h"
+
+static void gtk_hpaned_class_init       (GtkHPanedClass *klass);
+static void gtk_hpaned_init             (GtkHPaned      *hpaned);
+static void gtk_hpaned_size_request     (GtkWidget      *widget,
+                                        GtkRequisition *requisition);
+static void gtk_hpaned_size_allocate    (GtkWidget          *widget,
+                                        GtkAllocation      *allocation);
+static void gtk_hpaned_draw             (GtkWidget    *widget,
+                                        GdkRectangle *area);
+static void gtk_hpaned_xor_line         (GtkPaned *paned);
+static gint gtk_hpaned_button_press     (GtkWidget *widget,
+                                        GdkEventButton *event);
+static gint gtk_hpaned_button_release   (GtkWidget *widget,
+                                        GdkEventButton *event);
+static gint gtk_hpaned_motion           (GtkWidget *widget,
+                                        GdkEventMotion *event);
+
+guint
+gtk_hpaned_get_type ()
+{
+  static guint hpaned_type = 0;
+
+  if (!hpaned_type)
+    {
+      GtkTypeInfo hpaned_info =
+      {
+       "GtkHPaned",
+       sizeof (GtkHPaned),
+       sizeof (GtkHPanedClass),
+       (GtkClassInitFunc) gtk_hpaned_class_init,
+       (GtkObjectInitFunc) gtk_hpaned_init,
+       (GtkArgFunc) NULL,
+      };
+
+      hpaned_type = gtk_type_unique (gtk_paned_get_type (), &hpaned_info);
+    }
+
+  return hpaned_type;
+}
+
+static void
+gtk_hpaned_class_init (GtkHPanedClass *class)
+{
+  GtkWidgetClass *widget_class;
+
+  widget_class = (GtkWidgetClass*) class;
+
+  widget_class->size_request = gtk_hpaned_size_request;
+  widget_class->size_allocate = gtk_hpaned_size_allocate;
+  widget_class->draw = gtk_hpaned_draw;
+  widget_class->button_press_event = gtk_hpaned_button_press;
+  widget_class->button_release_event = gtk_hpaned_button_release;
+  widget_class->motion_notify_event = gtk_hpaned_motion;
+}
+
+static void
+gtk_hpaned_init (GtkHPaned *hpaned)
+{
+}
+
+GtkWidget*
+gtk_hpaned_new ()
+{
+  GtkHPaned *hpaned;
+
+  hpaned = gtk_type_new (gtk_hpaned_get_type ());
+
+  return GTK_WIDGET (hpaned);
+}
+
+static void
+gtk_hpaned_size_request (GtkWidget      *widget,
+                        GtkRequisition *requisition)
+{
+  GtkPaned *paned;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_HPANED (widget));
+  g_return_if_fail (requisition != NULL);
+
+  paned = GTK_PANED (widget);
+  requisition->width = 0;
+  requisition->height = 0;
+
+  if (paned->child1 && GTK_WIDGET_VISIBLE (paned->child1))
+    {
+      gtk_widget_size_request (paned->child1, &paned->child1->requisition);
+
+      requisition->height = paned->child1->requisition.height;
+      requisition->width = paned->child1->requisition.width;
+    }
+
+  if (paned->child2 && GTK_WIDGET_VISIBLE (paned->child2))
+    {
+      gtk_widget_size_request (paned->child2, &paned->child2->requisition);
+
+      requisition->height = MAX(requisition->height,
+                               paned->child2->requisition.height);
+      requisition->width += paned->child2->requisition.width;
+    }
+
+  requisition->width += GTK_CONTAINER (paned)->border_width * 2 + paned->gutter_size;
+  requisition->height += GTK_CONTAINER (paned)->border_width * 2;
+}
+
+static void
+gtk_hpaned_size_allocate (GtkWidget     *widget,
+                         GtkAllocation *allocation)
+{
+  GtkPaned *paned;
+  GtkAllocation child1_allocation;
+  GtkAllocation child2_allocation;
+  guint16 border_width;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_HPANED (widget));
+  g_return_if_fail (allocation != NULL);
+
+  widget->allocation = *allocation;
+
+  paned = GTK_PANED (widget);
+  border_width = GTK_CONTAINER (paned)->border_width;
+
+  if (!paned->position_set)
+    {
+      if (paned->child1 && GTK_WIDGET_VISIBLE (paned->child1))
+       paned->child1_size = paned->child1->requisition.width;
+      else
+       paned->child1_size = 0;
+    }
+
+  /* Move the handle first so we don't get extra expose events */
+
+  paned->handle_xpos = allocation->x + paned->child1_size + border_width + paned->gutter_size / 2 - paned->handle_size / 2;
+  paned->handle_ypos = allocation->y + allocation->height - border_width - 2*paned->handle_size;
+
+  if (GTK_WIDGET_REALIZED (widget))
+    {
+      gdk_window_move (paned->handle, paned->handle_xpos, paned->handle_ypos);
+      gdk_window_raise (paned->handle);
+    }
+
+  if (GTK_WIDGET_MAPPED (widget))
+    {
+      gdk_window_clear_area (widget->window,
+                            paned->groove_rectangle.x,
+                            paned->groove_rectangle.y,
+                            paned->groove_rectangle.width,
+                            paned->groove_rectangle.height);
+    }
+  
+  child1_allocation.height = child2_allocation.height = allocation->height - border_width * 2;
+  child1_allocation.width = paned->child1_size;
+  child1_allocation.x = allocation->x + border_width;
+  child1_allocation.y = child2_allocation.y = allocation->y + border_width;
+  
+  paned->groove_rectangle.x = child1_allocation.x 
+    + child1_allocation.width + paned->gutter_size / 2 - 1;
+  paned->groove_rectangle.y = allocation->y;
+  paned->groove_rectangle.width = 2;
+  paned->groove_rectangle.height = allocation->height;
+      
+  child2_allocation.x = paned->groove_rectangle.x + paned->gutter_size / 2 + 1;
+  child2_allocation.width = allocation->x + allocation->width
+    - child2_allocation.x - border_width;
+  
+  /* Now allocate the childen, making sure, when resizing not to
+   * overlap the windows */
+  if (GTK_WIDGET_MAPPED(widget) &&
+      paned->child1 && GTK_WIDGET_VISIBLE (paned->child1) &&
+      paned->child1->allocation.width < child1_allocation.width)
+    {
+      if (paned->child2 && GTK_WIDGET_VISIBLE (paned->child2))
+       gtk_widget_size_allocate (paned->child2, &child2_allocation);
+      gtk_widget_size_allocate (paned->child1, &child1_allocation);      
+    }
+  else
+    {
+      if (paned->child1 && GTK_WIDGET_VISIBLE (paned->child1))
+       gtk_widget_size_allocate (paned->child1, &child1_allocation);
+      if (paned->child2 && GTK_WIDGET_VISIBLE (paned->child2))
+       gtk_widget_size_allocate (paned->child2, &child2_allocation);
+    }
+}
+
+static void
+gtk_hpaned_draw (GtkWidget    *widget,
+               GdkRectangle *area)
+{
+  GtkPaned *paned;
+  GdkRectangle child_area;
+  guint16 border_width;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_PANED (widget));
+
+  if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget))
+    {
+      paned = GTK_PANED (widget);
+      border_width = GTK_CONTAINER (paned)->border_width;
+
+      if (paned->child1 &&
+         gtk_widget_intersect (paned->child1, area, &child_area))
+        gtk_widget_draw (paned->child1, &child_area);
+      if (paned->child2 &&
+         gtk_widget_intersect (paned->child2, area, &child_area))
+        gtk_widget_draw (paned->child2, &child_area);
+
+      gdk_draw_line (widget->window,
+                    widget->style->dark_gc[widget->state],
+                    widget->allocation.x + border_width + paned->child1_size + paned->gutter_size / 2 - 1,
+                    widget->allocation.y,
+                    widget->allocation.x + border_width + paned->child1_size + paned->gutter_size / 2 - 1,
+                    widget->allocation.y + widget->allocation.height - 1);
+      gdk_draw_line (widget->window,
+                    widget->style->light_gc[widget->state],
+                    widget->allocation.x + border_width + paned->child1_size + paned->gutter_size / 2,
+                    widget->allocation.y,
+                    widget->allocation.x + border_width + paned->child1_size + paned->gutter_size / 2,
+                    widget->allocation.y + widget->allocation.height - 1);
+    }
+}
+
+static void
+gtk_hpaned_xor_line (GtkPaned *paned)
+{
+  GtkWidget *widget;
+  GdkGCValues values;
+  guint16 xpos;
+
+  widget = GTK_WIDGET(paned);
+
+  if (!paned->xor_gc)
+    {
+      values.foreground = widget->style->white;
+      values.function = GDK_XOR;
+      values.subwindow_mode = GDK_INCLUDE_INFERIORS;
+      paned->xor_gc = gdk_gc_new_with_values (widget->window,
+                                             &values,
+                                             GDK_GC_FOREGROUND |
+                                             GDK_GC_FUNCTION |
+                                             GDK_GC_SUBWINDOW);
+    }
+
+  xpos = widget->allocation.x + paned->child1_size
+    + GTK_CONTAINER(paned)->border_width + paned->gutter_size / 2;
+
+  gdk_draw_line (widget->window, paned->xor_gc,
+                xpos,
+                widget->allocation.y,
+                xpos,
+                widget->allocation.y + widget->allocation.height - 1);
+}
+
+static gint
+gtk_hpaned_button_press (GtkWidget *widget, GdkEventButton *event)
+{
+  GtkPaned *paned;
+
+  g_return_val_if_fail (widget != NULL,FALSE);
+  g_return_val_if_fail (GTK_IS_PANED (widget),FALSE);
+
+  paned = GTK_PANED (widget);
+
+  if (!paned->in_drag &&
+      (event->window == paned->handle) && (event->button == 1))
+    {
+      paned->in_drag = TRUE;
+      /* We need a server grab here, not gtk_grab_add(), since
+       * we don't want to pass events on to the widget's children */
+      gdk_pointer_grab (paned->handle, FALSE,
+                       GDK_POINTER_MOTION_HINT_MASK 
+                       | GDK_BUTTON1_MOTION_MASK 
+                       | GDK_BUTTON_RELEASE_MASK,
+                       NULL, NULL, event->time);
+      paned->child1_size += event->x - paned->handle_size / 2;
+      paned->child1_size = CLAMP (paned->child1_size, 0,
+                                  widget->allocation.width - paned->gutter_size
+                                  - 2 * GTK_CONTAINER (paned)->border_width);
+      gtk_hpaned_xor_line (paned);
+    }
+
+  return TRUE;
+}
+
+static gint
+gtk_hpaned_button_release (GtkWidget *widget, GdkEventButton *event)
+{
+  GtkPaned *paned;
+
+  g_return_val_if_fail (widget != NULL,FALSE);
+  g_return_val_if_fail (GTK_IS_PANED (widget),FALSE);
+
+  paned = GTK_PANED (widget);
+
+  if (paned->in_drag && (event->button == 1))
+    {
+      gtk_hpaned_xor_line (paned);
+      paned->in_drag = FALSE;
+      paned->position_set = TRUE;
+      gdk_pointer_ungrab (event->time);
+      gtk_widget_queue_resize (GTK_WIDGET (paned));
+    }
+
+  return TRUE;
+}
+
+static gint
+gtk_hpaned_motion (GtkWidget *widget, GdkEventMotion *event)
+{
+  GtkPaned *paned;
+  gint x;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_PANED (widget), FALSE);
+
+  if (event->is_hint || event->window != widget->window)
+    gtk_widget_get_pointer(widget, &x, NULL);
+  else
+    x = event->x;
+
+  paned = GTK_PANED (widget);
+
+  if (paned->in_drag)
+    {
+      gtk_hpaned_xor_line (paned);
+      paned->child1_size = x - GTK_CONTAINER (paned)->border_width - paned->gutter_size / 2;
+      paned->child1_size = CLAMP (paned->child1_size, 0,
+                                  widget->allocation.width - paned->gutter_size
+                                  - 2 * GTK_CONTAINER (paned)->border_width);
+      gtk_hpaned_xor_line (paned);
+    }
+
+  return TRUE;
+}
diff --git a/gtk/gtkhpaned.h b/gtk/gtkhpaned.h
new file mode 100644 (file)
index 0000000..0a352e7
--- /dev/null
@@ -0,0 +1,59 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_HPANED_H__
+#define __GTK_HPANED_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkpaned.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_HPANED(obj)          GTK_CHECK_CAST (obj, gtk_hpaned_get_type (), GtkHPaned)
+#define GTK_HPANED_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_hpaned_get_type (), GtkHPanedClass)
+#define GTK_IS_HPANED(obj)       GTK_CHECK_TYPE (obj, gtk_hpaned_get_type ())
+
+
+typedef struct _GtkHPaned       GtkHPaned;
+typedef struct _GtkHPanedClass  GtkHPanedClass;
+
+struct _GtkHPaned
+{
+  GtkPaned paned;
+};
+
+struct _GtkHPanedClass
+{
+  GtkPanedClass parent_class;
+};
+
+
+guint      gtk_hpaned_get_type (void);
+GtkWidget* gtk_hpaned_new      ();
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_HPANED_H__ */
diff --git a/gtk/gtkhruler.c b/gtk/gtkhruler.c
new file mode 100644 (file)
index 0000000..ab6e691
--- /dev/null
@@ -0,0 +1,277 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+#include "gtkhruler.h"
+
+
+#define RULER_HEIGHT          14
+#define MINIMUM_INCR          5
+#define MAXIMUM_SUBDIVIDE     5
+#define MAXIMUM_SCALES        10
+
+#define ROUND(x) ((int) ((x) + 0.5))
+
+
+static void gtk_hruler_class_init    (GtkHRulerClass *klass);
+static void gtk_hruler_init          (GtkHRuler      *hruler);
+static gint gtk_hruler_motion_notify (GtkWidget      *widget,
+                                     GdkEventMotion *event);
+static void gtk_hruler_draw_ticks    (GtkRuler       *ruler);
+static void gtk_hruler_draw_pos      (GtkRuler       *ruler);
+
+
+guint
+gtk_hruler_get_type ()
+{
+  static guint hruler_type = 0;
+
+  if (!hruler_type)
+    {
+      GtkTypeInfo hruler_info =
+      {
+       "GtkHRuler",
+       sizeof (GtkHRuler),
+       sizeof (GtkHRulerClass),
+       (GtkClassInitFunc) gtk_hruler_class_init,
+       (GtkObjectInitFunc) gtk_hruler_init,
+       (GtkArgFunc) NULL,
+      };
+
+      hruler_type = gtk_type_unique (gtk_ruler_get_type (), &hruler_info);
+    }
+
+  return hruler_type;
+}
+
+static void
+gtk_hruler_class_init (GtkHRulerClass *klass)
+{
+  GtkWidgetClass *widget_class;
+  GtkRulerClass *ruler_class;
+
+  widget_class = (GtkWidgetClass*) klass;
+  ruler_class = (GtkRulerClass*) klass;
+
+  widget_class->motion_notify_event = gtk_hruler_motion_notify;
+
+  ruler_class->draw_ticks = gtk_hruler_draw_ticks;
+  ruler_class->draw_pos = gtk_hruler_draw_pos;
+}
+
+static void
+gtk_hruler_init (GtkHRuler *hruler)
+{
+  GtkWidget *widget;
+
+  widget = GTK_WIDGET (hruler);
+  widget->requisition.width = widget->style->klass->xthickness * 2 + 1;
+  widget->requisition.height = widget->style->klass->ythickness * 2 + RULER_HEIGHT;
+}
+
+
+GtkWidget*
+gtk_hruler_new ()
+{
+  return GTK_WIDGET (gtk_type_new (gtk_hruler_get_type ()));
+}
+
+static gint
+gtk_hruler_motion_notify (GtkWidget      *widget,
+                         GdkEventMotion *event)
+{
+  GtkRuler *ruler;
+  gint x;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_HRULER (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  ruler = GTK_RULER (widget);
+
+  if (event->is_hint)
+    gdk_window_get_pointer (widget->window, &x, NULL, NULL);
+  else
+    x = event->x;
+
+  ruler->position = ruler->lower + ((ruler->upper - ruler->lower) * x) / widget->allocation.width;
+
+  /*  Make sure the ruler has been allocated already  */
+  if (ruler->backing_store != NULL)
+    gtk_ruler_draw_pos (ruler);
+
+  return FALSE;
+}
+
+static void
+gtk_hruler_draw_ticks (GtkRuler *ruler)
+{
+  GtkWidget *widget;
+  GdkGC *gc;
+  gint i;
+  gint width, height;
+  gint xthickness;
+  gint ythickness;
+  gint length;
+  gfloat subd_incr;
+  gfloat step_incr;
+  gfloat increment;
+  gfloat start, end, cur;
+  gchar unit_str[12];
+  gint text_height;
+  gint digit_height;
+  gint pos;
+  gint scale;
+
+  g_return_if_fail (ruler != NULL);
+  g_return_if_fail (GTK_IS_HRULER (ruler));
+
+  if (GTK_WIDGET_DRAWABLE (ruler))
+    {
+      widget = GTK_WIDGET (ruler);
+
+      gc = widget->style->fg_gc[GTK_STATE_NORMAL];
+      xthickness = widget->style->klass->xthickness;
+      ythickness = widget->style->klass->ythickness;
+      digit_height = widget->style->font->ascent;
+
+      width = widget->allocation.width;
+      height = widget->allocation.height - ythickness * 2;
+      gdk_draw_line (ruler->backing_store, gc,
+                    xthickness,
+                    height + ythickness,
+                    widget->allocation.width - xthickness,
+                    height + ythickness);
+
+      if ((ruler->upper - ruler->lower) == 0)
+       return;
+
+      increment = (gfloat) width * ruler->metric->pixels_per_unit / (ruler->upper - ruler->lower);
+
+      /*  determine the scale
+       *   use the maximum extents of the ruler to determine the largest possible
+       *   number to be displayed.  calculate the height in pixels of this displayed
+       *   text as for the vertical ruler case.  use this height to find a scale
+       *   which leaves sufficient room for drawing the ruler.
+       */
+      scale = ceil (ruler->max_size / ruler->metric->pixels_per_unit);
+      sprintf (unit_str, "%d", scale);
+      text_height = strlen (unit_str) * digit_height + 1;
+
+      for (scale = 0; scale < MAXIMUM_SCALES; scale++)
+       if (ruler->metric->ruler_scale[scale] * increment > 2 * text_height)
+         break;
+
+      if (scale == MAXIMUM_SCALES)
+       scale = MAXIMUM_SCALES - 1;
+
+      for (i = 0; i < MAXIMUM_SUBDIVIDE; i++)
+       {
+         subd_incr = (gfloat) ruler->metric->ruler_scale[scale] / (gfloat) ruler->metric->subdivide[i];
+         step_incr = subd_incr * increment;
+         if (step_incr <= MINIMUM_INCR)
+           break;
+
+         start = floor ((ruler->lower / ruler->metric->pixels_per_unit) / subd_incr) * subd_incr;
+         end = ceil ((ruler->upper / ruler->metric->pixels_per_unit) / subd_incr) * subd_incr;
+
+         length = height / (i + 1) - 1;
+         if (i > 0)
+           length -= 2;
+
+         cur = start;
+         while (cur <= end)
+           {
+             pos = ROUND ((cur - (ruler->lower / ruler->metric->pixels_per_unit)) * increment);
+
+             gdk_draw_line (ruler->backing_store, gc,
+                            pos, height + ythickness, pos,
+                            height - length + ythickness);
+             if (i == 0)
+               {
+                 sprintf (unit_str, "%d", (int) cur);
+                 gdk_draw_string (ruler->backing_store, widget->style->font, gc,
+                                  pos + 2,
+                                  ythickness + digit_height - 1,
+                                  unit_str);
+               }
+
+             cur += subd_incr;
+           }
+       }
+    }
+}
+
+static void
+gtk_hruler_draw_pos (GtkRuler *ruler)
+{
+  GtkWidget *widget;
+  GdkGC *gc;
+  int i;
+  gint x, y;
+  gint width, height;
+  gint bs_width, bs_height;
+  gint xthickness;
+  gint ythickness;
+  gfloat increment;
+
+  g_return_if_fail (ruler != NULL);
+  g_return_if_fail (GTK_IS_HRULER (ruler));
+
+  if (GTK_WIDGET_DRAWABLE (ruler))
+    {
+      widget = GTK_WIDGET (ruler);
+
+      gc = widget->style->fg_gc[GTK_STATE_NORMAL];
+      xthickness = widget->style->klass->xthickness;
+      ythickness = widget->style->klass->ythickness;
+      width = widget->allocation.width;
+      height = widget->allocation.height - ythickness * 2;
+
+      bs_width = height / 2;
+      bs_width |= 1;  /* make sure it's odd */
+      bs_height = bs_width / 2 + 1;
+
+      if ((bs_width > 0) && (bs_height > 0))
+       {
+         /*  If a backing store exists, restore the ruler  */
+         if (ruler->backing_store && ruler->non_gr_exp_gc)
+           gdk_draw_pixmap (ruler->widget.window,
+                            ruler->non_gr_exp_gc,
+                            ruler->backing_store,
+                            ruler->xsrc, ruler->ysrc,
+                            ruler->xsrc, ruler->ysrc,
+                            bs_width, bs_height);
+
+         increment = (gfloat) width / (ruler->upper - ruler->lower);
+
+         x = ROUND ((ruler->position - ruler->lower) * increment) + (xthickness - bs_width) / 2 - 1;
+         y = (height + bs_height) / 2 + ythickness;
+
+         for (i = 0; i < bs_height; i++)
+           gdk_draw_line (widget->window, gc,
+                          x + i, y + i,
+                          x + bs_width - 1 - i, y + i);
+
+
+         ruler->xsrc = x;
+         ruler->ysrc = y;
+       }
+    }
+}
diff --git a/gtk/gtkhruler.h b/gtk/gtkhruler.h
new file mode 100644 (file)
index 0000000..c4bc744
--- /dev/null
@@ -0,0 +1,59 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_HRULER_H__
+#define __GTK_HRULER_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkruler.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_HRULER(obj)          GTK_CHECK_CAST (obj, gtk_hruler_get_type (), GtkHRuler)
+#define GTK_HRULER_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_hruler_get_type (), GtkHRulerClass)
+#define GTK_IS_HRULER(obj)       GTK_CHECK_TYPE (obj, gtk_hruler_get_type ())
+
+
+typedef struct _GtkHRuler       GtkHRuler;
+typedef struct _GtkHRulerClass  GtkHRulerClass;
+
+struct _GtkHRuler
+{
+  GtkRuler ruler;
+};
+
+struct _GtkHRulerClass
+{
+  GtkRulerClass parent_class;
+};
+
+
+guint      gtk_hruler_get_type (void);
+GtkWidget* gtk_hruler_new      (void);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_HRULER_H__ */
diff --git a/gtk/gtkhscale.c b/gtk/gtkhscale.c
new file mode 100644 (file)
index 0000000..3bebd30
--- /dev/null
@@ -0,0 +1,436 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdio.h>
+#include "gtkhscale.h"
+#include "gtksignal.h"
+#include "gdk/gdkkeysyms.h"
+
+
+#define SCALE_CLASS(w)  GTK_SCALE_CLASS (GTK_OBJECT (w)->klass)
+#define RANGE_CLASS(w)  GTK_RANGE_CLASS (GTK_OBJECT (w)->klass)
+
+
+static void gtk_hscale_class_init    (GtkHScaleClass *klass);
+static void gtk_hscale_init          (GtkHScale      *hscale);
+static void gtk_hscale_realize       (GtkWidget      *widget);
+static void gtk_hscale_size_request  (GtkWidget      *widget,
+                                     GtkRequisition *requisition);
+static void gtk_hscale_size_allocate (GtkWidget      *widget,
+                                     GtkAllocation  *allocation);
+static void gtk_hscale_pos_trough    (GtkHScale      *hscale,
+                                     gint           *x,
+                                     gint           *y,
+                                     gint           *w,
+                                     gint           *h);
+static void gtk_hscale_draw_slider   (GtkRange       *range);
+static void gtk_hscale_draw_value    (GtkScale       *scale);
+static gint gtk_hscale_trough_keys   (GtkRange *range,
+                                     GdkEventKey *key,
+                                     GtkScrollType *scroll,
+                                     GtkTroughType *pos);
+
+guint
+gtk_hscale_get_type ()
+{
+  static guint hscale_type = 0;
+
+  if (!hscale_type)
+    {
+      GtkTypeInfo hscale_info =
+      {
+       "GtkHScale",
+       sizeof (GtkHScale),
+       sizeof (GtkHScaleClass),
+       (GtkClassInitFunc) gtk_hscale_class_init,
+       (GtkObjectInitFunc) gtk_hscale_init,
+       (GtkArgFunc) NULL,
+      };
+
+      hscale_type = gtk_type_unique (gtk_scale_get_type (), &hscale_info);
+    }
+
+  return hscale_type;
+}
+
+static void
+gtk_hscale_class_init (GtkHScaleClass *class)
+{
+  GtkWidgetClass *widget_class;
+  GtkRangeClass *range_class;
+  GtkScaleClass *scale_class;
+
+  widget_class = (GtkWidgetClass*) class;
+  range_class = (GtkRangeClass*) class;
+  scale_class = (GtkScaleClass*) class;
+
+  widget_class->realize = gtk_hscale_realize;
+  widget_class->size_request = gtk_hscale_size_request;
+  widget_class->size_allocate = gtk_hscale_size_allocate;
+
+  range_class->slider_update = gtk_range_default_hslider_update;
+  range_class->trough_click = gtk_range_default_htrough_click;
+  range_class->motion = gtk_range_default_hmotion;
+  range_class->draw_slider = gtk_hscale_draw_slider;
+  range_class->trough_keys = gtk_hscale_trough_keys;
+
+  scale_class->draw_value = gtk_hscale_draw_value;
+}
+
+static void
+gtk_hscale_init (GtkHScale *hscale)
+{
+}
+
+GtkWidget*
+gtk_hscale_new (GtkAdjustment *adjustment)
+{
+  GtkHScale *hscale;
+
+  hscale = gtk_type_new (gtk_hscale_get_type ());
+
+  if (!adjustment)
+    adjustment = (GtkAdjustment*) gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+
+  gtk_range_set_adjustment (GTK_RANGE (hscale), adjustment);
+
+  return GTK_WIDGET (hscale);
+}
+
+
+static void
+gtk_hscale_realize (GtkWidget *widget)
+{
+  GtkRange *range;
+  GdkWindowAttr attributes;
+  gint attributes_mask;
+  gint x, y, w, h;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_HSCALE (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+  range = GTK_RANGE (widget);
+
+  attributes.x = widget->allocation.x;
+  attributes.y = widget->allocation.y;
+  attributes.width = widget->allocation.width;
+  attributes.height = widget->allocation.height;
+  attributes.wclass = GDK_INPUT_OUTPUT;
+  attributes.window_type = GDK_WINDOW_CHILD;
+  attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK;
+  attributes.visual = gtk_widget_get_visual (widget);
+  attributes.colormap = gtk_widget_get_colormap (widget);
+
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+  widget->window = gdk_window_new (widget->parent->window, &attributes, attributes_mask);
+
+  gtk_hscale_pos_trough (GTK_HSCALE (widget), &x, &y, &w, &h);
+  attributes.x = x;
+  attributes.y = y;
+  attributes.width = w;
+  attributes.height = h;
+  attributes.event_mask |= (GDK_BUTTON_PRESS_MASK |
+                           GDK_BUTTON_RELEASE_MASK |
+                           GDK_ENTER_NOTIFY_MASK |
+                           GDK_LEAVE_NOTIFY_MASK);
+
+  range->trough = gdk_window_new (widget->window, &attributes, attributes_mask);
+
+  attributes.width = SCALE_CLASS (range)->slider_length;
+  attributes.height = RANGE_CLASS (range)->slider_width;
+  attributes.event_mask |= (GDK_BUTTON_MOTION_MASK |
+                           GDK_POINTER_MOTION_HINT_MASK);
+
+  range->slider = gdk_window_new (range->trough, &attributes, attributes_mask);
+
+  widget->style = gtk_style_attach (widget->style, widget->window);
+
+  gdk_window_set_user_data (widget->window, widget);
+  gdk_window_set_user_data (range->trough, widget);
+  gdk_window_set_user_data (range->slider, widget);
+
+  gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
+  gtk_style_set_background (widget->style, range->trough, GTK_STATE_ACTIVE);
+  gtk_style_set_background (widget->style, range->slider, GTK_STATE_NORMAL);
+
+  gtk_range_slider_update (GTK_RANGE (widget));
+
+  gdk_window_show (range->slider);
+  gdk_window_show (range->trough);
+}
+
+static void
+gtk_hscale_size_request (GtkWidget      *widget,
+                        GtkRequisition *requisition)
+{
+  GtkScale *scale;
+  gint value_width;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_HSCALE (widget));
+  g_return_if_fail (requisition != NULL);
+
+  scale = GTK_SCALE (widget);
+
+  requisition->width = (SCALE_CLASS (scale)->slider_length +
+                       widget->style->klass->xthickness) * 2;
+  requisition->height = (RANGE_CLASS (scale)->slider_width +
+                        widget->style->klass->ythickness * 2);
+
+  if (scale->draw_value)
+    {
+      value_width = gtk_scale_value_width (scale);
+
+      if ((scale->value_pos == GTK_POS_LEFT) ||
+         (scale->value_pos == GTK_POS_RIGHT))
+       {
+         requisition->width += value_width + SCALE_CLASS (scale)->value_spacing;
+         if (requisition->height < (widget->style->font->ascent + widget->style->font->descent))
+           requisition->height = widget->style->font->ascent + widget->style->font->descent;
+       }
+      else if ((scale->value_pos == GTK_POS_TOP) ||
+              (scale->value_pos == GTK_POS_BOTTOM))
+       {
+         if (requisition->width < value_width)
+           requisition->width = value_width;
+         requisition->height += widget->style->font->ascent + widget->style->font->descent;
+       }
+    }
+}
+
+static void
+gtk_hscale_size_allocate (GtkWidget     *widget,
+                         GtkAllocation *allocation)
+{
+  GtkRange *range;
+  GtkScale *scale;
+  gint width, height;
+  gint x, y;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_HSCALE (widget));
+  g_return_if_fail (allocation != NULL);
+
+  widget->allocation = *allocation;
+  if (GTK_WIDGET_REALIZED (widget))
+    {
+      range = GTK_RANGE (widget);
+      scale = GTK_SCALE (widget);
+
+      gdk_window_move_resize (widget->window,
+                             allocation->x, allocation->y,
+                             allocation->width, allocation->height);
+
+      gtk_hscale_pos_trough (GTK_HSCALE (widget), &x, &y, &width, &height);
+
+      gdk_window_move_resize (range->trough, x, y, width, height);
+      gtk_range_slider_update (GTK_RANGE (widget));
+    }
+}
+
+static void
+gtk_hscale_pos_trough (GtkHScale *hscale,
+                      gint      *x,
+                      gint      *y,
+                      gint      *w,
+                      gint      *h)
+{
+  GtkWidget *widget;
+  GtkScale *scale;
+
+  g_return_if_fail (hscale != NULL);
+  g_return_if_fail (GTK_IS_HSCALE (hscale));
+  g_return_if_fail ((x != NULL) && (y != NULL) && (w != NULL) && (h != NULL));
+
+  widget = GTK_WIDGET (hscale);
+  scale = GTK_SCALE (hscale);
+
+  *w = widget->allocation.width;
+  *h = (RANGE_CLASS (scale)->slider_width +
+       widget->style->klass->ythickness * 2);
+
+  if (scale->draw_value)
+    {
+      *x = 0;
+      *y = 0;
+
+      switch (scale->value_pos)
+       {
+       case GTK_POS_LEFT:
+         *x += gtk_scale_value_width (scale) + SCALE_CLASS (scale)->value_spacing;
+         *y = (widget->allocation.height - *h) / 2;
+         *w -= *x;
+         break;
+       case GTK_POS_RIGHT:
+         *w -= gtk_scale_value_width (scale) + SCALE_CLASS (scale)->value_spacing;
+         *y = (widget->allocation.height - *h) / 2;
+         break;
+       case GTK_POS_TOP:
+         *y = (widget->style->font->ascent + widget->style->font->descent +
+               (widget->allocation.height - widget->requisition.height) / 2);
+         break;
+       case GTK_POS_BOTTOM:
+         *y = (widget->allocation.height - widget->requisition.height) / 2;
+         break;
+       }
+    }
+  else
+    {
+      *x = 0;
+      *y = (widget->allocation.height - *h) / 2;
+    }
+  *x += 1;
+  *w -= 2;
+}
+
+static void
+gtk_hscale_draw_slider (GtkRange *range)
+{
+  GtkStateType state_type;
+  gint width, height;
+
+  g_return_if_fail (range != NULL);
+  g_return_if_fail (GTK_IS_HSCALE (range));
+
+  if (range->slider)
+    {
+      if ((range->in_child == RANGE_CLASS (range)->slider) ||
+          (range->click_child == RANGE_CLASS (range)->slider))
+        state_type = GTK_STATE_PRELIGHT;
+      else
+        state_type = GTK_STATE_NORMAL;
+
+      gtk_style_set_background (GTK_WIDGET (range)->style, range->slider, state_type);
+      gdk_window_clear (range->slider);
+
+      gdk_window_get_size (range->slider, &width, &height);
+      gtk_draw_vline (GTK_WIDGET (range)->style, range->slider,
+                     state_type, 1, height - 2, width / 2);
+
+      gtk_draw_shadow (GTK_WIDGET (range)->style, range->slider,
+                       state_type, GTK_SHADOW_OUT,
+                       0, 0, -1, -1);
+    }
+}
+
+static void
+gtk_hscale_draw_value (GtkScale *scale)
+{
+  GtkStateType state_type;
+  gchar buffer[16];
+  gint text_width;
+  gint width, height;
+  gint x, y;
+
+  g_return_if_fail (scale != NULL);
+  g_return_if_fail (GTK_IS_HSCALE (scale));
+
+  if (scale->draw_value)
+    {
+      gdk_window_get_size (GTK_WIDGET (scale)->window, &width, &height);
+      gdk_window_clear_area (GTK_WIDGET (scale)->window, 1, 1, width - 2, height - 2);
+
+      sprintf (buffer, "%0.*f", GTK_RANGE (scale)->digits, GTK_RANGE (scale)->adjustment->value);
+      text_width = gdk_string_measure (GTK_WIDGET (scale)->style->font, buffer);
+
+      switch (scale->value_pos)
+       {
+       case GTK_POS_LEFT:
+         gdk_window_get_position (GTK_RANGE (scale)->trough, &x, &y);
+         gdk_window_get_size (GTK_RANGE (scale)->trough, &width, &height);
+
+         x -= SCALE_CLASS (scale)->value_spacing + text_width;
+         y += ((height -
+                (GTK_WIDGET (scale)->style->font->ascent +
+                 GTK_WIDGET (scale)->style->font->descent)) / 2 +
+               GTK_WIDGET (scale)->style->font->ascent);
+         break;
+       case GTK_POS_RIGHT:
+         gdk_window_get_position (GTK_RANGE (scale)->trough, &x, &y);
+         gdk_window_get_size (GTK_RANGE (scale)->trough, &width, &height);
+
+         x += width + SCALE_CLASS (scale)->value_spacing;
+         y += ((height -
+                (GTK_WIDGET (scale)->style->font->ascent +
+                 GTK_WIDGET (scale)->style->font->descent)) / 2 +
+               GTK_WIDGET (scale)->style->font->ascent);
+         break;
+       case GTK_POS_TOP:
+         gdk_window_get_position (GTK_RANGE (scale)->slider, &x, NULL);
+         gdk_window_get_position (GTK_RANGE (scale)->trough, NULL, &y);
+         gdk_window_get_size (GTK_RANGE (scale)->slider, &width, NULL);
+         gdk_window_get_size (GTK_RANGE (scale)->trough, NULL, &height);
+
+         x += (width - text_width) / 2;
+         y -= GTK_WIDGET (scale)->style->font->descent;
+         break;
+       case GTK_POS_BOTTOM:
+         gdk_window_get_position (GTK_RANGE (scale)->slider, &x, NULL);
+         gdk_window_get_position (GTK_RANGE (scale)->trough, NULL, &y);
+         gdk_window_get_size (GTK_RANGE (scale)->slider, &width, NULL);
+         gdk_window_get_size (GTK_RANGE (scale)->trough, NULL, &height);
+
+         x += (width - text_width) / 2;
+         y += height + GTK_WIDGET (scale)->style->font->ascent;
+         break;
+       }
+
+      state_type = GTK_STATE_NORMAL;
+      if (!GTK_WIDGET_IS_SENSITIVE (scale))
+       state_type = GTK_STATE_INSENSITIVE;
+
+      gtk_draw_string (GTK_WIDGET (scale)->style,
+                      GTK_WIDGET (scale)->window,
+                      state_type, x, y, buffer);
+    }
+}
+
+static gint
+gtk_hscale_trough_keys(GtkRange *range,
+                      GdkEventKey *key,
+                      GtkScrollType *scroll,
+                      GtkTroughType *pos)
+{
+  gint return_val = FALSE;
+  switch (key->keyval)
+    {
+    case GDK_Left:
+      return_val = TRUE;
+      if (key->state & GDK_CONTROL_MASK)
+       *scroll = GTK_SCROLL_PAGE_BACKWARD;
+      else
+       *scroll = GTK_SCROLL_STEP_BACKWARD;
+      break;
+    case GDK_Right:
+      return_val = TRUE;
+      if (key->state & GDK_CONTROL_MASK)
+       *scroll = GTK_SCROLL_PAGE_FORWARD;
+      else
+       *scroll = GTK_SCROLL_STEP_FORWARD;
+      break;
+    case GDK_Home:
+      return_val = TRUE;
+      *pos = GTK_TROUGH_START;
+      break;
+    case GDK_End:
+      return_val = TRUE;
+      *pos = GTK_TROUGH_END;
+      break;
+    }
+  return return_val;
+}
diff --git a/gtk/gtkhscale.h b/gtk/gtkhscale.h
new file mode 100644 (file)
index 0000000..61ae4fd
--- /dev/null
@@ -0,0 +1,59 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_HSCALE_H__
+#define __GTK_HSCALE_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkscale.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_HSCALE(obj)          GTK_CHECK_CAST (obj, gtk_hscale_get_type (), GtkHScale)
+#define GTK_HSCALE_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_hscale_get_type (), GtkHScaleClass)
+#define GTK_IS_HSCALE(obj)       GTK_CHECK_TYPE (obj, gtk_hscale_get_type ())
+
+
+typedef struct _GtkHScale       GtkHScale;
+typedef struct _GtkHScaleClass  GtkHScaleClass;
+
+struct _GtkHScale
+{
+  GtkScale scale;
+};
+
+struct _GtkHScaleClass
+{
+  GtkScaleClass parent_class;
+};
+
+
+guint      gtk_hscale_get_type (void);
+GtkWidget* gtk_hscale_new      (GtkAdjustment *adjustment);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_HSCALE_H__ */
diff --git a/gtk/gtkhscrollbar.c b/gtk/gtkhscrollbar.c
new file mode 100644 (file)
index 0000000..9b757d4
--- /dev/null
@@ -0,0 +1,383 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkhscrollbar.h"
+#include "gtksignal.h"
+#include "gdk/gdkkeysyms.h"
+
+
+#define EPSILON 0.01
+
+#define RANGE_CLASS(w)  GTK_RANGE_CLASS (GTK_OBJECT (w)->klass)
+
+
+static void gtk_hscrollbar_class_init       (GtkHScrollbarClass *klass);
+static void gtk_hscrollbar_init             (GtkHScrollbar      *hscrollbar);
+static void gtk_hscrollbar_realize          (GtkWidget          *widget);
+static void gtk_hscrollbar_size_allocate    (GtkWidget          *widget,
+                                            GtkAllocation      *allocation);
+static void gtk_hscrollbar_draw_step_forw   (GtkRange           *range);
+static void gtk_hscrollbar_draw_step_back   (GtkRange           *range);
+static void gtk_hscrollbar_slider_update    (GtkRange           *range);
+static void gtk_hscrollbar_calc_slider_size (GtkHScrollbar      *hscrollbar);
+static gint gtk_hscrollbar_trough_keys      (GtkRange *range,
+                                            GdkEventKey *key,
+                                            GtkScrollType *scroll,
+                                            GtkTroughType *pos);
+
+
+guint
+gtk_hscrollbar_get_type ()
+{
+  static guint hscrollbar_type = 0;
+
+  if (!hscrollbar_type)
+    {
+      GtkTypeInfo hscrollbar_info =
+      {
+       "GtkHScrollbar",
+       sizeof (GtkHScrollbar),
+       sizeof (GtkHScrollbarClass),
+       (GtkClassInitFunc) gtk_hscrollbar_class_init,
+       (GtkObjectInitFunc) gtk_hscrollbar_init,
+       (GtkArgFunc) NULL,
+      };
+
+      hscrollbar_type = gtk_type_unique (gtk_scrollbar_get_type (), &hscrollbar_info);
+    }
+
+  return hscrollbar_type;
+}
+
+static void
+gtk_hscrollbar_class_init (GtkHScrollbarClass *class)
+{
+  GtkWidgetClass *widget_class;
+  GtkRangeClass *range_class;
+
+  widget_class = (GtkWidgetClass*) class;
+  range_class = (GtkRangeClass*) class;
+
+  widget_class->realize = gtk_hscrollbar_realize;
+  widget_class->size_allocate = gtk_hscrollbar_size_allocate;
+
+  range_class->draw_step_forw = gtk_hscrollbar_draw_step_forw;
+  range_class->draw_step_back = gtk_hscrollbar_draw_step_back;
+  range_class->slider_update = gtk_hscrollbar_slider_update;
+  range_class->trough_click = gtk_range_default_htrough_click;
+  range_class->trough_keys = gtk_hscrollbar_trough_keys;
+  range_class->motion = gtk_range_default_hmotion;
+}
+
+static void
+gtk_hscrollbar_init (GtkHScrollbar *hscrollbar)
+{
+  GtkWidget *widget;
+  GtkRequisition *requisition;
+
+  widget = GTK_WIDGET (hscrollbar);
+  GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS);
+  requisition = &widget->requisition;
+
+  requisition->width = (RANGE_CLASS (widget)->min_slider_size +
+                       RANGE_CLASS (widget)->stepper_size +
+                       RANGE_CLASS (widget)->stepper_slider_spacing +
+                       widget->style->klass->xthickness) * 2;
+  requisition->height = (RANGE_CLASS (widget)->slider_width +
+                        widget->style->klass->ythickness * 2);
+}
+
+GtkWidget*
+gtk_hscrollbar_new (GtkAdjustment *adjustment)
+{
+  GtkHScrollbar *hscrollbar;
+
+  hscrollbar = gtk_type_new (gtk_hscrollbar_get_type ());
+
+  if (!adjustment)
+    adjustment = (GtkAdjustment*) gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+
+  gtk_range_set_adjustment (GTK_RANGE (hscrollbar), adjustment);
+
+  return GTK_WIDGET (hscrollbar);
+}
+
+
+static void
+gtk_hscrollbar_realize (GtkWidget *widget)
+{
+  GtkRange *range;
+  GdkWindowAttr attributes;
+  gint attributes_mask;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_HSCROLLBAR (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+  range = GTK_RANGE (widget);
+
+  attributes.x = widget->allocation.x;
+  attributes.y = widget->allocation.y + (widget->allocation.height - widget->requisition.height) / 2;
+  attributes.width = widget->allocation.width;
+  attributes.height = widget->requisition.height;
+  attributes.wclass = GDK_INPUT_OUTPUT;
+  attributes.window_type = GDK_WINDOW_CHILD;
+  attributes.visual = gtk_widget_get_visual (widget);
+  attributes.colormap = gtk_widget_get_colormap (widget);
+  attributes.event_mask = gtk_widget_get_events (widget);
+  attributes.event_mask |= (GDK_EXPOSURE_MASK |
+                           GDK_BUTTON_PRESS_MASK |
+                           GDK_BUTTON_RELEASE_MASK |
+                           GDK_ENTER_NOTIFY_MASK |
+                           GDK_LEAVE_NOTIFY_MASK);
+
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+  widget->window = gdk_window_new (widget->parent->window, &attributes, attributes_mask);
+  range->trough = widget->window;
+
+  attributes.x = widget->style->klass->xthickness;
+  attributes.y = widget->style->klass->ythickness;
+  attributes.width = RANGE_CLASS (widget)->stepper_size;
+  attributes.height = RANGE_CLASS (widget)->stepper_size;
+
+  range->step_back = gdk_window_new (range->trough, &attributes, attributes_mask);
+
+  attributes.x = (widget->allocation.width -
+                 widget->style->klass->xthickness -
+                 RANGE_CLASS (widget)->stepper_size);
+
+  range->step_forw = gdk_window_new (range->trough, &attributes, attributes_mask);
+
+  attributes.x = 0;
+  attributes.y = widget->style->klass->ythickness;
+  attributes.width = RANGE_CLASS (widget)->min_slider_size;
+  attributes.height = RANGE_CLASS (widget)->slider_width;
+  attributes.event_mask |= (GDK_BUTTON_MOTION_MASK |
+                           GDK_POINTER_MOTION_HINT_MASK);
+
+  range->slider = gdk_window_new (range->trough, &attributes, attributes_mask);
+
+  gtk_hscrollbar_calc_slider_size (GTK_HSCROLLBAR (widget));
+  gtk_range_slider_update (GTK_RANGE (widget));
+
+  widget->style = gtk_style_attach (widget->style, widget->window);
+
+  gdk_window_set_user_data (range->trough, widget);
+  gdk_window_set_user_data (range->slider, widget);
+  gdk_window_set_user_data (range->step_forw, widget);
+  gdk_window_set_user_data (range->step_back, widget);
+
+  gtk_style_set_background (widget->style, range->trough, GTK_STATE_ACTIVE);
+  gtk_style_set_background (widget->style, range->slider, GTK_STATE_NORMAL);
+  gtk_style_set_background (widget->style, range->step_forw, GTK_STATE_ACTIVE);
+  gtk_style_set_background (widget->style, range->step_back, GTK_STATE_ACTIVE);
+
+  gdk_window_show (range->slider);
+  gdk_window_show (range->step_forw);
+  gdk_window_show (range->step_back);
+}
+
+static void
+gtk_hscrollbar_size_allocate (GtkWidget     *widget,
+                             GtkAllocation *allocation)
+{
+  GtkRange *range;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_HSCROLLBAR (widget));
+  g_return_if_fail (allocation != NULL);
+
+  widget->allocation = *allocation;
+  if (GTK_WIDGET_REALIZED (widget))
+    {
+      range = GTK_RANGE (widget);
+
+      gdk_window_move_resize (range->trough,
+                             allocation->x,
+                             allocation->y + (allocation->height - widget->requisition.height) / 2,
+                             allocation->width, widget->requisition.height);
+      gdk_window_move_resize (range->step_back,
+                             widget->style->klass->xthickness,
+                             widget->style->klass->ythickness,
+                             RANGE_CLASS (widget)->stepper_size,
+                             widget->requisition.height - widget->style->klass->ythickness * 2);
+      gdk_window_move_resize (range->step_forw,
+                             allocation->width - widget->style->klass->xthickness -
+                             RANGE_CLASS (widget)->stepper_size,
+                             widget->style->klass->ythickness,
+                             RANGE_CLASS (widget)->stepper_size,
+                             widget->requisition.height - widget->style->klass->ythickness * 2);
+      gdk_window_resize (range->slider,
+                        RANGE_CLASS (widget)->min_slider_size,
+                        widget->requisition.height - widget->style->klass->ythickness * 2);
+
+      gtk_range_slider_update (GTK_RANGE (widget));
+    }
+}
+
+static void
+gtk_hscrollbar_draw_step_forw (GtkRange *range)
+{
+  GtkStateType state_type;
+  GtkShadowType shadow_type;
+
+  g_return_if_fail (range != NULL);
+  g_return_if_fail (GTK_IS_HSCROLLBAR (range));
+
+  if (GTK_WIDGET_DRAWABLE (range))
+    {
+      if (range->in_child == RANGE_CLASS (range)->step_forw)
+       {
+         if (range->click_child == RANGE_CLASS (range)->step_forw)
+           state_type = GTK_STATE_ACTIVE;
+         else
+           state_type = GTK_STATE_PRELIGHT;
+       }
+      else
+       state_type = GTK_STATE_NORMAL;
+
+      if (range->click_child == RANGE_CLASS (range)->step_forw)
+       shadow_type = GTK_SHADOW_IN;
+      else
+       shadow_type = GTK_SHADOW_OUT;
+
+      gtk_draw_arrow (GTK_WIDGET (range)->style, range->step_forw,
+                     state_type, shadow_type, GTK_ARROW_RIGHT,
+                     TRUE, 0, 0, -1, -1);
+    }
+}
+
+static void
+gtk_hscrollbar_draw_step_back (GtkRange *range)
+{
+  GtkStateType state_type;
+  GtkShadowType shadow_type;
+
+  g_return_if_fail (range != NULL);
+  g_return_if_fail (GTK_IS_HSCROLLBAR (range));
+
+  if (GTK_WIDGET_DRAWABLE (range))
+    {
+      if (range->in_child == RANGE_CLASS (range)->step_back)
+       {
+         if (range->click_child == RANGE_CLASS (range)->step_back)
+           state_type = GTK_STATE_ACTIVE;
+         else
+           state_type = GTK_STATE_PRELIGHT;
+       }
+      else
+       state_type = GTK_STATE_NORMAL;
+
+      if (range->click_child == RANGE_CLASS (range)->step_back)
+       shadow_type = GTK_SHADOW_IN;
+      else
+       shadow_type = GTK_SHADOW_OUT;
+
+      gtk_draw_arrow (GTK_WIDGET (range)->style, range->step_back,
+                     state_type, shadow_type, GTK_ARROW_LEFT,
+                     TRUE, 0, 0, -1, -1);
+    }
+}
+
+static void
+gtk_hscrollbar_slider_update (GtkRange *range)
+{
+  g_return_if_fail (range != NULL);
+  g_return_if_fail (GTK_IS_HSCROLLBAR (range));
+
+  gtk_hscrollbar_calc_slider_size (GTK_HSCROLLBAR (range));
+  gtk_range_default_hslider_update (range);
+}
+
+static void
+gtk_hscrollbar_calc_slider_size (GtkHScrollbar *hscrollbar)
+{
+  GtkRange *range;
+  gint step_back_x;
+  gint step_back_width;
+  gint step_forw_x;
+  gint slider_width;
+  gint slider_height;
+  gint left, right;
+  gint width;
+
+  g_return_if_fail (hscrollbar != NULL);
+  g_return_if_fail (GTK_IS_HSCROLLBAR (hscrollbar));
+
+  if (GTK_WIDGET_REALIZED (hscrollbar))
+    {
+      range = GTK_RANGE (hscrollbar);
+
+      gdk_window_get_size (range->step_back, &step_back_width, NULL);
+      gdk_window_get_position (range->step_back, &step_back_x, NULL);
+      gdk_window_get_position (range->step_forw, &step_forw_x, NULL);
+
+      left = (step_back_x +
+             step_back_width +
+             RANGE_CLASS (hscrollbar)->stepper_slider_spacing);
+      right = step_forw_x - RANGE_CLASS (hscrollbar)->stepper_slider_spacing;
+      width = right - left;
+
+      if ((range->adjustment->page_size > 0) &&
+         (range->adjustment->lower != range->adjustment->upper))
+       {
+         if (range->adjustment->page_size >
+             (range->adjustment->upper - range->adjustment->lower))
+           range->adjustment->page_size = range->adjustment->upper - range->adjustment->lower;
+
+         width = (width * range->adjustment->page_size /
+                  (range->adjustment->upper - range->adjustment->lower));
+
+         if (width < RANGE_CLASS (hscrollbar)->min_slider_size)
+           width = RANGE_CLASS (hscrollbar)->min_slider_size;
+       }
+
+      gdk_window_get_size (range->slider, &slider_width, &slider_height);
+
+      if (slider_width != width)
+       gdk_window_resize (range->slider, width, slider_height);
+    }
+}
+
+static gint
+gtk_hscrollbar_trough_keys(GtkRange *range,
+                          GdkEventKey *key,
+                          GtkScrollType *scroll,
+                          GtkTroughType *pos)
+{
+  gint return_val = FALSE;
+  switch (key->keyval)
+    {
+    case GDK_Left:
+      return_val = TRUE;
+      *scroll = GTK_SCROLL_STEP_BACKWARD;
+      break;
+    case GDK_Right:
+      return_val = TRUE;
+      *scroll = GTK_SCROLL_STEP_FORWARD;
+      break;
+    case GDK_Home:
+      return_val = TRUE;
+      *pos = GTK_TROUGH_START;
+      break;
+    case GDK_End:
+      return_val = TRUE;
+      *pos = GTK_TROUGH_END;
+      break;
+    }
+  return return_val;
+}
diff --git a/gtk/gtkhscrollbar.h b/gtk/gtkhscrollbar.h
new file mode 100644 (file)
index 0000000..7d69512
--- /dev/null
@@ -0,0 +1,59 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_HSCROLLBAR_H__
+#define __GTK_HSCROLLBAR_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkscrollbar.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_HSCROLLBAR(obj)          GTK_CHECK_CAST (obj, gtk_hscrollbar_get_type (), GtkHScrollbar)
+#define GTK_HSCROLLBAR_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_hscrollbar_get_type (), GtkHScrollbarClass)
+#define GTK_IS_HSCROLLBAR(obj)       GTK_CHECK_TYPE (obj, gtk_hscrollbar_get_type ())
+
+
+typedef struct _GtkHScrollbar       GtkHScrollbar;
+typedef struct _GtkHScrollbarClass  GtkHScrollbarClass;
+
+struct _GtkHScrollbar
+{
+  GtkScrollbar scrollbar;
+};
+
+struct _GtkHScrollbarClass
+{
+  GtkScrollbarClass parent_class;
+};
+
+
+guint      gtk_hscrollbar_get_type (void);
+GtkWidget* gtk_hscrollbar_new      (GtkAdjustment *adjustment);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_HSCROLLBAR_H__ */
diff --git a/gtk/gtkhseparator.c b/gtk/gtkhseparator.c
new file mode 100644 (file)
index 0000000..5f3a38c
--- /dev/null
@@ -0,0 +1,90 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkhseparator.h"
+
+
+static void gtk_hseparator_class_init (GtkHSeparatorClass *klass);
+static void gtk_hseparator_init       (GtkHSeparator      *hseparator);
+static gint gtk_hseparator_expose     (GtkWidget          *widget,
+                                      GdkEventExpose     *event);
+
+
+guint
+gtk_hseparator_get_type ()
+{
+  static guint hseparator_type = 0;
+
+  if (!hseparator_type)
+    {
+      GtkTypeInfo hseparator_info =
+      {
+       "GtkHSeparator",
+       sizeof (GtkHSeparator),
+       sizeof (GtkHSeparatorClass),
+       (GtkClassInitFunc) gtk_hseparator_class_init,
+       (GtkObjectInitFunc) gtk_hseparator_init,
+       (GtkArgFunc) NULL,
+      };
+
+      hseparator_type = gtk_type_unique (gtk_separator_get_type (), &hseparator_info);
+    }
+
+  return hseparator_type;
+}
+
+static void
+gtk_hseparator_class_init (GtkHSeparatorClass *class)
+{
+  GtkWidgetClass *widget_class;
+
+  widget_class = (GtkWidgetClass*) class;
+
+  widget_class->expose_event = gtk_hseparator_expose;
+}
+
+static void
+gtk_hseparator_init (GtkHSeparator *hseparator)
+{
+  GTK_WIDGET (hseparator)->requisition.width = 1;
+  GTK_WIDGET (hseparator)->requisition.height = GTK_WIDGET (hseparator)->style->klass->ythickness;
+}
+
+GtkWidget*
+gtk_hseparator_new ()
+{
+  return GTK_WIDGET (gtk_type_new (gtk_hseparator_get_type ()));
+}
+
+
+static gint
+gtk_hseparator_expose (GtkWidget      *widget,
+                      GdkEventExpose *event)
+{
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_HSEPARATOR (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    gtk_draw_hline (widget->style, widget->window, GTK_STATE_NORMAL,
+                   widget->allocation.x,
+                   widget->allocation.x + widget->allocation.width,
+                   widget->allocation.y + (widget->allocation.height -
+                                           widget->style->klass->ythickness) / 2);
+
+  return FALSE;
+}
diff --git a/gtk/gtkhseparator.h b/gtk/gtkhseparator.h
new file mode 100644 (file)
index 0000000..9902631
--- /dev/null
@@ -0,0 +1,59 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_HSEPARATOR_H__
+#define __GTK_HSEPARATOR_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkseparator.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_HSEPARATOR(obj)          GTK_CHECK_CAST (obj, gtk_hseparator_get_type (), GtkHSeparator)
+#define GTK_HSEPARATOR_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_hseparator_get_type (), GtkHSeparatorClass)
+#define GTK_IS_HSEPARATOR(obj)       GTK_CHECK_TYPE (obj, gtk_hseparator_get_type ())
+
+
+typedef struct _GtkHSeparator       GtkHSeparator;
+typedef struct _GtkHSeparatorClass  GtkHSeparatorClass;
+
+struct _GtkHSeparator
+{
+  GtkSeparator separator;
+};
+
+struct _GtkHSeparatorClass
+{
+  GtkSeparatorClass parent_class;
+};
+
+
+guint      gtk_hseparator_get_type (void);
+GtkWidget* gtk_hseparator_new      (void);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_HSEPARATOR_H__ */
diff --git a/gtk/gtkimage.c b/gtk/gtkimage.c
new file mode 100644 (file)
index 0000000..fddd06a
--- /dev/null
@@ -0,0 +1,181 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkcontainer.h"
+#include "gtkimage.h"
+
+
+static void gtk_image_class_init (GtkImageClass  *klass);
+static void gtk_image_init       (GtkImage       *image);
+static gint gtk_image_expose     (GtkWidget      *widget,
+                                 GdkEventExpose *event);
+
+
+guint
+gtk_image_get_type ()
+{
+  static guint image_type = 0;
+
+  if (!image_type)
+    {
+      GtkTypeInfo image_info =
+      {
+       "GtkImage",
+       sizeof (GtkImage),
+       sizeof (GtkImageClass),
+       (GtkClassInitFunc) gtk_image_class_init,
+       (GtkObjectInitFunc) gtk_image_init,
+       (GtkArgFunc) NULL,
+      };
+
+      image_type = gtk_type_unique (gtk_misc_get_type (), &image_info);
+    }
+
+  return image_type;
+}
+
+static void
+gtk_image_class_init (GtkImageClass *class)
+{
+  GtkWidgetClass *widget_class;
+
+  widget_class = (GtkWidgetClass*) class;
+
+  widget_class->expose_event = gtk_image_expose;
+}
+
+static void
+gtk_image_init (GtkImage *image)
+{
+  GTK_WIDGET_SET_FLAGS (image, GTK_NO_WINDOW);
+
+  image->image = NULL;
+  image->mask = NULL;
+}
+
+GtkWidget*
+gtk_image_new (GdkImage  *val,
+              GdkBitmap *mask)
+{
+  GtkImage *image;
+
+  g_return_val_if_fail (val != NULL, NULL);
+
+  image = gtk_type_new (gtk_image_get_type ());
+
+  gtk_image_set (image, val, mask);
+
+  return GTK_WIDGET (image);
+}
+
+void
+gtk_image_set (GtkImage  *image,
+              GdkImage  *val,
+              GdkBitmap *mask)
+{
+  g_return_if_fail (image != NULL);
+  g_return_if_fail (GTK_IS_IMAGE (image));
+
+  image->image = val;
+  image->mask = mask;
+
+  if (image->image)
+    {
+      GTK_WIDGET (image)->requisition.width = image->image->width + GTK_MISC (image)->xpad * 2;
+      GTK_WIDGET (image)->requisition.height = image->image->height + GTK_MISC (image)->ypad * 2;
+    }
+  else
+    {
+      GTK_WIDGET (image)->requisition.width = 0;
+      GTK_WIDGET (image)->requisition.height = 0;
+    }
+
+  if (GTK_WIDGET_VISIBLE (image))
+    gtk_widget_queue_resize (GTK_WIDGET (image));
+}
+
+void
+gtk_image_get (GtkImage   *image,
+              GdkImage  **val,
+              GdkBitmap **mask)
+{
+  g_return_if_fail (image != NULL);
+  g_return_if_fail (GTK_IS_IMAGE (image));
+
+  if (val)
+    *val = image->image;
+  if (mask)
+    *mask = image->mask;
+}
+
+
+static gint
+gtk_image_expose (GtkWidget      *widget,
+                 GdkEventExpose *event)
+{
+  GtkImage *image;
+  GtkMisc *misc;
+  GdkRectangle area;
+  gint x, y;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_IMAGE (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget))
+    {
+      image = GTK_IMAGE (widget);
+      misc = GTK_MISC (widget);
+
+      x = (widget->allocation.x * (1.0 - misc->xalign) +
+          (widget->allocation.x + widget->allocation.width
+           - (widget->requisition.width - misc->xpad * 2)) *
+          misc->xalign) + 0.5;
+      y = (widget->allocation.y * (1.0 - misc->yalign) +
+          (widget->allocation.y + widget->allocation.height
+           - (widget->requisition.height - misc->ypad * 2)) *
+          misc->yalign) + 0.5;
+
+      if (image->mask)
+       {
+         gdk_gc_set_clip_mask (widget->style->black_gc, image->mask);
+         gdk_gc_set_clip_origin (widget->style->black_gc, x, y);
+       }
+
+      area = event->area;
+      if ((area.x < 0) || (area.y < 0))
+       {
+         area.x = area.y = 0;
+         area.width = image->image->width;
+         area.height = image->image->height;
+       }
+
+      gdk_draw_image (widget->window,
+                     widget->style->black_gc,
+                     image->image,
+                     area.x, area.y, x+area.x, y+area.y,
+                     area.width, area.height);
+
+      if (image->mask)
+       {
+         gdk_gc_set_clip_mask (widget->style->black_gc, NULL);
+         gdk_gc_set_clip_origin (widget->style->black_gc, 0, 0);
+       }
+    }
+
+  return FALSE;
+}
diff --git a/gtk/gtkimage.h b/gtk/gtkimage.h
new file mode 100644 (file)
index 0000000..d3481d5
--- /dev/null
@@ -0,0 +1,69 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_IMAGE_H__
+#define __GTK_IMAGE_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkmisc.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_IMAGE(obj)          GTK_CHECK_CAST (obj, gtk_image_get_type (), GtkImage)
+#define GTK_IMAGE_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_image_get_type (), GtkImageClass)
+#define GTK_IS_IMAGE(obj)       GTK_CHECK_TYPE (obj, gtk_image_get_type ())
+
+
+typedef struct _GtkImage       GtkImage;
+typedef struct _GtkImageClass  GtkImageClass;
+
+struct _GtkImage
+{
+  GtkMisc misc;
+
+  GdkImage *image;
+  GdkBitmap *mask;
+};
+
+struct _GtkImageClass
+{
+  GtkMiscClass parent_class;
+};
+
+
+guint      gtk_image_get_type (void);
+GtkWidget* gtk_image_new      (GdkImage   *val,
+                              GdkBitmap  *mask);
+void       gtk_image_set      (GtkImage   *image,
+                              GdkImage   *val,
+                              GdkBitmap  *mask);
+void       gtk_image_get      (GtkImage   *image,
+                              GdkImage  **val,
+                              GdkBitmap **mask);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_IMAGE_H__ */
diff --git a/gtk/gtkinputdialog.c b/gtk/gtkinputdialog.c
new file mode 100644 (file)
index 0000000..1d412a3
--- /dev/null
@@ -0,0 +1,546 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * gtkinputdialog.c
+ *
+ * Copyright 1997 Owen Taylor <owt1@cornell.edu>
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include "gdk/gdkkeysyms.h"
+#include "gtkbutton.h"
+#include "gtkhbox.h"
+#include "gtkhseparator.h"
+#include "gtkinputdialog.h"
+#include "gtklabel.h"
+#include "gtklistitem.h"
+#include "gtkmain.h"
+#include "gtkmenu.h"
+#include "gtkmenuitem.h"
+#include "gtkoptionmenu.h"
+#include "gtkscrolledwindow.h"
+#include "gtksignal.h"
+#include "gtkvbox.h"
+
+typedef void (*GtkInputDialogSignal1) (GtkObject *object,
+                                 int   arg1,
+                                 gpointer   data);
+
+enum
+{
+  ENABLE_DEVICE,
+  DISABLE_DEVICE,
+  LAST_SIGNAL
+};
+
+
+#define AXIS_LIST_WIDTH 160
+#define AXIS_LIST_HEIGHT 175
+
+/* Forward declarations */
+
+static void gtk_input_dialog_marshal_signal1 (GtkObject      *object,
+                                             GtkSignalFunc   func,
+                                             gpointer        func_data,
+                                             GtkArg *args);
+static void gtk_input_dialog_class_init (GtkInputDialogClass *klass);
+static void gtk_input_dialog_init (GtkInputDialog *inputd);
+static GdkDeviceInfo *gtk_input_dialog_get_device_info(guint32 deviceid);
+static void gtk_input_dialog_set_device(GtkWidget *widget, gpointer data);
+static void gtk_input_dialog_destroy (GtkObject *object);
+static void gtk_input_dialog_set_mapping_mode(GtkWidget *w,
+                                             gpointer data);
+static void gtk_input_dialog_set_axis(GtkWidget *widget, gpointer data);
+static void gtk_input_dialog_fill_axes (GtkInputDialog *inputd,
+                                       GdkDeviceInfo *info);
+
+static GtkObjectClass *parent_class = NULL;
+static gint input_dialog_signals[LAST_SIGNAL] = { 0 };
+
+static void
+gtk_input_dialog_marshal_signal1 (GtkObject      *object,
+                                 GtkSignalFunc   func,
+                                 gpointer        func_data,
+                                 GtkArg *args)
+{
+  GtkInputDialogSignal1 rfunc;
+
+  rfunc = (GtkInputDialogSignal1) func;
+  (* rfunc) (object, GTK_VALUE_INT(args[0]), func_data);
+}
+
+static GdkDeviceInfo *
+gtk_input_dialog_get_device_info(guint32 deviceid)
+{
+  GList *tmp_list = gdk_input_list_devices();
+  while (tmp_list)
+    {
+      if (((GdkDeviceInfo *)tmp_list->data)->deviceid == deviceid)
+       return (GdkDeviceInfo *)tmp_list->data;
+      tmp_list = tmp_list->next;
+    }
+
+  return NULL;
+}
+
+guint
+gtk_input_dialog_get_type ()
+{
+  static guint input_dialog_type = 0;
+
+  if (!input_dialog_type)
+    {
+      GtkTypeInfo input_dialog_info =
+      {
+       "GtkInputDialog",
+       sizeof (GtkInputDialog),
+       sizeof (GtkInputDialogClass),
+       (GtkClassInitFunc) gtk_input_dialog_class_init,
+       (GtkObjectInitFunc) gtk_input_dialog_init,
+       (GtkArgFunc) NULL,
+      };
+
+      input_dialog_type = gtk_type_unique (gtk_dialog_get_type (),
+                                          &input_dialog_info);
+    }
+
+  return input_dialog_type;
+}
+
+static void
+gtk_input_dialog_class_init (GtkInputDialogClass *klass)
+{
+  GtkObjectClass *object_class;
+
+  object_class = (GtkObjectClass*) klass;
+
+  parent_class = gtk_type_class (gtk_dialog_get_type ());
+
+  input_dialog_signals[ENABLE_DEVICE] =
+    gtk_signal_new ("enable_device",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkInputDialogClass, enable_device),
+                   gtk_input_dialog_marshal_signal1,
+                   GTK_TYPE_NONE, 1, GTK_TYPE_INT);
+
+  input_dialog_signals[DISABLE_DEVICE] =
+    gtk_signal_new ("disable_device",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkInputDialogClass, disable_device),
+                   gtk_input_dialog_marshal_signal1,
+                   GTK_TYPE_NONE, 1, GTK_TYPE_INT);
+
+  gtk_object_class_add_signals (object_class, input_dialog_signals,
+                               LAST_SIGNAL);
+
+
+  object_class->destroy = gtk_input_dialog_destroy;
+  klass->enable_device = NULL;
+  klass->disable_device = NULL;
+}
+
+static void
+gtk_input_dialog_init (GtkInputDialog *inputd)
+{
+  GtkWidget *vbox;
+  GtkWidget *util_box;
+  GtkWidget *label;
+  GtkWidget *device_menu;
+  GtkWidget *mapping_menu;
+  GtkWidget *menuitem;
+  GtkWidget *optionmenu;
+  GtkWidget *separator;
+
+  GList *tmp_list;
+  GList *device_info;
+
+  device_info = gdk_input_list_devices();
+
+  /* shell and main vbox */
+
+  gtk_window_set_title (GTK_WINDOW (inputd), "Input");
+
+  vbox = gtk_vbox_new (FALSE, 4);
+  gtk_container_border_width(GTK_CONTAINER (vbox), 5);
+  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (inputd)->vbox), vbox, TRUE, TRUE, 0);
+
+  if (g_list_length(device_info) <= 1) /* only core device */
+    {
+      label = gtk_label_new ("No input devices");
+      gtk_container_add (GTK_CONTAINER (vbox), label);
+
+      gtk_widget_show (label);
+    }
+  else
+    {
+      /* menu for selecting device */
+
+      device_menu = gtk_menu_new ();
+
+      for (tmp_list = device_info; tmp_list; tmp_list = tmp_list->next) {
+       GdkDeviceInfo *info = (GdkDeviceInfo *)(tmp_list->data);
+       if (info->deviceid != GDK_CORE_POINTER)
+         {
+           menuitem = gtk_menu_item_new_with_label(info->name);
+
+           gtk_menu_append(GTK_MENU(device_menu),menuitem);
+           gtk_widget_show(menuitem);
+           gtk_object_set_user_data (GTK_OBJECT (menuitem), inputd);
+           gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+                               (GtkSignalFunc) gtk_input_dialog_set_device,
+                               (gpointer)((long)info->deviceid));
+         }
+      }
+
+      util_box = gtk_hbox_new (FALSE, 2);
+      gtk_box_pack_start (GTK_BOX (vbox), util_box, FALSE, FALSE, 0);
+
+      label = gtk_label_new("Device:");
+      gtk_box_pack_start (GTK_BOX (util_box), label, FALSE, FALSE, 2);
+
+      optionmenu = gtk_option_menu_new ();
+      gtk_box_pack_start (GTK_BOX (util_box), optionmenu, TRUE, TRUE, 2);
+      gtk_widget_show (optionmenu);
+      gtk_option_menu_set_menu (GTK_OPTION_MENU (optionmenu), device_menu);
+
+      gtk_widget_show (label);
+      gtk_widget_show (util_box);
+
+      /* Device options */
+
+      separator = gtk_hseparator_new();
+      gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, TRUE, 0);
+      gtk_widget_show (separator);
+
+      util_box = gtk_hbox_new (FALSE, 2);
+      gtk_box_pack_start (GTK_BOX (vbox), util_box, FALSE, FALSE, 0);
+
+      /* mapping mode option menu */
+
+      mapping_menu = gtk_menu_new ();
+
+      menuitem = gtk_menu_item_new_with_label("Disabled");
+      gtk_menu_append(GTK_MENU(mapping_menu),menuitem);
+      gtk_object_set_user_data (GTK_OBJECT (menuitem), inputd);
+      gtk_widget_show(menuitem);
+      gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+                         (GtkSignalFunc) gtk_input_dialog_set_mapping_mode,
+                         (gpointer)((long)GDK_MODE_DISABLED));
+
+      menuitem = gtk_menu_item_new_with_label("Screen");
+      gtk_menu_append(GTK_MENU(mapping_menu),menuitem);
+      gtk_object_set_user_data (GTK_OBJECT (menuitem), inputd);
+      gtk_widget_show(menuitem);
+      gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+                         (GtkSignalFunc) gtk_input_dialog_set_mapping_mode,
+                         (gpointer)((long)GDK_MODE_SCREEN));
+
+      menuitem = gtk_menu_item_new_with_label("Window");
+      gtk_menu_append(GTK_MENU(mapping_menu),menuitem);
+      gtk_object_set_user_data (GTK_OBJECT (menuitem), inputd);
+      gtk_widget_show(menuitem);
+      gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+                         (GtkSignalFunc) gtk_input_dialog_set_mapping_mode,
+                         (gpointer)((long)GDK_MODE_WINDOW));
+
+      label = gtk_label_new("Mode: ");
+      gtk_box_pack_start (GTK_BOX (util_box), label, FALSE, FALSE, 2);
+
+      inputd->mode_optionmenu = gtk_option_menu_new ();
+      gtk_box_pack_start (GTK_BOX (util_box), inputd->mode_optionmenu, FALSE, FALSE, 2);
+      gtk_widget_show (inputd->mode_optionmenu);
+      gtk_option_menu_set_menu (GTK_OPTION_MENU (inputd->mode_optionmenu), mapping_menu);
+
+      gtk_widget_show(label);
+
+      gtk_widget_show (util_box);
+
+      util_box = gtk_hbox_new (FALSE, 2);
+      gtk_box_pack_start (GTK_BOX(vbox), util_box, FALSE, FALSE, 0);
+
+      gtk_widget_show (label);
+      gtk_widget_show (util_box);
+
+      /*  The axis listbox  */
+
+      label = gtk_label_new ("Axes");
+      gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+
+      inputd->axis_listbox = gtk_scrolled_window_new (NULL, NULL);
+      gtk_widget_set_usize (inputd->axis_listbox, AXIS_LIST_WIDTH, AXIS_LIST_HEIGHT);
+      gtk_box_pack_start (GTK_BOX (vbox), inputd->axis_listbox, TRUE, TRUE, 0);
+      gtk_widget_show (inputd->axis_listbox);
+
+      inputd->axis_list = 0;
+
+      gtk_widget_show(label);
+
+      /* ...set_device expects to get input dialog from widget user data */
+      gtk_object_set_user_data (GTK_OBJECT (inputd), inputd);
+      gtk_input_dialog_set_device(GTK_WIDGET(inputd), (gpointer)((long)
+                             ((GdkDeviceInfo *)device_info->data)->deviceid));
+    }
+
+  /* buttons */
+
+  inputd->save_button = gtk_button_new_with_label ("Save");
+  GTK_WIDGET_SET_FLAGS (inputd->save_button, GTK_CAN_DEFAULT);
+  gtk_box_pack_start (GTK_BOX (GTK_DIALOG(inputd)->action_area),
+                     inputd->save_button, TRUE, TRUE, 0);
+  gtk_widget_show (inputd->save_button);
+
+  inputd->close_button = gtk_button_new_with_label ("Close");
+  GTK_WIDGET_SET_FLAGS (inputd->close_button, GTK_CAN_DEFAULT);
+  gtk_box_pack_start (GTK_BOX (GTK_DIALOG(inputd)->action_area),
+                     inputd->close_button, TRUE, TRUE, 0);
+
+  gtk_widget_show (inputd->close_button);
+  gtk_widget_grab_default (inputd->close_button);
+
+  gtk_widget_show (vbox);
+}
+
+
+GtkWidget*
+gtk_input_dialog_new (void)
+{
+  GtkInputDialog *inputd;
+
+  inputd = gtk_type_new (gtk_input_dialog_get_type ());
+
+  return GTK_WIDGET (inputd);
+}
+
+static void
+gtk_input_dialog_set_device(GtkWidget *widget, gpointer data)
+{
+  guint32 deviceid = (guint32)data;
+  GdkDeviceInfo *info;
+
+  GtkInputDialog *inputd = GTK_INPUT_DIALOG(
+                gtk_object_get_user_data(GTK_OBJECT(widget)));
+
+  inputd->current_device = deviceid;
+  info = gtk_input_dialog_get_device_info((guint32)data);
+
+  gtk_input_dialog_fill_axes(inputd, info);
+
+  gtk_option_menu_set_history(GTK_OPTION_MENU(inputd->mode_optionmenu),
+                             info->mode);
+}
+
+static void
+gtk_input_dialog_destroy (GtkObject *object)
+{
+  /*  GtkInputDialog *inputd = GTK_INPUT_DIALOG (object); */
+
+  /* Clean up ? */
+
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+gtk_input_dialog_set_mapping_mode(GtkWidget *w,
+                                 gpointer data)
+{
+  GtkInputDialog *inputd = GTK_INPUT_DIALOG(
+                gtk_object_get_user_data(GTK_OBJECT(w)));
+  GdkDeviceInfo *info = gtk_input_dialog_get_device_info (inputd->current_device);
+  GdkInputMode old_mode = info->mode;
+  GdkInputMode mode = (GdkInputMode)data;
+
+  if (mode != old_mode)
+    {
+      if (gdk_input_set_mode(inputd->current_device, mode))
+       {
+         if (mode == GDK_MODE_DISABLED)
+           gtk_signal_emit (GTK_OBJECT (inputd),
+                            input_dialog_signals[DISABLE_DEVICE],
+                            info->deviceid);
+         else
+           gtk_signal_emit (GTK_OBJECT (inputd),
+                            input_dialog_signals[ENABLE_DEVICE],
+                            info->deviceid);
+       }
+      else
+       gtk_option_menu_set_history (GTK_OPTION_MENU (inputd->mode_optionmenu),
+                                    old_mode);
+
+      /* FIXME: error dialog ? */
+    }
+}
+
+static void
+gtk_input_dialog_set_axis(GtkWidget *widget, gpointer data)
+{
+  GdkAxisUse use = (GdkAxisUse)data & 0xFFFF;
+  GdkAxisUse old_use;
+  GdkAxisUse *new_axes;
+  GtkInputDialog *inputd = GTK_INPUT_DIALOG (gtk_object_get_user_data (GTK_OBJECT (widget)));
+  GdkDeviceInfo *info = gtk_input_dialog_get_device_info (inputd->current_device);
+
+  gint axis = ((gint)data >> 16) - 1;
+  gint old_axis;
+  int i;
+
+  new_axes = g_new (GdkAxisUse, info->num_axes);
+  old_axis = -1;
+  for (i=0;i<info->num_axes;i++)
+    {
+      new_axes[i] = info->axes[i];
+      if (info->axes[i] == use)
+       old_axis = i;
+    }
+
+  if (axis != -1)
+    old_use = info->axes[axis];
+  else
+    old_use = GDK_AXIS_IGNORE;
+
+  if (axis == old_axis)
+    return;
+
+  /* we must always have an x and a y axis */
+  if ((axis == -1 && (use == GDK_AXIS_X || use == GDK_AXIS_Y)) ||
+      (old_axis == -1 && (old_use == GDK_AXIS_X || old_use == GDK_AXIS_Y)))
+    {
+      gtk_option_menu_set_history (
+               GTK_OPTION_MENU (inputd->axis_items[use]),
+               old_axis + 1);
+    }
+  else
+    {
+      if (axis != -1)
+       new_axes[axis] = use;
+
+      if (old_axis != -1)
+       new_axes[old_axis] = old_use;
+
+      if (old_use != GDK_AXIS_IGNORE)
+       {
+         gtk_option_menu_set_history (
+               GTK_OPTION_MENU (inputd->axis_items[old_use]),
+               old_axis + 1);
+       }
+      gdk_input_set_axes (info->deviceid, new_axes);
+    }
+
+  g_free (new_axes);
+}
+
+static void
+gtk_input_dialog_fill_axes(GtkInputDialog *inputd, GdkDeviceInfo *info)
+{
+  static char *axis_use_strings[GDK_AXIS_LAST] =
+  {
+    "",
+    "X",
+    "Y",
+    "Pressure",
+    "X Tilt",
+    "Y Tilt"
+  };
+
+  int i,j;
+  GtkWidget *list_item;
+  GtkWidget *menu;
+  GtkWidget *option_menu;
+  GtkWidget *vbox;
+  GtkWidget *hbox;
+  GtkWidget *label;
+
+  /* remove all the old items */
+  if (inputd->axis_list)
+    {
+      gtk_widget_hide (inputd->axis_list);     /* suppress resizes (or get warnings) */
+      gtk_widget_destroy (inputd->axis_list);
+    }
+  inputd->axis_list = gtk_vbox_new (FALSE, 0);
+  gtk_container_add (GTK_CONTAINER (inputd->axis_listbox), inputd->axis_list);
+  gtk_widget_show (inputd->axis_list);
+
+  gtk_widget_realize (inputd->axis_list);
+  gdk_window_set_background (inputd->axis_list->window,
+                            &inputd->axis_list->style->white);
+
+  for (i=GDK_AXIS_X;i<GDK_AXIS_LAST;i++)
+    {
+      list_item = gtk_list_item_new();
+
+      gtk_box_pack_start(GTK_BOX(inputd->axis_list),list_item,FALSE,FALSE,0);
+      gtk_widget_show (list_item);
+
+      vbox = gtk_vbox_new (FALSE, 0);
+      gtk_container_add(GTK_CONTAINER (list_item), vbox);
+
+      hbox = gtk_hbox_new (FALSE, 2);
+      gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 1);
+
+      /* create the label */
+
+      label = gtk_label_new(axis_use_strings[i]);
+      gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 2);
+
+      /* and the use option menu */
+      menu = gtk_menu_new();
+
+      for (j = -1; j < info->num_axes; j++)
+       {
+         char buffer[16];
+         GtkWidget *menu_item;
+
+         if (j == -1)
+           menu_item = gtk_menu_item_new_with_label ("none");
+         else
+           {
+             sprintf (buffer,"%d",j+1);
+             menu_item = gtk_menu_item_new_with_label (buffer);
+           }
+         gtk_object_set_user_data (GTK_OBJECT (menu_item), inputd);
+         gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                             (GtkSignalFunc) gtk_input_dialog_set_axis,
+                             (gpointer) ((long) (0x10000 * (j + 1) + i)));
+         gtk_widget_show (menu_item);
+         gtk_menu_append (GTK_MENU (menu), menu_item);
+       }
+
+      inputd->axis_items[i] = option_menu = gtk_option_menu_new ();
+      gtk_box_pack_start (GTK_BOX (hbox), option_menu, FALSE, FALSE, 2);
+
+      gtk_widget_show (option_menu);
+      gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), menu);
+      for (j = 0; j < info->num_axes; j++)
+       if (info->axes[j] == (GdkAxisUse) i)
+         {
+           gtk_option_menu_set_history (GTK_OPTION_MENU (option_menu), j+1);
+           break;
+         }
+
+      gtk_widget_show (label);
+
+      gtk_widget_show (hbox);
+      gtk_widget_show (vbox);
+    }
+}
diff --git a/gtk/gtkinputdialog.h b/gtk/gtkinputdialog.h
new file mode 100644 (file)
index 0000000..93c667f
--- /dev/null
@@ -0,0 +1,76 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_INPUTDIALOG_H__
+#define __GTK_INPUTDIALOG_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkdialog.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_INPUT_DIALOG(obj)          GTK_CHECK_CAST (obj, gtk_input_dialog_get_type (), GtkInputDialog)
+#define GTK_INPUT_DIALOG_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_input_dialog_get_type (), GtkInputDialogClass)
+#define GTK_IS_INPUT_DIALOG(obj)       GTK_CHECK_TYPE (obj, gtk_input_dialog_get_type ())
+
+
+typedef struct _GtkInputDialog       GtkInputDialog;
+typedef struct _GtkInputDialogClass  GtkInputDialogClass;
+
+struct _GtkInputDialog
+{
+  GtkDialog dialog;
+
+  GtkWidget *axis_list;
+  GtkWidget *axis_listbox;
+  GtkWidget *mode_optionmenu;
+
+  GtkWidget *close_button;
+  GtkWidget *save_button;
+  
+  GtkWidget *axis_items[GDK_AXIS_LAST];
+  guint32    current_device;
+};
+
+struct _GtkInputDialogClass
+{
+  GtkWindowClass parent_class;
+
+  void (* enable_device)               (GtkInputDialog    *inputd,
+                                       guint32            devid,
+                                       gpointer          *data);
+  void (* disable_device)              (GtkInputDialog    *inputd,
+                                       guint32            devid,
+                                       gpointer          *data);
+};
+
+
+guint      gtk_input_dialog_get_type     (void);
+GtkWidget* gtk_input_dialog_new          ();
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_INPUTDIALOG_H__ */
diff --git a/gtk/gtkitem.c b/gtk/gtkitem.c
new file mode 100644 (file)
index 0000000..6dd0ec8
--- /dev/null
@@ -0,0 +1,191 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkitem.h"
+#include "gtksignal.h"
+
+
+enum {
+  SELECT,
+  DESELECT,
+  TOGGLE,
+  LAST_SIGNAL
+};
+
+
+static void gtk_item_class_init (GtkItemClass *klass);
+static void gtk_item_init       (GtkItem      *item);
+static void gtk_item_map        (GtkWidget    *widget);
+static void gtk_item_unmap      (GtkWidget    *widget);
+static void gtk_item_realize    (GtkWidget    *widget);
+
+
+static gint item_signals[LAST_SIGNAL] = { 0 };
+
+
+guint
+gtk_item_get_type ()
+{
+  static guint item_type = 0;
+
+  if (!item_type)
+    {
+      GtkTypeInfo item_info =
+      {
+       "GtkItem",
+       sizeof (GtkItem),
+       sizeof (GtkItemClass),
+       (GtkClassInitFunc) gtk_item_class_init,
+       (GtkObjectInitFunc) gtk_item_init,
+       (GtkArgFunc) NULL,
+      };
+
+      item_type = gtk_type_unique (gtk_bin_get_type (), &item_info);
+    }
+
+  return item_type;
+}
+
+static void
+gtk_item_class_init (GtkItemClass *class)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+
+  object_class = (GtkObjectClass*) class;
+  widget_class = (GtkWidgetClass*) class;
+
+  item_signals[SELECT] =
+    gtk_signal_new ("select",
+                    GTK_RUN_FIRST,
+                    object_class->type,
+                    GTK_SIGNAL_OFFSET (GtkItemClass, select),
+                    gtk_signal_default_marshaller,
+                   GTK_TYPE_NONE, 0);
+  item_signals[DESELECT] =
+    gtk_signal_new ("deselect",
+                    GTK_RUN_FIRST,
+                    object_class->type,
+                    GTK_SIGNAL_OFFSET (GtkItemClass, deselect),
+                    gtk_signal_default_marshaller,
+                   GTK_TYPE_NONE, 0);
+  item_signals[TOGGLE] =
+    gtk_signal_new ("toggle",
+                    GTK_RUN_FIRST,
+                    object_class->type,
+                    GTK_SIGNAL_OFFSET (GtkItemClass, toggle),
+                    gtk_signal_default_marshaller,
+                   GTK_TYPE_NONE, 0);
+
+  gtk_object_class_add_signals (object_class, item_signals, LAST_SIGNAL);
+
+  widget_class->activate_signal = item_signals[TOGGLE];
+  widget_class->map = gtk_item_map;
+  widget_class->unmap = gtk_item_unmap;
+  widget_class->realize = gtk_item_realize;
+
+  class->select = NULL;
+  class->deselect = NULL;
+  class->toggle = NULL;
+}
+
+static void
+gtk_item_init (GtkItem *item)
+{
+  GTK_WIDGET_UNSET_FLAGS (item, GTK_NO_WINDOW);
+}
+
+void
+gtk_item_select (GtkItem *item)
+{
+  gtk_signal_emit (GTK_OBJECT (item), item_signals[SELECT]);
+}
+
+void
+gtk_item_deselect (GtkItem *item)
+{
+  gtk_signal_emit (GTK_OBJECT (item), item_signals[DESELECT]);
+}
+
+void
+gtk_item_toggle (GtkItem *item)
+{
+  gtk_signal_emit (GTK_OBJECT (item), item_signals[TOGGLE]);
+}
+
+
+static void
+gtk_item_map (GtkWidget *widget)
+{
+  GtkBin *bin;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_ITEM (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
+  gdk_window_show (widget->window);
+
+  bin = GTK_BIN (widget);
+
+  if (bin->child &&
+      GTK_WIDGET_VISIBLE (bin->child) &&
+      !GTK_WIDGET_MAPPED (bin->child))
+    gtk_widget_map (bin->child);
+}
+
+static void
+gtk_item_unmap (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_ITEM (widget));
+
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
+  gdk_window_hide (widget->window);
+}
+
+static void
+gtk_item_realize (GtkWidget *widget)
+{
+  GdkWindowAttr attributes;
+  gint attributes_mask;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_ITEM (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+
+  attributes.x = widget->allocation.x;
+  attributes.y = widget->allocation.y;
+  attributes.width = widget->allocation.width;
+  attributes.height = widget->allocation.height;
+  attributes.window_type = GDK_WINDOW_CHILD;
+  attributes.wclass = GDK_INPUT_OUTPUT;
+  attributes.visual = gtk_widget_get_visual (widget);
+  attributes.colormap = gtk_widget_get_colormap (widget);
+  attributes.event_mask = (GDK_EXPOSURE_MASK |
+                          GDK_BUTTON_PRESS_MASK |
+                          GDK_BUTTON_RELEASE_MASK |
+                          GDK_ENTER_NOTIFY_MASK |
+                          GDK_LEAVE_NOTIFY_MASK);
+
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+  widget->window = gdk_window_new (widget->parent->window, &attributes, attributes_mask);
+  gdk_window_set_user_data (widget->window, widget);
+
+  widget->style = gtk_style_attach (widget->style, widget->window);
+  gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
+}
diff --git a/gtk/gtkitem.h b/gtk/gtkitem.h
new file mode 100644 (file)
index 0000000..36cf1ab
--- /dev/null
@@ -0,0 +1,65 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_ITEM_H__
+#define __GTK_ITEM_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkbin.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_ITEM(obj)          GTK_CHECK_CAST (obj, gtk_item_get_type (), GtkItem)
+#define GTK_ITEM_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_item_get_type (), GtkItemClass)
+#define GTK_IS_ITEM(obj)       GTK_CHECK_TYPE (obj, gtk_item_get_type ())
+
+
+typedef struct _GtkItem       GtkItem;
+typedef struct _GtkItemClass  GtkItemClass;
+
+struct _GtkItem
+{
+  GtkBin bin;
+};
+
+struct _GtkItemClass
+{
+  GtkBinClass parent_class;
+
+  void (* select)   (GtkItem *item);
+  void (* deselect) (GtkItem *item);
+  void (* toggle)   (GtkItem *item);
+};
+
+
+guint  gtk_item_get_type (void);
+void   gtk_item_select   (GtkItem *item);
+void   gtk_item_deselect (GtkItem *item);
+void   gtk_item_toggle   (GtkItem *item);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_ITEM_H__ */
diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c
new file mode 100644 (file)
index 0000000..5cd1f80
--- /dev/null
@@ -0,0 +1,329 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <string.h>
+#include "gtklabel.h"
+
+
+static void gtk_label_class_init   (GtkLabelClass  *klass);
+static void gtk_label_init         (GtkLabel       *label);
+static void gtk_label_destroy      (GtkObject      *object);
+static void gtk_label_size_request (GtkWidget      *widget,
+                                   GtkRequisition *requisition);
+static gint gtk_label_expose       (GtkWidget      *widget,
+                                   GdkEventExpose *event);
+
+
+static GtkMiscClass *parent_class = NULL;
+
+
+guint
+gtk_label_get_type ()
+{
+  static guint label_type = 0;
+
+  if (!label_type)
+    {
+      GtkTypeInfo label_info =
+      {
+       "GtkLabel",
+       sizeof (GtkLabel),
+       sizeof (GtkLabelClass),
+       (GtkClassInitFunc) gtk_label_class_init,
+       (GtkObjectInitFunc) gtk_label_init,
+       (GtkArgFunc) NULL,
+      };
+
+      label_type = gtk_type_unique (gtk_misc_get_type (), &label_info);
+    }
+
+  return label_type;
+}
+
+void
+gtk_label_class_init (GtkLabelClass *class)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+
+  object_class = (GtkObjectClass*) class;
+  widget_class = (GtkWidgetClass*) class;
+
+  parent_class = gtk_type_class (gtk_misc_get_type ());
+
+  object_class->destroy = gtk_label_destroy;
+
+  widget_class->size_request = gtk_label_size_request;
+  widget_class->expose_event = gtk_label_expose;
+}
+
+void
+gtk_label_init (GtkLabel *label)
+{
+  GTK_WIDGET_SET_FLAGS (label, GTK_NO_WINDOW);
+
+  label->label = NULL;
+  label->row = NULL;
+  label->jtype = GTK_JUSTIFY_CENTER;
+}
+
+GtkWidget*
+gtk_label_new (const char *str)
+{
+  GtkLabel *label;
+
+  g_return_val_if_fail (str != NULL, NULL);
+
+  label = gtk_type_new (gtk_label_get_type ());
+
+  gtk_label_set (label, str);
+
+  return GTK_WIDGET (label);
+}
+
+void
+gtk_label_set (GtkLabel *label,
+              const char *str)
+{
+  char* p;
+
+  g_return_if_fail (label != NULL);
+  g_return_if_fail (GTK_IS_LABEL (label));
+  g_return_if_fail (str != NULL);
+
+  if (label->label)
+    g_free (label->label);
+  label->label = g_strdup (str);
+
+  if (label->row)
+    g_slist_free (label->row);
+  label->row = NULL;
+  label->row = g_slist_append (label->row, label->label);
+  p = label->label;
+  while ((p = strchr(p, '\n')))
+    label->row = g_slist_append (label->row, ++p);
+
+  if (GTK_WIDGET_VISIBLE (label))
+    {
+      if (GTK_WIDGET_MAPPED (label))
+       gdk_window_clear_area (GTK_WIDGET (label)->window,
+                              GTK_WIDGET (label)->allocation.x,
+                              GTK_WIDGET (label)->allocation.y,
+                              GTK_WIDGET (label)->allocation.width,
+                              GTK_WIDGET (label)->allocation.height);
+
+      gtk_widget_queue_resize (GTK_WIDGET (label));
+    }
+}
+
+void
+gtk_label_set_justify (GtkLabel *label, GtkJustification jtype)
+{
+  g_return_if_fail (label != NULL);
+  g_return_if_fail (GTK_IS_LABEL (label));
+
+  if ((GtkJustification) label->jtype != jtype)
+    {
+      label->jtype = jtype;
+      
+      if (GTK_WIDGET_VISIBLE (label))
+        {
+          if (GTK_WIDGET_MAPPED (label))
+            gdk_window_clear_area (GTK_WIDGET (label)->window,
+                                   GTK_WIDGET (label)->allocation.x,
+                                   GTK_WIDGET (label)->allocation.y,
+                                   GTK_WIDGET (label)->allocation.width,
+                                   GTK_WIDGET (label)->allocation.height);
+          
+          gtk_widget_queue_resize (GTK_WIDGET (label));
+        }
+    }
+}
+
+void
+gtk_label_get (GtkLabel  *label,
+              char     **str)
+{
+  g_return_if_fail (label != NULL);
+  g_return_if_fail (GTK_IS_LABEL (label));
+  g_return_if_fail (str != NULL);
+
+  *str = label->label;
+}
+
+
+static void
+gtk_label_destroy (GtkObject *object)
+{
+  GtkLabel *label;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_LABEL (object));
+
+  label = GTK_LABEL (object);
+
+  if (GTK_WIDGET (object)->parent &&
+      GTK_WIDGET_MAPPED (object))
+    gtk_widget_unmap (GTK_WIDGET (object));
+
+  g_free (label->label);
+  g_slist_free (label->row);
+
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+gtk_label_size_request (GtkWidget      *widget,
+                       GtkRequisition *requisition)
+{
+  GtkLabel *label;
+  GSList *row;
+  gint width;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_LABEL (widget));
+  g_return_if_fail (requisition != NULL);
+
+  label = GTK_LABEL (widget);
+
+  row = label->row;
+  width = 0;
+  while (row)
+    {
+      if (row->next)
+         width = MAX (width,
+                       gdk_text_width (GTK_WIDGET (label)->style->font, row->data,
+                                       (gchar*) row->next->data - (gchar*) row->data));
+      else
+        width = MAX (width, gdk_string_width (GTK_WIDGET (label)->style->font, row->data));
+      row = row->next;
+    }
+  
+  requisition->width = width + label->misc.xpad * 2;
+  requisition->height = ((GTK_WIDGET (label)->style->font->ascent +
+                          GTK_WIDGET (label)->style->font->descent + 2) *
+                         g_slist_length(label->row) +
+                         label->misc.ypad * 2);
+}
+
+static gint
+gtk_label_expose (GtkWidget      *widget,
+                 GdkEventExpose *event)
+{
+  GtkLabel *label;
+  GtkMisc *misc;
+  GSList *row;
+  gint state;
+  gint offset;
+  gint len;
+  gint maxl;
+  gint x, y;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_LABEL (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget))
+    {
+      label = GTK_LABEL (widget);
+      misc = GTK_MISC (widget);
+
+      state = widget->state;
+      if (!GTK_WIDGET_IS_SENSITIVE (widget))
+       state = GTK_STATE_INSENSITIVE;
+
+      /* We only draw the label if we have been allocated at least as
+       *  much space as we requested. If we have less space than we
+       *  need to draw the string then we _should_ have asked our
+       *  parent container to resize and a new allocation _should_
+       *  be forthcoming so there is no reason to redraw (incorrectly)
+       *  here.
+       */
+      if ((widget->allocation.width >= widget->requisition.width) &&
+         (widget->allocation.height >= widget->requisition.height))
+       {
+         maxl = widget->requisition.width - misc->xpad * 2;
+         x = widget->allocation.x + misc->xpad +
+              (widget->allocation.width - widget->requisition.width) * misc->xalign + 0.5;
+         y = (widget->allocation.y * (1.0 - misc->yalign) +
+              (widget->allocation.y + widget->allocation.height - (widget->requisition.height -
+                                                                   misc->ypad * 2)) *
+              misc->yalign + widget->style->font->ascent) + 1.5;
+          
+         row = label->row;
+         while (row && row->next)
+            {
+              len = (gchar*) row->next->data - (gchar*) row->data;
+              offset = 0;
+              if (label->jtype == GTK_JUSTIFY_CENTER)
+               offset = (maxl - gdk_text_width (widget->style->font, row->data, len)) / 2;
+              else if (label->jtype == GTK_JUSTIFY_RIGHT)
+               offset = (maxl - gdk_text_width (widget->style->font, row->data, len));
+              if (state == GTK_STATE_INSENSITIVE)
+                gdk_draw_text (widget->window, widget->style->font,
+                               widget->style->white_gc,
+                               offset + x + 1, y + 1, row->data, len);
+              
+              gdk_draw_text (widget->window, widget->style->font,
+                             widget->style->fg_gc[state],
+                             offset + x, y, row->data, len);
+              row = row->next;
+              y += widget->style->font->ascent + widget->style->font->descent + 2;
+            }
+          
+        /* COMMENT: we can avoid gdk_text_width() calls here storing in label->row
+           the widths of the rows calculated in gtk_label_set.
+           Once we have a wrapping interface we can support GTK_JUSTIFY_FILL.
+         */
+        offset = 0;
+        if (label->jtype == GTK_JUSTIFY_CENTER)
+           offset = (maxl - gdk_string_width (widget->style->font, row->data)) / 2;
+        else if (label->jtype == GTK_JUSTIFY_RIGHT)
+           offset = (maxl - gdk_string_width (widget->style->font, row->data));
+        if (state == GTK_STATE_INSENSITIVE)
+          gdk_draw_string (widget->window, widget->style->font,
+                            widget->style->white_gc,
+                            offset + x + 1, y + 1, row->data);
+         
+        gdk_draw_string (widget->window, widget->style->font,
+                          widget->style->fg_gc[state],
+                          offset + x, y, row->data);
+
+         /*
+         gdk_draw_rectangle (widget->window,
+                             widget->style->bg_gc[GTK_STATE_SELECTED], FALSE,
+                             widget->allocation.x, widget->allocation.y,
+                             widget->allocation.width - 1, widget->allocation.height - 1);
+                             */
+       }
+      else
+       {
+         /*
+         g_print ("gtk_label_expose: allocation too small: %d %d ( %d %d )\n",
+                  widget->allocation.width, widget->allocation.height,
+                  widget->requisition.width, widget->requisition.height);
+                  */
+       }
+    }
+
+  return TRUE;
+}
+
+
+
+
diff --git a/gtk/gtklabel.h b/gtk/gtklabel.h
new file mode 100644 (file)
index 0000000..81eca4a
--- /dev/null
@@ -0,0 +1,69 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_LABEL_H__
+#define __GTK_LABEL_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkmisc.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_LABEL(obj)          GTK_CHECK_CAST (obj, gtk_label_get_type (), GtkLabel)
+#define GTK_LABEL_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_label_get_type (), GtkLabelClass)
+#define GTK_IS_LABEL(obj)       GTK_CHECK_TYPE (obj, gtk_label_get_type ())
+
+
+typedef struct _GtkLabel       GtkLabel;
+typedef struct _GtkLabelClass  GtkLabelClass;
+
+struct _GtkLabel
+{
+  GtkMisc misc;
+
+  char *label;
+  GSList *row;
+  guint jtype : 2;
+};
+
+struct _GtkLabelClass
+{
+  GtkMiscClass parent_class;
+};
+
+
+guint      gtk_label_get_type    (void);
+GtkWidget* gtk_label_new         (const char        *str);
+void       gtk_label_set         (GtkLabel          *label,
+                                  const char        *str);
+void       gtk_label_set_justify (GtkLabel          *label,
+                                  GtkJustification   jtype);
+void       gtk_label_get         (GtkLabel          *label,
+                                  char             **str);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_LABEL_H__ */
diff --git a/gtk/gtklist.c b/gtk/gtklist.c
new file mode 100644 (file)
index 0000000..7d7d4a6
--- /dev/null
@@ -0,0 +1,1007 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtklist.h"
+#include "gtklistitem.h"
+#include "gtkmain.h"
+#include "gtksignal.h"
+
+
+enum {
+  SELECTION_CHANGED,
+  SELECT_CHILD,
+  UNSELECT_CHILD,
+  LAST_SIGNAL
+};
+
+
+typedef void (*GtkListSignal) (GtkObject *object,
+                              gpointer   arg1,
+                              gpointer   data);
+
+
+static void gtk_list_class_init      (GtkListClass   *klass);
+static void gtk_list_init            (GtkList        *list);
+static void gtk_list_destroy         (GtkObject      *object);
+static void gtk_list_map             (GtkWidget      *widget);
+static void gtk_list_unmap           (GtkWidget      *widget);
+static void gtk_list_realize         (GtkWidget      *widget);
+static void gtk_list_draw            (GtkWidget      *widget,
+                                     GdkRectangle   *area);
+static gint gtk_list_expose          (GtkWidget      *widget,
+                                     GdkEventExpose *event);
+static gint gtk_list_motion_notify   (GtkWidget      *widget,
+                                     GdkEventMotion *event);
+static gint gtk_list_button_press    (GtkWidget      *widget,
+                                     GdkEventButton *event);
+static gint gtk_list_button_release  (GtkWidget      *widget,
+                                     GdkEventButton *event);
+static void gtk_list_size_request    (GtkWidget      *widget,
+                                     GtkRequisition *requisition);
+static void gtk_list_size_allocate   (GtkWidget      *widget,
+                                     GtkAllocation  *allocation);
+static void gtk_list_add             (GtkContainer   *container,
+                                     GtkWidget      *widget);
+static void gtk_list_remove          (GtkContainer   *container,
+                                     GtkWidget      *widget);
+static void gtk_list_foreach         (GtkContainer   *container,
+                                     GtkCallback     callback,
+                                     gpointer        callback_data);
+
+static void gtk_real_list_select_child   (GtkList       *list,
+                                         GtkWidget     *child);
+static void gtk_real_list_unselect_child (GtkList       *list,
+                                         GtkWidget     *child);
+
+static void gtk_list_marshal_signal (GtkObject      *object,
+                                    GtkSignalFunc   func,
+                                    gpointer        func_data,
+                                    GtkArg         *args);
+
+
+static GtkContainerClass *parent_class = NULL;
+static gint list_signals[LAST_SIGNAL] = { 0 };
+
+
+guint
+gtk_list_get_type ()
+{
+  static guint list_type = 0;
+
+  if (!list_type)
+    {
+      GtkTypeInfo list_info =
+      {
+       "GtkList",
+       sizeof (GtkList),
+       sizeof (GtkListClass),
+       (GtkClassInitFunc) gtk_list_class_init,
+       (GtkObjectInitFunc) gtk_list_init,
+       (GtkArgFunc) NULL,
+      };
+
+      list_type = gtk_type_unique (gtk_container_get_type (), &list_info);
+    }
+
+  return list_type;
+}
+
+static void
+gtk_list_class_init (GtkListClass *class)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+  GtkContainerClass *container_class;
+
+  object_class = (GtkObjectClass*) class;
+  widget_class = (GtkWidgetClass*) class;
+  container_class = (GtkContainerClass*) class;
+
+  parent_class = gtk_type_class (gtk_container_get_type ());
+
+  list_signals[SELECTION_CHANGED] =
+    gtk_signal_new ("selection_changed",
+                    GTK_RUN_FIRST,
+                    object_class->type,
+                    GTK_SIGNAL_OFFSET (GtkListClass, selection_changed),
+                    gtk_signal_default_marshaller,
+                   GTK_TYPE_NONE, 0);
+  list_signals[SELECT_CHILD] =
+    gtk_signal_new ("select_child",
+                    GTK_RUN_FIRST,
+                    object_class->type,
+                    GTK_SIGNAL_OFFSET (GtkListClass, select_child),
+                    gtk_list_marshal_signal,
+                   GTK_TYPE_NONE, 1,
+                    GTK_TYPE_WIDGET);
+  list_signals[UNSELECT_CHILD] =
+    gtk_signal_new ("unselect_child",
+                    GTK_RUN_FIRST,
+                    object_class->type,
+                    GTK_SIGNAL_OFFSET (GtkListClass, unselect_child),
+                    gtk_list_marshal_signal,
+                   GTK_TYPE_NONE, 1,
+                    GTK_TYPE_WIDGET);
+
+  gtk_object_class_add_signals (object_class, list_signals, LAST_SIGNAL);
+
+  object_class->destroy = gtk_list_destroy;
+
+  widget_class->map = gtk_list_map;
+  widget_class->unmap = gtk_list_unmap;
+  widget_class->realize = gtk_list_realize;
+  widget_class->draw = gtk_list_draw;
+  widget_class->expose_event = gtk_list_expose;
+  widget_class->motion_notify_event = gtk_list_motion_notify;
+  widget_class->button_press_event = gtk_list_button_press;
+  widget_class->button_release_event = gtk_list_button_release;
+  widget_class->size_request = gtk_list_size_request;
+  widget_class->size_allocate = gtk_list_size_allocate;
+
+  container_class->add = gtk_list_add;
+  container_class->remove = gtk_list_remove;
+  container_class->foreach = gtk_list_foreach;
+
+  class->selection_changed = NULL;
+  class->select_child = gtk_real_list_select_child;
+  class->unselect_child = gtk_real_list_unselect_child;
+}
+
+static void
+gtk_list_init (GtkList *list)
+{
+  list->children = NULL;
+  list->selection = NULL;
+  list->timer = 0;
+  list->selection_start_pos = 0;
+  list->selection_end_pos = 0;
+  list->selection_mode = GTK_SELECTION_SINGLE;
+  list->scroll_direction = 0;
+  list->have_grab = FALSE;
+}
+
+GtkWidget*
+gtk_list_new ()
+{
+  return GTK_WIDGET (gtk_type_new (gtk_list_get_type ()));
+}
+
+void
+gtk_list_insert_items (GtkList *list,
+                      GList   *items,
+                      gint     position)
+{
+  GtkWidget *widget;
+  GList *tmp_list;
+  GList *last;
+  gint nchildren;
+
+  g_return_if_fail (list != NULL);
+  g_return_if_fail (GTK_IS_LIST (list));
+
+  if (!items)
+    return;
+
+  tmp_list = items;
+  while (tmp_list)
+    {
+      widget = tmp_list->data;
+      tmp_list = tmp_list->next;
+
+      gtk_widget_set_parent (widget, GTK_WIDGET (list));
+
+      if (GTK_WIDGET_VISIBLE (widget->parent))
+       {
+         if (GTK_WIDGET_REALIZED (widget->parent) &&
+             !GTK_WIDGET_REALIZED (widget))
+           gtk_widget_realize (widget);
+
+         if (GTK_WIDGET_MAPPED (widget->parent) &&
+             !GTK_WIDGET_MAPPED (widget))
+           gtk_widget_map (widget);
+       }
+    }
+
+  nchildren = g_list_length (list->children);
+  if ((position < 0) || (position > nchildren))
+    position = nchildren;
+
+  if (position == nchildren)
+    {
+      if (list->children)
+       {
+         tmp_list = g_list_last (list->children);
+         tmp_list->next = items;
+         items->prev = tmp_list;
+       }
+      else
+       {
+         list->children = items;
+       }
+    }
+  else
+    {
+      tmp_list = g_list_nth (list->children, position);
+      last = g_list_last (items);
+
+      if (tmp_list->prev)
+       tmp_list->prev->next = items;
+      last->next = tmp_list;
+      items->prev = tmp_list->prev;
+      tmp_list->prev = last;
+
+      if (tmp_list == list->children)
+       list->children = items;
+    }
+
+  if (list->children && !list->selection &&
+      (list->selection_mode == GTK_SELECTION_BROWSE))
+    {
+      widget = list->children->data;
+      gtk_list_select_child (list, widget);
+    }
+
+  if (GTK_WIDGET_VISIBLE (list))
+    gtk_widget_queue_resize (GTK_WIDGET (list));
+}
+
+void
+gtk_list_append_items (GtkList *list,
+                      GList   *items)
+{
+  g_return_if_fail (list != NULL);
+  g_return_if_fail (GTK_IS_LIST (list));
+
+  gtk_list_insert_items (list, items, -1);
+}
+
+void
+gtk_list_prepend_items (GtkList *list,
+                       GList   *items)
+{
+  g_return_if_fail (list != NULL);
+  g_return_if_fail (GTK_IS_LIST (list));
+
+  gtk_list_insert_items (list, items, 0);
+}
+
+void
+gtk_list_remove_items (GtkList *list,
+                      GList   *items)
+{
+  GtkWidget *widget;
+  GList *selected_widgets;
+  GList *tmp_list;
+
+  g_return_if_fail (list != NULL);
+  g_return_if_fail (GTK_IS_LIST (list));
+
+  tmp_list = items;
+  selected_widgets = NULL;
+  widget = NULL;
+
+  while (tmp_list)
+    {
+      widget = tmp_list->data;
+      tmp_list = tmp_list->next;
+
+      if (widget->state == GTK_STATE_SELECTED)
+       selected_widgets = g_list_prepend (selected_widgets, widget);
+
+      list->children = g_list_remove (list->children, widget);
+
+      if (GTK_WIDGET_MAPPED (widget))
+       gtk_widget_unmap (widget);
+
+      gtk_widget_unparent (widget);
+    }
+
+  if (selected_widgets)
+    {
+      tmp_list = selected_widgets;
+      while (tmp_list)
+       {
+         widget = tmp_list->data;
+         tmp_list = tmp_list->next;
+
+         gtk_list_unselect_child (list, widget);
+       }
+
+      gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]);
+    }
+
+  g_list_free (selected_widgets);
+
+  if (list->children && !list->selection &&
+      (list->selection_mode == GTK_SELECTION_BROWSE))
+    {
+      widget = list->children->data;
+      gtk_list_select_child (list, widget);
+    }
+
+  if (GTK_WIDGET_VISIBLE (list))
+    gtk_widget_queue_resize (GTK_WIDGET (list));
+}
+
+void
+gtk_list_clear_items (GtkList *list,
+                     gint     start,
+                     gint     end)
+{
+  GtkWidget *widget;
+  GList *start_list;
+  GList *end_list;
+  GList *tmp_list;
+  gint nchildren;
+  gint selection_changed;
+
+  g_return_if_fail (list != NULL);
+  g_return_if_fail (GTK_IS_LIST (list));
+
+  nchildren = g_list_length (list->children);
+
+  if (nchildren > 0)
+    {
+      if ((end < 0) || (end > nchildren))
+       end = nchildren;
+
+      g_return_if_fail (start < end);
+
+      start_list = g_list_nth (list->children, start);
+      end_list = g_list_nth (list->children, end);
+
+      if (start_list->prev)
+        start_list->prev->next = end_list;
+      if (end_list && end_list->prev)
+        end_list->prev->next = NULL;
+      if (end_list)
+        end_list->prev = start_list->prev;
+      if (start_list == list->children)
+        list->children = end_list;
+
+      selection_changed = FALSE;
+      widget = NULL;
+      tmp_list = start_list;
+
+      while (tmp_list)
+       {
+         widget = tmp_list->data;
+         tmp_list = tmp_list->next;
+
+         if (widget->state == GTK_STATE_SELECTED)
+           {
+             selection_changed = TRUE;
+             list->selection = g_list_remove (list->selection, widget);
+           }
+
+         /* list->children = g_list_remove (list->children, widget); */
+         /* gtk_widget_unparent (widget); */
+
+         gtk_widget_destroy (widget);
+       }
+
+      if (list->children && !list->selection &&
+         (list->selection_mode == GTK_SELECTION_BROWSE))
+       {
+         gtk_list_select_child (list, widget);
+         widget = list->children->data;
+       }
+
+      if (selection_changed)
+       gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]);
+
+      gtk_widget_queue_resize (GTK_WIDGET (list));
+    }
+}
+
+void
+gtk_list_select_item (GtkList *list,
+                     gint     item)
+{
+  GList *tmp_list;
+
+  g_return_if_fail (list != NULL);
+  g_return_if_fail (GTK_IS_LIST (list));
+
+  tmp_list = g_list_nth (list->children, item);
+  if (tmp_list)
+    gtk_list_select_child (list, GTK_WIDGET (tmp_list->data));
+}
+
+void
+gtk_list_unselect_item (GtkList *list,
+                       gint     item)
+{
+  GList *tmp_list;
+
+  g_return_if_fail (list != NULL);
+  g_return_if_fail (GTK_IS_LIST (list));
+
+  tmp_list = g_list_nth (list->children, item);
+  if (tmp_list)
+    gtk_list_unselect_child (list, GTK_WIDGET (tmp_list->data));
+}
+
+void
+gtk_list_select_child (GtkList   *list,
+                      GtkWidget *child)
+{
+  gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECT_CHILD], child);
+}
+
+void
+gtk_list_unselect_child (GtkList   *list,
+                        GtkWidget *child)
+{
+  gtk_signal_emit (GTK_OBJECT (list), list_signals[UNSELECT_CHILD], child);
+}
+
+gint
+gtk_list_child_position (GtkList   *list,
+                        GtkWidget *child)
+{
+  GList *children;
+  gint pos;
+
+  g_return_val_if_fail (list != NULL, -1);
+  g_return_val_if_fail (GTK_IS_LIST (list), -1);
+  g_return_val_if_fail (child != NULL, -1);
+
+  pos = 0;
+  children = list->children;
+
+  while (children)
+    {
+      if (child == GTK_WIDGET (children->data))
+       return pos;
+
+      pos += 1;
+      children = children->next;
+    }
+
+  return -1;
+}
+
+void
+gtk_list_set_selection_mode (GtkList          *list,
+                            GtkSelectionMode  mode)
+{
+  g_return_if_fail (list != NULL);
+  g_return_if_fail (GTK_IS_LIST (list));
+
+  list->selection_mode = mode;
+}
+
+
+static void
+gtk_list_destroy (GtkObject *object)
+{
+  GtkList *list;
+  GtkWidget *child;
+  GList *children;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_LIST (object));
+
+  list = GTK_LIST (object);
+
+  children = list->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      child->parent = NULL;
+      gtk_object_unref (GTK_OBJECT (child));
+      gtk_widget_destroy (child);
+    }
+
+  g_list_free (list->children);
+  g_list_free (list->selection);
+
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+gtk_list_map (GtkWidget *widget)
+{
+  GtkList *list;
+  GtkWidget *child;
+  GList *children;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_LIST (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
+  list = GTK_LIST (widget);
+
+  gdk_window_show (widget->window);
+
+  children = list->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (child) &&
+         !GTK_WIDGET_MAPPED (child))
+       gtk_widget_map (child);
+    }
+}
+
+static void
+gtk_list_unmap (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_LIST (widget));
+
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
+  gdk_window_hide (widget->window);
+}
+
+static void
+gtk_list_realize (GtkWidget *widget)
+{
+  GdkWindowAttr attributes;
+  gint attributes_mask;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_LIST (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+
+  attributes.window_type = GDK_WINDOW_CHILD;
+  attributes.x = widget->allocation.x;
+  attributes.y = widget->allocation.y;
+  attributes.width = widget->allocation.width;
+  attributes.height = widget->allocation.height;
+  attributes.wclass = GDK_INPUT_OUTPUT;
+  attributes.visual = gtk_widget_get_visual (widget);
+  attributes.colormap = gtk_widget_get_colormap (widget);
+  attributes.event_mask = GDK_EXPOSURE_MASK;
+
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+
+  widget->window = gdk_window_new (widget->parent->window, &attributes, attributes_mask);
+  gdk_window_set_user_data (widget->window, widget);
+
+  widget->style = gtk_style_attach (widget->style, widget->window);
+  gdk_window_set_background (widget->window, &widget->style->white);
+}
+
+static void
+gtk_list_draw (GtkWidget    *widget,
+              GdkRectangle *area)
+{
+  GtkList *list;
+  GtkWidget *child;
+  GdkRectangle child_area;
+  GList *children;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_LIST (widget));
+  g_return_if_fail (area != NULL);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      list = GTK_LIST (widget);
+
+      children = list->children;
+      while (children)
+       {
+         child = children->data;
+         children = children->next;
+
+         if (gtk_widget_intersect (child, area, &child_area))
+           gtk_widget_draw (child, &child_area);
+       }
+    }
+}
+
+static gint
+gtk_list_expose (GtkWidget      *widget,
+                GdkEventExpose *event)
+{
+  GtkList *list;
+  GtkWidget *child;
+  GdkEventExpose child_event;
+  GList *children;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_LIST (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      list = GTK_LIST (widget);
+
+      child_event = *event;
+
+      children = list->children;
+      while (children)
+       {
+         child = children->data;
+         children = children->next;
+
+         if (GTK_WIDGET_NO_WINDOW (child) &&
+             gtk_widget_intersect (child, &event->area, &child_event.area))
+           gtk_widget_event (child, (GdkEvent*) &child_event);
+       }
+    }
+
+  return FALSE;
+}
+
+static gint
+gtk_list_motion_notify (GtkWidget      *widget,
+                       GdkEventMotion *event)
+{
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_LIST (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  g_print ("gtk_list_motion_notify\n");
+
+  return FALSE;
+}
+
+static gint
+gtk_list_button_press (GtkWidget      *widget,
+                      GdkEventButton *event)
+{
+  GtkList *list;
+  GtkWidget *item;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_LIST (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  list = GTK_LIST (widget);
+  item = gtk_get_event_widget ((GdkEvent*) event);
+
+  while (!gtk_type_is_a (GTK_WIDGET_TYPE (item), gtk_list_item_get_type ()))
+    item = item->parent;
+
+  gtk_list_select_child (list, item);
+
+  return FALSE;
+}
+
+static gint
+gtk_list_button_release (GtkWidget      *widget,
+                        GdkEventButton *event)
+{
+  GtkList *list;
+  GtkWidget *item;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_LIST (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  list = GTK_LIST (widget);
+  item = gtk_get_event_widget ((GdkEvent*) event);
+
+  return FALSE;
+}
+
+static void
+gtk_list_size_request (GtkWidget      *widget,
+                      GtkRequisition *requisition)
+{
+  GtkList *list;
+  GtkWidget *child;
+  GList *children;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_LIST (widget));
+  g_return_if_fail (requisition != NULL);
+
+  list = GTK_LIST (widget);
+  requisition->width = 0;
+  requisition->height = 0;
+
+  children = list->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (child))
+       {
+         gtk_widget_size_request (child, &child->requisition);
+
+         requisition->width = MAX (requisition->width, child->requisition.width);
+         requisition->height += child->requisition.height;
+       }
+    }
+
+  requisition->width += GTK_CONTAINER (list)->border_width * 2;
+  requisition->height += GTK_CONTAINER (list)->border_width * 2;
+
+  requisition->width = MAX (requisition->width, 1);
+  requisition->height = MAX (requisition->height, 1);
+}
+
+static void
+gtk_list_size_allocate (GtkWidget     *widget,
+                       GtkAllocation *allocation)
+{
+  GtkList *list;
+  GtkWidget *child;
+  GtkAllocation child_allocation;
+  GList *children;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_LIST (widget));
+  g_return_if_fail (allocation != NULL);
+
+  list = GTK_LIST (widget);
+
+  widget->allocation = *allocation;
+  if (GTK_WIDGET_REALIZED (widget))
+    gdk_window_move_resize (widget->window,
+                           allocation->x, allocation->y,
+                           allocation->width, allocation->height);
+
+  if (list->children)
+    {
+      child_allocation.x = GTK_CONTAINER (list)->border_width;
+      child_allocation.y = GTK_CONTAINER (list)->border_width;
+      child_allocation.width = allocation->width - child_allocation.x * 2;
+
+      children = list->children;
+
+      while (children)
+       {
+         child = children->data;
+         children = children->next;
+
+         if (GTK_WIDGET_VISIBLE (child))
+           {
+             child_allocation.height = child->requisition.height;
+
+             gtk_widget_size_allocate (child, &child_allocation);
+
+             child_allocation.y += child_allocation.height;
+           }
+       }
+    }
+}
+
+static void
+gtk_list_add (GtkContainer *container,
+             GtkWidget    *widget)
+{
+  GtkList *list;
+
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_LIST (container));
+  g_return_if_fail (widget != NULL);
+
+  list = GTK_LIST (container);
+
+  gtk_widget_set_parent (widget, GTK_WIDGET (container));
+  if (GTK_WIDGET_VISIBLE (widget->parent))
+    {
+      if (GTK_WIDGET_REALIZED (widget->parent) &&
+         !GTK_WIDGET_REALIZED (widget))
+       gtk_widget_realize (widget);
+
+      if (GTK_WIDGET_MAPPED (widget->parent) &&
+         !GTK_WIDGET_MAPPED (widget))
+       gtk_widget_map (widget);
+    }
+
+  list->children = g_list_append (list->children, widget);
+
+  if (!list->selection && (list->selection_mode == GTK_SELECTION_BROWSE))
+    {
+      gtk_list_select_child (list, widget);
+    }
+
+  if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
+    gtk_widget_queue_resize (widget);
+}
+
+static void
+gtk_list_remove (GtkContainer *container,
+                GtkWidget    *widget)
+{
+  GList *item_list;
+  
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_LIST (container));
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (container == GTK_CONTAINER (widget->parent));
+  
+  
+  item_list = g_list_alloc ();
+  item_list->data = widget;
+  
+  gtk_list_remove_items (GTK_LIST (container), item_list);
+  
+  g_list_free (item_list);
+}
+
+static void
+gtk_list_foreach (GtkContainer *container,
+                 GtkCallback   callback,
+                 gpointer      callback_data)
+{
+  GtkList *list;
+  GtkWidget *child;
+  GList *children;
+
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_LIST (container));
+  g_return_if_fail (callback != NULL);
+
+  list = GTK_LIST (container);
+  children = list->children;
+
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      (* callback) (child, callback_data);
+    }
+}
+
+
+static void
+gtk_real_list_select_child (GtkList   *list,
+                           GtkWidget *child)
+{
+  GList *selection;
+  GList *tmp_list;
+  GtkWidget *tmp_item;
+
+  g_return_if_fail (list != NULL);
+  g_return_if_fail (GTK_IS_LIST (list));
+  g_return_if_fail (child != NULL);
+  g_return_if_fail (GTK_IS_LIST_ITEM (child));
+
+  switch (list->selection_mode)
+    {
+    case GTK_SELECTION_SINGLE:
+      selection = list->selection;
+
+      while (selection)
+       {
+         tmp_item = selection->data;
+
+         if (tmp_item != child)
+           {
+             gtk_list_item_deselect (GTK_LIST_ITEM (tmp_item));
+
+             tmp_list = selection;
+             selection = selection->next;
+
+             list->selection = g_list_remove_link (list->selection, tmp_list);
+
+             g_list_free (tmp_list);
+           }
+         else
+           selection = selection->next;
+       }
+
+      if (child->state == GTK_STATE_NORMAL)
+       {
+         gtk_list_item_select (GTK_LIST_ITEM (child));
+         list->selection = g_list_prepend (list->selection, child);
+       }
+      else if (child->state == GTK_STATE_SELECTED)
+       {
+         gtk_list_item_deselect (GTK_LIST_ITEM (child));
+         list->selection = g_list_remove (list->selection, child);
+       }
+
+      gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]);
+      break;
+
+    case GTK_SELECTION_BROWSE:
+      selection = list->selection;
+
+      while (selection)
+       {
+         tmp_item = selection->data;
+
+         if (tmp_item != child)
+           {
+             gtk_list_item_deselect (GTK_LIST_ITEM (tmp_item));
+
+             tmp_list = selection;
+             selection = selection->next;
+
+             list->selection = g_list_remove_link (list->selection, tmp_list);
+
+             g_list_free (tmp_list);
+           }
+         else
+           selection = selection->next;
+       }
+
+      if (child->state == GTK_STATE_NORMAL)
+       {
+         gtk_list_item_select (GTK_LIST_ITEM (child));
+         list->selection = g_list_prepend (list->selection, child);
+         gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]);
+       }
+      break;
+
+    case GTK_SELECTION_MULTIPLE:
+      if (child->state == GTK_STATE_NORMAL)
+       {
+         gtk_list_item_select (GTK_LIST_ITEM (child));
+         list->selection = g_list_prepend (list->selection, child);
+         gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]);
+       }
+      else if (child->state == GTK_STATE_SELECTED)
+       {
+         gtk_list_item_deselect (GTK_LIST_ITEM (child));
+         list->selection = g_list_remove (list->selection, child);
+         gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]);
+       }
+      break;
+
+    case GTK_SELECTION_EXTENDED:
+      break;
+    }
+}
+
+static void
+gtk_real_list_unselect_child (GtkList   *list,
+                             GtkWidget *child)
+{
+  g_return_if_fail (list != NULL);
+  g_return_if_fail (GTK_IS_LIST (list));
+  g_return_if_fail (child != NULL);
+  g_return_if_fail (GTK_IS_LIST_ITEM (child));
+
+  switch (list->selection_mode)
+    {
+    case GTK_SELECTION_SINGLE:
+    case GTK_SELECTION_MULTIPLE:
+    case GTK_SELECTION_BROWSE:
+      if (child->state == GTK_STATE_SELECTED)
+       {
+         gtk_list_item_deselect (GTK_LIST_ITEM (child));
+         list->selection = g_list_remove (list->selection, child);
+         gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]);
+       }
+      break;
+
+    case GTK_SELECTION_EXTENDED:
+      break;
+    }
+}
+
+
+static void
+gtk_list_marshal_signal (GtkObject      *object,
+                        GtkSignalFunc   func,
+                        gpointer        func_data,
+                        GtkArg         *args)
+{
+  GtkListSignal rfunc;
+
+  rfunc = (GtkListSignal) func;
+
+  (* rfunc) (object, GTK_VALUE_OBJECT (args[0]), func_data);
+}
diff --git a/gtk/gtklist.h b/gtk/gtklist.h
new file mode 100644 (file)
index 0000000..3eff261
--- /dev/null
@@ -0,0 +1,107 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_LIST_H__
+#define __GTK_LIST_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkcontainer.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_LIST(obj)          GTK_CHECK_CAST (obj, gtk_list_get_type (), GtkList)
+#define GTK_LIST_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_list_get_type (), GtkListClass)
+#define GTK_IS_LIST(obj)       GTK_CHECK_TYPE (obj, gtk_list_get_type ())
+
+
+typedef struct _GtkList       GtkList;
+typedef struct _GtkListClass  GtkListClass;
+
+typedef enum
+{
+  GTK_SELECTION_SINGLE,
+  GTK_SELECTION_BROWSE,
+  GTK_SELECTION_MULTIPLE,
+  GTK_SELECTION_EXTENDED
+} GtkSelectionMode;
+
+struct _GtkList
+{
+  GtkContainer container;
+
+  GList *children;
+  GList *selection;
+
+  guint32 timer;
+  guint16 selection_start_pos;
+  guint16 selection_end_pos;
+  guint selection_mode : 2;
+  guint scroll_direction : 1;
+  guint have_grab : 1;
+};
+
+struct _GtkListClass
+{
+  GtkContainerClass parent_class;
+
+  void (* selection_changed) (GtkList   *list);
+  void (* select_child)      (GtkList   *list,
+                             GtkWidget *child);
+  void (* unselect_child)    (GtkList   *list,
+                             GtkWidget *child);
+};
+
+
+guint      gtk_list_get_type           (void);
+GtkWidget* gtk_list_new                (void);
+void       gtk_list_insert_items       (GtkList          *list,
+                                       GList            *items,
+                                       gint              position);
+void       gtk_list_append_items       (GtkList          *list,
+                                       GList            *items);
+void       gtk_list_prepend_items      (GtkList          *list,
+                                       GList            *items);
+void       gtk_list_remove_items       (GtkList          *list,
+                                       GList            *items);
+void       gtk_list_clear_items        (GtkList          *list,
+                                       gint              start,
+                                       gint              end);
+void       gtk_list_select_item        (GtkList          *list,
+                                       gint              item);
+void       gtk_list_unselect_item      (GtkList          *list,
+                                       gint              item);
+void       gtk_list_select_child       (GtkList          *list,
+                                       GtkWidget        *child);
+void       gtk_list_unselect_child     (GtkList          *list,
+                                       GtkWidget        *child);
+gint       gtk_list_child_position     (GtkList          *list,
+                                       GtkWidget        *child);
+void       gtk_list_set_selection_mode (GtkList          *list,
+                                       GtkSelectionMode  mode);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_LIST_H__ */
diff --git a/gtk/gtklistitem.c b/gtk/gtklistitem.c
new file mode 100644 (file)
index 0000000..6420270
--- /dev/null
@@ -0,0 +1,394 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtklabel.h"
+#include "gtklistitem.h"
+#include "gtklist.h"
+
+static void gtk_list_item_class_init    (GtkListItemClass *klass);
+static void gtk_list_item_init          (GtkListItem      *list_item);
+static void gtk_list_item_realize       (GtkWidget        *widget);
+static void gtk_list_item_size_request  (GtkWidget        *widget,
+                                        GtkRequisition   *requisition);
+static void gtk_list_item_size_allocate (GtkWidget        *widget,
+                                        GtkAllocation    *allocation);
+static void gtk_list_item_draw          (GtkWidget        *widget,
+                                        GdkRectangle     *area);
+static void gtk_list_item_draw_focus    (GtkWidget        *widget);
+static gint gtk_list_item_button_press  (GtkWidget        *widget,
+                                        GdkEventButton   *event);
+static gint gtk_list_item_expose        (GtkWidget        *widget,
+                                        GdkEventExpose   *event);
+static gint gtk_list_item_focus_in      (GtkWidget        *widget,
+                                        GdkEventFocus    *event);
+static gint gtk_list_item_focus_out     (GtkWidget        *widget,
+                                        GdkEventFocus    *event);
+static void gtk_real_list_item_select   (GtkItem          *item);
+static void gtk_real_list_item_deselect (GtkItem          *item);
+static void gtk_real_list_item_toggle   (GtkItem          *item);
+
+
+static GtkItemClass *parent_class = NULL;
+
+
+guint
+gtk_list_item_get_type ()
+{
+  static guint list_item_type = 0;
+
+  if (!list_item_type)
+    {
+      GtkTypeInfo list_item_info =
+      {
+       "GtkListItem",
+       sizeof (GtkListItem),
+       sizeof (GtkListItemClass),
+       (GtkClassInitFunc) gtk_list_item_class_init,
+       (GtkObjectInitFunc) gtk_list_item_init,
+       (GtkArgFunc) NULL,
+      };
+
+      list_item_type = gtk_type_unique (gtk_item_get_type (), &list_item_info);
+    }
+
+  return list_item_type;
+}
+
+static void
+gtk_list_item_class_init (GtkListItemClass *class)
+{
+  GtkWidgetClass *widget_class;
+  GtkItemClass *item_class;
+
+  widget_class = (GtkWidgetClass*) class;
+  item_class = (GtkItemClass*) class;
+
+  parent_class = gtk_type_class (gtk_item_get_type ());
+
+  widget_class->realize = gtk_list_item_realize;
+  widget_class->size_request = gtk_list_item_size_request;
+  widget_class->size_allocate = gtk_list_item_size_allocate;
+  widget_class->draw = gtk_list_item_draw;
+  widget_class->draw_focus = gtk_list_item_draw_focus;
+  widget_class->button_press_event = gtk_list_item_button_press;
+  widget_class->expose_event = gtk_list_item_expose;
+  widget_class->focus_in_event = gtk_list_item_focus_in;
+  widget_class->focus_out_event = gtk_list_item_focus_out;
+
+  item_class->select = gtk_real_list_item_select;
+  item_class->deselect = gtk_real_list_item_deselect;
+  item_class->toggle = gtk_real_list_item_toggle;
+}
+
+static void
+gtk_list_item_init (GtkListItem *list_item)
+{
+  GTK_WIDGET_SET_FLAGS (list_item, GTK_CAN_FOCUS);
+}
+
+GtkWidget*
+gtk_list_item_new ()
+{
+  return GTK_WIDGET (gtk_type_new (gtk_list_item_get_type ()));
+}
+
+GtkWidget*
+gtk_list_item_new_with_label (const gchar *label)
+{
+  GtkWidget *list_item;
+  GtkWidget *label_widget;
+
+  list_item = gtk_list_item_new ();
+  label_widget = gtk_label_new (label);
+  gtk_misc_set_alignment (GTK_MISC (label_widget), 0.0, 0.5);
+
+  gtk_container_add (GTK_CONTAINER (list_item), label_widget);
+  gtk_widget_show (label_widget);
+
+  return list_item;
+}
+
+void
+gtk_list_item_select (GtkListItem *list_item)
+{
+  gtk_item_select (GTK_ITEM (list_item));
+}
+
+void
+gtk_list_item_deselect (GtkListItem *list_item)
+{
+  gtk_item_deselect (GTK_ITEM (list_item));
+}
+
+
+static void
+gtk_list_item_realize (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_LIST_ITEM (widget));
+
+  if (GTK_WIDGET_CLASS (parent_class)->realize)
+    (* GTK_WIDGET_CLASS (parent_class)->realize) (widget);
+
+  gdk_window_set_background (widget->window, &widget->style->white);
+}
+
+static void
+gtk_list_item_size_request (GtkWidget      *widget,
+                           GtkRequisition *requisition)
+{
+  GtkBin *bin;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_LIST_ITEM (widget));
+  g_return_if_fail (requisition != NULL);
+
+  bin = GTK_BIN (widget);
+
+  requisition->width = (GTK_CONTAINER (widget)->border_width +
+                       widget->style->klass->xthickness) * 2;
+  requisition->height = GTK_CONTAINER (widget)->border_width * 2;
+
+  if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
+    {
+      gtk_widget_size_request (bin->child, &bin->child->requisition);
+
+      requisition->width += bin->child->requisition.width;
+      requisition->height += bin->child->requisition.height;
+    }
+}
+
+static void
+gtk_list_item_size_allocate (GtkWidget     *widget,
+                            GtkAllocation *allocation)
+{
+  GtkBin *bin;
+  GtkAllocation child_allocation;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_LIST_ITEM (widget));
+  g_return_if_fail (allocation != NULL);
+
+  widget->allocation = *allocation;
+  if (GTK_WIDGET_REALIZED (widget))
+    gdk_window_move_resize (widget->window,
+                           allocation->x, allocation->y,
+                           allocation->width, allocation->height);
+
+  bin = GTK_BIN (widget);
+
+  if (bin->child)
+    {
+      child_allocation.x = (GTK_CONTAINER (widget)->border_width +
+                           widget->style->klass->xthickness);
+      child_allocation.y = GTK_CONTAINER (widget)->border_width;
+      child_allocation.width = allocation->width - child_allocation.x * 2;
+      child_allocation.height = allocation->height - child_allocation.y * 2;
+
+      gtk_widget_size_allocate (bin->child, &child_allocation);
+    }
+}
+
+static void
+gtk_list_item_draw (GtkWidget    *widget,
+                   GdkRectangle *area)
+{
+  GtkBin *bin;
+  GdkRectangle child_area;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_LIST_ITEM (widget));
+  g_return_if_fail (area != NULL);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      bin = GTK_BIN (widget);
+
+      if (!GTK_WIDGET_IS_SENSITIVE (widget))
+       gtk_style_set_background (widget->style, widget->window, GTK_STATE_INSENSITIVE);
+      else if (widget->state == GTK_STATE_NORMAL)
+       gdk_window_set_background (widget->window, &widget->style->white);
+      else
+       gtk_style_set_background (widget->style, widget->window, widget->state);
+
+      gdk_window_clear_area (widget->window, area->x, area->y,
+                            area->width, area->height);
+
+      if (bin->child && gtk_widget_intersect (bin->child, area, &child_area))
+       gtk_widget_draw (bin->child, &child_area);
+
+      gtk_widget_draw_focus (widget);
+    }
+}
+
+static void
+gtk_list_item_draw_focus (GtkWidget *widget)
+{
+  GdkGC *gc;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_LIST_ITEM (widget));
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      if (GTK_WIDGET_HAS_FOCUS (widget))
+       gc = widget->style->black_gc;
+      else if (!GTK_WIDGET_IS_SENSITIVE (widget))
+       gc = widget->style->bg_gc[GTK_STATE_INSENSITIVE];
+      else if (widget->state == GTK_STATE_NORMAL)
+       gc = widget->style->white_gc;
+      else
+       gc = widget->style->bg_gc[widget->state];
+
+      gdk_draw_rectangle (widget->window, gc, FALSE, 0, 0,
+                         widget->allocation.width - 1,
+                         widget->allocation.height - 1);
+    }
+}
+
+static gint
+gtk_list_item_button_press (GtkWidget      *widget,
+                           GdkEventButton *event)
+{
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_LIST_ITEM (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (event->type == GDK_BUTTON_PRESS)
+    if (!GTK_WIDGET_HAS_FOCUS (widget))
+      gtk_widget_grab_focus (widget);
+
+  return FALSE;
+}
+
+static gint
+gtk_list_item_expose (GtkWidget      *widget,
+                     GdkEventExpose *event)
+{
+  GtkBin *bin;
+  GdkEventExpose child_event;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_LIST_ITEM (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      bin = GTK_BIN (widget);
+
+      if (!GTK_WIDGET_IS_SENSITIVE (widget))
+       gdk_window_set_background (widget->window, &widget->style->bg[GTK_STATE_INSENSITIVE]);
+      else if (widget->state == GTK_STATE_NORMAL)
+       gdk_window_set_background (widget->window, &widget->style->white);
+      else
+       gdk_window_set_background (widget->window, &widget->style->bg[widget->state]);
+
+      gdk_window_clear_area (widget->window, event->area.x, event->area.y,
+                            event->area.width, event->area.height);
+
+      if (bin->child)
+       {
+         child_event = *event;
+
+         if (GTK_WIDGET_NO_WINDOW (bin->child) &&
+             gtk_widget_intersect (bin->child, &event->area, &child_event.area))
+           gtk_widget_event (bin->child, (GdkEvent*) &child_event);
+       }
+
+      gtk_widget_draw_focus (widget);
+    }
+
+  return FALSE;
+}
+
+static gint
+gtk_list_item_focus_in (GtkWidget     *widget,
+                       GdkEventFocus *event)
+{
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_LIST_ITEM (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
+  gtk_widget_draw_focus (widget);
+
+  return FALSE;
+}
+
+static gint
+gtk_list_item_focus_out (GtkWidget     *widget,
+                        GdkEventFocus *event)
+{
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_LIST_ITEM (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
+  gtk_widget_draw_focus (widget);
+
+  return FALSE;
+}
+
+static void
+gtk_real_list_item_select (GtkItem *item)
+{
+  g_return_if_fail (item != NULL);
+  g_return_if_fail (GTK_IS_LIST_ITEM (item));
+
+  if (GTK_WIDGET (item)->state == GTK_STATE_SELECTED)
+    return;
+
+  gtk_widget_set_state (GTK_WIDGET (item), GTK_STATE_SELECTED);
+  gtk_widget_queue_draw (GTK_WIDGET (item));
+}
+
+static void
+gtk_real_list_item_deselect (GtkItem *item)
+{
+  g_return_if_fail (item != NULL);
+  g_return_if_fail (GTK_IS_LIST_ITEM (item));
+
+  if (GTK_WIDGET (item)->state == GTK_STATE_NORMAL)
+    return;
+
+  gtk_widget_set_state (GTK_WIDGET (item), GTK_STATE_NORMAL);
+  gtk_widget_queue_draw (GTK_WIDGET (item));
+}
+
+static void
+gtk_real_list_item_toggle (GtkItem *item)
+{
+  g_return_if_fail (item != NULL);
+  g_return_if_fail (GTK_IS_LIST_ITEM (item));
+  
+  if (GTK_WIDGET (item)->parent && GTK_IS_LIST (GTK_WIDGET (item)->parent))
+    gtk_list_select_child (GTK_LIST (GTK_WIDGET (item)->parent),
+                          GTK_WIDGET (item));
+  else
+    {
+      /* Should we really bother with this bit? A listitem not in a list?
+       * -Johannes Keukelaar
+       * yes, always be on the save side!
+       * -timj
+       */
+      if (GTK_WIDGET (item)->state == GTK_STATE_SELECTED)
+       gtk_widget_set_state (GTK_WIDGET (item), GTK_STATE_NORMAL);
+      else
+       gtk_widget_set_state (GTK_WIDGET (item), GTK_STATE_SELECTED);
+      gtk_widget_queue_draw (GTK_WIDGET (item));
+    }
+}
diff --git a/gtk/gtklistitem.h b/gtk/gtklistitem.h
new file mode 100644 (file)
index 0000000..4220ae7
--- /dev/null
@@ -0,0 +1,62 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_LIST_ITEM_H__
+#define __GTK_LIST_ITEM_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkitem.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_LIST_ITEM(obj)          GTK_CHECK_CAST (obj, gtk_list_item_get_type (), GtkListItem)
+#define GTK_LIST_ITEM_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_list_item_get_type (), GtkListItemClass)
+#define GTK_IS_LIST_ITEM(obj)       GTK_CHECK_TYPE (obj, gtk_list_item_get_type ())
+
+
+typedef struct _GtkListItem       GtkListItem;
+typedef struct _GtkListItemClass  GtkListItemClass;
+
+struct _GtkListItem
+{
+  GtkItem item;
+};
+
+struct _GtkListItemClass
+{
+  GtkItemClass parent_class;
+};
+
+
+guint      gtk_list_item_get_type       (void);
+GtkWidget* gtk_list_item_new            (void);
+GtkWidget* gtk_list_item_new_with_label (const gchar      *label);
+void       gtk_list_item_select         (GtkListItem      *list_item);
+void       gtk_list_item_deselect       (GtkListItem      *list_item);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_LIST_ITEM_H__ */
diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c
new file mode 100644 (file)
index 0000000..50d2624
--- /dev/null
@@ -0,0 +1,1129 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include "gtkbutton.h"
+#include "gtkhscrollbar.h"
+#include "gtkhseparator.h"
+#include "gtkmain.h"
+#include "gtkpreview.h"
+#include "gtkrc.h"
+#include "gtkselection.h"
+#include "gtksignal.h"
+#include "gtktable.h"
+#include "gtktext.h"
+#include "gtkvbox.h"
+#include "gtkvscrollbar.h"
+#include "gtkwidget.h"
+#include "gtkwindow.h"
+
+
+/* Private type definitions
+ */
+typedef struct _GtkInitFunction     GtkInitFunction;
+typedef struct _GtkTimeoutFunction  GtkTimeoutFunction;
+typedef struct _GtkIdleFunction     GtkIdleFunction;
+
+struct _GtkInitFunction
+{
+  GtkFunction function;
+  gpointer data;
+};
+
+struct _GtkTimeoutFunction
+{
+  gint tag;
+  guint32 start;
+  guint32 interval;
+  guint32 originterval;
+  gint interp;
+  GtkFunction function;
+  gpointer data;
+  GtkDestroyNotify destroy;
+};
+
+struct _GtkIdleFunction
+{
+  gint tag;
+  gint interp;
+  GtkFunction function;
+  gpointer data;
+  GtkDestroyNotify destroy;
+};
+
+
+static void  gtk_exit_func       (void);
+static void  gtk_timeout_insert  (GtkTimeoutFunction *timeoutf);
+static void  gtk_handle_current_timeouts (guint32 the_time);
+static void  gtk_handle_current_idles ();
+static void  gtk_handle_timeouts (void);
+static void  gtk_handle_idle     (void);
+static void  gtk_handle_timer    (void);
+static void  gtk_propagate_event (GtkWidget *widget,
+                                 GdkEvent  *event);
+static void  gtk_error           (char *str);
+static void  gtk_warning         (char *str);
+static void  gtk_message         (char *str);
+static void  gtk_print           (char *str);
+
+
+static int done;
+static int initialized = FALSE;
+static GdkEvent next_event;
+static GdkEvent current_event;
+static gint have_event = FALSE;
+static gint have_next_event = FALSE;
+
+static GList *grabs = NULL;                /* A list of grabs. The grabbing widget
+                                           *  is the first one on the list.
+                                           */
+static GList *init_functions = NULL;       /* A list of init functions.
+                                           */
+static GList *timeout_functions = NULL;    /* A list of timeout functions sorted by
+                                           *  when the length of the time interval
+                                           *  remaining. Therefore, the first timeout
+                                           *  function to expire is at the head of
+                                           *  the list and the last to expire is at
+                                           *  the tail of the list.
+                                           */
+static GList *idle_functions = NULL;       /* A list of idle functions.
+                                           */
+
+static GList *current_idles = NULL;
+static GList *current_timeouts = NULL;
+static GMemChunk *timeout_mem_chunk = NULL;
+static GMemChunk *idle_mem_chunk = NULL;
+
+static GdkVisual *gtk_visual;              /* The visual to be used in creating new
+                                           *  widgets.
+                                           */
+static GdkColormap *gtk_colormap;          /* The colormap to be used in creating new
+                                           *  widgets.
+                                           */
+
+
+void
+gtk_init (int    *argc,
+         char ***argv)
+{
+  if (0)
+    {
+      g_set_error_handler (gtk_error);
+      g_set_warning_handler (gtk_warning);
+      g_set_message_handler (gtk_message);
+      g_set_print_handler (gtk_print);
+    }
+
+  /* Initialize "gdk". We simply pass along the 'argc' and 'argv'
+   *  parameters as they contain information that
+   */
+  gdk_init (argc, argv);
+
+  /* Initialize the default visual and colormap to be
+   *  used in creating widgets. (We want to use the system
+   *  defaults so as to be nice to the colormap).
+   */
+  gtk_visual = gdk_visual_get_system ();
+  gtk_colormap = gdk_colormap_get_system ();
+  gtk_rc_init ();
+
+  gtk_type_init ();
+
+  /* Register an exit function to make sure we are able to cleanup.
+   */
+  if (ATEXIT (gtk_exit_func))
+    g_warning ("unable to register exit function");
+
+  /* Set the 'initialized' flag.
+   */
+  initialized = TRUE;
+}
+
+void
+gtk_exit (int errorcode)
+{
+  /* Only if "gtk" has been initialized should we de-initialize.
+   */
+ /* de-initialisation is done by the gtk_exit_funct(),
+    no need to do this here (Alex J.) */
+  gdk_exit(errorcode);
+}
+
+gchar*
+gtk_set_locale ()
+{
+  return gdk_set_locale ();
+}
+
+void
+gtk_main ()
+{
+  GList *tmp_list;
+  GList *functions;
+  GtkInitFunction *init;
+  int old_done;
+
+  tmp_list = functions = init_functions;
+  init_functions = NULL;
+
+  while (tmp_list)
+    {
+      init = tmp_list->data;
+      tmp_list = tmp_list->next;
+
+      (* init->function) (init->data);
+      g_free (init);
+    }
+
+  g_list_free (functions);
+
+  old_done = done;
+  while (!gtk_main_iteration ())
+    ;
+  done = old_done;
+}
+
+void
+gtk_main_quit ()
+{
+  done = TRUE;
+}
+
+gint
+gtk_main_iteration ()
+{
+  GdkEvent event_copy;
+  GtkWidget *event_widget;
+  GtkWidget *grab_widget;
+
+  done = FALSE;
+
+  /* If this is a recursive call, and there are pending timeouts or
+     idles, finish them, then return immediately to avoid blocking
+     in gdk_event_get() */
+  if (current_timeouts)
+    {
+      gtk_handle_current_timeouts( gdk_time_get());
+      return done;
+    }
+  if (current_idles)
+    {
+      gtk_handle_current_idles();
+      return done;
+    }
+
+  /* If there is a valid event in 'next_event' then copy
+   *  it to 'event' and unset the flag.
+   */
+  if (have_next_event)
+    {
+      have_next_event = FALSE;
+      have_event = TRUE;
+      current_event = next_event;
+    }
+
+  /* If we don't have an event then get one.
+   */
+  if (!have_event)
+    {
+      /* Handle setting of the "gdk" timer. If there are no
+       *  timeout functions, then the timer is turned off.
+       *  If there are timeout functions, then the timer is
+       *  set to the shortest timeout interval (which is
+       *  the first timeout function).
+       */
+      gtk_handle_timer ();
+
+      have_event = gdk_event_get (&current_event, NULL, NULL);
+    }
+
+  /* "gdk_event_get" can return FALSE if the timer goes off
+   *  and no events are pending. Therefore, we should make
+   *  sure that we got an event before continuing.
+   */
+  if (have_event)
+    {
+      have_event = FALSE;
+
+      /* If there are any events pending then get the next one.
+       */
+      if (gdk_events_pending () > 0)
+       have_next_event = gdk_event_get (&next_event, NULL, NULL);
+
+      /* Try to compress enter/leave notify events. These event
+       *  pairs occur when the mouse is dragged quickly across
+       *  a window with many buttons (or through a menu). Instead
+       *  of highlighting and de-highlighting each widget that
+       *  is crossed it is better to simply de-highlight the widget
+       *  which contained the mouse initially and highlight the
+       *  widget which ends up containing the mouse.
+       */
+      if (have_next_event)
+       if (((current_event.type == GDK_ENTER_NOTIFY) ||
+            (current_event.type == GDK_LEAVE_NOTIFY)) &&
+           ((next_event.type == GDK_ENTER_NOTIFY) ||
+            (next_event.type == GDK_LEAVE_NOTIFY)) &&
+           (next_event.type != current_event.type) &&
+           (next_event.any.window == current_event.any.window))
+         return done;
+
+      /* Find the widget which got the event. We store the widget
+       *  in the user_data field of GdkWindow's.
+       */
+      event_widget = gtk_get_event_widget (&current_event);
+
+      /* If there is a grab in effect...
+       */
+      if (grabs)
+       {
+         grab_widget = grabs->data;
+
+         /* If the grab widget is an ancestor of the event widget
+          *  then we send the event to the original event widget.
+          *  This is the key to implementing modality.
+          */
+         if (gtk_widget_is_ancestor (event_widget, grab_widget))
+           grab_widget = event_widget;
+       }
+      else
+       {
+         grab_widget = event_widget;
+       }
+
+      /* Not all events get sent to the grabbing widget.
+       * The delete, destroy, expose, focus change and resize
+       *  events still get sent to the event widget because
+       *  1) these events have no meaning for the grabbing widget
+       *  and 2) redirecting these events to the grabbing widget
+       *  could cause the display to be messed up.
+       */
+      event_copy = current_event;
+      switch (event_copy.type)
+       {
+       case GDK_NOTHING:
+         break;
+
+       case GDK_DELETE:
+         if (gtk_widget_event (event_widget, &event_copy))
+           gtk_widget_destroy (event_widget);
+         break;
+
+       case GDK_DESTROY:
+         gtk_widget_event (event_widget, &event_copy);
+         gtk_widget_destroy (event_widget);
+         break;
+
+       case GDK_PROPERTY_NOTIFY:
+         /* To handle selection INCR transactions, we select
+            PropertyNotify events on the requestor window and create
+            a corresponding (fake) GdkWindow so that events get
+            here. There won't be a widget though, so we have to handle
+            them specially */
+
+         if (event_widget == NULL)
+           {
+             gtk_selection_incr_event (event_copy.any.window,
+                                       &event_copy.property);
+             break;
+           }
+         /* otherwise fall through */
+
+       case GDK_EXPOSE:
+       case GDK_FOCUS_CHANGE:
+       case GDK_CONFIGURE:
+       case GDK_MAP:
+       case GDK_UNMAP:
+       case GDK_SELECTION_CLEAR:
+       case GDK_SELECTION_REQUEST:
+       case GDK_SELECTION_NOTIFY:
+       case GDK_CLIENT_EVENT:
+         gtk_widget_event (event_widget, &event_copy);
+         break;
+
+       case GDK_MOTION_NOTIFY:
+       case GDK_BUTTON_PRESS:
+       case GDK_2BUTTON_PRESS:
+       case GDK_3BUTTON_PRESS:
+       case GDK_BUTTON_RELEASE:
+       case GDK_KEY_PRESS:
+       case GDK_KEY_RELEASE:
+       case GDK_PROXIMITY_IN:
+       case GDK_PROXIMITY_OUT:
+       case GDK_OTHER_EVENT:
+       case GDK_DRAG_BEGIN:
+       case GDK_DRAG_REQUEST:
+       case GDK_DROP_ENTER:
+       case GDK_DROP_LEAVE:
+       case GDK_DROP_DATA_AVAIL:
+         gtk_propagate_event (grab_widget, &event_copy);
+         break;
+
+       case GDK_ENTER_NOTIFY:
+       case GDK_LEAVE_NOTIFY:
+         if (grab_widget && GTK_WIDGET_IS_SENSITIVE (grab_widget))
+           gtk_widget_event (grab_widget, &event_copy);
+         break;
+       }
+    }
+  else
+    {
+     if (gdk_events_pending() == 0)
+       gtk_handle_idle ();
+    }
+
+  /* Handle a timeout functions that may have expired.
+   */
+  gtk_handle_timeouts ();
+
+  return done;
+}
+
+gint
+gtk_true (void)
+{
+  return TRUE;
+}
+
+gint
+gtk_false (void)
+{
+  return FALSE;
+}
+
+void
+gtk_grab_add (GtkWidget *widget)
+{
+  /* Place the grab on the front of the list of grabs.
+   */
+  grabs = g_list_prepend (grabs, widget);
+}
+
+void
+gtk_grab_remove (GtkWidget *widget)
+{
+  /* Remove the grab from the list of grabs.
+   * Note: the grab being removed may be in
+   *  the middle of the list.
+   */
+  grabs = g_list_remove (grabs, widget);
+}
+
+void
+gtk_init_add (GtkFunction function,
+             gpointer    data)
+{
+  GtkInitFunction *init;
+
+  init = g_new (GtkInitFunction, 1);
+  init->function = function;
+  init->data = data;
+
+  init_functions = g_list_prepend (init_functions, init);
+}
+
+static gint
+gtk_timeout_add_internal (guint32     interval,
+                         gint        interp,
+                         GtkFunction function,
+                         gpointer    data,
+                         GtkDestroyNotify destroy)
+{
+  static gint timeout_tag = 1;
+  GtkTimeoutFunction *timeoutf;
+
+  /* Create a new timeout function structure.
+   * The start time is the current time.
+   */
+  if (!timeout_mem_chunk)
+    timeout_mem_chunk = g_mem_chunk_new ("timeout mem chunk", sizeof (GtkTimeoutFunction),
+                                        1024, G_ALLOC_AND_FREE);
+
+  timeoutf = g_chunk_new (GtkTimeoutFunction, timeout_mem_chunk);
+
+  timeoutf->tag = timeout_tag++;
+  timeoutf->start = gdk_time_get ();
+  timeoutf->interval = interval;
+  timeoutf->originterval = interval;
+  timeoutf->interp = interp;
+  timeoutf->function = function;
+  timeoutf->data = data;
+  timeoutf->destroy = destroy;
+
+  gtk_timeout_insert (timeoutf);
+
+  return timeoutf->tag;
+}
+
+static void
+gtk_timeout_destroy (GtkTimeoutFunction *timeoutf)
+{
+  if (timeoutf->destroy)
+    (timeoutf->destroy) (timeoutf->data);
+  g_mem_chunk_free (timeout_mem_chunk, timeoutf);
+}
+
+gint
+gtk_timeout_add (guint32     interval,
+                GtkFunction function,
+                gpointer    data)
+{
+  return gtk_timeout_add_internal (interval, FALSE, function, data, NULL);
+}
+
+gint
+gtk_timeout_add_interp (guint32            interval,
+                       GtkCallbackMarshal function,
+                       gpointer           data,
+                       GtkDestroyNotify   destroy)
+{
+  return gtk_timeout_add_internal (interval, TRUE,
+                                  (GtkFunction) function,
+                                   data, destroy);
+}
+
+void
+gtk_timeout_remove (gint tag)
+{
+  GtkTimeoutFunction *timeoutf;
+  GList *tmp_list;
+
+  /* Remove a timeout function.
+   * (Which, basically, involves searching the
+   *  list for the tag).
+   */
+  tmp_list = timeout_functions;
+  while (tmp_list)
+    {
+      timeoutf = tmp_list->data;
+      
+      if (timeoutf->tag == tag)
+       {
+         timeout_functions = g_list_remove_link (timeout_functions, tmp_list);
+         g_list_free (tmp_list);
+         gtk_timeout_destroy (timeoutf);
+         
+         return;
+       }
+      
+      tmp_list = tmp_list->next;
+    }
+
+  tmp_list = current_timeouts;
+  while (tmp_list)
+    {
+      timeoutf = tmp_list->data;
+      
+      if (timeoutf->tag == tag)
+       {
+         current_timeouts = g_list_remove_link (current_timeouts, tmp_list);
+         g_list_free (tmp_list);
+         gtk_timeout_destroy (timeoutf);
+         
+         return;
+       }
+      
+      tmp_list = tmp_list->next;
+    }
+}
+
+static gint
+gtk_idle_add_internal (gint             interp,
+                      GtkFunction      function,
+                      gpointer         data,
+                      GtkDestroyNotify destroy)
+{
+  static gint idle_tag = 1;
+  GtkIdleFunction *idlef;
+
+  if (!idle_mem_chunk)
+    idle_mem_chunk = g_mem_chunk_new ("idle mem chunk", sizeof (GtkIdleFunction),
+                                     1024, G_ALLOC_AND_FREE);
+
+  idlef = g_chunk_new (GtkIdleFunction, idle_mem_chunk);
+
+  idlef->tag = idle_tag++;
+  idlef->interp = interp;
+  idlef->function = function;
+  idlef->data = data;
+  idlef->destroy = destroy;
+
+  idle_functions = g_list_append (idle_functions, idlef);
+
+  return idlef->tag;
+}
+
+static void
+gtk_idle_destroy (GtkIdleFunction *idlef)
+{
+  if (idlef->destroy)
+    idlef->destroy (idlef->data);
+  g_mem_chunk_free (idle_mem_chunk, idlef);
+}
+
+gint
+gtk_idle_add (GtkFunction function,
+             gpointer    data)
+{
+  return gtk_idle_add_internal (FALSE, function, data, NULL);
+}
+
+gint
+gtk_idle_add_interp (GtkCallbackMarshal function,
+                    gpointer           data,
+                    GtkDestroyNotify   destroy)
+{
+  return gtk_idle_add_internal (TRUE, (GtkFunction)function, data, destroy);
+}
+
+void
+gtk_idle_remove (gint tag)
+{
+  GtkIdleFunction *idlef;
+  GList *tmp_list;
+
+  tmp_list = idle_functions;
+  while (tmp_list)
+    {
+      idlef = tmp_list->data;
+      
+      if (idlef->tag == tag)
+       {
+         idle_functions = g_list_remove_link (idle_functions, tmp_list);
+         g_list_free (tmp_list);
+         gtk_idle_destroy (idlef);
+         
+         return;
+       }
+      
+      tmp_list = tmp_list->next;
+    }
+
+  tmp_list = current_idles;
+  while (tmp_list)
+    {
+      idlef = tmp_list->data;
+      
+      if (idlef->tag == tag)
+       {
+         current_idles = g_list_remove_link (current_idles, tmp_list);
+         g_list_free (tmp_list);
+         gtk_idle_destroy (idlef);
+         
+         return;
+       }
+      
+      tmp_list = tmp_list->next;
+    }
+}
+
+void
+gtk_idle_remove_by_data (gpointer data)
+{
+  GtkIdleFunction *idlef;
+  GList *tmp_list;
+
+  tmp_list = idle_functions;
+  while (tmp_list)
+    {
+      idlef = tmp_list->data;
+      
+      if (idlef->data == data)
+       {
+         idle_functions = g_list_remove_link (idle_functions, tmp_list);
+         g_list_free (tmp_list);
+         g_mem_chunk_free (idle_mem_chunk, idlef);
+         
+         return;
+       }
+      
+      tmp_list = tmp_list->next;
+    }
+
+  tmp_list = current_idles;
+  while (tmp_list)
+    {
+      idlef = tmp_list->data;
+      
+      if (idlef->data == data)
+       {
+         current_idles = g_list_remove_link (current_idles, tmp_list);
+         g_list_free (tmp_list);
+         g_mem_chunk_free (idle_mem_chunk, idlef);
+         
+         return;
+       }
+      
+      tmp_list = tmp_list->next;
+    }
+}
+
+void
+gtk_get_current_event (GdkEvent *event)
+{
+  g_assert (event != NULL);
+
+  *event = current_event;
+}
+
+GtkWidget*
+gtk_get_event_widget (GdkEvent *event)
+{
+  GtkWidget *widget;
+  gdk_window_get_user_data (event->any.window, (void**) &widget);
+
+  return widget;
+}
+
+static void
+gtk_exit_func ()
+{
+  if (initialized)
+    {
+      initialized = FALSE;
+      gtk_preview_uninit ();
+    }
+}
+
+static void
+gtk_timeout_insert (GtkTimeoutFunction *timeoutf)
+{
+  GtkTimeoutFunction *temp;
+  GList *temp_list;
+  GList *new_list;
+
+  g_assert (timeoutf != NULL);
+
+  /* Insert the timeout function appropriately.
+   * Appropriately meaning sort it into the list
+   *  of timeout functions.
+   */
+  temp_list = timeout_functions;
+  while (temp_list)
+    {
+      temp = temp_list->data;
+      if (timeoutf->interval < temp->interval)
+       {
+         new_list = g_list_alloc ();
+         new_list->data = timeoutf;
+         new_list->next = temp_list;
+         new_list->prev = temp_list->prev;
+         if (temp_list->prev)
+           temp_list->prev->next = new_list;
+         temp_list->prev = new_list;
+         
+         if (temp_list == timeout_functions)
+           timeout_functions = new_list;
+         
+         return;
+       }
+      
+      temp_list = temp_list->next;
+    }
+  
+  timeout_functions = g_list_append (timeout_functions, timeoutf);
+}
+
+static gint
+gtk_invoke_timeout_function (GtkTimeoutFunction *timeoutf)
+{
+  if (!timeoutf->interp)
+    return timeoutf->function (timeoutf->data);
+  else
+    {
+      GtkArg args[1];
+      gint ret_val = FALSE;
+      args[0].name = NULL;
+      args[0].type = GTK_TYPE_BOOL;
+      args[0].d.pointer_data = &ret_val;
+      ((GtkCallbackMarshal)timeoutf->function) (NULL,
+                                               timeoutf->data,
+                                               0, args);
+      return ret_val;
+    }
+}
+
+static void
+gtk_handle_current_timeouts (guint32 the_time)
+{
+  GList *tmp_list;
+  GtkTimeoutFunction *timeoutf;
+
+  while (current_timeouts)
+    {
+      tmp_list = current_timeouts;
+      timeoutf = tmp_list->data;
+
+      current_timeouts = g_list_remove_link (current_timeouts, tmp_list);
+      g_list_free (tmp_list);
+      
+      if (gtk_invoke_timeout_function (timeoutf) == FALSE)
+       {
+         gtk_timeout_destroy (timeoutf);
+       }
+      else
+       {
+         timeoutf->interval = timeoutf->originterval;
+         timeoutf->start = the_time;
+         gtk_timeout_insert (timeoutf);
+       }
+    }
+}
+
+/* Utility function - make up for an ommision in glib */
+static GList *
+gtk_main_list_concat (GList *list1, GList *list2)
+{
+  GList *tmp_list;
+  GList *list;
+
+  if (list2)
+    {
+      tmp_list = g_list_last (list1);
+      if (tmp_list)
+       tmp_list->next = list2;
+      else
+       list1 = list2;
+      list2->prev = tmp_list;
+    }
+
+  return list1;
+}
+
+static void
+gtk_handle_timeouts ()
+{
+  guint32 the_time;
+  GList *tmp_list;
+  GList *tmp_list2;
+  GList *tmp_list3;
+  GtkTimeoutFunction *timeoutf;
+
+  /* Caller must already have called gtk_handle_current_timeouts if
+   * necessary */
+  g_assert (current_timeouts == NULL);
+
+  if (timeout_functions)
+    {
+      the_time = gdk_time_get ();
+
+      tmp_list = timeout_functions;
+      while (tmp_list)
+       {
+         timeoutf = tmp_list->data;
+
+         if (timeoutf->interval <= (the_time - timeoutf->start))
+           {
+             tmp_list2 = tmp_list;
+             tmp_list = tmp_list->next;
+
+             timeout_functions = g_list_remove_link (timeout_functions, tmp_list2);
+             current_timeouts = gtk_main_list_concat (current_timeouts, tmp_list2);
+           }
+         else
+           {
+             timeoutf->interval -= (the_time - timeoutf->start);
+             timeoutf->start = the_time;
+             tmp_list = tmp_list->next;
+           }
+       }
+
+      if (current_timeouts)
+       gtk_handle_current_timeouts(the_time);
+    }
+}
+
+static gint
+gtk_idle_invoke_function (GtkIdleFunction *idlef)
+{
+  if (!idlef->interp)
+    return idlef->function (idlef->data);
+  else
+    {
+      GtkArg args[1];
+      gint ret_val = FALSE;
+      args[0].name = NULL;
+      args[0].type = GTK_TYPE_BOOL;
+      args[0].d.pointer_data = &ret_val;
+      ((GtkCallbackMarshal)idlef->function) (NULL,
+                                            idlef->data,
+                                            0, args);
+      return ret_val;
+    }
+}
+  
+static void
+gtk_handle_current_idles ()
+{
+  GList *tmp_list;
+  GtkIdleFunction *idlef;
+
+  while (current_idles)
+    {
+      tmp_list = current_idles;
+      idlef = tmp_list->data;
+
+      current_idles = g_list_remove_link (current_idles, tmp_list);
+      
+      if (gtk_idle_invoke_function (idlef) == FALSE)
+       {
+         g_list_free (tmp_list);
+         gtk_idle_destroy (idlef);
+       }
+      else
+       {
+         idle_functions = gtk_main_list_concat (idle_functions, tmp_list);
+       }
+    }
+}
+
+static void
+gtk_handle_idle ()
+{
+  GtkIdleFunction *idlef;
+  GList *tmp_list;
+  GList *tmp_list2;
+
+  /* Caller must already have called gtk_handle_current_idles if
+     necessary */
+  g_assert (current_idles == NULL);
+
+  if (idle_functions)
+    {
+      current_idles = idle_functions;
+      idle_functions = NULL;
+
+      gtk_handle_current_idles();
+    }
+}
+
+static void
+gtk_handle_timer ()
+{
+  GtkTimeoutFunction *timeoutf;
+
+  if (idle_functions)
+    {
+      gdk_timer_set (0);
+      gdk_timer_enable ();
+    }
+  else if (timeout_functions)
+    {
+      timeoutf = timeout_functions->data;
+      gdk_timer_set (timeoutf->interval);
+      gdk_timer_enable ();
+    }
+  else
+    {
+      gdk_timer_set (0);
+      gdk_timer_disable ();
+    }
+}
+
+static void
+gtk_propagate_event (GtkWidget *widget,
+                    GdkEvent  *event)
+{
+  GtkWidget *parent;
+  gint handled_event;
+  gint parent_old_value;
+  gint old_value;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (event != NULL);
+
+  handled_event = FALSE;
+
+  if ((event->type == GDK_KEY_PRESS) ||
+      (event->type == GDK_KEY_RELEASE))
+    {
+      /* Only send key events to window widgets.
+       *  The window widget will in turn pass the
+       *  key event on to the currently focused widget
+       *  for that window.
+       */
+      parent = gtk_widget_get_ancestor (widget, gtk_window_get_type ());
+      if (parent && GTK_WIDGET_IS_SENSITIVE (parent))
+       {
+         parent_old_value = GTK_OBJECT_IN_CALL (parent);
+         GTK_OBJECT_SET_FLAGS (parent, GTK_IN_CALL);
+
+         handled_event = gtk_widget_event (parent, event);
+
+         if (!parent_old_value)
+           GTK_OBJECT_UNSET_FLAGS (parent, GTK_IN_CALL);
+
+         if (GTK_OBJECT_NEED_DESTROY (parent) && !GTK_OBJECT_IN_CALL (parent))
+           {
+             gtk_object_destroy (GTK_OBJECT (parent));
+             return;
+           }
+       }
+    }
+
+  if (!handled_event)
+    {
+      old_value = GTK_OBJECT_IN_CALL (widget);
+      GTK_OBJECT_SET_FLAGS (widget, GTK_IN_CALL);
+
+      /* Other events get propagated up the widget tree
+       *  so that parents can see the button and motion
+       *  events of the children.
+       */
+      parent = widget;
+      while (parent)
+       {
+         parent_old_value = GTK_OBJECT_IN_CALL (parent);
+         GTK_OBJECT_SET_FLAGS (parent, GTK_IN_CALL);
+
+         handled_event = (!GTK_WIDGET_IS_SENSITIVE (parent) ||
+                          gtk_widget_event (parent, event));
+
+         if (!parent_old_value)
+           GTK_OBJECT_UNSET_FLAGS (parent, GTK_IN_CALL);
+
+         if (handled_event)
+           break;
+
+         if (GTK_OBJECT_NEED_DESTROY (parent) && !GTK_OBJECT_IN_CALL (parent))
+           {
+             gtk_object_destroy (GTK_OBJECT (parent));
+             break;
+           }
+
+         parent = parent->parent;
+       }
+
+      if (!old_value)
+       GTK_OBJECT_UNSET_FLAGS (widget, GTK_IN_CALL);
+
+      if (GTK_OBJECT_NEED_DESTROY (widget) && !GTK_OBJECT_IN_CALL (widget))
+       gtk_object_destroy (GTK_OBJECT (widget));
+    }
+}
+
+
+static void
+gtk_error (char *str)
+{
+  gtk_print (str);
+}
+
+static void
+gtk_warning (char *str)
+{
+  gtk_print (str);
+}
+
+static void
+gtk_message (char *str)
+{
+  gtk_print (str);
+}
+
+static void
+gtk_print (char *str)
+{
+  static GtkWidget *window = NULL;
+  static GtkWidget *text;
+  static int level = 0;
+  GtkWidget *box1;
+  GtkWidget *box2;
+  GtkWidget *table;
+  GtkWidget *hscrollbar;
+  GtkWidget *vscrollbar;
+  GtkWidget *separator;
+  GtkWidget *button;
+
+  if (level > 0)
+    {
+      fputs (str, stdout);
+      fflush (stdout);
+      return;
+    }
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+      /*
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) gtk_widget_destroyed,
+                         &window);
+                         */
+      gtk_window_set_title (GTK_WINDOW (window), "Messages");
+
+      box1 = gtk_vbox_new (FALSE, 0);
+      gtk_container_add (GTK_CONTAINER (window), box1);
+      gtk_widget_show (box1);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      table = gtk_table_new (2, 2, FALSE);
+      gtk_table_set_row_spacing (GTK_TABLE (table), 0, 2);
+      gtk_table_set_col_spacing (GTK_TABLE (table), 0, 2);
+      gtk_box_pack_start (GTK_BOX (box2), table, TRUE, TRUE, 0);
+      gtk_widget_show (table);
+
+      text = gtk_text_new (NULL, NULL);
+      gtk_text_set_editable (GTK_TEXT (text), FALSE);
+      gtk_table_attach_defaults (GTK_TABLE (table), text, 0, 1, 0, 1);
+      gtk_widget_show (text);
+      gtk_widget_realize (text);
+
+      hscrollbar = gtk_hscrollbar_new (GTK_TEXT (text)->hadj);
+      gtk_table_attach (GTK_TABLE (table), hscrollbar, 0, 1, 1, 2,
+                        GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
+      gtk_widget_show (hscrollbar);
+
+      vscrollbar = gtk_vscrollbar_new (GTK_TEXT (text)->vadj);
+      gtk_table_attach (GTK_TABLE (table), vscrollbar, 1, 2, 0, 1,
+                        GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+      gtk_widget_show (vscrollbar);
+
+      separator = gtk_hseparator_new ();
+      gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
+      gtk_widget_show (separator);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                 (GtkSignalFunc) gtk_widget_hide,
+                                 GTK_OBJECT (window));
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+    }
+
+  level += 1;
+  gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL, str, -1);
+  level -= 1;
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+}
diff --git a/gtk/gtkmain.h b/gtk/gtkmain.h
new file mode 100644 (file)
index 0000000..9d014e4
--- /dev/null
@@ -0,0 +1,76 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_MAIN_H__
+#define __GTK_MAIN_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkwidget.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* Initialization, exit, mainloop and miscellaneous routines
+ */
+void       gtk_init              (int          *argc,
+                                 char       ***argv);
+void       gtk_exit              (gint          error_code);
+gchar*     gtk_set_locale        (void);
+void       gtk_main              (void);
+void       gtk_main_quit         (void);
+gint       gtk_main_iteration    (void);
+
+gint      gtk_true              (void);
+gint      gtk_false             (void);
+
+void       gtk_grab_add          (GtkWidget     *widget);
+void       gtk_grab_remove       (GtkWidget     *widget);
+
+void       gtk_init_add          (GtkFunction    function,
+                                 gpointer       data);
+
+gint       gtk_timeout_add         (guint32        interval,
+                                    GtkFunction    function,
+                                    gpointer       data);
+gint       gtk_timeout_add_interp  (guint32        interval,
+                                    GtkCallbackMarshal function,
+                                    gpointer       data,
+                                    GtkDestroyNotify notify);
+void       gtk_timeout_remove      (gint           tag);
+
+gint       gtk_idle_add            (GtkFunction    function,
+                                    gpointer       data);
+gint       gtk_idle_add_interp     (GtkCallbackMarshal function,
+                                    gpointer           data,
+                                    GtkDestroyNotify   destroy);
+void       gtk_idle_remove         (gint           tag);
+void       gtk_idle_remove_by_data (gpointer     data);
+
+void       gtk_get_current_event (GdkEvent      *event);
+GtkWidget* gtk_get_event_widget  (GdkEvent      *event);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_MAIN_H__ */
diff --git a/gtk/gtkmenu.c b/gtk/gtkmenu.c
new file mode 100644 (file)
index 0000000..13fff90
--- /dev/null
@@ -0,0 +1,732 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <ctype.h>
+#include "gdk/gdkkeysyms.h"
+#include "gtkmain.h"
+#include "gtkmenu.h"
+#include "gtkmenuitem.h"
+#include "gtksignal.h"
+
+
+#define MENU_ITEM_CLASS(w)  GTK_MENU_ITEM_CLASS (GTK_OBJECT (w)->klass)
+
+
+static void gtk_menu_class_init     (GtkMenuClass      *klass);
+static void gtk_menu_init           (GtkMenu           *menu);
+static void gtk_menu_show           (GtkWidget         *widget);
+static void gtk_menu_map            (GtkWidget         *widget);
+static void gtk_menu_unmap          (GtkWidget         *widget);
+static void gtk_menu_realize        (GtkWidget         *widget);
+static void gtk_menu_size_request   (GtkWidget         *widget,
+                                    GtkRequisition    *requisition);
+static void gtk_menu_size_allocate  (GtkWidget         *widget,
+                                    GtkAllocation     *allocation);
+static void gtk_menu_paint          (GtkWidget         *widget);
+static void gtk_menu_draw           (GtkWidget         *widget,
+                                    GdkRectangle      *area);
+static gint gtk_menu_expose         (GtkWidget         *widget,
+                                    GdkEventExpose    *event);
+static gint gtk_menu_configure      (GtkWidget         *widget,
+                                    GdkEventConfigure *event);
+static gint gtk_menu_key_press      (GtkWidget         *widget,
+                                    GdkEventKey       *event);
+static gint gtk_menu_need_resize    (GtkContainer      *container);
+static void gtk_menu_deactivate     (GtkMenuShell      *menu_shell);
+
+
+guint
+gtk_menu_get_type ()
+{
+  static guint menu_type = 0;
+
+  if (!menu_type)
+    {
+      GtkTypeInfo menu_info =
+      {
+       "GtkMenu",
+       sizeof (GtkMenu),
+       sizeof (GtkMenuClass),
+       (GtkClassInitFunc) gtk_menu_class_init,
+       (GtkObjectInitFunc) gtk_menu_init,
+       (GtkArgFunc) NULL,
+      };
+
+      menu_type = gtk_type_unique (gtk_menu_shell_get_type (), &menu_info);
+    }
+
+  return menu_type;
+}
+
+static void
+gtk_menu_class_init (GtkMenuClass *class)
+{
+  GtkWidgetClass *widget_class;
+  GtkContainerClass *container_class;
+  GtkMenuShellClass *menu_shell_class;
+
+  widget_class = (GtkWidgetClass*) class;
+  container_class = (GtkContainerClass*) class;
+  menu_shell_class = (GtkMenuShellClass*) class;
+
+  widget_class->show = gtk_menu_show;
+  widget_class->map = gtk_menu_map;
+  widget_class->unmap = gtk_menu_unmap;
+  widget_class->realize = gtk_menu_realize;
+  widget_class->draw = gtk_menu_draw;
+  widget_class->size_request = gtk_menu_size_request;
+  widget_class->size_allocate = gtk_menu_size_allocate;
+  widget_class->expose_event = gtk_menu_expose;
+  widget_class->configure_event = gtk_menu_configure;
+  widget_class->key_press_event = gtk_menu_key_press;
+
+  container_class->need_resize = gtk_menu_need_resize;
+
+  menu_shell_class->submenu_placement = GTK_LEFT_RIGHT;
+  menu_shell_class->deactivate = gtk_menu_deactivate;
+}
+
+static void
+gtk_menu_init (GtkMenu *menu)
+{
+  GTK_WIDGET_SET_FLAGS (menu, GTK_ANCHORED);
+
+  menu->parent_menu_item = NULL;
+  menu->old_active_menu_item = NULL;
+  menu->accelerator_table = NULL;
+  menu->position_func = NULL;
+  menu->position_func_data = NULL;
+
+  GTK_MENU_SHELL (menu)->menu_flag = TRUE;
+}
+
+GtkWidget*
+gtk_menu_new ()
+{
+  return GTK_WIDGET (gtk_type_new (gtk_menu_get_type ()));
+}
+
+void
+gtk_menu_append (GtkMenu   *menu,
+                GtkWidget *child)
+{
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), child);
+}
+
+void
+gtk_menu_prepend (GtkMenu   *menu,
+                 GtkWidget *child)
+{
+  gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), child);
+}
+
+void
+gtk_menu_insert (GtkMenu   *menu,
+                GtkWidget *child,
+                gint       position)
+{
+  gtk_menu_shell_insert (GTK_MENU_SHELL (menu), child, position);
+}
+
+void
+gtk_menu_popup (GtkMenu             *menu,
+               GtkWidget           *parent_menu_shell,
+               GtkWidget           *parent_menu_item,
+               GtkMenuPositionFunc  func,
+               gpointer             data,
+               gint                 button,
+               guint32              activate_time)
+{
+  g_return_if_fail (menu != NULL);
+  g_return_if_fail (GTK_IS_MENU (menu));
+
+  GTK_MENU_SHELL (menu)->parent_menu_shell = parent_menu_shell;
+  GTK_MENU_SHELL (menu)->active = TRUE;
+  GTK_MENU_SHELL (menu)->button = button;
+
+  menu->parent_menu_item = parent_menu_item;
+  menu->position_func = func;
+  menu->position_func_data = data;
+  GTK_MENU_SHELL (menu)->activate_time = activate_time;
+
+  gtk_widget_show (GTK_WIDGET (menu));
+  gtk_grab_add (GTK_WIDGET (menu));
+}
+
+void
+gtk_menu_popdown (GtkMenu *menu)
+{
+  GtkMenuShell *menu_shell;
+
+  g_return_if_fail (menu != NULL);
+  g_return_if_fail (GTK_IS_MENU (menu));
+
+  menu_shell = GTK_MENU_SHELL (menu);
+
+  menu_shell->parent_menu_shell = NULL;
+  menu_shell->active = FALSE;
+
+  if (menu_shell->active_menu_item)
+    {
+      menu->old_active_menu_item = menu_shell->active_menu_item;
+      gtk_menu_item_deselect (GTK_MENU_ITEM (menu_shell->active_menu_item));
+      menu_shell->active_menu_item = NULL;
+    }
+
+  gtk_widget_hide (GTK_WIDGET (menu));
+  gtk_grab_remove (GTK_WIDGET (menu));
+}
+
+GtkWidget*
+gtk_menu_get_active (GtkMenu *menu)
+{
+  GtkWidget *child;
+  GList *children;
+
+  g_return_val_if_fail (menu != NULL, NULL);
+  g_return_val_if_fail (GTK_IS_MENU (menu), NULL);
+
+  if (!menu->old_active_menu_item)
+    {
+      child = NULL;
+      children = GTK_MENU_SHELL (menu)->children;
+
+      while (children)
+       {
+         child = children->data;
+         children = children->next;
+
+         if (GTK_BIN (child)->child)
+           break;
+         child = NULL;
+       }
+
+      menu->old_active_menu_item = child;
+    }
+
+  return menu->old_active_menu_item;
+}
+
+void
+gtk_menu_set_active (GtkMenu *menu,
+                    gint     index)
+{
+  GtkWidget *child;
+  GList *tmp_list;
+
+  g_return_if_fail (menu != NULL);
+  g_return_if_fail (GTK_IS_MENU (menu));
+
+  tmp_list = g_list_nth (GTK_MENU_SHELL (menu)->children, index);
+  if (tmp_list)
+    {
+      child = tmp_list->data;
+      if (GTK_BIN (child)->child)
+       menu->old_active_menu_item = child;
+    }
+}
+
+void
+gtk_menu_set_accelerator_table (GtkMenu             *menu,
+                               GtkAcceleratorTable *table)
+{
+  g_return_if_fail (menu != NULL);
+  g_return_if_fail (GTK_IS_MENU (menu));
+
+  if (menu->accelerator_table)
+    gtk_accelerator_table_unref (menu->accelerator_table);
+
+  menu->accelerator_table = table;
+  if (menu->accelerator_table)
+    gtk_accelerator_table_ref (menu->accelerator_table);
+}
+
+
+static void
+gtk_menu_show (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MENU (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
+  gtk_widget_map (widget);
+}
+
+static void
+gtk_menu_map (GtkWidget *widget)
+{
+  GtkMenu *menu;
+  GtkMenuShell *menu_shell;
+  GtkWidget *child;
+  GList *children;
+  GtkAllocation allocation;
+  gint x, y;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MENU (widget));
+
+  menu = GTK_MENU (widget);
+  menu_shell = GTK_MENU_SHELL (widget);
+  GTK_WIDGET_SET_FLAGS (menu_shell, GTK_MAPPED);
+  GTK_WIDGET_UNSET_FLAGS (menu_shell, GTK_UNMAPPED);
+
+  gtk_widget_size_request (widget, &widget->requisition);
+
+  if (menu_shell->menu_flag)
+    {
+      menu_shell->menu_flag = FALSE;
+
+      allocation.x = widget->allocation.x;
+      allocation.y = widget->allocation.y;
+      allocation.width = widget->requisition.width;
+      allocation.height = widget->requisition.height;
+
+      gtk_widget_size_allocate (widget, &allocation);
+    }
+
+  gdk_window_get_pointer (NULL, &x, &y, NULL);
+
+  if (menu->position_func)
+    (* menu->position_func) (menu, &x, &y, menu->position_func_data);
+  else
+    {
+      gint screen_width;
+      gint screen_height;
+
+      screen_width = gdk_screen_width ();
+      screen_height = gdk_screen_height ();
+
+      x -= 2;
+      y -= 2;
+
+      if ((x + widget->requisition.width) > screen_width)
+       x -= ((x + widget->requisition.width) - screen_width);
+      if (x < 0)
+       x = 0;
+      if ((y + widget->requisition.height) > screen_height)
+       y -= ((y + widget->requisition.height) - screen_height);
+      if (y < 0)
+       y = 0;
+    }
+
+  gdk_window_move_resize (widget->window, x, y,
+                         widget->requisition.width,
+                         widget->requisition.height);
+
+  children = menu_shell->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (child) && !GTK_WIDGET_MAPPED (child))
+        gtk_widget_map (child);
+    }
+
+  gdk_window_show (widget->window);
+}
+
+static void
+gtk_menu_unmap (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MENU (widget));
+
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
+  GTK_WIDGET_SET_FLAGS (widget, GTK_UNMAPPED);
+  gdk_window_hide (widget->window);
+}
+
+static void
+gtk_menu_realize (GtkWidget *widget)
+{
+  GdkWindowAttr attributes;
+  gint attributes_mask;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MENU (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+
+  attributes.x = widget->allocation.x;
+  attributes.y = widget->allocation.y;
+  attributes.width = widget->allocation.width;
+  attributes.height = widget->allocation.height;
+  attributes.wclass = GDK_INPUT_OUTPUT;
+  attributes.visual = gtk_widget_get_visual (widget);
+  attributes.colormap = gtk_widget_get_colormap (widget);
+  attributes.window_type = GDK_WINDOW_TEMP;
+  attributes.event_mask = gtk_widget_get_events (widget);
+  attributes.event_mask |= (GDK_EXPOSURE_MASK |
+                           GDK_KEY_PRESS_MASK |
+                           GDK_STRUCTURE_MASK);
+
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+  widget->window = gdk_window_new (NULL, &attributes, attributes_mask);
+  gdk_window_set_user_data (widget->window, widget);
+
+  widget->style = gtk_style_attach (widget->style, widget->window);
+  gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
+}
+
+static void
+gtk_menu_size_request (GtkWidget      *widget,
+                      GtkRequisition *requisition)
+{
+  GtkMenu *menu;
+  GtkMenuShell *menu_shell;
+  GtkWidget *child;
+  GList *children;
+  gint max_accelerator_size;
+  gint max_toggle_size;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MENU (widget));
+  g_return_if_fail (requisition != NULL);
+
+  menu = GTK_MENU (widget);
+  menu_shell = GTK_MENU_SHELL (widget);
+
+  requisition->width = 0;
+  requisition->height = 0;
+
+  max_accelerator_size = 0;
+  max_toggle_size = 0;
+
+  children = menu_shell->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (child))
+       {
+         GTK_MENU_ITEM (child)->show_submenu_indicator = TRUE;
+         gtk_widget_size_request (child, &child->requisition);
+
+         requisition->width = MAX (requisition->width, child->requisition.width);
+         requisition->height += child->requisition.height;
+
+         max_accelerator_size = MAX (max_accelerator_size, GTK_MENU_ITEM (child)->accelerator_size);
+         max_toggle_size = MAX (max_toggle_size, MENU_ITEM_CLASS (child)->toggle_size);
+       }
+    }
+
+  requisition->width += max_toggle_size + max_accelerator_size;
+  requisition->width += (GTK_CONTAINER (menu)->border_width +
+                        widget->style->klass->xthickness) * 2;
+  requisition->height += (GTK_CONTAINER (menu)->border_width +
+                         widget->style->klass->ythickness) * 2;
+
+  children = menu_shell->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      GTK_MENU_ITEM (child)->accelerator_size = max_accelerator_size;
+      GTK_MENU_ITEM (child)->toggle_size = max_toggle_size;
+    }
+}
+
+static void
+gtk_menu_size_allocate (GtkWidget     *widget,
+                       GtkAllocation *allocation)
+{
+  GtkMenu *menu;
+  GtkMenuShell *menu_shell;
+  GtkWidget *child;
+  GtkAllocation child_allocation;
+  GList *children;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MENU (widget));
+  g_return_if_fail (allocation != NULL);
+
+  menu = GTK_MENU (widget);
+  menu_shell = GTK_MENU_SHELL (widget);
+
+  widget->allocation = *allocation;
+
+  if (menu_shell->children)
+    {
+      child_allocation.x = (GTK_CONTAINER (menu)->border_width +
+                           widget->style->klass->xthickness);
+      child_allocation.y = (GTK_CONTAINER (menu)->border_width +
+                           widget->style->klass->ythickness);
+      child_allocation.width = allocation->width - child_allocation.x * 2;
+
+      children = menu_shell->children;
+      while (children)
+       {
+         child = children->data;
+         children = children->next;
+
+         if (GTK_WIDGET_VISIBLE (child))
+           {
+             child_allocation.height = child->requisition.height;
+
+             gtk_widget_size_allocate (child, &child_allocation);
+
+             child_allocation.y += child_allocation.height;
+           }
+       }
+    }
+}
+
+static void
+gtk_menu_paint (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MENU (widget));
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      gtk_draw_shadow (widget->style,
+                      widget->window,
+                      GTK_STATE_NORMAL,
+                      GTK_SHADOW_OUT,
+                      0, 0,
+                      widget->allocation.width,
+                      widget->allocation.height);
+    }
+}
+
+static void
+gtk_menu_draw (GtkWidget    *widget,
+              GdkRectangle *area)
+{
+  GtkMenuShell *menu_shell;
+  GtkWidget *child;
+  GdkRectangle child_area;
+  GList *children;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MENU (widget));
+  g_return_if_fail (area != NULL);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      gtk_menu_paint (widget);
+
+      menu_shell = GTK_MENU_SHELL (widget);
+
+      children = menu_shell->children;
+      while (children)
+       {
+         child = children->data;
+         children = children->next;
+
+         if (gtk_widget_intersect (child, area, &child_area))
+           gtk_widget_draw (child, &child_area);
+       }
+    }
+}
+
+static gint
+gtk_menu_expose (GtkWidget      *widget,
+                GdkEventExpose *event)
+{
+  GtkMenuShell *menu_shell;
+  GtkWidget *child;
+  GdkEventExpose child_event;
+  GList *children;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_MENU (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (!GTK_WIDGET_UNMAPPED (widget))
+    GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      gtk_menu_paint (widget);
+
+      menu_shell = GTK_MENU_SHELL (widget);
+      child_event = *event;
+
+      children = menu_shell->children;
+      while (children)
+       {
+         child = children->data;
+         children = children->next;
+
+         if (GTK_WIDGET_NO_WINDOW (child) &&
+             gtk_widget_intersect (child, &event->area, &child_event.area))
+           gtk_widget_event (child, (GdkEvent*) &child_event);
+       }
+    }
+
+  return FALSE;
+}
+
+static gint
+gtk_menu_configure (GtkWidget         *widget,
+                   GdkEventConfigure *event)
+{
+  GtkAllocation allocation;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_MENU (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (GTK_MENU_SHELL (widget)->menu_flag)
+    {
+      GTK_MENU_SHELL (widget)->menu_flag = FALSE;
+
+      allocation.x = 0;
+      allocation.y = 0;
+      allocation.width = event->width;
+      allocation.height = event->height;
+
+      gtk_widget_size_allocate (widget, &allocation);
+    }
+
+  return FALSE;
+}
+
+static gint
+gtk_menu_key_press (GtkWidget   *widget,
+                   GdkEventKey *event)
+{
+  GtkAllocation allocation;
+  GtkAcceleratorTable *table;
+  GtkMenuShell *menu_shell;
+  GtkMenuItem *menu_item;
+  gchar *signame;
+  int delete;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_MENU (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  delete = ((event->keyval == GDK_Delete) ||
+           (event->keyval == GDK_BackSpace));
+
+  if (delete || ((event->keyval >= 0x20) && (event->keyval <= 0xFF)))
+    {
+      menu_shell = GTK_MENU_SHELL (widget);
+      menu_item = GTK_MENU_ITEM (menu_shell->active_menu_item);
+
+      if (menu_item && GTK_BIN (menu_item)->child)
+       {
+         /* block resizes */
+         gtk_container_block_resize (GTK_CONTAINER (widget));
+
+         table = NULL;
+         /* if the menu item currently has an accelerator then we'll
+          *  remove it before we do anything else.
+          */
+         if (menu_item->accelerator_signal)
+           {
+             signame = gtk_signal_name (menu_item->accelerator_signal);
+             table = gtk_accelerator_table_find (GTK_OBJECT (widget),
+                                                 signame,
+                                                 menu_item->accelerator_key,
+                                                 menu_item->accelerator_mods);
+             if (!table)
+               table = GTK_MENU (widget)->accelerator_table;
+             gtk_widget_remove_accelerator (GTK_WIDGET (menu_item),
+                                            table, signame);
+           }
+
+         if (!table)
+           table = GTK_MENU (widget)->accelerator_table;
+
+         /* if we aren't simply deleting the accelerator, then we'll install
+          *  the new one now.
+          */
+         if (!delete)
+           gtk_widget_install_accelerator (GTK_WIDGET (menu_item),
+                                           table, "activate",
+                                           toupper (event->keyval),
+                                           event->state);
+
+         /* check and see if the menu has changed size. */
+         gtk_widget_size_request (widget, &widget->requisition);
+
+         allocation.x = widget->allocation.x;
+         allocation.y = widget->allocation.y;
+         allocation.width = widget->requisition.width;
+         allocation.height = widget->requisition.height;
+
+         if ((allocation.width == widget->allocation.width) &&
+             (allocation.height == widget->allocation.height))
+           {
+             gtk_widget_queue_draw (widget);
+           }
+         else
+           {
+             gtk_widget_size_allocate (GTK_WIDGET (widget), &allocation);
+             gtk_menu_map (widget);
+           }
+
+         /* unblock resizes */
+         gtk_container_unblock_resize (GTK_CONTAINER (widget));
+       }
+    }
+
+  return FALSE;
+}
+
+static gint
+gtk_menu_need_resize (GtkContainer *container)
+{
+  GtkAllocation allocation;
+
+  g_return_val_if_fail (container != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_MENU (container), FALSE);
+
+  if (GTK_WIDGET_VISIBLE (container))
+    {
+      GTK_MENU_SHELL (container)->menu_flag = FALSE;
+
+      gtk_widget_size_request (GTK_WIDGET (container),
+                              &GTK_WIDGET (container)->requisition);
+
+      allocation.x = GTK_WIDGET (container)->allocation.x;
+      allocation.y = GTK_WIDGET (container)->allocation.y;
+      allocation.width = GTK_WIDGET (container)->requisition.width;
+      allocation.height = GTK_WIDGET (container)->requisition.height;
+
+      gtk_widget_size_allocate (GTK_WIDGET (container), &allocation);
+    }
+  else
+    {
+      GTK_MENU_SHELL (container)->menu_flag = TRUE;
+    }
+
+  return FALSE;
+}
+
+static void
+gtk_menu_deactivate (GtkMenuShell *menu_shell)
+{
+  GtkMenuShell *parent;
+
+  g_return_if_fail (menu_shell != NULL);
+  g_return_if_fail (GTK_IS_MENU (menu_shell));
+
+  parent = GTK_MENU_SHELL (menu_shell->parent_menu_shell);
+
+  menu_shell->activate_time = 0;
+  gtk_menu_popdown (GTK_MENU (menu_shell));
+
+  if (parent)
+    gtk_menu_shell_deactivate (parent);
+}
diff --git a/gtk/gtkmenu.h b/gtk/gtkmenu.h
new file mode 100644 (file)
index 0000000..5cd5d28
--- /dev/null
@@ -0,0 +1,94 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_MENU_H__
+#define __GTK_MENU_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkaccelerator.h>
+#include <gtk/gtkmenushell.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_MENU(obj)          GTK_CHECK_CAST (obj, gtk_menu_get_type (), GtkMenu)
+#define GTK_MENU_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_menu_get_type (), GtkMenuClass)
+#define GTK_IS_MENU(obj)       GTK_CHECK_TYPE (obj, gtk_menu_get_type ())
+
+
+typedef struct _GtkMenu       GtkMenu;
+typedef struct _GtkMenuClass  GtkMenuClass;
+
+typedef void (*GtkMenuPositionFunc) (GtkMenu  *menu,
+                                    gint     *x,
+                                    gint     *y,
+                                    gpointer  user_data);
+
+struct _GtkMenu
+{
+  GtkMenuShell menu_shell;
+
+  GList *children;
+
+  GtkWidget *parent_menu_item;
+  GtkWidget *old_active_menu_item;
+
+  GtkAcceleratorTable *accelerator_table;
+  GtkMenuPositionFunc position_func;
+  gpointer position_func_data;
+};
+
+struct _GtkMenuClass
+{
+  GtkMenuShellClass parent_class;
+};
+
+
+guint      gtk_menu_get_type              (void);
+GtkWidget* gtk_menu_new                   (void);
+void       gtk_menu_append                (GtkMenu             *menu,
+                                          GtkWidget           *child);
+void       gtk_menu_prepend               (GtkMenu             *menu,
+                                          GtkWidget           *child);
+void       gtk_menu_insert                (GtkMenu             *menu,
+                                          GtkWidget           *child,
+                                          gint                 position);
+void       gtk_menu_popup                 (GtkMenu             *menu,
+                                          GtkWidget           *parent_menu_shell,
+                                          GtkWidget           *parent_menu_item,
+                                          GtkMenuPositionFunc  func,
+                                          gpointer             data,
+                                          gint                 button,
+                                          guint32              activate_time);
+void       gtk_menu_popdown               (GtkMenu             *menu);
+GtkWidget* gtk_menu_get_active            (GtkMenu             *menu);
+void       gtk_menu_set_active            (GtkMenu             *menu,
+                                          gint                 index);
+void       gtk_menu_set_accelerator_table (GtkMenu             *menu,
+                                          GtkAcceleratorTable *table);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_MENU_H__ */
diff --git a/gtk/gtkmenubar.c b/gtk/gtkmenubar.c
new file mode 100644 (file)
index 0000000..19f0aa3
--- /dev/null
@@ -0,0 +1,310 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkmain.h"
+#include "gtkmenubar.h"
+#include "gtkmenuitem.h"
+
+
+#define BORDER_SPACING  2
+#define CHILD_SPACING   3
+
+
+static void gtk_menu_bar_class_init    (GtkMenuBarClass *klass);
+static void gtk_menu_bar_init          (GtkMenuBar      *menu_bar);
+static void gtk_menu_bar_size_request  (GtkWidget       *widget,
+                                       GtkRequisition  *requisition);
+static void gtk_menu_bar_size_allocate (GtkWidget       *widget,
+                                       GtkAllocation   *allocation);
+static void gtk_menu_bar_paint         (GtkWidget       *widget);
+static void gtk_menu_bar_draw          (GtkWidget       *widget,
+                                       GdkRectangle    *area);
+static gint gtk_menu_bar_expose        (GtkWidget       *widget,
+                                       GdkEventExpose  *event);
+
+
+guint
+gtk_menu_bar_get_type ()
+{
+  static guint menu_bar_type = 0;
+
+  if (!menu_bar_type)
+    {
+      GtkTypeInfo menu_bar_info =
+      {
+       "GtkMenuBar",
+       sizeof (GtkMenuBar),
+       sizeof (GtkMenuBarClass),
+       (GtkClassInitFunc) gtk_menu_bar_class_init,
+       (GtkObjectInitFunc) gtk_menu_bar_init,
+       (GtkArgFunc) NULL,
+      };
+
+      menu_bar_type = gtk_type_unique (gtk_menu_shell_get_type (), &menu_bar_info);
+    }
+
+  return menu_bar_type;
+}
+
+static void
+gtk_menu_bar_class_init (GtkMenuBarClass *class)
+{
+  GtkWidgetClass *widget_class;
+  GtkMenuShellClass *menu_shell_class;
+
+  widget_class = (GtkWidgetClass*) class;
+  menu_shell_class = (GtkMenuShellClass*) class;
+
+  widget_class->draw = gtk_menu_bar_draw;
+  widget_class->size_request = gtk_menu_bar_size_request;
+  widget_class->size_allocate = gtk_menu_bar_size_allocate;
+  widget_class->expose_event = gtk_menu_bar_expose;
+
+  menu_shell_class->submenu_placement = GTK_TOP_BOTTOM;
+}
+
+static void
+gtk_menu_bar_init (GtkMenuBar *menu_bar)
+{
+}
+
+GtkWidget*
+gtk_menu_bar_new ()
+{
+  return GTK_WIDGET (gtk_type_new (gtk_menu_bar_get_type ()));
+}
+
+void
+gtk_menu_bar_append (GtkMenuBar *menu_bar,
+                    GtkWidget  *child)
+{
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu_bar), child);
+}
+
+void
+gtk_menu_bar_prepend (GtkMenuBar *menu_bar,
+                     GtkWidget  *child)
+{
+  gtk_menu_shell_prepend (GTK_MENU_SHELL (menu_bar), child);
+}
+
+void
+gtk_menu_bar_insert (GtkMenuBar *menu_bar,
+                    GtkWidget  *child,
+                    gint        position)
+{
+  gtk_menu_shell_insert (GTK_MENU_SHELL (menu_bar), child, position);
+}
+
+
+static void
+gtk_menu_bar_size_request (GtkWidget      *widget,
+                          GtkRequisition *requisition)
+{
+  GtkMenuBar *menu_bar;
+  GtkMenuShell *menu_shell;
+  GtkWidget *child;
+  GList *children;
+  gint nchildren;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MENU_BAR (widget));
+  g_return_if_fail (requisition != NULL);
+
+  requisition->width = 0;
+  requisition->height = 0;
+
+  if (GTK_WIDGET_VISIBLE (widget))
+    {
+      menu_bar = GTK_MENU_BAR (widget);
+      menu_shell = GTK_MENU_SHELL (widget);
+
+      nchildren = 0;
+      children = menu_shell->children;
+
+      while (children)
+       {
+         child = children->data;
+         children = children->next;
+
+         if (GTK_WIDGET_VISIBLE (child))
+           {
+             GTK_MENU_ITEM (child)->show_submenu_indicator = FALSE;
+             gtk_widget_size_request (child, &child->requisition);
+
+             requisition->width += child->requisition.width;
+             requisition->height = MAX (requisition->height, child->requisition.height);
+
+             nchildren += 1;
+           }
+       }
+
+      requisition->width += (GTK_CONTAINER (menu_bar)->border_width +
+                            widget->style->klass->xthickness +
+                            BORDER_SPACING) * 2;
+      requisition->height += (GTK_CONTAINER (menu_bar)->border_width +
+                             widget->style->klass->ythickness +
+                             BORDER_SPACING) * 2;
+
+      if (nchildren > 0)
+       requisition->width += 2 * CHILD_SPACING * (nchildren - 1);
+    }
+}
+
+static void
+gtk_menu_bar_size_allocate (GtkWidget     *widget,
+                           GtkAllocation *allocation)
+{
+  GtkMenuBar *menu_bar;
+  GtkMenuShell *menu_shell;
+  GtkWidget *child;
+  GList *children;
+  GtkAllocation child_allocation;
+  guint offset;
+  
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MENU_BAR (widget));
+  g_return_if_fail (allocation != NULL);
+
+  menu_bar = GTK_MENU_BAR (widget);
+  menu_shell = GTK_MENU_SHELL (widget);
+
+  widget->allocation = *allocation;
+  if (GTK_WIDGET_REALIZED (widget))
+    gdk_window_move_resize (widget->window,
+                           allocation->x, allocation->y,
+                           allocation->width, allocation->height);
+
+  if (menu_shell->children)
+    {
+      child_allocation.x = (GTK_CONTAINER (menu_bar)->border_width +
+                           widget->style->klass->xthickness +
+                           BORDER_SPACING);
+      offset = child_allocation.x;     /* Window edge to menubar start */
+
+      child_allocation.y = (GTK_CONTAINER (menu_bar)->border_width +
+                           widget->style->klass->ythickness +
+                           BORDER_SPACING);
+      child_allocation.height = allocation->height - child_allocation.y * 2;
+
+      children = menu_shell->children;
+      while (children)
+       {
+         child = children->data;
+         children = children->next;
+
+         /* Support for the right justified help menu */
+         if ( (children == NULL) && (GTK_IS_MENU_ITEM(child))
+             && (GTK_MENU_ITEM(child)->right_justify)) {
+                 child_allocation.x = allocation->width -
+                         child_allocation.width - CHILD_SPACING - offset;
+         }
+         if (GTK_WIDGET_VISIBLE (child))
+           {
+             child_allocation.width = child->requisition.width;
+
+             gtk_widget_size_allocate (child, &child_allocation);
+
+             child_allocation.x += child_allocation.width + CHILD_SPACING * 2;
+           }
+       }
+    }
+}
+
+static void
+gtk_menu_bar_paint (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MENU_BAR (widget));
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      gtk_draw_shadow (widget->style,
+                      widget->window,
+                      GTK_STATE_NORMAL,
+                      GTK_SHADOW_OUT,
+                      0, 0,
+                      widget->allocation.width,
+                      widget->allocation.height);
+    }
+}
+
+static void
+gtk_menu_bar_draw (GtkWidget    *widget,
+                  GdkRectangle *area)
+{
+  GtkMenuShell *menu_shell;
+  GtkWidget *child;
+  GdkRectangle child_area;
+  GList *children;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MENU_BAR (widget));
+  g_return_if_fail (area != NULL);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      gtk_menu_bar_paint (widget);
+
+      menu_shell = GTK_MENU_SHELL (widget);
+
+      children = menu_shell->children;
+      while (children)
+       {
+         child = children->data;
+         children = children->next;
+
+         if (gtk_widget_intersect (child, area, &child_area))
+           gtk_widget_draw (child, &child_area);
+       }
+    }
+}
+
+static gint
+gtk_menu_bar_expose (GtkWidget      *widget,
+                    GdkEventExpose *event)
+{
+  GtkMenuShell *menu_shell;
+  GtkWidget *child;
+  GdkEventExpose child_event;
+  GList *children;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_MENU_BAR (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      gtk_menu_bar_paint (widget);
+
+      menu_shell = GTK_MENU_SHELL (widget);
+      child_event = *event;
+
+      children = menu_shell->children;
+      while (children)
+       {
+         child = children->data;
+         children = children->next;
+
+         if (GTK_WIDGET_NO_WINDOW (child) &&
+             gtk_widget_intersect (child, &event->area, &child_event.area))
+           gtk_widget_event (child, (GdkEvent*) &child_event);
+       }
+    }
+
+  return FALSE;
+}
diff --git a/gtk/gtkmenubar.h b/gtk/gtkmenubar.h
new file mode 100644 (file)
index 0000000..691e8f3
--- /dev/null
@@ -0,0 +1,66 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_MENU_BAR_H__
+#define __GTK_MENU_BAR_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkmenushell.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_MENU_BAR(obj)          GTK_CHECK_CAST (obj, gtk_menu_bar_get_type (), GtkMenuBar)
+#define GTK_MENU_BAR_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_menu_bar_get_type (), GtkMenuBarClass)
+#define GTK_IS_MENU_BAR(obj)       GTK_CHECK_TYPE (obj, gtk_menu_bar_get_type ())
+
+
+typedef struct _GtkMenuBar       GtkMenuBar;
+typedef struct _GtkMenuBarClass  GtkMenuBarClass;
+
+struct _GtkMenuBar
+{
+  GtkMenuShell menu_shell;
+};
+
+struct _GtkMenuBarClass
+{
+  GtkMenuShellClass parent_class;
+};
+
+
+guint      gtk_menu_bar_get_type (void);
+GtkWidget* gtk_menu_bar_new      (void);
+void       gtk_menu_bar_append   (GtkMenuBar *menu_bar,
+                                 GtkWidget  *child);
+void       gtk_menu_bar_prepend  (GtkMenuBar *menu_bar,
+                                 GtkWidget  *child);
+void       gtk_menu_bar_insert   (GtkMenuBar *menu_bar,
+                                 GtkWidget  *child,
+                                 gint        position);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_MENU_BAR_H__ */
diff --git a/gtk/gtkmenufactory.c b/gtk/gtkmenufactory.c
new file mode 100644 (file)
index 0000000..d6e9ea6
--- /dev/null
@@ -0,0 +1,541 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <string.h>
+#include "gtkcheckmenuitem.h"
+#include "gtkmenu.h"
+#include "gtkmenubar.h"
+#include "gtkmenufactory.h"
+#include "gtkmenuitem.h"
+#include "gtksignal.h"
+
+
+enum
+{
+  CREATE  = 1 << 0,
+  DESTROY = 1 << 1,
+  CHECK   = 1 << 2
+};
+
+
+static void         gtk_menu_factory_create            (GtkMenuFactory *factory,
+                                                       GtkMenuEntry   *entry,
+                                                       GtkWidget      *parent,
+                                                       const char     *path);
+static void         gtk_menu_factory_remove            (GtkMenuFactory *factory,
+                                                       GtkWidget      *parent,
+                                                       const char     *path);
+static GtkWidget*   gtk_menu_factory_make_widget       (GtkMenuFactory *factory);
+static GtkMenuPath* gtk_menu_factory_get               (GtkWidget      *parent,
+                                                       const char     *path,
+                                                       int             flags);
+static GtkMenuPath* gtk_menu_factory_find_recurse      (GtkMenuFactory *factory,
+                                                       GtkWidget      *parent,
+                                                       const char     *path);
+static void         gtk_menu_factory_parse_accelerator (const char     *accelerator,
+                                                       char     *accelerator_key,
+                                                       guint8         *accelerator_mods);
+
+
+GtkMenuFactory*
+gtk_menu_factory_new (GtkMenuFactoryType type)
+{
+  GtkMenuFactory *factory;
+
+  factory = g_new (GtkMenuFactory, 1);
+  factory->path = NULL;
+  factory->type = type;
+  factory->table = NULL;
+  factory->widget = NULL;
+  factory->subfactories = NULL;
+
+  return factory;
+}
+
+void
+gtk_menu_factory_destroy (GtkMenuFactory *factory)
+{
+  GtkMenuFactory *subfactory;
+  GList *tmp_list;
+
+  g_return_if_fail (factory != NULL);
+
+  if (factory->path)
+    g_free (factory->path);
+
+  tmp_list = factory->subfactories;
+  while (tmp_list)
+    {
+      subfactory = tmp_list->data;
+      tmp_list = tmp_list->next;
+
+      gtk_menu_factory_destroy (subfactory);
+    }
+}
+
+void
+gtk_menu_factory_add_entries (GtkMenuFactory *factory,
+                             GtkMenuEntry   *entries,
+                             int             nentries)
+{
+  int i;
+
+  g_return_if_fail (factory != NULL);
+  g_return_if_fail (entries != NULL);
+  g_return_if_fail (nentries > 0);
+
+  if (!factory->widget)
+    factory->widget = gtk_menu_factory_make_widget (factory);
+
+  for (i = 0; i < nentries; i++)
+    gtk_menu_factory_create (factory, &entries[i], factory->widget, entries[i].path);
+}
+
+void
+gtk_menu_factory_add_subfactory (GtkMenuFactory *factory,
+                                GtkMenuFactory *subfactory,
+                                const char     *path)
+{
+  g_return_if_fail (factory != NULL);
+  g_return_if_fail (subfactory != NULL);
+  g_return_if_fail (path != NULL);
+
+  if (subfactory->path)
+    g_free (subfactory->path);
+  subfactory->path = g_strdup (path);
+
+  factory->subfactories = g_list_append (factory->subfactories, subfactory);
+}
+
+void
+gtk_menu_factory_remove_paths (GtkMenuFactory  *factory,
+                              char           **paths,
+                              int              npaths)
+{
+  int i;
+
+  g_return_if_fail (factory != NULL);
+  g_return_if_fail (paths != NULL);
+  g_return_if_fail (npaths > 0);
+
+  if (factory->widget)
+    {
+      for (i = 0; i < npaths; i++)
+       gtk_menu_factory_remove (factory, factory->widget, paths[i]);
+    }
+}
+
+void
+gtk_menu_factory_remove_entries (GtkMenuFactory *factory,
+                                GtkMenuEntry   *entries,
+                                int             nentries)
+{
+  int i;
+
+  g_return_if_fail (factory != NULL);
+  g_return_if_fail (entries != NULL);
+  g_return_if_fail (nentries > 0);
+
+  if (factory->widget)
+    {
+      for (i = 0; i < nentries; i++)
+       gtk_menu_factory_remove (factory, factory->widget, entries[i].path);
+    }
+}
+
+void
+gtk_menu_factory_remove_subfactory (GtkMenuFactory *factory,
+                                   GtkMenuFactory *subfactory,
+                                   const char     *path)
+{
+  g_return_if_fail (factory != NULL);
+  g_return_if_fail (subfactory != NULL);
+  g_return_if_fail (path != NULL);
+
+  g_warning ("FIXME: gtk_menu_factory_remove_subfactory");
+}
+
+GtkMenuPath*
+gtk_menu_factory_find (GtkMenuFactory *factory,
+                      const char     *path)
+{
+  g_return_val_if_fail (factory != NULL, NULL);
+  g_return_val_if_fail (path != NULL, NULL);
+
+  return gtk_menu_factory_find_recurse (factory, factory->widget, path);
+}
+
+
+static void
+gtk_menu_factory_create (GtkMenuFactory *factory,
+                        GtkMenuEntry   *entry,
+                        GtkWidget      *parent,
+                        const char     *path)
+{
+  GtkMenuFactory *subfactory;
+  GtkMenuPath *menu_path;
+  GtkWidget *menu;
+  GList *tmp_list;
+  char tmp_path[256];
+  char accelerator_key;
+  guint8 accelerator_mods;
+  char *p;
+
+  g_return_if_fail (factory != NULL);
+  g_return_if_fail (entry != NULL);
+
+  /* If 'path' is empty, then simply return.
+   */
+  if (!path || path[0] == '\0')
+    return;
+
+  /* Strip off the next part of the path.
+   */
+  p = strchr (path, '/');
+
+  /* If this is the last part of the path ('p' is
+   *  NULL), then we create an item.
+   */
+  if (!p)
+    {
+      /* Check to see if this item is a separator.
+       */
+      if (strcmp (path, "<separator>") == 0)
+       {
+         entry->widget = gtk_menu_item_new ();
+         gtk_container_add (GTK_CONTAINER (parent), entry->widget);
+         gtk_widget_show (entry->widget);
+       }
+      else
+       {
+         if (strncmp (path, "<check>", 7) == 0)
+           menu_path = gtk_menu_factory_get (parent, path + 7, CREATE | CHECK);
+         else
+           menu_path = gtk_menu_factory_get (parent, path, CREATE);
+         entry->widget = menu_path->widget;
+
+         if (strcmp (path, "<nothing>") == 0)
+           gtk_widget_hide (entry->widget);
+
+         if (entry->accelerator)
+           {
+             gtk_menu_factory_parse_accelerator (entry->accelerator,
+                                                 &accelerator_key,
+                                                 &accelerator_mods);
+             if (!factory->table)
+               {
+                 factory->table = gtk_accelerator_table_new ();
+                 gtk_accelerator_table_ref (factory->table);
+               }
+
+             gtk_widget_install_accelerator (menu_path->widget,
+                                             factory->table,
+                                             "activate",
+                                             accelerator_key,
+                                             accelerator_mods);
+           }
+
+         if (entry->callback)
+           gtk_signal_connect (GTK_OBJECT (menu_path->widget), "activate",
+                               (GtkSignalFunc) entry->callback,
+                               entry->callback_data);
+       }
+    }
+  else
+    {
+      strncpy (tmp_path, path, (unsigned int) ((long) p - (long) path));
+      tmp_path[(long) p - (long) path] = '\0';
+
+      menu_path = gtk_menu_factory_get (parent, tmp_path, 0);
+      if (!menu_path)
+       {
+         tmp_list = factory->subfactories;
+         while (tmp_list)
+           {
+             subfactory = tmp_list->data;
+             tmp_list = tmp_list->next;
+
+             if (subfactory->path &&
+                 (strcmp (subfactory->path, tmp_path) == 0))
+               {
+                 if (!subfactory->widget)
+                   subfactory->widget = gtk_menu_factory_make_widget (subfactory);
+                 gtk_menu_factory_create (subfactory, entry, subfactory->widget, p + 1);
+                 return;
+               }
+           }
+
+         menu_path = gtk_menu_factory_get (parent, tmp_path, CREATE);
+       }
+
+      entry->widget = menu_path->widget;
+      menu = GTK_MENU_ITEM (menu_path->widget)->submenu;
+
+      if (!menu)
+       {
+         menu = gtk_menu_new ();
+         gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_path->widget), menu);
+
+         if (!factory->table)
+           {
+             factory->table = gtk_accelerator_table_new ();
+             gtk_accelerator_table_ref (factory->table);
+           }
+         gtk_menu_set_accelerator_table (GTK_MENU (menu), factory->table);
+       }
+
+      gtk_menu_factory_create (factory, entry, menu, p + 1);
+    }
+}
+
+static void
+gtk_menu_factory_remove (GtkMenuFactory *factory,
+                        GtkWidget      *parent,
+                        const char     *path)
+{
+  GtkMenuFactory *subfactory;
+  GtkMenuPath *menu_path;
+  GtkWidget *menu;
+  GList *tmp_list;
+  char tmp_path[256];
+  char *p;
+
+  if (!path || path[0] == '\0')
+    return;
+
+  p = strchr (path, '/');
+
+  if (!p)
+    {
+      if (parent)
+       gtk_menu_factory_get (parent, path, DESTROY);
+    }
+  else
+    {
+      strncpy (tmp_path, path, (unsigned int) ((long) p - (long) path));
+      tmp_path[(long) p - (long) path] = '\0';
+
+      menu_path = gtk_menu_factory_get (parent, tmp_path, 0);
+      if (!menu_path)
+       {
+         tmp_list = factory->subfactories;
+         while (tmp_list)
+           {
+             subfactory = tmp_list->data;
+             tmp_list = tmp_list->next;
+
+             if (subfactory->path &&
+                 (strcmp (subfactory->path, tmp_path) == 0))
+               {
+                 if (!subfactory->widget)
+                   return;
+                 gtk_menu_factory_remove (subfactory, subfactory->widget, p + 1);
+               }
+           }
+       }
+      else
+       {
+         menu = GTK_MENU_ITEM (menu_path->widget)->submenu;
+         if (menu)
+           gtk_menu_factory_remove (factory, menu, p + 1);
+       }
+    }
+}
+
+static GtkWidget*
+gtk_menu_factory_make_widget (GtkMenuFactory *factory)
+{
+  GtkWidget *widget;
+
+  g_return_val_if_fail (factory != NULL, NULL);
+
+  switch (factory->type)
+    {
+    case GTK_MENU_FACTORY_MENU:
+      widget = gtk_menu_new ();
+
+      if (!factory->table)
+       {
+         factory->table = gtk_accelerator_table_new ();
+         gtk_accelerator_table_ref (factory->table);
+       }
+      gtk_menu_set_accelerator_table (GTK_MENU (widget), factory->table);
+      return widget;
+    case GTK_MENU_FACTORY_MENU_BAR:
+      return gtk_menu_bar_new ();
+    case GTK_MENU_FACTORY_OPTION_MENU:
+      g_error ("not implemented");
+      break;
+    }
+
+  return NULL;
+}
+
+static GtkMenuPath*
+gtk_menu_factory_get (GtkWidget *parent,
+                     const char *path,
+                     int        flags)
+{
+  GtkMenuPath *menu_path;
+  GList *tmp_list;
+
+  tmp_list = gtk_object_get_user_data (GTK_OBJECT (parent));
+  while (tmp_list)
+    {
+      menu_path = tmp_list->data;
+      tmp_list = tmp_list->next;
+
+      if (strcmp (menu_path->path, path) == 0)
+       {
+         if (flags & DESTROY)
+           {
+             tmp_list = gtk_object_get_user_data (GTK_OBJECT (parent));
+             tmp_list = g_list_remove (tmp_list, menu_path);
+             gtk_object_set_user_data (GTK_OBJECT (parent), tmp_list);
+
+             gtk_widget_destroy (menu_path->widget);
+             g_free (menu_path->path);
+             g_free (menu_path);
+
+             return NULL;
+           }
+         else
+           {
+             return menu_path;
+           }
+       }
+    }
+
+  if (flags & CREATE)
+    {
+      menu_path = g_new (GtkMenuPath, 1);
+      menu_path->path = g_strdup (path);
+
+      if (flags & CHECK)
+       menu_path->widget = gtk_check_menu_item_new_with_label (path);
+      else
+       menu_path->widget = gtk_menu_item_new_with_label (path);
+
+      gtk_container_add (GTK_CONTAINER (parent), menu_path->widget);
+      gtk_object_set_user_data (GTK_OBJECT (menu_path->widget), NULL);
+      gtk_widget_show (menu_path->widget);
+
+      tmp_list = gtk_object_get_user_data (GTK_OBJECT (parent));
+      tmp_list = g_list_prepend (tmp_list, menu_path);
+      gtk_object_set_user_data (GTK_OBJECT (parent), tmp_list);
+
+      return menu_path;
+    }
+
+  return NULL;
+}
+
+static GtkMenuPath*
+gtk_menu_factory_find_recurse (GtkMenuFactory *factory,
+                              GtkWidget      *parent,
+                              const char     *path)
+{
+  GtkMenuFactory *subfactory;
+  GtkMenuPath *menu_path;
+  GtkWidget *menu;
+  GList *tmp_list;
+  char tmp_path[256];
+  char *p;
+
+  if (!path || path[0] == '\0')
+    return NULL;
+
+  p = strchr (path, '/');
+
+  if (!p)
+    {
+      if (parent)
+       return gtk_menu_factory_get (parent, path, 0);
+    }
+  else
+    {
+      strncpy (tmp_path, path, (unsigned int) ((long) p - (long) path));
+      tmp_path[(long) p - (long) path] = '\0';
+
+      menu_path = gtk_menu_factory_get (parent, tmp_path, 0);
+      if (!menu_path)
+       {
+         tmp_list = factory->subfactories;
+         while (tmp_list)
+           {
+             subfactory = tmp_list->data;
+             tmp_list = tmp_list->next;
+
+             if (subfactory->path &&
+                 (strcmp (subfactory->path, tmp_path) == 0))
+               {
+                 if (!subfactory->widget)
+                   return NULL;
+                 return gtk_menu_factory_find_recurse (subfactory, subfactory->widget, p + 1);
+               }
+           }
+
+         return NULL;
+       }
+
+      menu = GTK_MENU_ITEM (menu_path->widget)->submenu;
+      if (menu)
+       return gtk_menu_factory_find_recurse (factory, menu, p + 1);
+    }
+
+  return NULL;
+}
+
+static void
+gtk_menu_factory_parse_accelerator (const char   *accelerator,
+                                    char   *accelerator_key,
+                                   guint8 *accelerator_mods)
+{
+  int done;
+
+  g_return_if_fail (accelerator != NULL);
+  g_return_if_fail (accelerator_key != NULL);
+  g_return_if_fail (accelerator_mods != NULL);
+
+  *accelerator_key = 0;
+  *accelerator_mods = 0;
+
+  done = FALSE;
+  while (!done)
+    {
+      if (strncmp (accelerator, "<shift>", 7) == 0)
+        {
+          accelerator += 7;
+          *accelerator_mods |= GDK_SHIFT_MASK;
+        }
+      else if (strncmp (accelerator, "<alt>", 5) == 0)
+        {
+          accelerator += 5;
+          *accelerator_mods |= GDK_MOD1_MASK;
+        }
+      else if (strncmp (accelerator, "<control>", 9) == 0)
+        {
+          accelerator += 9;
+          *accelerator_mods |= GDK_CONTROL_MASK;
+        }
+      else
+        {
+          done = TRUE;
+          *accelerator_key = accelerator[0];
+        }
+    }
+}
diff --git a/gtk/gtkmenufactory.h b/gtk/gtkmenufactory.h
new file mode 100644 (file)
index 0000000..d95fdb7
--- /dev/null
@@ -0,0 +1,88 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_MENU_FACTORY_H__
+#define __GTK_MENU_FACTORY_H__
+
+
+#include <gtk/gtkwidget.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+typedef struct _GtkMenuEntry    GtkMenuEntry;
+typedef struct _GtkMenuPath     GtkMenuPath;
+typedef struct _GtkMenuFactory  GtkMenuFactory;
+
+typedef void (*GtkMenuCallback) (GtkWidget *widget,
+                                gpointer   user_data);
+
+struct _GtkMenuEntry
+{
+  char *path;
+  char *accelerator;
+  GtkMenuCallback callback;
+  gpointer callback_data;
+  GtkWidget *widget;
+};
+
+struct _GtkMenuPath
+{
+  char *path;
+  GtkWidget *widget;
+};
+
+struct _GtkMenuFactory
+{
+  char *path;
+  GtkMenuFactoryType type;
+  GtkAcceleratorTable *table;
+  GtkWidget *widget;
+  GList *subfactories;
+};
+
+
+GtkMenuFactory* gtk_menu_factory_new               (GtkMenuFactoryType  type);
+void            gtk_menu_factory_destroy           (GtkMenuFactory     *factory);
+void            gtk_menu_factory_add_entries       (GtkMenuFactory     *factory,
+                                                   GtkMenuEntry       *entries,
+                                                   int                 nentries);
+void            gtk_menu_factory_add_subfactory    (GtkMenuFactory     *factory,
+                                                   GtkMenuFactory     *subfactory,
+                                                   const char         *path);
+void            gtk_menu_factory_remove_paths      (GtkMenuFactory     *factory,
+                                                   char              **paths,
+                                                   int                 npaths);
+void            gtk_menu_factory_remove_entries    (GtkMenuFactory     *factory,
+                                                   GtkMenuEntry       *entries,
+                                                   int                 nentries);
+void            gtk_menu_factory_remove_subfactory (GtkMenuFactory     *factory,
+                                                   GtkMenuFactory     *subfactory,
+                                                   const char         *path);
+GtkMenuPath*    gtk_menu_factory_find              (GtkMenuFactory     *factory,
+                                                   const char         *path);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_MENU_FACTORY_H__ */
diff --git a/gtk/gtkmenuitem.c b/gtk/gtkmenuitem.c
new file mode 100644 (file)
index 0000000..f7715fb
--- /dev/null
@@ -0,0 +1,746 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <string.h>
+#include "gtklabel.h"
+#include "gtkmain.h"
+#include "gtkmenu.h"
+#include "gtkmenuitem.h"
+#include "gtksignal.h"
+
+
+#define BORDER_SPACING  3
+#define SELECT_TIMEOUT  20
+
+#define MENU_ITEM_CLASS(w)  GTK_MENU_ITEM_CLASS (GTK_OBJECT (w)->klass)
+
+
+enum {
+  ACTIVATE,
+  LAST_SIGNAL
+};
+
+
+static void gtk_menu_item_class_init     (GtkMenuItemClass *klass);
+static void gtk_menu_item_init           (GtkMenuItem      *menu_item);
+static void gtk_menu_item_destroy        (GtkObject        *object);
+static void gtk_menu_item_size_request   (GtkWidget        *widget,
+                                         GtkRequisition   *requisition);
+static void gtk_menu_item_size_allocate  (GtkWidget        *widget,
+                                         GtkAllocation    *allocation);
+static gint gtk_menu_item_install_accel  (GtkWidget        *widget,
+                                         const gchar      *signal_name,
+                                         gchar             key,
+                                         guint8            modifiers);
+static void gtk_menu_item_remove_accel   (GtkWidget        *widget,
+                                         const gchar      *signal_name);
+static void gtk_menu_item_paint          (GtkWidget        *widget,
+                                         GdkRectangle     *area);
+static void gtk_menu_item_draw           (GtkWidget        *widget,
+                                         GdkRectangle     *area);
+static gint gtk_menu_item_expose         (GtkWidget        *widget,
+                                         GdkEventExpose   *event);
+static gint gtk_menu_item_enter          (GtkWidget        *widget,
+                                         GdkEventCrossing *event);
+static gint gtk_menu_item_leave          (GtkWidget        *widget,
+                                         GdkEventCrossing *event);
+static void gtk_real_menu_item_select    (GtkItem          *item);
+static void gtk_real_menu_item_deselect  (GtkItem          *item);
+static gint gtk_menu_item_select_timeout (gpointer          data);
+static void gtk_menu_item_position_menu  (GtkMenu          *menu,
+                                         gint             *x,
+                                         gint             *y,
+                                         gpointer          user_data);
+
+static GtkItemClass *parent_class;
+static gint menu_item_signals[LAST_SIGNAL] = { 0 };
+
+
+guint
+gtk_menu_item_get_type ()
+{
+  static guint menu_item_type = 0;
+
+  if (!menu_item_type)
+    {
+      GtkTypeInfo menu_item_info =
+      {
+       "GtkMenuItem",
+       sizeof (GtkMenuItem),
+       sizeof (GtkMenuItemClass),
+       (GtkClassInitFunc) gtk_menu_item_class_init,
+       (GtkObjectInitFunc) gtk_menu_item_init,
+       (GtkArgFunc) NULL,
+      };
+
+      menu_item_type = gtk_type_unique (gtk_item_get_type (), &menu_item_info);
+    }
+
+  return menu_item_type;
+}
+
+static void
+gtk_menu_item_class_init (GtkMenuItemClass *klass)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+  GtkItemClass *item_class;
+
+  object_class = (GtkObjectClass*) klass;
+  widget_class = (GtkWidgetClass*) klass;
+  item_class = (GtkItemClass*) klass;
+
+  parent_class = gtk_type_class (gtk_item_get_type ());
+
+  menu_item_signals[ACTIVATE] =
+    gtk_signal_new ("activate",
+                    GTK_RUN_FIRST,
+                    object_class->type,
+                    GTK_SIGNAL_OFFSET (GtkMenuItemClass, activate),
+                    gtk_signal_default_marshaller,
+                   GTK_TYPE_NONE, 0);
+
+  gtk_object_class_add_signals (object_class, menu_item_signals, LAST_SIGNAL);
+
+  object_class->destroy = gtk_menu_item_destroy;
+
+  widget_class->activate_signal = menu_item_signals[ACTIVATE];
+  widget_class->size_request = gtk_menu_item_size_request;
+  widget_class->size_allocate = gtk_menu_item_size_allocate;
+  widget_class->install_accelerator = gtk_menu_item_install_accel;
+  widget_class->remove_accelerator = gtk_menu_item_remove_accel;
+  widget_class->draw = gtk_menu_item_draw;
+  widget_class->expose_event = gtk_menu_item_expose;
+  widget_class->enter_notify_event = gtk_menu_item_enter;
+  widget_class->leave_notify_event = gtk_menu_item_leave;
+
+  item_class->select = gtk_real_menu_item_select;
+  item_class->deselect = gtk_real_menu_item_deselect;
+
+  klass->activate = NULL;
+
+  klass->toggle_size = 0;
+  klass->shift_text = "Shft";
+  klass->control_text = "Ctl";
+  klass->alt_text = "Alt";
+  klass->separator_text = "+";
+}
+
+static void
+gtk_menu_item_init (GtkMenuItem *menu_item)
+{
+  menu_item->submenu = NULL;
+  menu_item->accelerator_key = 0;
+  menu_item->accelerator_mods = 0;
+  menu_item->accelerator_size = 0;
+  menu_item->accelerator_signal = 0;
+  menu_item->toggle_size = 0;
+  menu_item->show_toggle_indicator = FALSE;
+  menu_item->show_submenu_indicator = FALSE;
+  menu_item->submenu_direction = GTK_DIRECTION_RIGHT;
+  menu_item->submenu_placement = GTK_TOP_BOTTOM;
+  menu_item->right_justify = FALSE;
+
+  menu_item->timer = 0;
+}
+
+GtkWidget*
+gtk_menu_item_new ()
+{
+  return GTK_WIDGET (gtk_type_new (gtk_menu_item_get_type ()));
+}
+
+GtkWidget*
+gtk_menu_item_new_with_label (const gchar *label)
+{
+  GtkWidget *menu_item;
+  GtkWidget *label_widget;
+
+  menu_item = gtk_menu_item_new ();
+  label_widget = gtk_label_new (label);
+  gtk_misc_set_alignment (GTK_MISC (label_widget), 0.0, 0.5);
+
+  gtk_container_add (GTK_CONTAINER (menu_item), label_widget);
+  gtk_widget_show (label_widget);
+
+  return menu_item;
+}
+
+static void
+gtk_menu_item_destroy (GtkObject *object)
+{
+  GtkMenuItem *menu_item;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_MENU_ITEM (object));
+
+  menu_item = GTK_MENU_ITEM (object);
+
+  if (menu_item->submenu)
+    {
+      gtk_object_unref (GTK_OBJECT (menu_item->submenu));
+      /* gtk_widget_destroy (menu_item->submenu); */
+    }
+
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+void
+gtk_menu_item_set_submenu (GtkMenuItem *menu_item,
+                          GtkWidget   *submenu)
+{
+  g_return_if_fail (menu_item != NULL);
+  g_return_if_fail (GTK_IS_MENU_ITEM (menu_item));
+
+  if (menu_item->submenu)
+    {
+      g_return_if_fail (!GTK_WIDGET_VISIBLE (menu_item->submenu));
+      gtk_object_unref (GTK_OBJECT (menu_item->submenu));
+    }
+
+  menu_item->submenu = submenu;
+
+  if (menu_item->submenu)
+    gtk_object_ref (GTK_OBJECT (menu_item->submenu));
+
+  if (GTK_WIDGET (menu_item)->parent)
+    gtk_widget_queue_resize (GTK_WIDGET (menu_item));
+}
+
+void
+gtk_menu_item_set_placement (GtkMenuItem         *menu_item,
+                            GtkSubmenuPlacement  placement)
+{
+  g_return_if_fail (menu_item != NULL);
+  g_return_if_fail (GTK_IS_MENU_ITEM (menu_item));
+
+  menu_item->submenu_placement = placement;
+}
+
+void
+gtk_menu_item_accelerator_size (GtkMenuItem *menu_item)
+{
+  char buf[32];
+
+  g_return_if_fail (menu_item != NULL);
+  g_return_if_fail (GTK_IS_MENU_ITEM (menu_item));
+
+  if (menu_item->accelerator_key)
+    {
+      gtk_menu_item_accelerator_text (menu_item, buf);
+      menu_item->accelerator_size = gdk_string_width (GTK_WIDGET (menu_item)->style->font, buf) + 13;
+    }
+  else if (menu_item->submenu && menu_item->show_submenu_indicator)
+    {
+      menu_item->accelerator_size = 21;
+    }
+  else
+    {
+      menu_item->accelerator_size = 0;
+    }
+}
+
+void
+gtk_menu_item_accelerator_text (GtkMenuItem *menu_item,
+                               gchar       *buffer)
+{
+  g_return_if_fail (menu_item != NULL);
+  g_return_if_fail (GTK_IS_MENU_ITEM (menu_item));
+
+  if (menu_item->accelerator_key)
+    {
+      buffer[0] = '\0';
+      if (menu_item->accelerator_mods & GDK_SHIFT_MASK)
+       {
+         strcat (buffer, MENU_ITEM_CLASS (menu_item)->shift_text);
+         strcat (buffer, MENU_ITEM_CLASS (menu_item)->separator_text);
+       }
+      if (menu_item->accelerator_mods & GDK_CONTROL_MASK)
+       {
+         strcat (buffer, MENU_ITEM_CLASS (menu_item)->control_text);
+         strcat (buffer, MENU_ITEM_CLASS (menu_item)->separator_text);
+       }
+      if (menu_item->accelerator_mods & GDK_MOD1_MASK)
+       {
+         strcat (buffer, MENU_ITEM_CLASS (menu_item)->alt_text);
+         strcat (buffer, MENU_ITEM_CLASS (menu_item)->separator_text);
+       }
+      strncat (buffer, &menu_item->accelerator_key, 1);
+    }
+}
+
+void
+gtk_menu_item_configure (GtkMenuItem *menu_item,
+                        gint         show_toggle_indicator,
+                        gint         show_submenu_indicator)
+{
+  g_return_if_fail (menu_item != NULL);
+  g_return_if_fail (GTK_IS_MENU_ITEM (menu_item));
+
+  menu_item->show_toggle_indicator = (show_toggle_indicator == TRUE);
+  menu_item->show_submenu_indicator = (show_submenu_indicator == TRUE);
+}
+
+void
+gtk_menu_item_select (GtkMenuItem *menu_item)
+{
+  gtk_item_select (GTK_ITEM (menu_item));
+}
+
+void
+gtk_menu_item_deselect (GtkMenuItem *menu_item)
+{
+  gtk_item_deselect (GTK_ITEM (menu_item));
+}
+
+void
+gtk_menu_item_activate (GtkMenuItem *menu_item)
+{
+  gtk_signal_emit (GTK_OBJECT (menu_item), menu_item_signals[ACTIVATE]);
+}
+
+
+static void
+gtk_menu_item_size_request (GtkWidget      *widget,
+                           GtkRequisition *requisition)
+{
+  GtkBin *bin;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MENU_ITEM (widget));
+  g_return_if_fail (requisition != NULL);
+
+  bin = GTK_BIN (widget);
+
+  gtk_menu_item_accelerator_size (GTK_MENU_ITEM (widget));
+
+  requisition->width = (GTK_CONTAINER (widget)->border_width +
+                       widget->style->klass->xthickness +
+                       BORDER_SPACING) * 2;
+  requisition->height = (GTK_CONTAINER (widget)->border_width +
+                        widget->style->klass->ythickness) * 2;
+
+  if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
+    {
+      gtk_widget_size_request (bin->child, &bin->child->requisition);
+
+      requisition->width += bin->child->requisition.width;
+      requisition->height += bin->child->requisition.height;
+    }
+}
+
+static void
+gtk_menu_item_size_allocate (GtkWidget     *widget,
+                            GtkAllocation *allocation)
+{
+  GtkBin *bin;
+  GtkAllocation child_allocation;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MENU_ITEM (widget));
+  g_return_if_fail (allocation != NULL);
+
+  widget->allocation = *allocation;
+  if (GTK_WIDGET_REALIZED (widget))
+    gdk_window_move_resize (widget->window,
+                            allocation->x, allocation->y,
+                            allocation->width, allocation->height);
+
+  bin = GTK_BIN (widget);
+
+  if (bin->child)
+    {
+      child_allocation.x = (GTK_CONTAINER (widget)->border_width +
+                            widget->style->klass->xthickness +
+                           BORDER_SPACING);
+      child_allocation.y = GTK_CONTAINER (widget)->border_width;
+      child_allocation.width = allocation->width - child_allocation.x * 2;
+      child_allocation.height = allocation->height - child_allocation.y * 2;
+      child_allocation.x += GTK_MENU_ITEM (widget)->toggle_size;
+      child_allocation.width -= (GTK_MENU_ITEM (widget)->toggle_size +
+                                GTK_MENU_ITEM (widget)->accelerator_size);
+
+      gtk_widget_size_allocate (bin->child, &child_allocation);
+    }
+}
+
+static gint
+gtk_menu_item_install_accel (GtkWidget   *widget,
+                            const gchar *signal_name,
+                            gchar        key,
+                            guint8       modifiers)
+{
+  GtkMenuItem *menu_item;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_MENU_ITEM (widget), FALSE);
+  g_return_val_if_fail (signal_name != NULL, FALSE);
+
+  menu_item = GTK_MENU_ITEM (widget);
+
+  menu_item->accelerator_signal = gtk_signal_lookup (signal_name, GTK_OBJECT_TYPE (widget));
+  if (menu_item->accelerator_signal > 0)
+    {
+      menu_item->accelerator_key = key;
+      menu_item->accelerator_mods = modifiers;
+
+      if (widget->parent)
+       gtk_widget_queue_resize (widget);
+
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+static void
+gtk_menu_item_remove_accel (GtkWidget   *widget,
+                           const gchar *signal_name)
+{
+  GtkMenuItem *menu_item;
+  gint signal_num;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MENU_ITEM (widget));
+  g_return_if_fail (signal_name != NULL);
+
+  menu_item = GTK_MENU_ITEM (widget);
+
+  signal_num = gtk_signal_lookup (signal_name, GTK_OBJECT_TYPE (widget));
+  if (menu_item->accelerator_signal == signal_num)
+    {
+      menu_item->accelerator_key = 0;
+      menu_item->accelerator_mods = 0;
+      menu_item->accelerator_signal = 0;
+
+      if (GTK_WIDGET_VISIBLE (widget))
+       {
+         gtk_widget_queue_draw (widget);
+         GTK_MENU_SHELL (widget->parent)->menu_flag = TRUE;
+       }
+      else
+       gtk_container_need_resize (GTK_CONTAINER (widget->parent));
+    }
+}
+
+static void
+gtk_menu_item_paint (GtkWidget    *widget,
+                    GdkRectangle *area)
+{
+  GtkMenuItem *menu_item;
+  GtkStateType state_type;
+  GtkShadowType shadow_type;
+  GdkFont *font;
+  gint width, height;
+  gint x, y;
+  char buf[32];
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MENU_ITEM (widget));
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      menu_item = GTK_MENU_ITEM (widget);
+
+      state_type = widget->state;
+      if (!GTK_WIDGET_IS_SENSITIVE (widget))
+       state_type = GTK_STATE_INSENSITIVE;
+
+      gtk_style_set_background (widget->style, widget->window, state_type);
+      gdk_window_clear_area (widget->window, area->x, area->y, area->width, area->height);
+
+      x = GTK_CONTAINER (menu_item)->border_width;
+      y = GTK_CONTAINER (menu_item)->border_width;
+      width = widget->allocation.width - x * 2;
+      height = widget->allocation.height - y * 2;
+
+      if ((state_type == GTK_STATE_PRELIGHT) &&
+         (GTK_BIN (menu_item)->child))
+       gtk_draw_shadow (widget->style,
+                        widget->window,
+                        GTK_STATE_PRELIGHT,
+                        GTK_SHADOW_OUT,
+                        x, y, width, height);
+
+      if (menu_item->accelerator_key)
+       {
+         gtk_menu_item_accelerator_text (menu_item, buf);
+
+         font = widget->style->font;
+         x = x + width - menu_item->accelerator_size + 13 - 4;
+         y = y + ((height - (font->ascent + font->descent)) / 2) + font->ascent;
+
+         if (state_type == GTK_STATE_INSENSITIVE)
+           gdk_draw_string (widget->window, widget->style->font,
+                            widget->style->white_gc,
+                            x + 1, y + 1, buf);
+
+         gdk_draw_string (widget->window, widget->style->font,
+                          widget->style->fg_gc[state_type],
+                          x, y, buf);
+       }
+      else if (menu_item->submenu && menu_item->show_submenu_indicator)
+       {
+         shadow_type = GTK_SHADOW_OUT;
+         if (state_type == GTK_STATE_PRELIGHT)
+           shadow_type = GTK_SHADOW_IN;
+
+         gtk_draw_arrow (widget->style, widget->window,
+                         state_type, shadow_type, GTK_ARROW_RIGHT, FALSE,
+                         x + width - 15, y + height / 2 - 5, 10, 10);
+       }
+      else if (!GTK_BIN (menu_item)->child)
+       {
+         gtk_draw_hline (widget->style, widget->window, GTK_STATE_NORMAL,
+                         0, widget->allocation.width, 0);
+       }
+    }
+}
+
+static void
+gtk_menu_item_draw (GtkWidget    *widget,
+                   GdkRectangle *area)
+{
+  GtkBin *bin;
+  GdkRectangle child_area;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MENU_ITEM (widget));
+  g_return_if_fail (area != NULL);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      gtk_menu_item_paint (widget, area);
+
+      bin = GTK_BIN (widget);
+
+      if (bin->child)
+        {
+          if (gtk_widget_intersect (bin->child, area, &child_area))
+            gtk_widget_draw (bin->child, &child_area);
+        }
+    }
+}
+
+static gint
+gtk_menu_item_expose (GtkWidget      *widget,
+                     GdkEventExpose *event)
+{
+  GtkBin *bin;
+  GdkEventExpose child_event;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_MENU_ITEM (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      gtk_menu_item_paint (widget, &event->area);
+
+      bin = GTK_BIN (widget);
+
+      if (bin->child)
+        {
+          child_event = *event;
+
+          if (GTK_WIDGET_NO_WINDOW (bin->child) &&
+              gtk_widget_intersect (bin->child, &event->area, &child_event.area))
+            gtk_widget_event (bin->child, (GdkEvent*) &child_event);
+        }
+    }
+
+  return FALSE;
+}
+
+static gint
+gtk_menu_item_enter (GtkWidget        *widget,
+                    GdkEventCrossing *event)
+{
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_MENU_ITEM (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  return gtk_widget_event (widget->parent, (GdkEvent*) event);
+}
+
+static gint
+gtk_menu_item_leave (GtkWidget        *widget,
+                    GdkEventCrossing *event)
+{
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_MENU_ITEM (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  return gtk_widget_event (widget->parent, (GdkEvent*) event);
+}
+
+static void
+gtk_real_menu_item_select (GtkItem *item)
+{
+  GtkMenuItem *menu_item;
+
+  g_return_if_fail (item != NULL);
+  g_return_if_fail (GTK_IS_MENU_ITEM (item));
+
+  menu_item = GTK_MENU_ITEM (item);
+
+  if (menu_item->submenu && !GTK_WIDGET_VISIBLE (menu_item->submenu))
+    menu_item->timer = gtk_timeout_add (SELECT_TIMEOUT, gtk_menu_item_select_timeout, menu_item);
+
+  gtk_widget_set_state (GTK_WIDGET (menu_item), GTK_STATE_PRELIGHT);
+  gtk_widget_draw (GTK_WIDGET (menu_item), NULL);
+}
+
+static void
+gtk_real_menu_item_deselect (GtkItem *item)
+{
+  GtkMenuItem *menu_item;
+
+  g_return_if_fail (item != NULL);
+  g_return_if_fail (GTK_IS_MENU_ITEM (item));
+
+  menu_item = GTK_MENU_ITEM (item);
+
+  if (menu_item->submenu)
+    {
+      if (menu_item->timer)
+       gtk_timeout_remove (menu_item->timer);
+      else
+       gtk_menu_popdown (GTK_MENU (menu_item->submenu));
+    }
+
+  gtk_widget_set_state (GTK_WIDGET (menu_item), GTK_STATE_NORMAL);
+  gtk_widget_draw (GTK_WIDGET (menu_item), NULL);
+}
+
+static gint
+gtk_menu_item_select_timeout (gpointer data)
+{
+  GtkMenuItem *menu_item;
+
+  menu_item = GTK_MENU_ITEM (data);
+  menu_item->timer = 0;
+
+  gtk_menu_popup (GTK_MENU (menu_item->submenu),
+                 GTK_WIDGET (menu_item)->parent,
+                 GTK_WIDGET (menu_item),
+                 gtk_menu_item_position_menu,
+                 menu_item,
+                 GTK_MENU_SHELL (GTK_WIDGET (menu_item)->parent)->button,
+                 0);
+
+  return FALSE;
+}
+
+static void
+gtk_menu_item_position_menu (GtkMenu  *menu,
+                            gint     *x,
+                            gint     *y,
+                            gpointer  user_data)
+{
+  GtkMenuItem *menu_item;
+  GtkMenuItem *parent_menu_item;
+  gint screen_width;
+  gint screen_height;
+  gint twidth, theight;
+  gint tx, ty;
+
+  g_return_if_fail (menu != NULL);
+  g_return_if_fail (x != NULL);
+  g_return_if_fail (y != NULL);
+
+  menu_item = GTK_MENU_ITEM (user_data);
+
+  twidth = GTK_WIDGET (menu)->requisition.width;
+  theight = GTK_WIDGET (menu)->requisition.height;
+
+  screen_width = gdk_screen_width ();
+  screen_height = gdk_screen_height ();
+
+  g_return_if_fail (gdk_window_get_origin (GTK_WIDGET (menu_item)->window, &tx, &ty));
+
+  switch (menu_item->submenu_placement)
+    {
+    case GTK_TOP_BOTTOM:
+      if ((ty + GTK_WIDGET (menu_item)->allocation.height + theight) <= screen_height)
+       ty += GTK_WIDGET (menu_item)->allocation.height;
+      else if ((ty - theight) >= 0)
+       ty -= theight;
+      else
+       ty += GTK_WIDGET (menu_item)->allocation.height;
+
+      if ((tx + twidth) > screen_width)
+       {
+         tx -= ((tx + twidth) - screen_width);
+         if (tx < 0)
+           tx = 0;
+       }
+      break;
+
+    case GTK_LEFT_RIGHT:
+      menu_item->submenu_direction = GTK_DIRECTION_RIGHT;
+      parent_menu_item = GTK_MENU_ITEM (GTK_MENU (GTK_WIDGET (menu_item)->parent)->parent_menu_item);
+      if (parent_menu_item)
+       menu_item->submenu_direction = parent_menu_item->submenu_direction;
+
+      switch (menu_item->submenu_direction)
+       {
+       case GTK_DIRECTION_LEFT:
+         if ((tx - twidth) >= 0)
+           tx -= twidth;
+         else
+           {
+             menu_item->submenu_direction = GTK_DIRECTION_RIGHT;
+             tx += GTK_WIDGET (menu_item)->allocation.width - 5;
+           }
+         break;
+
+       case GTK_DIRECTION_RIGHT:
+         if ((tx + GTK_WIDGET (menu_item)->allocation.width + twidth - 5) <= screen_width)
+           tx += GTK_WIDGET (menu_item)->allocation.width - 5;
+         else
+           {
+             menu_item->submenu_direction = GTK_DIRECTION_LEFT;
+             tx -= twidth;
+           }
+         break;
+       }
+
+      if ((ty + GTK_WIDGET (menu_item)->allocation.height / 4 + theight) <= screen_height)
+       ty += GTK_WIDGET (menu_item)->allocation.height / 4;
+      else
+       {
+         ty -= ((ty + theight) - screen_height);
+         if (ty < 0)
+           ty = 0;
+       }
+      break;
+    }
+
+  *x = tx;
+  *y = ty;
+}
+
+void
+gtk_menu_item_right_justify(GtkMenuItem *menuitem)
+{
+  g_return_if_fail (menuitem != NULL);
+  g_return_if_fail (GTK_IS_MENU_ITEM (menuitem));
+
+  menuitem->right_justify = 1;
+}
diff --git a/gtk/gtkmenuitem.h b/gtk/gtkmenuitem.h
new file mode 100644 (file)
index 0000000..da51681
--- /dev/null
@@ -0,0 +1,98 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_MENU_ITEM_H__
+#define __GTK_MENU_ITEM_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkitem.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_MENU_ITEM(obj)          GTK_CHECK_CAST (obj, gtk_menu_item_get_type (), GtkMenuItem)
+#define GTK_MENU_ITEM_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_menu_item_get_type (), GtkMenuItemClass)
+#define GTK_IS_MENU_ITEM(obj)       GTK_CHECK_TYPE (obj, gtk_menu_item_get_type ())
+
+
+typedef struct _GtkMenuItem       GtkMenuItem;
+typedef struct _GtkMenuItemClass  GtkMenuItemClass;
+
+struct _GtkMenuItem
+{
+  GtkItem item;
+
+  GtkWidget *submenu;
+
+  gint    accelerator_signal;
+  gchar   accelerator_key;
+  guint8  accelerator_mods;
+  guint16 accelerator_size;
+  guint16 toggle_size;
+
+  guint show_toggle_indicator : 1;
+  guint show_submenu_indicator : 1;
+  guint submenu_placement : 1;
+  guint submenu_direction : 1;
+  guint right_justify: 1;
+  gint timer;
+};
+
+struct _GtkMenuItemClass
+{
+  GtkItemClass parent_class;
+
+  gint toggle_size;
+
+  gchar *shift_text;
+  gchar *control_text;
+  gchar *alt_text;
+  gchar *separator_text;
+
+  void (* activate) (GtkMenuItem *menu_item);
+};
+
+
+guint      gtk_menu_item_get_type         (void);
+GtkWidget* gtk_menu_item_new              (void);
+GtkWidget* gtk_menu_item_new_with_label   (const gchar         *label);
+void       gtk_menu_item_set_submenu      (GtkMenuItem         *menu_item,
+                                          GtkWidget           *submenu);
+void       gtk_menu_item_set_placement    (GtkMenuItem         *menu_item,
+                                          GtkSubmenuPlacement  placement);
+void       gtk_menu_item_accelerator_size (GtkMenuItem         *menu_item);
+void       gtk_menu_item_accelerator_text (GtkMenuItem         *menu_item,
+                                          gchar               *buffer);
+void       gtk_menu_item_configure        (GtkMenuItem         *menu_item,
+                                          gint                 show_toggle_indicator,
+                                          gint                 show_submenu_indicator);
+void       gtk_menu_item_select           (GtkMenuItem         *menu_item);
+void       gtk_menu_item_deselect         (GtkMenuItem         *menu_item);
+void       gtk_menu_item_activate         (GtkMenuItem         *menu_item);
+void       gtk_menu_item_right_justify    (GtkMenuItem         *menu_item);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_MENU_ITEM_H__ */
diff --git a/gtk/gtkmenushell.c b/gtk/gtkmenushell.c
new file mode 100644 (file)
index 0000000..6d3de5a
--- /dev/null
@@ -0,0 +1,633 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkmain.h"
+#include "gtkmenuitem.h"
+#include "gtkmenushell.h"
+#include "gtksignal.h"
+
+
+#define MENU_SHELL_TIMEOUT   500
+#define MENU_SHELL_CLASS(w)  GTK_MENU_SHELL_CLASS (GTK_OBJECT (w)->klass)
+
+
+enum {
+  DEACTIVATE,
+  LAST_SIGNAL
+};
+
+
+static void gtk_menu_shell_class_init        (GtkMenuShellClass *klass);
+static void gtk_menu_shell_init              (GtkMenuShell      *menu_shell);
+static void gtk_menu_shell_destroy           (GtkObject         *object);
+static void gtk_menu_shell_map               (GtkWidget         *widget);
+static void gtk_menu_shell_realize           (GtkWidget         *widget);
+static gint gtk_menu_shell_button_press      (GtkWidget         *widget,
+                                             GdkEventButton    *event);
+static gint gtk_menu_shell_button_release    (GtkWidget         *widget,
+                                             GdkEventButton    *event);
+static gint gtk_menu_shell_enter_notify      (GtkWidget         *widget,
+                                             GdkEventCrossing  *event);
+static gint gtk_menu_shell_leave_notify      (GtkWidget         *widget,
+                                             GdkEventCrossing  *event);
+static void gtk_menu_shell_add               (GtkContainer      *container,
+                                             GtkWidget         *widget);
+static void gtk_menu_shell_remove            (GtkContainer      *container,
+                                             GtkWidget         *widget);
+static void gtk_menu_shell_foreach           (GtkContainer      *container,
+                                             GtkCallback        callback,
+                                             gpointer           callback_data);
+static void gtk_real_menu_shell_deactivate   (GtkMenuShell      *menu_shell);
+static gint gtk_menu_shell_is_item           (GtkMenuShell      *menu_shell,
+                                             GtkWidget         *child);
+
+
+static GtkContainerClass *parent_class = NULL;
+static gint menu_shell_signals[LAST_SIGNAL] = { 0 };
+
+
+guint
+gtk_menu_shell_get_type ()
+{
+  static guint menu_shell_type = 0;
+
+  if (!menu_shell_type)
+    {
+      GtkTypeInfo menu_shell_info =
+      {
+       "GtkMenuShell",
+       sizeof (GtkMenuShell),
+       sizeof (GtkMenuShellClass),
+       (GtkClassInitFunc) gtk_menu_shell_class_init,
+       (GtkObjectInitFunc) gtk_menu_shell_init,
+       (GtkArgFunc) NULL,
+      };
+
+      menu_shell_type = gtk_type_unique (gtk_container_get_type (), &menu_shell_info);
+    }
+
+  return menu_shell_type;
+}
+
+static void
+gtk_menu_shell_class_init (GtkMenuShellClass *klass)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+  GtkContainerClass *container_class;
+
+  object_class = (GtkObjectClass*) klass;
+  widget_class = (GtkWidgetClass*) klass;
+  container_class = (GtkContainerClass*) klass;
+
+  parent_class = gtk_type_class (gtk_container_get_type ());
+
+  menu_shell_signals[DEACTIVATE] =
+    gtk_signal_new ("deactivate",
+                    GTK_RUN_FIRST,
+                    object_class->type,
+                    GTK_SIGNAL_OFFSET (GtkMenuShellClass, deactivate),
+                    gtk_signal_default_marshaller,
+                   GTK_TYPE_NONE, 0);
+
+  gtk_object_class_add_signals (object_class, menu_shell_signals, LAST_SIGNAL);
+
+  object_class->destroy = gtk_menu_shell_destroy;
+
+  widget_class->map = gtk_menu_shell_map;
+  widget_class->realize = gtk_menu_shell_realize;
+  widget_class->button_press_event = gtk_menu_shell_button_press;
+  widget_class->button_release_event = gtk_menu_shell_button_release;
+  widget_class->enter_notify_event = gtk_menu_shell_enter_notify;
+  widget_class->leave_notify_event = gtk_menu_shell_leave_notify;
+
+  container_class->add = gtk_menu_shell_add;
+  container_class->remove = gtk_menu_shell_remove;
+  container_class->foreach = gtk_menu_shell_foreach;
+
+  klass->submenu_placement = GTK_TOP_BOTTOM;
+  klass->deactivate = gtk_real_menu_shell_deactivate;
+}
+
+static void
+gtk_menu_shell_init (GtkMenuShell *menu_shell)
+{
+  menu_shell->children = NULL;
+  menu_shell->active_menu_item = NULL;
+  menu_shell->parent_menu_shell = NULL;
+  menu_shell->active = FALSE;
+  menu_shell->have_grab = FALSE;
+  menu_shell->have_xgrab = FALSE;
+  menu_shell->ignore_leave = FALSE;
+  menu_shell->button = 0;
+  menu_shell->menu_flag = 0;
+  menu_shell->activate_time = 0;
+}
+
+void
+gtk_menu_shell_append (GtkMenuShell *menu_shell,
+                      GtkWidget    *child)
+{
+  gtk_menu_shell_insert (menu_shell, child, -1);
+}
+
+void
+gtk_menu_shell_prepend (GtkMenuShell *menu_shell,
+                       GtkWidget    *child)
+{
+  gtk_menu_shell_insert (menu_shell, child, 0);
+}
+
+void
+gtk_menu_shell_insert (GtkMenuShell *menu_shell,
+                      GtkWidget    *child,
+                      gint          position)
+{
+  GList *tmp_list;
+  GList *new_list;
+  gint nchildren;
+
+  g_return_if_fail (menu_shell != NULL);
+  g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell));
+  g_return_if_fail (child != NULL);
+  g_return_if_fail (GTK_IS_MENU_ITEM (child));
+
+  gtk_widget_set_parent (child, GTK_WIDGET (menu_shell));
+
+  if (GTK_WIDGET_VISIBLE (child->parent))
+    {
+      if (GTK_WIDGET_REALIZED (child->parent) &&
+         !GTK_WIDGET_REALIZED (child))
+       gtk_widget_realize (child);
+
+      if (GTK_WIDGET_MAPPED (child->parent) &&
+         !GTK_WIDGET_MAPPED (child))
+       gtk_widget_map (child);
+    }
+
+  nchildren = g_list_length (menu_shell->children);
+  if ((position < 0) || (position > nchildren))
+    position = nchildren;
+
+  if (position == nchildren)
+    {
+      menu_shell->children = g_list_append (menu_shell->children, child);
+    }
+  else
+    {
+      tmp_list = g_list_nth (menu_shell->children, position);
+      new_list = g_list_alloc ();
+      new_list->data = child;
+
+      if (tmp_list->prev)
+       tmp_list->prev->next = new_list;
+      new_list->next = tmp_list;
+      new_list->prev = tmp_list->prev;
+      tmp_list->prev = new_list;
+
+      if (tmp_list == menu_shell->children)
+       menu_shell->children = new_list;
+    }
+
+  if (GTK_WIDGET_VISIBLE (menu_shell))
+    gtk_widget_queue_resize (GTK_WIDGET (menu_shell));
+}
+
+void
+gtk_menu_shell_deactivate (GtkMenuShell *menu_shell)
+{
+  g_return_if_fail (menu_shell != NULL);
+  g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell));
+
+  gtk_signal_emit (GTK_OBJECT (menu_shell), menu_shell_signals[DEACTIVATE]);
+}
+
+static void
+gtk_menu_shell_destroy (GtkObject *object)
+{
+  GtkMenuShell *menu_shell;
+  GtkWidget *child;
+  GList *children;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_MENU_SHELL (object));
+
+  menu_shell = GTK_MENU_SHELL (object);
+
+  children = menu_shell->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      child->parent = NULL;
+      gtk_object_unref (GTK_OBJECT (child));
+      gtk_widget_destroy (child);
+    }
+
+  g_list_free (menu_shell->children);
+
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+gtk_menu_shell_map (GtkWidget *widget)
+{
+  GtkMenuShell *menu_shell;
+  GtkWidget *child;
+  GList *children;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MENU_SHELL (widget));
+
+  menu_shell = GTK_MENU_SHELL (widget);
+  GTK_WIDGET_SET_FLAGS (menu_shell, GTK_MAPPED);
+  gdk_window_show (widget->window);
+
+  children = menu_shell->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (child) && !GTK_WIDGET_MAPPED (child))
+       gtk_widget_map (child);
+    }
+}
+
+static void
+gtk_menu_shell_realize (GtkWidget *widget)
+{
+  GdkWindowAttr attributes;
+  gint attributes_mask;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MENU_SHELL (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+
+  attributes.x = widget->allocation.x;
+  attributes.y = widget->allocation.y;
+  attributes.width = widget->allocation.width;
+  attributes.height = widget->allocation.height;
+  attributes.window_type = GDK_WINDOW_CHILD;
+  attributes.wclass = GDK_INPUT_OUTPUT;
+  attributes.visual = gtk_widget_get_visual (widget);
+  attributes.colormap = gtk_widget_get_colormap (widget);
+  attributes.event_mask = gtk_widget_get_events (widget);
+  attributes.event_mask |= (GDK_EXPOSURE_MASK |
+                           GDK_BUTTON_PRESS_MASK |
+                           GDK_BUTTON_RELEASE_MASK |
+                           GDK_ENTER_NOTIFY_MASK |
+                           GDK_LEAVE_NOTIFY_MASK);
+
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+  widget->window = gdk_window_new (widget->parent->window, &attributes, attributes_mask);
+  gdk_window_set_user_data (widget->window, widget);
+
+  widget->style = gtk_style_attach (widget->style, widget->window);
+  gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
+}
+
+static gint
+gtk_menu_shell_button_press (GtkWidget      *widget,
+                            GdkEventButton *event)
+{
+  GtkMenuShell *menu_shell;
+  GtkWidget *menu_item;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_MENU_SHELL (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (event->type != GDK_BUTTON_PRESS)
+    return FALSE;
+
+  menu_shell = GTK_MENU_SHELL (widget);
+
+  if (menu_shell->parent_menu_shell)
+    {
+      gtk_widget_event (menu_shell->parent_menu_shell, (GdkEvent*) event);
+    }
+  else if (!menu_shell->active || !menu_shell->button)
+    {
+      if (!menu_shell->active)
+       {
+         gtk_grab_add (GTK_WIDGET (widget));
+         menu_shell->have_grab = TRUE;
+       }
+      menu_shell->active = TRUE;
+
+      menu_item = gtk_get_event_widget ((GdkEvent*) event);
+      if (GTK_IS_MENU_ITEM (menu_item) && gtk_menu_shell_is_item (menu_shell, menu_item))
+       {
+         if ((menu_item->parent == widget) &&
+             (menu_item != menu_shell->active_menu_item))
+           {
+             if (menu_shell->active_menu_item)
+               gtk_menu_item_deselect (GTK_MENU_ITEM (menu_shell->active_menu_item));
+
+             menu_shell->active_menu_item = menu_item;
+             gtk_menu_item_set_placement (GTK_MENU_ITEM (menu_shell->active_menu_item),
+                                          MENU_SHELL_CLASS (menu_shell)->submenu_placement);
+             gtk_menu_item_select (GTK_MENU_ITEM (menu_shell->active_menu_item));
+           }
+       }
+      else if (!menu_shell->button)
+       {
+         gtk_menu_shell_deactivate (menu_shell);
+       }
+
+      if (menu_shell->active)
+       menu_shell->button = event->button;
+    }
+  else
+    {
+      widget = gtk_get_event_widget ((GdkEvent*) event);
+      if (widget == GTK_WIDGET (menu_shell))
+       gtk_menu_shell_deactivate (menu_shell);
+    }
+
+  return TRUE;
+}
+
+static gint
+gtk_menu_shell_button_release (GtkWidget      *widget,
+                              GdkEventButton *event)
+{
+  GtkMenuShell *menu_shell;
+  GtkWidget *menu_item;
+  gint deactivate;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_MENU_SHELL (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  menu_shell = GTK_MENU_SHELL (widget);
+  if (menu_shell->active)
+    {
+      if (menu_shell->button && (event->button != menu_shell->button))
+       {
+         menu_shell->button = 0;
+         if (menu_shell->parent_menu_shell)
+           gtk_widget_event (menu_shell->parent_menu_shell, (GdkEvent*) event);
+         return TRUE;
+       }
+
+      menu_shell->button = 0;
+      menu_item = gtk_get_event_widget ((GdkEvent*) event);
+      deactivate = TRUE;
+
+      if ((event->time - menu_shell->activate_time) > MENU_SHELL_TIMEOUT)
+       {
+         if (menu_shell->active_menu_item == menu_item)
+           {
+             if (GTK_MENU_ITEM (menu_item)->submenu == NULL)
+               {
+                 gtk_menu_shell_deactivate (menu_shell);
+                 gtk_widget_activate (menu_item);
+                 return TRUE;
+               }
+           }
+         else if (menu_shell->parent_menu_shell)
+           {
+             menu_shell->active = TRUE;
+             gtk_widget_event (menu_shell->parent_menu_shell, (GdkEvent*) event);
+             return TRUE;
+           }
+       }
+      else
+       deactivate = FALSE;
+
+      if ((!deactivate || (menu_shell->active_menu_item == menu_item)) &&
+         (gdk_pointer_grab (widget->window, TRUE,
+                            GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
+                            GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK,
+                            NULL, NULL, event->time) == 0))
+       {
+         deactivate = FALSE;
+         menu_shell->have_xgrab = TRUE;
+         menu_shell->ignore_leave = TRUE;
+       }
+      else
+       deactivate = TRUE;
+
+      if (deactivate)
+       gtk_menu_shell_deactivate (menu_shell);
+    }
+
+  return TRUE;
+}
+
+static gint
+gtk_menu_shell_enter_notify (GtkWidget        *widget,
+                            GdkEventCrossing *event)
+{
+  GtkMenuShell *menu_shell;
+  GtkWidget *menu_item;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_MENU_SHELL (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  menu_shell = GTK_MENU_SHELL (widget);
+  if (menu_shell->active)
+    {
+      menu_item = gtk_get_event_widget ((GdkEvent*) event);
+
+      if (!GTK_WIDGET_IS_SENSITIVE (menu_item))
+       return TRUE;
+
+      if ((menu_item->parent == widget) &&
+         (menu_shell->active_menu_item != menu_item) &&
+         GTK_IS_MENU_ITEM (menu_item))
+       {
+         if ((event->detail != GDK_NOTIFY_INFERIOR) &&
+             (GTK_WIDGET_STATE (menu_item) != GTK_STATE_PRELIGHT))
+           {
+             if (menu_shell->active_menu_item)
+               gtk_menu_item_deselect (GTK_MENU_ITEM (menu_shell->active_menu_item));
+
+             menu_shell->active_menu_item = menu_item;
+             gtk_menu_item_set_placement (GTK_MENU_ITEM (menu_shell->active_menu_item),
+                                          MENU_SHELL_CLASS (menu_shell)->submenu_placement);
+             gtk_menu_item_select (GTK_MENU_ITEM (menu_shell->active_menu_item));
+           }
+       }
+      else if (menu_shell->parent_menu_shell)
+       {
+         gtk_widget_event (menu_shell->parent_menu_shell, (GdkEvent*) event);
+       }
+    }
+
+  return TRUE;
+}
+
+static gint
+gtk_menu_shell_leave_notify (GtkWidget        *widget,
+                            GdkEventCrossing *event)
+{
+  GtkMenuShell *menu_shell;
+  GtkMenuItem *menu_item;
+  GtkWidget *event_widget;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_MENU_SHELL (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (GTK_WIDGET_VISIBLE (widget))
+    {
+      menu_shell = GTK_MENU_SHELL (widget);
+      event_widget = gtk_get_event_widget ((GdkEvent*) event);
+
+      if (!GTK_IS_MENU_ITEM (event_widget))
+       return TRUE;
+
+      menu_item = GTK_MENU_ITEM (event_widget);
+
+      if (!GTK_WIDGET_IS_SENSITIVE (menu_item))
+       return TRUE;
+
+      if (menu_shell->ignore_leave)
+       {
+         menu_shell->ignore_leave = FALSE;
+         return TRUE;
+       }
+
+      if ((menu_shell->active_menu_item == event_widget) &&
+         (menu_item->submenu == NULL))
+       {
+         if ((event->detail != GDK_NOTIFY_INFERIOR) &&
+             (GTK_WIDGET_STATE (menu_item) != GTK_STATE_NORMAL))
+           {
+             gtk_menu_item_deselect (GTK_MENU_ITEM (menu_shell->active_menu_item));
+             menu_shell->active_menu_item = NULL;
+           }
+       }
+      else if (menu_shell->parent_menu_shell)
+       {
+         gtk_widget_event (menu_shell->parent_menu_shell, (GdkEvent*) event);
+       }
+    }
+
+  return TRUE;
+}
+
+static void
+gtk_menu_shell_add (GtkContainer *container,
+                   GtkWidget    *widget)
+{
+  gtk_menu_shell_append (GTK_MENU_SHELL (container), widget);
+}
+
+static void
+gtk_menu_shell_remove (GtkContainer *container,
+                      GtkWidget    *widget)
+{
+  GtkMenuShell *menu_shell;
+
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_MENU_SHELL (container));
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MENU_ITEM (widget));
+
+  gtk_widget_unparent (widget);
+
+  menu_shell = GTK_MENU_SHELL (container);
+  menu_shell->children = g_list_remove (menu_shell->children, widget);
+
+  if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
+    gtk_widget_queue_resize (GTK_WIDGET (container));
+}
+
+static void
+gtk_menu_shell_foreach (GtkContainer *container,
+                       GtkCallback   callback,
+                       gpointer      callback_data)
+{
+  GtkMenuShell *menu_shell;
+  GtkWidget *child;
+  GList *children;
+
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_MENU_SHELL (container));
+  g_return_if_fail (callback != NULL);
+
+  menu_shell = GTK_MENU_SHELL (container);
+
+  children = menu_shell->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      (* callback) (child, callback_data);
+    }
+}
+
+
+static void
+gtk_real_menu_shell_deactivate (GtkMenuShell *menu_shell)
+{
+  g_return_if_fail (menu_shell != NULL);
+  g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell));
+
+  if (menu_shell->active)
+    {
+      menu_shell->button = 0;
+      menu_shell->active = FALSE;
+
+      if (menu_shell->active_menu_item)
+       {
+         gtk_menu_item_deselect (GTK_MENU_ITEM (menu_shell->active_menu_item));
+         menu_shell->active_menu_item = NULL;
+       }
+
+      if (menu_shell->have_grab)
+       {
+         menu_shell->have_grab = FALSE;
+         gtk_grab_remove (GTK_WIDGET (menu_shell));
+       }
+      if (menu_shell->have_xgrab)
+       {
+         menu_shell->have_xgrab = FALSE;
+         gdk_pointer_ungrab (GDK_CURRENT_TIME);
+       }
+    }
+}
+
+static gint
+gtk_menu_shell_is_item (GtkMenuShell *menu_shell,
+                       GtkWidget    *child)
+{
+  GtkMenuShell *parent;
+
+  g_return_val_if_fail (menu_shell != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_MENU_SHELL (menu_shell), FALSE);
+  g_return_val_if_fail (child != NULL, FALSE);
+
+  parent = GTK_MENU_SHELL (child->parent);
+  while (parent && GTK_IS_MENU_SHELL (parent))
+    {
+      if (parent == menu_shell)
+       return TRUE;
+      parent = GTK_MENU_SHELL (parent->parent_menu_shell);
+    }
+
+  return FALSE;
+}
diff --git a/gtk/gtkmenushell.h b/gtk/gtkmenushell.h
new file mode 100644 (file)
index 0000000..a468631
--- /dev/null
@@ -0,0 +1,83 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_MENU_SHELL_H__
+#define __GTK_MENU_SHELL_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkcontainer.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_MENU_SHELL(obj)          GTK_CHECK_CAST (obj, gtk_menu_shell_get_type (), GtkMenuShell)
+#define GTK_MENU_SHELL_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_menu_shell_get_type (), GtkMenuShellClass)
+#define GTK_IS_MENU_SHELL(obj)       GTK_CHECK_TYPE (obj, gtk_menu_shell_get_type ())
+
+
+typedef struct _GtkMenuShell       GtkMenuShell;
+typedef struct _GtkMenuShellClass  GtkMenuShellClass;
+
+struct _GtkMenuShell
+{
+  GtkContainer container;
+
+  GList *children;
+  GtkWidget *active_menu_item;
+  GtkWidget *parent_menu_shell;
+
+  guint active : 1;
+  guint have_grab : 1;
+  guint have_xgrab : 1;
+  guint button : 2;
+  guint ignore_leave : 1;
+  guint menu_flag : 1;
+
+  guint32 activate_time;
+};
+
+struct _GtkMenuShellClass
+{
+  GtkContainerClass parent_class;
+
+  guint submenu_placement : 1;
+
+  void (*deactivate) (GtkMenuShell *menu_shell);
+};
+
+
+guint gtk_menu_shell_get_type   (void);
+void  gtk_menu_shell_append     (GtkMenuShell *menu_shell,
+                                GtkWidget    *child);
+void  gtk_menu_shell_prepend    (GtkMenuShell *menu_shell,
+                                GtkWidget    *child);
+void  gtk_menu_shell_insert     (GtkMenuShell *menu_shell,
+                                GtkWidget    *child,
+                                gint          position);
+void  gtk_menu_shell_deactivate (GtkMenuShell *menu_shell);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_MENU_SHELL_H__ */
diff --git a/gtk/gtkmisc.c b/gtk/gtkmisc.c
new file mode 100644 (file)
index 0000000..0ef8f07
--- /dev/null
@@ -0,0 +1,181 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkcontainer.h"
+#include "gtkmisc.h"
+
+
+static void gtk_misc_class_init (GtkMiscClass *klass);
+static void gtk_misc_init       (GtkMisc      *misc);
+static void gtk_misc_realize    (GtkWidget    *widget);
+
+
+guint
+gtk_misc_get_type ()
+{
+  static guint misc_type = 0;
+
+  if (!misc_type)
+    {
+      GtkTypeInfo misc_info =
+      {
+       "GtkMisc",
+       sizeof (GtkMisc),
+       sizeof (GtkMiscClass),
+       (GtkClassInitFunc) gtk_misc_class_init,
+       (GtkObjectInitFunc) gtk_misc_init,
+       (GtkArgFunc) NULL,
+      };
+
+      misc_type = gtk_type_unique (gtk_widget_get_type (), &misc_info);
+    }
+
+  return misc_type;
+}
+
+static void
+gtk_misc_class_init (GtkMiscClass *class)
+{
+  GtkWidgetClass *widget_class;
+
+  widget_class = (GtkWidgetClass*) class;
+
+  widget_class->realize = gtk_misc_realize;
+}
+
+static void
+gtk_misc_init (GtkMisc *misc)
+{
+  GTK_WIDGET_SET_FLAGS (misc, GTK_BASIC);
+
+  misc->xalign = 0.5;
+  misc->yalign = 0.5;
+  misc->xpad = 0;
+  misc->ypad = 0;
+}
+
+void
+gtk_misc_set_alignment (GtkMisc *misc,
+                       gfloat   xalign,
+                       gfloat   yalign)
+{
+  g_return_if_fail (misc != NULL);
+  g_return_if_fail (GTK_IS_MISC (misc));
+
+  if (xalign < 0.0)
+    xalign = 0.0;
+  else if (xalign > 1.0)
+    xalign = 1.0;
+
+  if (yalign < 0.0)
+    yalign = 0.0;
+  else if (yalign > 1.0)
+    yalign = 1.0;
+
+  if ((xalign != misc->xalign) || (yalign != misc->yalign))
+    {
+      misc->xalign = xalign;
+      misc->yalign = yalign;
+
+      /* clear the area that was allocated before the change
+      */
+      if (GTK_WIDGET_VISIBLE (misc))
+        {
+          GtkWidget *widget;
+
+          widget = GTK_WIDGET (misc);
+          gdk_window_clear_area (widget->window,
+                                 widget->allocation.x,
+                                 widget->allocation.y,
+                                 widget->allocation.width,
+                                 widget->allocation.height);
+        }
+
+      gtk_widget_queue_draw (GTK_WIDGET (misc));
+    }
+}
+
+void
+gtk_misc_set_padding (GtkMisc *misc,
+                     gint     xpad,
+                     gint     ypad)
+{
+  GtkRequisition *requisition;
+
+  g_return_if_fail (misc != NULL);
+  g_return_if_fail (GTK_IS_MISC (misc));
+
+  if (xpad < 0)
+    xpad = 0;
+  if (ypad < 0)
+    ypad = 0;
+
+  if ((xpad != misc->xpad) || (ypad != misc->ypad))
+    {
+      requisition = &(GTK_WIDGET (misc)->requisition);
+      requisition->width -= misc->xpad * 2;
+      requisition->height -= misc->ypad * 2;
+
+      misc->xpad = xpad;
+      misc->ypad = ypad;
+
+      requisition->width += misc->xpad * 2;
+      requisition->height += misc->ypad * 2;
+
+      if (GTK_WIDGET (misc)->parent && GTK_WIDGET_VISIBLE (misc))
+       gtk_widget_queue_resize (GTK_WIDGET (misc));
+    }
+}
+
+static void
+gtk_misc_realize (GtkWidget *widget)
+{
+  GtkMisc *misc;
+  GdkWindowAttr attributes;
+  gint attributes_mask;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_MISC (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+  misc = GTK_MISC (widget);
+
+  if (GTK_WIDGET_NO_WINDOW (widget))
+    {
+      widget->window = widget->parent->window;
+      widget->style = gtk_style_attach (widget->style, widget->window);
+    }
+  else
+    {
+      attributes.window_type = GDK_WINDOW_CHILD;
+      attributes.x = widget->allocation.x;
+      attributes.y = widget->allocation.y;
+      attributes.width = widget->allocation.width;
+      attributes.height = widget->allocation.height;
+      attributes.wclass = GDK_INPUT_OUTPUT;
+      attributes.visual = gtk_widget_get_visual (widget);
+      attributes.colormap = gtk_widget_get_colormap (widget);
+      attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK;
+      attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+
+      widget->window = gdk_window_new (widget->parent->window, &attributes, attributes_mask);
+      gdk_window_set_user_data (widget->window, widget);
+
+      widget->style = gtk_style_attach (widget->style, widget->window);
+      gdk_window_set_back_pixmap (widget->window, NULL, TRUE);
+    }
+}
diff --git a/gtk/gtkmisc.h b/gtk/gtkmisc.h
new file mode 100644 (file)
index 0000000..1bc9cbb
--- /dev/null
@@ -0,0 +1,70 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_MISC_H__
+#define __GTK_MISC_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkwidget.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_MISC(obj)          GTK_CHECK_CAST (obj, gtk_misc_get_type (), GtkMisc)
+#define GTK_MISC_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_misc_get_type (), GtkMiscClass)
+#define GTK_IS_MISC(obj)       GTK_CHECK_TYPE (obj, gtk_misc_get_type ())
+
+
+typedef struct _GtkMisc       GtkMisc;
+typedef struct _GtkMiscClass  GtkMiscClass;
+
+struct _GtkMisc
+{
+  GtkWidget widget;
+
+  gfloat xalign;
+  gfloat yalign;
+
+  guint16 xpad;
+  guint16 ypad;
+};
+
+struct _GtkMiscClass
+{
+  GtkWidgetClass parent_class;
+};
+
+
+guint  gtk_misc_get_type      (void);
+void   gtk_misc_set_alignment (GtkMisc *misc,
+                              gfloat   xalign,
+                              gfloat   yalign);
+void   gtk_misc_set_padding   (GtkMisc *misc,
+                              gint     xpad,
+                              gint     ypad);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_LABEL_H__ */
diff --git a/gtk/gtknotebook.c b/gtk/gtknotebook.c
new file mode 100644 (file)
index 0000000..0b31150
--- /dev/null
@@ -0,0 +1,1303 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtknotebook.h"
+
+
+#define CHILD_SPACING  2
+#define TAB_OVERLAP    2
+#define TAB_CURVATURE  1
+
+
+static void gtk_notebook_class_init     (GtkNotebookClass *klass);
+static void gtk_notebook_init           (GtkNotebook      *notebook);
+static void gtk_notebook_destroy        (GtkObject        *object);
+static void gtk_notebook_map            (GtkWidget        *widget);
+static void gtk_notebook_unmap          (GtkWidget        *widget);
+static void gtk_notebook_realize        (GtkWidget        *widget);
+static void gtk_notebook_unrealize      (GtkWidget        *widget);
+static void gtk_notebook_size_request   (GtkWidget        *widget,
+                                        GtkRequisition   *requisition);
+static void gtk_notebook_size_allocate  (GtkWidget        *widget,
+                                        GtkAllocation    *allocation);
+static void gtk_notebook_paint          (GtkWidget        *widget,
+                                        GdkRectangle     *area);
+static void gtk_notebook_draw           (GtkWidget        *widget,
+                                        GdkRectangle     *area);
+static gint gtk_notebook_expose         (GtkWidget        *widget,
+                                        GdkEventExpose   *event);
+static gint gtk_notebook_button_press   (GtkWidget        *widget,
+                                        GdkEventButton   *event);
+static void gtk_notebook_add            (GtkContainer     *container,
+                                        GtkWidget        *widget);
+static void gtk_notebook_remove         (GtkContainer     *container,
+                                        GtkWidget        *widget);
+static void gtk_notebook_foreach        (GtkContainer     *container,
+                                        GtkCallback       callback,
+                                        gpointer          callback_data);
+static void gtk_notebook_switch_page    (GtkNotebook      *notebook,
+                                        GtkNotebookPage  *page);
+static void gtk_notebook_draw_tab       (GtkNotebook      *notebook,
+                                        GtkNotebookPage  *page,
+                                        GdkRectangle     *area);
+static void gtk_notebook_pages_allocate (GtkNotebook      *notebook,
+                                        GtkAllocation    *allocation);
+static void gtk_notebook_page_allocate  (GtkNotebook      *notebook,
+                                        GtkNotebookPage  *page,
+                                        GtkAllocation    *allocation);
+
+
+static GtkContainerClass *parent_class = NULL;
+
+
+guint
+gtk_notebook_get_type ()
+{
+  static guint notebook_type = 0;
+
+  if (!notebook_type)
+    {
+      GtkTypeInfo notebook_info =
+      {
+       "GtkNotebook",
+       sizeof (GtkNotebook),
+       sizeof (GtkNotebookClass),
+       (GtkClassInitFunc) gtk_notebook_class_init,
+       (GtkObjectInitFunc) gtk_notebook_init,
+       (GtkArgFunc) NULL,
+      };
+
+      notebook_type = gtk_type_unique (gtk_container_get_type (), &notebook_info);
+    }
+
+  return notebook_type;
+}
+
+static void
+gtk_notebook_class_init (GtkNotebookClass *class)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+  GtkContainerClass *container_class;
+
+  object_class = (GtkObjectClass*) class;
+  widget_class = (GtkWidgetClass*) class;
+  container_class = (GtkContainerClass*) class;
+
+  parent_class = gtk_type_class (gtk_container_get_type ());
+
+  object_class->destroy = gtk_notebook_destroy;
+
+  widget_class->map = gtk_notebook_map;
+  widget_class->unmap = gtk_notebook_unmap;
+  widget_class->realize = gtk_notebook_realize;
+  widget_class->unrealize = gtk_notebook_unrealize;
+  widget_class->size_request = gtk_notebook_size_request;
+  widget_class->size_allocate = gtk_notebook_size_allocate;
+  widget_class->draw = gtk_notebook_draw;
+  widget_class->expose_event = gtk_notebook_expose;
+  widget_class->button_press_event = gtk_notebook_button_press;
+
+  container_class->add = gtk_notebook_add;
+  container_class->remove = gtk_notebook_remove;
+  container_class->foreach = gtk_notebook_foreach;
+}
+
+static void
+gtk_notebook_init (GtkNotebook *notebook)
+{
+  notebook->cur_page = NULL;
+  notebook->children = NULL;
+  notebook->show_tabs = TRUE;
+  notebook->show_border = TRUE;
+  notebook->tab_pos = GTK_POS_TOP;
+}
+
+GtkWidget*
+gtk_notebook_new ()
+{
+  return GTK_WIDGET (gtk_type_new (gtk_notebook_get_type ()));
+}
+
+void
+gtk_notebook_append_page (GtkNotebook *notebook,
+                         GtkWidget   *child,
+                         GtkWidget   *tab_label)
+{
+  g_return_if_fail (notebook != NULL);
+  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+  g_return_if_fail (child != NULL);
+  g_return_if_fail (tab_label != NULL);
+
+  gtk_notebook_insert_page (notebook, child, tab_label, -1);
+}
+
+void
+gtk_notebook_prepend_page (GtkNotebook *notebook,
+                          GtkWidget   *child,
+                          GtkWidget   *tab_label)
+{
+  g_return_if_fail (notebook != NULL);
+  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+  g_return_if_fail (child != NULL);
+  g_return_if_fail (tab_label != NULL);
+
+  gtk_notebook_insert_page (notebook, child, tab_label, 0);
+}
+
+void
+gtk_notebook_insert_page (GtkNotebook *notebook,
+                         GtkWidget   *child,
+                         GtkWidget   *tab_label,
+                         gint         position)
+{
+  GtkNotebookPage *page;
+  gint nchildren;
+
+  g_return_if_fail (notebook != NULL);
+  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+  g_return_if_fail (child != NULL);
+  g_return_if_fail (tab_label != NULL);
+
+  page = g_new (GtkNotebookPage, 1);
+  page->child = child;
+  page->tab_label = tab_label;
+  page->requisition.width = 0;
+  page->requisition.height = 0;
+  page->allocation.x = 0;
+  page->allocation.y = 0;
+  page->allocation.width = 0;
+  page->allocation.height = 0;
+
+  nchildren = g_list_length (notebook->children);
+  if ((position < 0) || (position > nchildren))
+    position = nchildren;
+
+  notebook->children = g_list_insert (notebook->children, page, position);
+
+  if (!notebook->cur_page)
+    notebook->cur_page = page;
+
+  gtk_widget_show (tab_label);
+  gtk_widget_set_parent (child, GTK_WIDGET (notebook));
+  gtk_widget_set_parent (tab_label, GTK_WIDGET (notebook));
+
+  if (GTK_WIDGET_VISIBLE (notebook))
+    {
+      if (GTK_WIDGET_REALIZED (notebook) &&
+         !GTK_WIDGET_REALIZED (child))
+       gtk_widget_realize (child);
+      
+      if (GTK_WIDGET_MAPPED (notebook) &&
+         !GTK_WIDGET_MAPPED (child) && notebook->cur_page == page)
+       gtk_widget_map (child);
+
+      if (GTK_WIDGET_REALIZED (notebook) &&
+         !GTK_WIDGET_REALIZED (tab_label))
+       gtk_widget_realize (tab_label);
+      
+      if (GTK_WIDGET_MAPPED (notebook) &&
+         !GTK_WIDGET_MAPPED (tab_label))
+       gtk_widget_map (tab_label);
+    }
+
+  if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (notebook))
+    gtk_widget_queue_resize (child);
+}
+
+void
+gtk_notebook_remove_page (GtkNotebook *notebook,
+                         gint         page_num)
+{
+  GtkNotebookPage *page;
+  GList *tmp_list;
+
+  g_return_if_fail (notebook != NULL);
+  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+
+  tmp_list = g_list_nth (notebook->children, page_num);
+  if (tmp_list)
+    {
+      page = tmp_list->data;
+
+      if (notebook->cur_page == page)
+       gtk_notebook_prev_page (notebook);
+      if (notebook->cur_page == page)
+       notebook->cur_page = NULL;
+
+      notebook->children = g_list_remove_link (notebook->children, tmp_list);
+      g_list_free (tmp_list);
+      g_free (page);
+    }
+}
+
+gint
+gtk_notebook_current_page (GtkNotebook *notebook)
+{
+  GList *children;
+  gint cur_page;
+
+  g_return_val_if_fail (notebook != NULL, -1);
+  g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), -1);
+
+  if (notebook->cur_page)
+    {
+      cur_page = 0;
+      children = notebook->children;
+
+      while (children)
+       {
+         if (children->data == notebook->cur_page)
+           break;
+         children = children->next;
+         cur_page += 1;
+       }
+
+      if (!children)
+       cur_page = -1;
+    }
+  else
+    {
+      cur_page = -1;
+    }
+
+  return cur_page;
+}
+
+void
+gtk_notebook_set_page (GtkNotebook *notebook,
+                      gint         page_num)
+{
+  GtkNotebookPage *page;
+  GList *tmp_list;
+
+  g_return_if_fail (notebook != NULL);
+  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+
+  tmp_list = g_list_nth (notebook->children, page_num);
+  if (tmp_list)
+    {
+      page = tmp_list->data;
+      gtk_notebook_switch_page (notebook, page);
+    }
+}
+
+void
+gtk_notebook_next_page (GtkNotebook *notebook)
+{
+  GtkNotebookPage *page;
+  GList *children;
+
+  g_return_if_fail (notebook != NULL);
+  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+
+  children = notebook->children;
+  while (children)
+    {
+      page = children->data;
+
+      if (notebook->cur_page == page)
+       {
+         children = children->next;
+         if (!children)
+           children = notebook->children;
+         page = children->data;
+
+         gtk_notebook_switch_page (notebook, page);
+       }
+
+      children = children->next;
+    }
+}
+
+void
+gtk_notebook_prev_page (GtkNotebook *notebook)
+{
+  GtkNotebookPage *page;
+  GList *children;
+
+  g_return_if_fail (notebook != NULL);
+  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+
+  children = notebook->children;
+  while (children)
+    {
+      page = children->data;
+
+      if (notebook->cur_page == page)
+       {
+         children = children->prev;
+         if (!children)
+           children = g_list_last (notebook->children);
+         page = children->data;
+
+         gtk_notebook_switch_page (notebook, page);
+       }
+
+      children = children->next;
+    }
+}
+
+void
+gtk_notebook_set_tab_pos (GtkNotebook     *notebook,
+                         GtkPositionType  pos)
+{
+  g_return_if_fail (notebook != NULL);
+  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+
+  if (notebook->tab_pos != pos)
+    {
+      notebook->tab_pos = pos;
+
+      if (GTK_WIDGET_VISIBLE (notebook))
+       gtk_widget_queue_resize (GTK_WIDGET (notebook));
+    }
+}
+
+void
+gtk_notebook_set_show_tabs (GtkNotebook *notebook,
+                           gint         show_tabs)
+{
+  g_return_if_fail (notebook != NULL);
+  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+
+  if (notebook->show_tabs != show_tabs)
+    {
+      notebook->show_tabs = show_tabs;
+
+      if (GTK_WIDGET_VISIBLE (notebook))
+       gtk_widget_queue_resize (GTK_WIDGET (notebook));
+    }
+}
+
+void
+gtk_notebook_set_show_border (GtkNotebook *notebook,
+                             gint         show_border)
+{
+  g_return_if_fail (notebook != NULL);
+  g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+
+  if (notebook->show_border != show_border)
+    {
+      notebook->show_border = show_border;
+
+      if (GTK_WIDGET_VISIBLE (notebook))
+       gtk_widget_queue_resize (GTK_WIDGET (notebook));
+    }
+}
+
+static void
+gtk_notebook_destroy (GtkObject *object)
+{
+  GtkNotebook *notebook;
+  GtkNotebookPage *page;
+  GList *children;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_NOTEBOOK (object));
+
+  notebook = GTK_NOTEBOOK (object);
+
+  children = notebook->children;
+  while (children)
+    {
+      page = children->data;
+      children = children->next;
+
+      page->child->parent = NULL;
+      page->tab_label->parent = NULL;
+
+      gtk_object_unref (GTK_OBJECT (page->child));
+      gtk_object_unref (GTK_OBJECT (page->tab_label));
+
+      gtk_widget_destroy (page->child);
+      gtk_widget_destroy (page->tab_label);
+
+      g_free (page);
+    }
+
+  g_list_free (notebook->children);
+
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+gtk_notebook_map (GtkWidget *widget)
+{
+  GtkNotebook *notebook;
+  GtkNotebookPage *page;
+  GList *children;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_NOTEBOOK (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
+  gdk_window_show (widget->window);
+
+  notebook = GTK_NOTEBOOK (widget);
+
+  if (notebook->cur_page &&
+      GTK_WIDGET_VISIBLE (notebook->cur_page->child) &&
+      !GTK_WIDGET_MAPPED (notebook->cur_page->child))
+    gtk_widget_map (notebook->cur_page->child);
+
+  children = notebook->children;
+  while (children)
+    {
+      page = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (page->child) &&
+         !GTK_WIDGET_MAPPED (page->tab_label))
+       gtk_widget_map (page->tab_label);
+    }
+}
+
+static void
+gtk_notebook_unmap (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_NOTEBOOK (widget));
+
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
+  gdk_window_hide (widget->window);
+}
+
+static void
+gtk_notebook_realize (GtkWidget *widget)
+{
+  GtkNotebook *notebook;
+  GdkWindowAttr attributes;
+  gint attributes_mask;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_NOTEBOOK (widget));
+
+  notebook = GTK_NOTEBOOK (widget);
+  GTK_WIDGET_SET_FLAGS (notebook, GTK_REALIZED);
+
+  attributes.window_type = GDK_WINDOW_CHILD;
+  attributes.x = widget->allocation.x;
+  attributes.y = widget->allocation.y;
+  attributes.width = widget->allocation.width;
+  attributes.height = widget->allocation.height;
+  attributes.wclass = GDK_INPUT_OUTPUT;
+  attributes.visual = gtk_widget_get_visual (widget);
+  attributes.colormap = gtk_widget_get_colormap (widget);
+  attributes.event_mask = gtk_widget_get_events (widget);
+  attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK;
+
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+
+  widget->window = gdk_window_new (widget->parent->window, &attributes, attributes_mask);
+  gdk_window_set_user_data (widget->window, notebook);
+
+  widget->style = gtk_style_attach (widget->style, widget->window);
+  gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
+}
+
+static void
+gtk_notebook_unrealize (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_NOTEBOOK (widget));
+
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED | GTK_MAPPED);
+
+  gtk_style_detach (widget->style);
+  gdk_window_destroy (widget->window);
+  widget->window = NULL;
+}
+
+static void
+gtk_notebook_size_request (GtkWidget      *widget,
+                          GtkRequisition *requisition)
+{
+  GtkNotebook *notebook;
+  GtkNotebookPage *page;
+  GList *children;
+  gint tab_width;
+  gint tab_height;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_NOTEBOOK (widget));
+  g_return_if_fail (requisition != NULL);
+
+  notebook = GTK_NOTEBOOK (widget);
+  widget->requisition.width = 0;
+  widget->requisition.height = 0;
+
+  children = notebook->children;
+  while (children)
+    {
+      page = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (page->child))
+       {
+         gtk_widget_size_request (page->child, &page->child->requisition);
+
+         widget->requisition.width = MAX (widget->requisition.width,
+                                          page->child->requisition.width);
+         widget->requisition.height = MAX (widget->requisition.height,
+                                           page->child->requisition.height);
+       }
+    }
+
+  widget->requisition.width += GTK_CONTAINER (widget)->border_width * 2;
+  widget->requisition.height += GTK_CONTAINER (widget)->border_width * 2;
+
+  if (notebook->show_tabs)
+    {
+      widget->requisition.width += GTK_WIDGET (widget)->style->klass->xthickness * 2;
+      widget->requisition.height += GTK_WIDGET (widget)->style->klass->ythickness * 2;
+
+      tab_width = 0;
+      tab_height = 0;
+
+      children = notebook->children;
+      while (children)
+       {
+         page = children->data;
+         children = children->next;
+
+         if (GTK_WIDGET_VISIBLE (page->child))
+           {
+             gtk_widget_size_request (page->tab_label, &page->tab_label->requisition);
+
+             page->requisition.width = (page->tab_label->requisition.width +
+                                        (GTK_WIDGET (widget)->style->klass->xthickness +
+                                         CHILD_SPACING) * 2);
+             page->requisition.height = (page->tab_label->requisition.height +
+                                         (GTK_WIDGET (widget)->style->klass->ythickness +
+                                          CHILD_SPACING) * 2);
+
+             switch (notebook->tab_pos)
+               {
+               case GTK_POS_TOP:
+               case GTK_POS_BOTTOM:
+                 page->requisition.width -= TAB_OVERLAP;
+                 page->requisition.height -= GTK_WIDGET (widget)->style->klass->ythickness;
+
+                 tab_width += page->requisition.width;
+                 tab_height = MAX (tab_height, page->requisition.height);
+                 break;
+               case GTK_POS_LEFT:
+               case GTK_POS_RIGHT:
+                 page->requisition.width -= GTK_WIDGET (widget)->style->klass->xthickness;
+                 page->requisition.height -= TAB_OVERLAP;
+
+                 tab_width = MAX (tab_width, page->requisition.width);
+                 tab_height += page->requisition.height;
+                 break;
+               }
+           }
+       }
+
+      children = notebook->children;
+      while (children)
+       {
+         page = children->data;
+         children = children->next;
+
+         if (GTK_WIDGET_VISIBLE (page->child))
+           {
+             if ((notebook->tab_pos == GTK_POS_TOP) ||
+                 (notebook->tab_pos == GTK_POS_BOTTOM))
+               page->requisition.height = tab_height;
+             else
+               page->requisition.width = tab_width;
+           }
+       }
+
+      switch (notebook->tab_pos)
+       {
+       case GTK_POS_TOP:
+       case GTK_POS_BOTTOM:
+         tab_width += GTK_WIDGET (widget)->style->klass->xthickness;
+         widget->requisition.width = MAX (widget->requisition.width, tab_width);
+         widget->requisition.height += tab_height;
+         break;
+       case GTK_POS_LEFT:
+       case GTK_POS_RIGHT:
+         tab_height += GTK_WIDGET (widget)->style->klass->ythickness;
+         widget->requisition.width += tab_width;
+         widget->requisition.height = MAX (widget->requisition.height, tab_height);
+         break;
+       }
+    }
+  else if (notebook->show_border)
+    {
+      widget->requisition.width += GTK_WIDGET (widget)->style->klass->xthickness * 2;
+      widget->requisition.height += GTK_WIDGET (widget)->style->klass->ythickness * 2;
+    }
+}
+
+static void
+gtk_notebook_size_allocate (GtkWidget     *widget,
+                           GtkAllocation *allocation)
+{
+  GtkNotebook *notebook;
+  GtkNotebookPage *page;
+  GtkAllocation child_allocation;
+  GList *children;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_NOTEBOOK (widget));
+  g_return_if_fail (allocation != NULL);
+
+  widget->allocation = *allocation;
+  if (GTK_WIDGET_REALIZED (widget))
+    gdk_window_move_resize (widget->window,
+                           allocation->x, allocation->y,
+                           allocation->width, allocation->height);
+
+  notebook = GTK_NOTEBOOK (widget);
+  if (notebook->children)
+    {
+      child_allocation.x = GTK_CONTAINER (widget)->border_width;
+      child_allocation.y = GTK_CONTAINER (widget)->border_width;
+      child_allocation.width = allocation->width - child_allocation.x * 2;
+      child_allocation.height = allocation->height - child_allocation.y * 2;
+
+      if (notebook->show_tabs || notebook->show_border)
+       {
+         child_allocation.x += GTK_WIDGET (widget)->style->klass->xthickness;
+         child_allocation.y += GTK_WIDGET (widget)->style->klass->ythickness;
+         child_allocation.width -= GTK_WIDGET (widget)->style->klass->xthickness * 2;
+         child_allocation.height -= GTK_WIDGET (widget)->style->klass->ythickness * 2;
+
+         if (notebook->show_tabs && notebook->children)
+           {
+             switch (notebook->tab_pos)
+               {
+               case GTK_POS_TOP:
+                 child_allocation.y += notebook->cur_page->requisition.height;
+               case GTK_POS_BOTTOM:
+                 child_allocation.height -= notebook->cur_page->requisition.height;
+                 break;
+               case GTK_POS_LEFT:
+                 child_allocation.x += notebook->cur_page->requisition.width;
+               case GTK_POS_RIGHT:
+                 child_allocation.width -= notebook->cur_page->requisition.width;
+                 break;
+               }
+           }
+       }
+
+      children = notebook->children;
+      while (children)
+       {
+         page = children->data;
+         children = children->next;
+
+         if (GTK_WIDGET_VISIBLE (page->child))
+           gtk_widget_size_allocate (page->child, &child_allocation);
+       }
+
+      if (notebook->show_tabs && notebook->children)
+       gtk_notebook_pages_allocate (notebook, allocation);
+    }
+}
+
+static void
+gtk_notebook_paint (GtkWidget    *widget,
+                   GdkRectangle *area)
+{
+  GtkNotebook *notebook;
+  GtkNotebookPage *page;
+  GList *children;
+  GdkPoint points[6];
+  gint width, height;
+  gint x, y;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_NOTEBOOK (widget));
+  g_return_if_fail (area != NULL);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      notebook = GTK_NOTEBOOK (widget);
+
+      gdk_window_clear_area (widget->window,
+                            area->x, area->y,
+                            area->width, area->height);
+
+      if (notebook->show_tabs || notebook->show_border)
+       {
+         x = GTK_CONTAINER (widget)->border_width;
+         y = GTK_CONTAINER (widget)->border_width;
+         width = widget->allocation.width - x * 2;
+         height = widget->allocation.height - y * 2;
+
+         if (notebook->show_tabs && notebook->children)
+           {
+             switch (notebook->tab_pos)
+               {
+               case GTK_POS_TOP:
+                 y += notebook->cur_page->allocation.height;
+               case GTK_POS_BOTTOM:
+                 height -= notebook->cur_page->allocation.height;
+                 break;
+               case GTK_POS_LEFT:
+                 x += notebook->cur_page->allocation.width;
+               case GTK_POS_RIGHT:
+                 width -= notebook->cur_page->allocation.width;
+                 break;
+               }
+
+             switch (notebook->tab_pos)
+               {
+               case GTK_POS_TOP:
+                 points[0].x = notebook->cur_page->allocation.x;
+                 points[0].y = y;
+                 points[1].x = x;
+                 points[1].y = y;
+                 points[2].x = x;
+                 points[2].y = y + height - 1;
+                 points[3].x = x + width - 1;
+                 points[3].y = y + height - 1;
+                 points[4].x = x + width - 1;
+                 points[4].y = y;
+                 points[5].x = (notebook->cur_page->allocation.x +
+                                notebook->cur_page->allocation.width -
+                                GTK_WIDGET (notebook)->style->klass->xthickness);
+                 points[5].y = y;
+
+                 if (points[5].x == (x + width))
+                   points[5].x -= 1;
+                 break;
+               case GTK_POS_BOTTOM:
+                 points[0].x = (notebook->cur_page->allocation.x +
+                                notebook->cur_page->allocation.width -
+                                GTK_WIDGET (notebook)->style->klass->xthickness);
+                 points[0].y = y + height - 1;
+                 points[1].x = x + width - 1;
+                 points[1].y = y + height - 1;
+                 points[2].x = x + width - 1;
+                 points[2].y = y;
+                 points[3].x = x;
+                 points[3].y = y;
+                 points[4].x = x;
+                 points[4].y = y + height - 1;
+                 points[5].x = notebook->cur_page->allocation.x;
+                 points[5].y = y + height - 1;
+
+                 if (points[0].x == (x + width))
+                   points[0].x -= 1;
+                 break;
+               case GTK_POS_LEFT:
+                 points[0].x = x;
+                 points[0].y = (notebook->cur_page->allocation.y +
+                                notebook->cur_page->allocation.height -
+                                GTK_WIDGET (notebook)->style->klass->ythickness);
+                 points[1].x = x;
+                 points[1].y = y + height - 1;
+                 points[2].x = x + width - 1;
+                 points[2].y = y + height - 1;
+                 points[3].x = x + width - 1;
+                 points[3].y = y;
+                 points[4].x = x;
+                 points[4].y = y;
+                 points[5].x = x;
+                 points[5].y = notebook->cur_page->allocation.y;
+
+                 if (points[0].y == (y + height))
+                   points[0].y -= 1;
+                 break;
+               case GTK_POS_RIGHT:
+                 points[0].x = x + width - 1;
+                 points[0].y = notebook->cur_page->allocation.y;
+                 points[1].x = x + width - 1;
+                 points[1].y = y;
+                 points[2].x = x;
+                 points[2].y = y;
+                 points[3].x = x;
+                 points[3].y = y + height - 1;
+                 points[4].x = x + width - 1;
+                 points[4].y = y + height - 1;
+                 points[5].x = x + width - 1;
+                 points[5].y = (notebook->cur_page->allocation.y +
+                                notebook->cur_page->allocation.height -
+                                GTK_WIDGET (notebook)->style->klass->ythickness);
+
+                 if (points[5].y == (y + height))
+                   points[5].y -= 1;
+                 break;
+               }
+
+             gtk_draw_polygon (widget->style, widget->window,
+                               GTK_STATE_NORMAL, GTK_SHADOW_OUT,
+                               points, 6, FALSE);
+
+             children = g_list_last (notebook->children);
+             while (children)
+               {
+                 page = children->data;
+                 children = children->prev;
+
+                 if (notebook->cur_page != page)
+                   gtk_notebook_draw_tab (notebook, page, area);
+               }
+
+             if (notebook->cur_page)
+               gtk_notebook_draw_tab (notebook, notebook->cur_page, area);
+           }
+         else if (notebook->show_border)
+           {
+             gtk_draw_shadow (widget->style, widget->window,
+                              GTK_STATE_NORMAL, GTK_SHADOW_OUT,
+                              x, y, width, height);
+           }
+       }
+    }
+}
+
+static void
+gtk_notebook_draw (GtkWidget    *widget,
+                  GdkRectangle *area)
+{
+  GtkNotebook *notebook;
+  GdkRectangle child_area;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_NOTEBOOK (widget));
+  g_return_if_fail (area != NULL);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      notebook = GTK_NOTEBOOK (widget);
+
+      gtk_notebook_paint (widget, area);
+
+      if (notebook->cur_page &&
+         gtk_widget_intersect (notebook->cur_page->child, area, &child_area))
+       gtk_widget_draw (notebook->cur_page->child, &child_area);
+    }
+}
+
+static gint
+gtk_notebook_expose (GtkWidget      *widget,
+                    GdkEventExpose *event)
+{
+  GtkNotebook *notebook;
+  GdkEventExpose child_event;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      notebook = GTK_NOTEBOOK (widget);
+
+      gtk_notebook_paint (widget, &event->area);
+
+      child_event = *event;
+      if (notebook->cur_page && GTK_WIDGET_NO_WINDOW (notebook->cur_page->child) &&
+         gtk_widget_intersect (notebook->cur_page->child, &event->area, &child_event.area))
+       gtk_widget_event (notebook->cur_page->child, (GdkEvent*) &child_event);
+    }
+
+  return FALSE;
+}
+
+static gint
+gtk_notebook_button_press (GtkWidget      *widget,
+                          GdkEventButton *event)
+{
+  GtkNotebook *notebook;
+  GtkNotebookPage *page;
+  GList *children;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if ((event->type != GDK_BUTTON_PRESS) ||
+      (event->window != widget->window))
+    return FALSE;
+
+  notebook = GTK_NOTEBOOK (widget);
+
+  children = notebook->children;
+  while (children)
+    {
+      page = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (page->child) &&
+         (event->x >= page->allocation.x) &&
+         (event->y >= page->allocation.y) &&
+         (event->x <= (page->allocation.x + page->allocation.width)) &&
+         (event->y <= (page->allocation.y + page->allocation.height)))
+       {
+         gtk_notebook_switch_page (notebook, page);
+         break;
+       }
+    }
+
+  return FALSE;
+}
+
+static void
+gtk_notebook_add (GtkContainer *container,
+                 GtkWidget    *widget)
+{
+  g_warning ("gtk_notebook_add: use gtk_notebook_{append,prepend}_page instead\n");
+}
+
+static void
+gtk_notebook_remove (GtkContainer *container,
+                    GtkWidget    *widget)
+{
+  GtkNotebook *notebook;
+  GtkNotebookPage *page;
+  GList *children;
+
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_NOTEBOOK (container));
+  g_return_if_fail (widget != NULL);
+
+  notebook = GTK_NOTEBOOK (container);
+
+  children = notebook->children;
+  while (children)
+    {
+      page = children->data;
+
+      if (page->child == widget)
+       {
+         gtk_widget_unparent (page->child);
+         gtk_widget_unparent (page->tab_label);
+
+         notebook->children = g_list_remove_link (notebook->children, children);
+         g_list_free (children);
+         g_free (page);
+
+         if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
+           gtk_widget_queue_resize (GTK_WIDGET (container));
+
+         break;
+       }
+
+      children = children->next;
+    }
+}
+
+static void
+gtk_notebook_foreach (GtkContainer *container,
+                     GtkCallback   callback,
+                     gpointer      callback_data)
+{
+  GtkNotebook *notebook;
+  GtkNotebookPage *page;
+  GList *children;
+
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_NOTEBOOK (container));
+  g_return_if_fail (callback != NULL);
+
+  notebook = GTK_NOTEBOOK (container);
+
+  children = notebook->children;
+  while (children)
+    {
+      page = children->data;
+      children = children->next;
+
+      (* callback) (page->child, callback_data);
+    }
+}
+
+static void
+gtk_notebook_switch_page (GtkNotebook     *notebook,
+                         GtkNotebookPage *page)
+{
+  g_return_if_fail (notebook != NULL);
+  g_return_if_fail (page != NULL);
+
+  if (notebook->cur_page != page)
+    {
+      if (notebook->cur_page && GTK_WIDGET_MAPPED (notebook->cur_page->child))
+       gtk_widget_unmap (notebook->cur_page->child);
+
+      notebook->cur_page = page;
+      gtk_notebook_pages_allocate (notebook, &GTK_WIDGET (notebook)->allocation);
+
+      if (GTK_WIDGET_MAPPED (notebook))
+       gtk_widget_map (notebook->cur_page->child);
+
+      if (GTK_WIDGET_DRAWABLE (notebook))
+       gtk_widget_queue_draw (GTK_WIDGET (notebook));
+    }
+}
+
+static void
+gtk_notebook_draw_tab (GtkNotebook     *notebook,
+                      GtkNotebookPage *page,
+                      GdkRectangle    *area)
+{
+  GdkRectangle child_area;
+  GdkRectangle page_area;
+  GtkStateType state_type;
+  GdkPoint points[6];
+
+  g_return_if_fail (notebook != NULL);
+  g_return_if_fail (page != NULL);
+  g_return_if_fail (area != NULL);
+
+  page_area.x = page->allocation.x;
+  page_area.y = page->allocation.y;
+  page_area.width = page->allocation.width;
+  page_area.height = page->allocation.height;
+
+  if (gdk_rectangle_intersect (&page_area, area, &child_area))
+    {
+      switch (notebook->tab_pos)
+       {
+       case GTK_POS_TOP:
+         points[0].x = page->allocation.x + page->allocation.width - 1;
+         points[0].y = page->allocation.y + page->allocation.height - 1;
+
+         points[1].x = page->allocation.x + page->allocation.width - 1;
+         points[1].y = page->allocation.y + TAB_CURVATURE;
+
+         points[2].x = page->allocation.x + page->allocation.width - TAB_CURVATURE - 1;
+         points[2].y = page->allocation.y;
+
+         points[3].x = page->allocation.x + TAB_CURVATURE;
+         points[3].y = page->allocation.y;
+
+         points[4].x = page->allocation.x;
+         points[4].y = page->allocation.y + TAB_CURVATURE;
+
+         points[5].x = page->allocation.x;
+         points[5].y = page->allocation.y + page->allocation.height - 1;
+         break;
+       case GTK_POS_BOTTOM:
+         points[0].x = page->allocation.x;
+         points[0].y = page->allocation.y;
+
+         points[1].x = page->allocation.x;
+         points[1].y = page->allocation.y + page->allocation.height - TAB_CURVATURE - 1;
+
+         points[2].x = page->allocation.x + TAB_CURVATURE;
+         points[2].y = page->allocation.y + page->allocation.height - 1;
+
+         points[3].x = page->allocation.x + page->allocation.width - TAB_CURVATURE - 1;
+         points[3].y = page->allocation.y + page->allocation.height - 1;
+
+         points[4].x = page->allocation.x + page->allocation.width - 1;
+         points[4].y = page->allocation.y + page->allocation.height - TAB_CURVATURE - 1;
+
+         points[5].x = page->allocation.x + page->allocation.width - 1;
+         points[5].y = page->allocation.y;
+         break;
+       case GTK_POS_LEFT:
+         points[0].x = page->allocation.x + page->allocation.width - 1;
+         points[0].y = page->allocation.y;
+
+         points[1].x = page->allocation.x + TAB_CURVATURE;
+         points[1].y = page->allocation.y;
+
+         points[2].x = page->allocation.x;
+         points[2].y = page->allocation.y + TAB_CURVATURE;
+
+         points[3].x = page->allocation.x;
+         points[3].y = page->allocation.y + page->allocation.height - TAB_CURVATURE - 1;
+
+         points[4].x = page->allocation.x + TAB_CURVATURE;
+         points[4].y = page->allocation.y + page->allocation.height - 1;
+
+         points[5].x = page->allocation.x + page->allocation.width - 1;
+         points[5].y = page->allocation.y + page->allocation.height - 1;
+         break;
+       case GTK_POS_RIGHT:
+         points[0].x = page->allocation.x;
+         points[0].y = page->allocation.y + page->allocation.height - 1;
+
+         points[1].x = page->allocation.x + page->allocation.width - TAB_CURVATURE - 1;
+         points[1].y = page->allocation.y + page->allocation.height - 1;
+
+         points[2].x = page->allocation.x + page->allocation.width - 1;
+         points[2].y = page->allocation.y + page->allocation.height - TAB_CURVATURE - 1;
+
+         points[3].x = page->allocation.x + page->allocation.width - 1;
+         points[3].y = page->allocation.y + TAB_CURVATURE;
+
+         points[4].x = page->allocation.x + page->allocation.width - TAB_CURVATURE - 1;
+         points[4].y = page->allocation.y;
+
+         points[5].x = page->allocation.x;
+         points[5].y = page->allocation.y;
+         break;
+       }
+
+      if (notebook->cur_page == page)
+       state_type = GTK_STATE_NORMAL;
+      else
+       state_type = GTK_STATE_ACTIVE;
+
+      gtk_draw_polygon (GTK_WIDGET (notebook)->style,
+                       GTK_WIDGET (notebook)->window,
+                       state_type, GTK_SHADOW_OUT,
+                       points, 6, (notebook->cur_page != page));
+
+      if (gtk_widget_intersect (page->tab_label, area, &child_area))
+       gtk_widget_draw (page->tab_label, &child_area);
+    }
+}
+
+static void
+gtk_notebook_pages_allocate (GtkNotebook   *notebook,
+                            GtkAllocation *allocation)
+{
+  GtkNotebookPage *page;
+  GtkAllocation child_allocation;
+  GList *children;
+
+  if (notebook->show_tabs && notebook->children)
+    {
+      child_allocation.x = GTK_CONTAINER (notebook)->border_width;
+      child_allocation.y = GTK_CONTAINER (notebook)->border_width;
+
+      switch (notebook->tab_pos)
+       {
+       case GTK_POS_BOTTOM:
+         child_allocation.y = allocation->height - notebook->cur_page->requisition.height;
+       case GTK_POS_TOP:
+         child_allocation.height = notebook->cur_page->requisition.height;
+         break;
+       case GTK_POS_RIGHT:
+         child_allocation.x = allocation->width - notebook->cur_page->requisition.width;
+       case GTK_POS_LEFT:
+         child_allocation.width = notebook->cur_page->requisition.width;
+         break;
+       }
+
+      children = notebook->children;
+      while (children)
+       {
+         page = children->data;
+         children = children->next;
+
+         if (GTK_WIDGET_VISIBLE (page->child))
+           {
+             switch (notebook->tab_pos)
+               {
+               case GTK_POS_TOP:
+               case GTK_POS_BOTTOM:
+                 child_allocation.width = page->requisition.width + TAB_OVERLAP;
+                 break;
+               case GTK_POS_LEFT:
+               case GTK_POS_RIGHT:
+                 child_allocation.height = page->requisition.height + TAB_OVERLAP;
+                 break;
+               }
+
+             gtk_notebook_page_allocate (notebook, page, &child_allocation);
+
+             switch (notebook->tab_pos)
+               {
+               case GTK_POS_TOP:
+               case GTK_POS_BOTTOM:
+                 child_allocation.x += child_allocation.width - TAB_OVERLAP;
+                 break;
+               case GTK_POS_LEFT:
+               case GTK_POS_RIGHT:
+                 child_allocation.y += child_allocation.height - TAB_OVERLAP;
+                 break;
+               }
+           }
+       }
+    }
+}
+
+static void
+gtk_notebook_page_allocate (GtkNotebook     *notebook,
+                           GtkNotebookPage *page,
+                           GtkAllocation   *allocation)
+{
+  GtkAllocation child_allocation;
+  gint xthickness, ythickness;
+
+  g_return_if_fail (notebook != NULL);
+  g_return_if_fail (page != NULL);
+  g_return_if_fail (allocation != NULL);
+
+  page->allocation = *allocation;
+
+  xthickness = GTK_WIDGET (notebook)->style->klass->xthickness;
+  ythickness = GTK_WIDGET (notebook)->style->klass->ythickness;
+
+  if (notebook->cur_page != page)
+    {
+      switch (notebook->tab_pos)
+       {
+       case GTK_POS_TOP:
+         page->allocation.y += ythickness;
+       case GTK_POS_BOTTOM:
+         page->allocation.height -= ythickness;
+         break;
+       case GTK_POS_LEFT:
+         page->allocation.x += xthickness;
+       case GTK_POS_RIGHT:
+         page->allocation.width -= xthickness;
+         break;
+       }
+    }
+
+  switch (notebook->tab_pos)
+    {
+    case GTK_POS_TOP:
+      child_allocation.x = xthickness + CHILD_SPACING;
+      child_allocation.y = ythickness + CHILD_SPACING;
+      child_allocation.width = page->allocation.width - child_allocation.x * 2;
+      child_allocation.height = page->allocation.height - child_allocation.y;
+      child_allocation.x += page->allocation.x;
+      child_allocation.y += page->allocation.y;
+      break;
+    case GTK_POS_BOTTOM:
+      child_allocation.x = xthickness + CHILD_SPACING;
+      child_allocation.y = ythickness + CHILD_SPACING;
+      child_allocation.width = page->allocation.width - child_allocation.x * 2;
+      child_allocation.height = page->allocation.height - child_allocation.y;
+      child_allocation.x += page->allocation.x;
+      child_allocation.y = page->allocation.y;
+      break;
+    case GTK_POS_LEFT:
+      child_allocation.x = xthickness + CHILD_SPACING;
+      child_allocation.y = ythickness + CHILD_SPACING;
+      child_allocation.width = page->allocation.width - child_allocation.x;
+      child_allocation.height = page->allocation.height - child_allocation.y * 2;
+      child_allocation.x += page->allocation.x;
+      child_allocation.y += page->allocation.y;
+      break;
+    case GTK_POS_RIGHT:
+      child_allocation.x = xthickness + CHILD_SPACING;
+      child_allocation.y = ythickness + CHILD_SPACING;
+      child_allocation.width = page->allocation.width - child_allocation.x;
+      child_allocation.height = page->allocation.height - child_allocation.y * 2;
+      child_allocation.x = page->allocation.x;
+      child_allocation.y += page->allocation.y;
+      break;
+    }
+
+  gtk_widget_size_allocate (page->tab_label, &child_allocation);
+}
diff --git a/gtk/gtknotebook.h b/gtk/gtknotebook.h
new file mode 100644 (file)
index 0000000..402823b
--- /dev/null
@@ -0,0 +1,98 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_NOTEBOOK_H__
+#define __GTK_NOTEBOOK_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkcontainer.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_NOTEBOOK(obj)          GTK_CHECK_CAST (obj, gtk_notebook_get_type (), GtkNotebook)
+#define GTK_NOTEBOOK_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_notebook_get_type (), GtkNotebookClass)
+#define GTK_IS_NOTEBOOK(obj)       GTK_CHECK_TYPE (obj, gtk_notebook_get_type ())
+
+
+typedef struct _GtkNotebook       GtkNotebook;
+typedef struct _GtkNotebookClass  GtkNotebookClass;
+typedef struct _GtkNotebookPage   GtkNotebookPage;
+
+struct _GtkNotebook
+{
+  GtkContainer container;
+
+  GtkNotebookPage *cur_page;
+  GList *children;
+
+  guint show_tabs : 1;
+  guint show_border : 1;
+  guint tab_pos : 2;
+};
+
+struct _GtkNotebookClass
+{
+  GtkContainerClass parent_class;
+};
+
+struct _GtkNotebookPage
+{
+  GtkWidget *child;
+  GtkWidget *tab_label;
+  GtkRequisition requisition;
+  GtkAllocation allocation;
+};
+
+
+guint      gtk_notebook_get_type        (void);
+GtkWidget* gtk_notebook_new             (void);
+void       gtk_notebook_append_page     (GtkNotebook      *notebook,
+                                        GtkWidget        *child,
+                                        GtkWidget        *tab_label);
+void       gtk_notebook_prepend_page    (GtkNotebook      *notebook,
+                                        GtkWidget        *child,
+                                        GtkWidget        *tab_label);
+void       gtk_notebook_insert_page     (GtkNotebook      *notebook,
+                                        GtkWidget        *child,
+                                        GtkWidget        *tab_label,
+                                        gint              position);
+void       gtk_notebook_remove_page     (GtkNotebook      *notebook,
+                                        gint              page_num);
+gint       gtk_notebook_current_page    (GtkNotebook      *notebook);
+void       gtk_notebook_set_page        (GtkNotebook      *notebook,
+                                        gint              page_num);
+void       gtk_notebook_next_page       (GtkNotebook      *notebook);
+void       gtk_notebook_prev_page       (GtkNotebook      *notebook);
+void       gtk_notebook_set_tab_pos     (GtkNotebook      *notebook,
+                                        GtkPositionType   pos);
+void       gtk_notebook_set_show_tabs   (GtkNotebook      *notebook,
+                                        gint              show_tabs);
+void       gtk_notebook_set_show_border (GtkNotebook      *notebook,
+                                        gint              show_border);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_NOTEBOOK_H__ */
diff --git a/gtk/gtkobject.c b/gtk/gtkobject.c
new file mode 100644 (file)
index 0000000..ffe487e
--- /dev/null
@@ -0,0 +1,994 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdarg.h>
+#include <string.h>
+#include "gtkobject.h"
+#include "gtksignal.h"
+
+
+#define OBJECT_DATA_ID_CHUNK  1024
+
+
+enum {
+  DESTROY,
+  LAST_SIGNAL
+};
+
+
+typedef struct _GtkObjectData  GtkObjectData;
+typedef struct _GtkArgInfo     GtkArgInfo;
+
+struct _GtkObjectData
+{
+  guint id;
+  gpointer data;
+  GtkObjectData *next;
+};
+
+struct _GtkArgInfo
+{
+  char *name;
+  GtkType type;
+};
+
+
+static void           gtk_object_class_init    (GtkObjectClass *klass);
+static void           gtk_object_init          (GtkObject      *object);
+static void           gtk_object_arg           (GtkObject      *object,
+                                               GtkArg         *arg);
+static void           gtk_real_object_destroy  (GtkObject      *object);
+static void           gtk_object_data_init     (void);
+static GtkObjectData* gtk_object_data_new      (void);
+static void           gtk_object_data_destroy  (GtkObjectData  *odata);
+static guint*         gtk_object_data_id_alloc (void);
+GtkArg*               gtk_object_collect_args  (gint    *nargs,
+                                               va_list  args1,
+                                               va_list  args2);
+
+
+static gint object_signals[LAST_SIGNAL] = { 0 };
+
+static gint object_data_init = TRUE;
+static GHashTable *object_data_ht = NULL;
+static GMemChunk *object_data_mem_chunk = NULL;
+static GtkObjectData *object_data_free_list = NULL;
+static GSList *object_data_id_list = NULL;
+static gint object_data_id_index = 0;
+
+static GHashTable *arg_info_ht = NULL;
+
+static const char *user_data_key = "user_data";
+
+
+/*****************************************
+ * gtk_object_get_type:
+ *
+ *   arguments:
+ *
+ *   results:
+ *     The type identifier for GtkObject's
+ *****************************************/
+
+void
+gtk_object_init_type ()
+{
+  GtkType object_type = 0;
+  GtkTypeInfo object_info =
+  {
+    "GtkObject",
+    sizeof (GtkObject),
+    sizeof (GtkObjectClass),
+    (GtkClassInitFunc) gtk_object_class_init,
+    (GtkObjectInitFunc) gtk_object_init,
+    (GtkArgFunc) gtk_object_arg,
+  };
+
+  object_type = gtk_type_unique (0, &object_info);
+  g_assert (object_type == GTK_TYPE_OBJECT);
+}
+
+GtkType
+gtk_object_get_type ()
+{
+  return GTK_TYPE_OBJECT;
+}
+
+/*****************************************
+ * gtk_object_class_init:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static void
+gtk_object_class_init (GtkObjectClass *class)
+{
+  class->signals = NULL;
+  class->nsignals = 0;
+
+  gtk_object_add_arg_type ("GtkObject::user_data", GTK_TYPE_POINTER);
+  gtk_object_add_arg_type ("GtkObject::signal", GTK_TYPE_SIGNAL);
+
+  object_signals[DESTROY] =
+    gtk_signal_new ("destroy",
+                    GTK_RUN_LAST,
+                    class->type,
+                    GTK_SIGNAL_OFFSET (GtkObjectClass, destroy),
+                    gtk_signal_default_marshaller,
+                   GTK_TYPE_NONE, 0);
+
+  gtk_object_class_add_signals (class, object_signals, LAST_SIGNAL);
+
+  class->destroy = gtk_real_object_destroy;
+}
+
+/*****************************************
+ * gtk_object_init:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static void
+gtk_object_init (GtkObject *object)
+{
+  object->flags = 0;
+  object->ref_count = 0;
+  object->object_data = NULL;
+}
+
+/*****************************************
+ * gtk_object_arg:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static void
+gtk_object_arg (GtkObject *object,
+               GtkArg    *arg)
+{
+  if (strcmp (arg->name, "user_data") == 0)
+    {
+      gtk_object_set_user_data (object, GTK_VALUE_POINTER (*arg));
+    }
+  else if (strncmp (arg->name, "signal", 6) == 0)
+    {
+      if ((arg->name[6] != ':') || (arg->name[7] != ':'))
+       {
+         g_print ("invalid signal argument: \"%s\"\n", arg->name);
+         return;
+       }
+
+      gtk_signal_connect (object, arg->name + 8,
+                         (GtkSignalFunc) GTK_VALUE_SIGNAL (*arg).f,
+                         GTK_VALUE_SIGNAL (*arg).d);
+    }
+}
+
+/*****************************************
+ * gtk_object_class_add_signals:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_object_class_add_signals (GtkObjectClass *class,
+                             gint           *signals,
+                             gint            nsignals)
+{
+  gint *new_signals;
+  gint i;
+
+  g_return_if_fail (class != NULL);
+
+  new_signals = g_new (gint, class->nsignals + nsignals);
+  for (i = 0; i < class->nsignals; i++)
+    new_signals[i] = class->signals[i];
+  for (i = 0; i < nsignals; i++)
+    new_signals[class->nsignals + i] = signals[i];
+
+  class->signals = new_signals;
+  class->nsignals += nsignals;
+}
+
+/*****************************************
+ * gtk_object_ref:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_object_ref (GtkObject *object)
+{
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_OBJECT (object));
+
+  object->ref_count += 1;
+}
+
+/*****************************************
+ * gtk_object_new:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_object_unref (GtkObject *object)
+{
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_OBJECT (object));
+
+  if (object->ref_count > 0)
+    object->ref_count -= 1;
+}
+
+/*****************************************
+ * gtk_object_new:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+GtkObject*
+gtk_object_new (guint type,
+               ...)
+{
+  GtkObject *obj;
+  GtkArg *args;
+  gint nargs;
+  va_list args1;
+  va_list args2;
+
+  obj = gtk_type_new (type);
+
+  va_start (args1, type);
+  va_start (args2, type);
+
+  args = gtk_object_collect_args (&nargs, args1, args2);
+  gtk_object_setv (obj, nargs, args);
+  g_free (args);
+
+  va_end (args1);
+  va_end (args2);
+
+  return obj;
+}
+
+/*****************************************
+ * gtk_object_newv:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+GtkObject*
+gtk_object_newv (guint   type,
+                gint    nargs,
+                GtkArg *args)
+{
+  gpointer obj;
+
+  obj = gtk_type_new (type);
+  gtk_object_setv (obj, nargs, args);
+
+  return obj;
+}
+
+/*****************************************
+ * gtk_object_set:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_object_set (GtkObject *obj,
+               ...)
+{
+  GtkArg *args;
+  gint nargs;
+  va_list args1;
+  va_list args2;
+
+  g_return_if_fail (obj != NULL);
+
+  va_start (args1, obj);
+  va_start (args2, obj);
+
+  args = gtk_object_collect_args (&nargs, args1, args2);
+  gtk_object_setv (obj, nargs, args);
+  g_free (args);
+
+  va_end (args1);
+  va_end (args2);
+}
+
+/*****************************************
+ * gtk_object_setv:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_object_setv (GtkObject *obj,
+                gint       nargs,
+                GtkArg    *args)
+{
+  guint class_type;
+  char class_name[1024];
+  char *arg_name;
+  int i;
+
+  g_return_if_fail (obj != NULL);
+
+  for (i = 0; i < nargs; i++)
+    {
+      arg_name = strchr (args[i].name, ':');
+      if (!arg_name || (arg_name[0] != ':') || (arg_name[1] != ':'))
+       {
+         g_print ("invalid arg name: \"%s\"\n", args[i].name);
+         continue;
+       }
+
+      strncpy (class_name, args[i].name, (long) (arg_name - args[i].name));
+      class_name[(long) (arg_name - args[i].name)] = '\0';
+
+      args[i].name = arg_name + 2;
+
+      class_type = gtk_type_from_name (class_name);
+      gtk_type_set_arg (obj, class_type, &args[i]);
+    }
+}
+
+/*****************************************
+ * gtk_object_add_arg_type:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_object_add_arg_type (const char *arg_name,
+                        GtkType     arg_type)
+{
+  GtkArgInfo *info;
+
+  info = g_new (GtkArgInfo, 1);
+  info->name = g_strdup(arg_name);
+  info->type = arg_type;
+
+  if (!arg_info_ht)
+    arg_info_ht = g_hash_table_new (g_string_hash, g_string_equal);
+
+  g_hash_table_insert (arg_info_ht, info->name, info);
+}
+
+/*****************************************
+ * gtk_object_get_arg_type:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+GtkType
+gtk_object_get_arg_type (const char *arg_name)
+{
+  GtkArgInfo *info;
+  char buffer[1024];
+  char *t;
+
+  if (!arg_info_ht)
+    return GTK_TYPE_INVALID;
+
+  t = strchr (arg_name, ':');
+  if (!t || (t[0] != ':') || (t[1] != ':'))
+    {
+      g_print ("invalid arg name: \"%s\"\n", arg_name);
+      return GTK_TYPE_INVALID;
+    }
+
+  t = strchr (t + 2, ':');
+  if (t)
+    {
+      strncpy (buffer, arg_name, (long) (t - arg_name));
+      buffer[(long) (t - arg_name)] = '\0';
+      arg_name = buffer;
+    }
+
+  info = g_hash_table_lookup (arg_info_ht, (gpointer) arg_name);
+  if (info)
+    return info->type;
+
+  return GTK_TYPE_INVALID;
+}
+
+/*****************************************
+ * gtk_object_destroy:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_object_destroy (GtkObject *object)
+{
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_OBJECT (object));
+
+  if ((object->ref_count > 0) || GTK_OBJECT_IN_CALL (object))
+    {
+      GTK_OBJECT_SET_FLAGS (object, GTK_NEED_DESTROY);
+    }
+  else
+    {
+      GTK_OBJECT_UNSET_FLAGS (object, GTK_NEED_DESTROY);
+      GTK_OBJECT_SET_FLAGS (object, GTK_BEING_DESTROYED);
+
+      gtk_signal_emit (object, object_signals[DESTROY]);
+    }
+}
+
+/*****************************************
+ * gtk_object_set_data:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_object_set_data (GtkObject   *object,
+                    const gchar *key,
+                    gpointer     data)
+{
+  GtkObjectData *odata;
+  GtkObjectData *prev;
+  guint *id;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_OBJECT (object));
+  g_return_if_fail (key != NULL);
+
+  if (object_data_init)
+    gtk_object_data_init ();
+
+  id = g_hash_table_lookup (object_data_ht, (gpointer) key);
+
+  if (!data)
+    {
+      if (id)
+       {
+         prev = NULL;
+         odata = object->object_data;
+
+         while (odata)
+           {
+             if (odata->id == *id)
+               {
+                 if (prev)
+                   prev->next = odata->next;
+                 if (odata == object->object_data)
+                   object->object_data = odata->next;
+
+                 gtk_object_data_destroy (odata);
+                 break;
+               }
+
+             prev = odata;
+             odata = odata->next;
+           }
+       }
+    }
+  else
+    {
+      if (!id)
+       {
+         id = gtk_object_data_id_alloc ();
+         g_hash_table_insert (object_data_ht, (gpointer) key, id);
+       }
+
+      odata = object->object_data;
+      while (odata)
+       {
+         if (odata->id == *id)
+           {
+             odata->data = data;
+             return;
+           }
+
+         odata = odata->next;
+       }
+
+      odata = gtk_object_data_new ();
+      odata->id = *id;
+      odata->data = data;
+
+      odata->next = object->object_data;
+      object->object_data = odata;
+    }
+}
+
+/*****************************************
+ * gtk_object_get_data:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+gpointer
+gtk_object_get_data (GtkObject   *object,
+                    const gchar *key)
+{
+  GtkObjectData *odata;
+  guint *id;
+
+  g_return_val_if_fail (object != NULL, NULL);
+  g_return_val_if_fail (GTK_IS_OBJECT (object), NULL);
+  g_return_val_if_fail (key != NULL, NULL);
+
+  if (object_data_init)
+    gtk_object_data_init ();
+
+  id = g_hash_table_lookup (object_data_ht, (gpointer) key);
+  if (id)
+    {
+      odata = object->object_data;
+      while (odata)
+       {
+         if (odata->id == *id)
+           return odata->data;
+         odata = odata->next;
+       }
+    }
+
+  return NULL;
+}
+
+/*****************************************
+ * gtk_object_remove_data:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_object_remove_data (GtkObject   *object,
+                       const gchar *key)
+{
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_OBJECT (object));
+  g_return_if_fail (key != NULL);
+
+  gtk_object_set_data (object, key, NULL);
+}
+
+/*****************************************
+ * gtk_object_set_user_data:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_object_set_user_data (GtkObject *object,
+                         gpointer   data)
+{
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_OBJECT (object));
+
+  gtk_object_set_data (object, user_data_key, data);
+}
+
+/*****************************************
+ * gtk_object_get_user_data:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+gpointer
+gtk_object_get_user_data (GtkObject *object)
+{
+  g_return_val_if_fail (object != NULL, NULL);
+  g_return_val_if_fail (GTK_IS_OBJECT (object), NULL);
+
+  return gtk_object_get_data (object, user_data_key);
+}
+
+/*****************************************
+ * gtk_object_check_cast:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+GtkObject*
+gtk_object_check_cast (GtkObject *obj,
+                      GtkType    cast_type)
+{
+  if (obj && obj->klass && !gtk_type_is_a (obj->klass->type, cast_type))
+    {
+      gchar *from_name = gtk_type_name (obj->klass->type);
+      gchar *to_name = gtk_type_name (cast_type);
+
+      g_warning ("invalid cast from \"%s\" to \"%s\"",
+                from_name ? from_name : "(unknown)",
+                to_name ? to_name : "(unknown)");
+    }
+
+  return obj;
+}
+
+/*****************************************
+ * gtk_object_check_class_cast:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+GtkObjectClass*
+gtk_object_check_class_cast (GtkObjectClass *klass,
+                            GtkType         cast_type)
+{
+  if (klass && !gtk_type_is_a (klass->type, cast_type))
+    g_warning ("invalid cast from \"%sClass\" to \"%sClass\"",
+              gtk_type_name (klass->type),
+              gtk_type_name (cast_type));
+
+  return klass;
+}
+
+/*****************************************
+ * gtk_real_object_destroy:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static void
+gtk_real_object_destroy (GtkObject *object)
+{
+  GtkObjectData *odata;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_OBJECT (object));
+
+  gtk_signal_handlers_destroy (object);
+
+  if (object->object_data)
+    {
+      odata = object->object_data;
+      while (odata->next)
+       odata = odata->next;
+
+      odata->next = object_data_free_list;
+      object_data_free_list = object->object_data;
+    }
+
+  g_free (object);
+}
+
+/*****************************************
+ * gtk_object_data_init:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static void
+gtk_object_data_init ()
+{
+  if (object_data_init)
+    {
+      object_data_init = FALSE;
+
+      object_data_ht = g_hash_table_new (g_string_hash, g_string_equal);
+    }
+}
+
+/*****************************************
+ * gtk_object_data_new:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static GtkObjectData*
+gtk_object_data_new ()
+{
+  GtkObjectData *odata;
+
+  if (!object_data_mem_chunk)
+    object_data_mem_chunk = g_mem_chunk_new ("object data mem chunk",
+                                            sizeof (GtkObjectData),
+                                            1024, G_ALLOC_AND_FREE);
+
+  odata = g_chunk_new (GtkObjectData, object_data_mem_chunk);
+
+  odata->id = 0;
+  odata->data = NULL;
+  odata->next = NULL;
+
+  return odata;
+}
+
+/*****************************************
+ * gtk_object_data_destroy:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static void
+gtk_object_data_destroy (GtkObjectData *odata)
+{
+  g_return_if_fail (odata != NULL);
+
+  g_mem_chunk_free (object_data_mem_chunk, odata);
+}
+
+/*****************************************
+ * gtk_object_data_id_alloc:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static guint*
+gtk_object_data_id_alloc ()
+{
+  static guint next_id = 1;
+  guint *ids;
+
+  if (!object_data_id_list ||
+      (object_data_id_index == OBJECT_DATA_ID_CHUNK))
+    {
+      ids = g_new (guint, OBJECT_DATA_ID_CHUNK);
+      object_data_id_index = 0;
+      object_data_id_list = g_slist_prepend (object_data_id_list, ids);
+    }
+  else
+    {
+      ids = object_data_id_list->data;
+    }
+
+  ids[object_data_id_index] = next_id++;
+  return &ids[object_data_id_index++];
+}
+
+/*****************************************
+ * gtk_object_data_id_alloc:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+GtkArg*
+gtk_object_collect_args (gint    *nargs,
+                        va_list  args1,
+                        va_list  args2)
+{
+  GtkArg *args;
+  GtkType type;
+  char *name;
+  int done;
+  int i, n;
+
+  n = 0;
+  done = FALSE;
+
+  while (!done)
+    {
+      name = va_arg (args1, char *);
+      if (!name)
+       {
+         done = TRUE;
+         continue;
+       }
+
+      type = gtk_object_get_arg_type (name);
+
+      switch (GTK_FUNDAMENTAL_TYPE (type))
+       {
+       case GTK_TYPE_INVALID:
+         g_print ("invalid arg name: \"%s\" %x\n", name, type);
+         (void) va_arg (args1, long);
+         continue;
+       case GTK_TYPE_NONE:
+         break;
+       case GTK_TYPE_CHAR:
+       case GTK_TYPE_BOOL:
+       case GTK_TYPE_INT:
+       case GTK_TYPE_UINT:
+       case GTK_TYPE_ENUM:
+       case GTK_TYPE_FLAGS:
+         (void) va_arg (args1, gint);
+         break;
+       case GTK_TYPE_LONG:
+       case GTK_TYPE_ULONG:
+         (void) va_arg (args1, glong);
+         break;
+       case GTK_TYPE_FLOAT:
+         (void) va_arg (args1, gfloat);
+         break;
+       case GTK_TYPE_STRING:
+         (void) va_arg (args1, gchar*);
+         break;
+       case GTK_TYPE_POINTER:
+       case GTK_TYPE_BOXED:
+         (void) va_arg (args1, gpointer);
+         break;
+       case GTK_TYPE_SIGNAL:
+         (void) va_arg (args1, GtkFunction);
+         (void) va_arg (args1, gpointer);
+         break;
+       case GTK_TYPE_FOREIGN:
+         (void) va_arg (args1, gpointer);
+         (void) va_arg (args1, GtkDestroyNotify);
+         break;
+       case GTK_TYPE_CALLBACK:
+         (void) va_arg (args1, GtkCallbackMarshal);
+         (void) va_arg (args1, gpointer);
+         (void) va_arg (args1, GtkDestroyNotify);
+         break;
+       case GTK_TYPE_C_CALLBACK:
+         (void) va_arg (args1, GtkFunction);
+         (void) va_arg (args1, gpointer);
+         break;
+       case GTK_TYPE_ARGS:
+         (void) va_arg (args1, gint);
+         (void) va_arg (args1, GtkArg*);
+         break;
+       case GTK_TYPE_OBJECT:
+         (void) va_arg (args1, GtkObject*);
+         break;
+       default:
+         g_error ("unsupported type %s in args", gtk_type_name (type));
+         break;
+       }
+
+      n += 1;
+    }
+
+  *nargs = n;
+  args = NULL;
+
+  if (n > 0)
+    {
+      args = g_new0 (GtkArg, n);
+
+      for (i = 0; i < n; i++)
+       {
+         args[i].name = va_arg (args2, char *);
+         args[i].type = gtk_object_get_arg_type (args[i].name);
+
+         switch (GTK_FUNDAMENTAL_TYPE (args[i].type))
+           {
+           case GTK_TYPE_INVALID:
+             (void) va_arg (args2, long);
+             i -= 1;
+             continue;
+           case GTK_TYPE_NONE:
+             break;
+           case GTK_TYPE_CHAR:
+             GTK_VALUE_CHAR(args[i]) = va_arg (args2, gint);
+             break;
+           case GTK_TYPE_BOOL:
+             GTK_VALUE_BOOL(args[i]) = va_arg (args2, gint);
+             break;
+           case GTK_TYPE_INT:
+             GTK_VALUE_INT(args[i]) = va_arg (args2, gint);
+             break;
+           case GTK_TYPE_UINT:
+             GTK_VALUE_UINT(args[i]) = va_arg (args2, guint);
+             break;
+           case GTK_TYPE_ENUM:
+             GTK_VALUE_ENUM(args[i]) = va_arg (args2, gint);
+             break;
+           case GTK_TYPE_FLAGS:
+             GTK_VALUE_FLAGS(args[i]) = va_arg (args2, gint);
+             break;
+           case GTK_TYPE_LONG:
+             GTK_VALUE_LONG(args[i]) = va_arg (args2, glong);
+             break;
+           case GTK_TYPE_ULONG:
+             GTK_VALUE_ULONG(args[i]) = va_arg (args2, gulong);
+             break;
+           case GTK_TYPE_FLOAT:
+             GTK_VALUE_FLOAT(args[i]) = va_arg (args2, gfloat);
+             break;
+           case GTK_TYPE_STRING:
+             GTK_VALUE_STRING(args[i]) = va_arg (args2, gchar*);
+             break;
+           case GTK_TYPE_POINTER:
+             GTK_VALUE_POINTER(args[i]) = va_arg (args2, gpointer);
+             break;
+           case GTK_TYPE_BOXED:
+             GTK_VALUE_BOXED(args[i]) = va_arg (args2, gpointer);
+             break;
+           case GTK_TYPE_SIGNAL:
+             GTK_VALUE_SIGNAL(args[i]).f = va_arg (args2, GtkFunction);
+             GTK_VALUE_SIGNAL(args[i]).d = va_arg (args2, gpointer);
+             break;
+           case GTK_TYPE_FOREIGN:
+             GTK_VALUE_FOREIGN(args[i]).data = va_arg (args2, gpointer);
+             GTK_VALUE_FOREIGN(args[i]).notify =
+               va_arg (args2, GtkDestroyNotify);
+             break;
+           case GTK_TYPE_CALLBACK:
+             GTK_VALUE_CALLBACK(args[i]).marshal =
+               va_arg (args2, GtkCallbackMarshal);
+             GTK_VALUE_CALLBACK(args[i]).data = va_arg (args2, gpointer);
+             GTK_VALUE_CALLBACK(args[i]).notify =
+               va_arg (args2, GtkDestroyNotify);
+             break;
+           case GTK_TYPE_C_CALLBACK:
+             GTK_VALUE_C_CALLBACK(args[i]).func = va_arg (args2, GtkFunction);
+             GTK_VALUE_C_CALLBACK(args[i]).func_data =
+               va_arg (args2, gpointer);
+             break;
+           case GTK_TYPE_ARGS:
+             GTK_VALUE_ARGS(args[i]).n_args = va_arg (args2, gint);
+             GTK_VALUE_ARGS(args[i]).args = va_arg (args2, GtkArg*);
+             break;
+           case GTK_TYPE_OBJECT:
+             GTK_VALUE_OBJECT(args[i]) = va_arg (args2, GtkObject*);
+             g_assert (GTK_VALUE_OBJECT(args[i]) == NULL ||
+                       GTK_CHECK_TYPE (GTK_VALUE_OBJECT(args[i]),
+                                       args[i].type));
+             break;
+           default:
+             g_error ("unsupported type %s in args",
+                      gtk_type_name (args[i].type));
+             break;
+           }
+       }
+    }
+
+  return args;
+}
diff --git a/gtk/gtkobject.h b/gtk/gtkobject.h
new file mode 100644 (file)
index 0000000..023bbbf
--- /dev/null
@@ -0,0 +1,250 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_OBJECT_H__
+#define __GTK_OBJECT_H__
+
+
+#include <gtk/gtkenums.h>
+#include <gtk/gtktypeutils.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* GtkObject only uses the first 3 bits of the "flags" field.
+ *  They refer to the following flags.
+ * GtkWidget uses the remaining bits. Though this is a kinda nasty
+ *  break up, it does make the size of GtkWidget smaller.
+ */
+enum
+{
+  GTK_NEED_DESTROY      = 1 << 0,
+  GTK_BEING_DESTROYED   = 1 << 1,
+  GTK_IN_CALL           = 1 << 2
+};
+
+
+/* The debugging versions of the casting macros make sure the cast is "ok"
+ *  before proceeding, but they are definately slower than their less
+ *  careful counterparts as they involve no less than 3 function calls.
+ */
+#ifdef NDEBUG
+
+#define GTK_CHECK_CAST(obj,cast_type,cast)         ((cast*) obj)
+#define GTK_CHECK_CLASS_CAST(klass,cast_type,cast) ((cast*) klass)
+
+#else /* NDEBUG */
+
+#define GTK_CHECK_CAST(obj,cast_type,cast) \
+  ((cast*) gtk_object_check_cast ((GtkObject*) obj, cast_type))
+
+#define GTK_CHECK_CLASS_CAST(klass,cast_type,cast) \
+  ((cast*) gtk_object_check_class_cast ((GtkObjectClass*) klass, cast_type))
+
+#endif /* NDEBUG */
+
+
+/* Determines whether 'obj' is a type of 'otype'.
+ */
+#define GTK_CHECK_TYPE(obj,otype)  (gtk_type_is_a (((GtkObject*) obj)->klass->type, otype))
+
+
+/* Macro for casting a pointer to a GtkObject pointer.
+ */
+#define GTK_OBJECT(obj)                   GTK_CHECK_CAST (obj, gtk_object_get_type (), GtkObject)
+
+/* Macros for extracting various fields from GtkObject and
+ *  GtkObjectClass.
+ */
+#define GTK_OBJECT_CLASS(klass)           GTK_CHECK_CLASS_CAST (klass, gtk_object_get_type (), GtkObjectClass)
+#define GTK_OBJECT_FLAGS(obj)             (GTK_OBJECT (obj)->flags)
+#define GTK_OBJECT_NEED_DESTROY(obj)      (GTK_OBJECT_FLAGS (obj) & GTK_NEED_DESTROY)
+#define GTK_OBJECT_BEING_DESTROYED(obj)   (GTK_OBJECT_FLAGS (obj) & GTK_BEING_DESTROYED)
+#define GTK_OBJECT_IN_CALL(obj)           (GTK_OBJECT_FLAGS (obj) & GTK_IN_CALL)
+#define GTK_OBJECT_DESTROY(obj)           (GTK_OBJECT (obj)->klass->destroy)
+#define GTK_OBJECT_TYPE(obj)              (GTK_OBJECT (obj)->klass->type)
+#define GTK_OBJECT_SIGNALS(obj)           (GTK_OBJECT (obj)->klass->signals)
+#define GTK_OBJECT_NSIGNALS(obj)          (GTK_OBJECT (obj)->klass->signals)
+
+/* Macro for testing whether "obj" is of type GtkObject.
+ */
+#define GTK_IS_OBJECT(obj)                GTK_CHECK_TYPE (obj, gtk_object_get_type ())
+
+/* Macros for setting and clearing bits in the "flags" field of GtkObject.
+ */
+#define GTK_OBJECT_SET_FLAGS(obj,flag)    (GTK_OBJECT_FLAGS (obj) |= (flag))
+#define GTK_OBJECT_UNSET_FLAGS(obj,flag)  (GTK_OBJECT_FLAGS (obj) &= ~(flag))
+
+
+typedef struct _GtkObjectClass  GtkObjectClass;
+
+
+/* GtkObject is the base of the object hierarchy. It defines
+ *  the few basic items that all derived classes contain.
+ */
+struct _GtkObject
+{
+  /* 32 bits of flags. GtkObject only uses 3 of these bits and
+   *  GtkWidget uses the rest. This is done because structs are
+   *  aligned on 4 or 8 byte boundaries. If bitfields were used
+   *  both here and in GtkWidget much space would be wasted.
+   */
+  guint32 flags;
+
+  /* 16 bit reference count. "gtk_object_destroy" actually only
+   *  destroys an object when its ref count is 0. (Decrementing
+   *  a reference count of 0 is defined as a no-op).
+   */
+  guint16 ref_count;
+
+  /* A pointer to the objects class. This will actually point to
+   *  the derived objects class struct (which will be derived from
+   *  GtkObjectClass).
+   */
+  GtkObjectClass *klass;
+
+  /* The list of signal handlers and other data
+   *  fields for this object.
+   */
+  gpointer object_data;
+};
+
+/* GtkObjectClass is the base of the class hierarchy. It defines
+ *  the basic necessities for the class mechanism to work. Namely,
+ *  the "type", "signals" and "nsignals" fields.
+ */
+struct _GtkObjectClass
+{
+  /* The type identifier for the objects class. There is
+   *  one unique identifier per class.
+   */
+  guint type;
+
+  /* The signals this object class handles. "signals" is an
+   *  array of signal ID's.
+   */
+  gint *signals;
+
+  /* The number of signals listed in "signals".
+   */
+  gint nsignals;
+
+  /* The destroy function for objects. In one way ore another
+   *  this is defined for all objects. If an object class overrides
+   *  this method in order to perform class specific destruction
+   *  then it should still call it after it is finished with its
+   *  own cleanup. (See the destroy function for GtkWidget for
+   *  an example of how to do this).
+   */
+  void (* destroy) (GtkObject *object);
+};
+
+
+/* Get the type identifier for GtkObject's.
+ */
+guint gtk_object_get_type (void);
+
+/* Append "signals" to those already defined in "class".
+ */
+void gtk_object_class_add_signals (GtkObjectClass *klass,
+                                  gint           *signals,
+                                  gint            nsignals);
+
+void gtk_object_ref (GtkObject *object);
+
+void gtk_object_unref (GtkObject *object);
+
+GtkObject* gtk_object_new (guint type,
+                          ...);
+
+GtkObject* gtk_object_newv (guint   type,
+                           gint    nargs,
+                           GtkArg *args);
+
+void gtk_object_set (GtkObject *obj,
+                    ...);
+
+void gtk_object_setv (GtkObject *obj,
+                     gint       nargs,
+                     GtkArg    *args);
+
+void gtk_object_add_arg_type (const char *arg_name,
+                             GtkType     arg_type);
+
+GtkType gtk_object_get_arg_type (const char *arg_name);
+
+/* Emit the "destroy" signal for "object". Normally it is
+ *  permissible to emit a signal for an object instead of
+ *  calling the corresponding convenience routine, however
+ *  "gtk_object_destroy" should be called instead of emitting
+ *  the signal manually as it checks to see if the object is
+ *  currently handling another signal emittion (very likely)
+ *  and sets the GTK_NEED_DESTROY flag which tells the object
+ *  to be destroyed when it is done handling the signal emittion.
+ */
+void gtk_object_destroy (GtkObject *object);
+
+/* Set 'data' to the "object_data" field of the object. The
+ *  data is indexed by the "key". If there is already data
+ *  associated with "key" then the new data will replace it.
+ *  If 'data' is NULL then this call is equivalent to
+ *  'gtk_object_remove_data'.
+ */
+void gtk_object_set_data (GtkObject   *object,
+                         const gchar *key,
+                         gpointer     data);
+
+/* Get the data associated with "key".
+ */
+gpointer gtk_object_get_data (GtkObject   *object,
+                             const gchar *key);
+
+/* Remove the data associated with "key". This call is
+ *  equivalent to 'gtk_object_set_data' where 'data' is NULL.
+ */
+void gtk_object_remove_data (GtkObject   *object,
+                            const gchar *key);
+
+/* Set the "user_data" object data field of "object". It should
+ *  be noted that this is no different than calling 'gtk_object_data_add'
+ *  with a key of "user_data". It is merely provided as a convenience.
+ */
+void gtk_object_set_user_data (GtkObject *object,
+                              gpointer   data);
+
+/* Get the "user_data" object data field of "object". It should
+ *  be noted that this is no different than calling 'gtk_object_data_find'
+ *  with a key of "user_data". It is merely provided as a convenience.
+ */
+gpointer gtk_object_get_user_data (GtkObject *object);
+
+GtkObject* gtk_object_check_cast (GtkObject *obj,
+                                 GtkType    cast_type);
+
+GtkObjectClass* gtk_object_check_class_cast (GtkObjectClass *klass,
+                                            GtkType         cast_type);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_OBJECT_H__ */
diff --git a/gtk/gtkoptionmenu.c b/gtk/gtkoptionmenu.c
new file mode 100644 (file)
index 0000000..919aa26
--- /dev/null
@@ -0,0 +1,584 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkmenu.h"
+#include "gtkmenuitem.h"
+#include "gtkoptionmenu.h"
+#include "gtksignal.h"
+
+
+#define CHILD_LEFT_SPACING        5
+#define CHILD_RIGHT_SPACING       1
+#define CHILD_TOP_SPACING         1
+#define CHILD_BOTTOM_SPACING      1
+#define OPTION_INDICATOR_WIDTH    12
+#define OPTION_INDICATOR_HEIGHT   8
+#define OPTION_INDICATOR_SPACING  2
+
+
+static void gtk_option_menu_class_init      (GtkOptionMenuClass *klass);
+static void gtk_option_menu_init            (GtkOptionMenu      *option_menu);
+static void gtk_option_menu_destroy         (GtkObject          *object);
+static void gtk_option_menu_size_request    (GtkWidget          *widget,
+                                            GtkRequisition     *requisition);
+static void gtk_option_menu_size_allocate   (GtkWidget          *widget,
+                                            GtkAllocation      *allocation);
+static void gtk_option_menu_paint           (GtkWidget          *widget,
+                                            GdkRectangle       *area);
+static void gtk_option_menu_draw            (GtkWidget          *widget,
+                                            GdkRectangle       *area);
+static gint gtk_option_menu_expose          (GtkWidget          *widget,
+                                            GdkEventExpose     *event);
+static gint gtk_option_menu_button_press    (GtkWidget          *widget,
+                                            GdkEventButton     *event);
+static void gtk_option_menu_deactivate      (GtkMenuShell       *menu_shell,
+                                            GtkOptionMenu      *option_menu);
+static void gtk_option_menu_update_contents (GtkOptionMenu      *option_menu);
+static void gtk_option_menu_remove_contents (GtkOptionMenu      *option_menu);
+static void gtk_option_menu_calc_size       (GtkOptionMenu      *option_menu);
+static void gtk_option_menu_position        (GtkMenu            *menu,
+                                            gint               *x,
+                                            gint               *y,
+                                            gpointer            user_data);
+
+
+static GtkButtonClass *parent_class = NULL;
+
+
+guint
+gtk_option_menu_get_type ()
+{
+  static guint option_menu_type = 0;
+
+  if (!option_menu_type)
+    {
+      GtkTypeInfo option_menu_info =
+      {
+       "GtkOptionMenu",
+       sizeof (GtkOptionMenu),
+       sizeof (GtkOptionMenuClass),
+       (GtkClassInitFunc) gtk_option_menu_class_init,
+       (GtkObjectInitFunc) gtk_option_menu_init,
+       (GtkArgFunc) NULL,
+      };
+
+      option_menu_type = gtk_type_unique (gtk_button_get_type (), &option_menu_info);
+    }
+
+  return option_menu_type;
+}
+
+static void
+gtk_option_menu_class_init (GtkOptionMenuClass *class)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+  GtkButtonClass *button_class;
+
+  object_class = (GtkObjectClass*) class;
+  widget_class = (GtkWidgetClass*) class;
+  button_class = (GtkButtonClass*) class;
+
+  parent_class = gtk_type_class (gtk_button_get_type ());
+
+  object_class->destroy = gtk_option_menu_destroy;
+
+  widget_class->draw = gtk_option_menu_draw;
+  widget_class->draw_focus = NULL;
+  widget_class->size_request = gtk_option_menu_size_request;
+  widget_class->size_allocate = gtk_option_menu_size_allocate;
+  widget_class->expose_event = gtk_option_menu_expose;
+  widget_class->button_press_event = gtk_option_menu_button_press;
+}
+
+static void
+gtk_option_menu_init (GtkOptionMenu *option_menu)
+{
+  GTK_WIDGET_UNSET_FLAGS (option_menu, GTK_CAN_FOCUS);
+
+  option_menu->menu = NULL;
+  option_menu->menu_item = NULL;
+  option_menu->width = 0;
+  option_menu->height = 0;
+}
+
+GtkWidget*
+gtk_option_menu_new ()
+{
+  return GTK_WIDGET (gtk_type_new (gtk_option_menu_get_type ()));
+}
+
+GtkWidget*
+gtk_option_menu_get_menu (GtkOptionMenu *option_menu)
+{
+  g_return_val_if_fail (option_menu != NULL, NULL);
+  g_return_val_if_fail (GTK_IS_OPTION_MENU (option_menu), NULL);
+
+  return option_menu->menu;
+}
+
+void
+gtk_option_menu_set_menu (GtkOptionMenu *option_menu,
+                         GtkWidget     *menu)
+{
+  g_return_if_fail (option_menu != NULL);
+  g_return_if_fail (GTK_IS_OPTION_MENU (option_menu));
+  g_return_if_fail (menu != NULL);
+  g_return_if_fail (GTK_IS_MENU (menu));
+
+  gtk_option_menu_remove_menu (option_menu);
+
+  option_menu->menu = menu;
+  gtk_object_ref (GTK_OBJECT (option_menu->menu));
+
+  gtk_option_menu_calc_size (option_menu);
+
+  gtk_signal_connect (GTK_OBJECT (option_menu->menu), "deactivate",
+                     (GtkSignalFunc) gtk_option_menu_deactivate,
+                     option_menu);
+
+  if (GTK_WIDGET (option_menu)->parent)
+    gtk_widget_queue_resize (GTK_WIDGET (option_menu));
+
+  gtk_option_menu_update_contents (option_menu);
+}
+
+void
+gtk_option_menu_remove_menu (GtkOptionMenu *option_menu)
+{
+  g_return_if_fail (option_menu != NULL);
+  g_return_if_fail (GTK_IS_OPTION_MENU (option_menu));
+
+  if (option_menu->menu)
+    {
+      gtk_option_menu_remove_contents (option_menu);
+      gtk_signal_disconnect_by_data (GTK_OBJECT (option_menu->menu),
+                                    option_menu);
+
+      gtk_object_unref (GTK_OBJECT (option_menu->menu));
+      option_menu->menu = NULL;
+    }
+}
+
+void
+gtk_option_menu_set_history (GtkOptionMenu *option_menu,
+                            gint           index)
+{
+  GtkWidget *menu_item;
+
+  g_return_if_fail (option_menu != NULL);
+  g_return_if_fail (GTK_IS_OPTION_MENU (option_menu));
+
+  if (option_menu->menu)
+    {
+      gtk_menu_set_active (GTK_MENU (option_menu->menu), index);
+      menu_item = gtk_menu_get_active (GTK_MENU (option_menu->menu));
+
+      if (menu_item != option_menu->menu_item)
+       {
+         gtk_option_menu_remove_contents (option_menu);
+         gtk_option_menu_update_contents (option_menu);
+       }
+    }
+}
+
+
+static void
+gtk_option_menu_destroy (GtkObject *object)
+{
+  GtkOptionMenu *option_menu;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_OPTION_MENU (object));
+
+  option_menu = GTK_OPTION_MENU (object);
+
+  gtk_option_menu_remove_contents (option_menu);
+  if (option_menu->menu)
+    {
+      gtk_object_unref (GTK_OBJECT (option_menu->menu));
+      gtk_widget_destroy (option_menu->menu);
+    }
+
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+gtk_option_menu_size_request (GtkWidget      *widget,
+                             GtkRequisition *requisition)
+{
+  GtkOptionMenu *option_menu;
+  gint tmp;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_OPTION_MENU (widget));
+  g_return_if_fail (requisition != NULL);
+
+  option_menu = GTK_OPTION_MENU (widget);
+
+  requisition->width = ((GTK_CONTAINER (widget)->border_width +
+                        GTK_WIDGET (widget)->style->klass->xthickness) * 2 +
+                       option_menu->width +
+                       OPTION_INDICATOR_WIDTH +
+                       OPTION_INDICATOR_SPACING * 5 +
+                       CHILD_LEFT_SPACING + CHILD_RIGHT_SPACING);
+  requisition->height = ((GTK_CONTAINER (widget)->border_width +
+                         GTK_WIDGET (widget)->style->klass->ythickness) * 2 +
+                        option_menu->height +
+                        CHILD_TOP_SPACING + CHILD_BOTTOM_SPACING);
+
+  tmp = (requisition->height - option_menu->height +
+        OPTION_INDICATOR_HEIGHT + OPTION_INDICATOR_SPACING * 2);
+  requisition->height = MAX (requisition->height, tmp);
+}
+
+static void
+gtk_option_menu_size_allocate (GtkWidget     *widget,
+                              GtkAllocation *allocation)
+{
+  GtkWidget *child;
+  GtkAllocation child_allocation;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_OPTION_MENU (widget));
+  g_return_if_fail (allocation != NULL);
+
+  widget->allocation = *allocation;
+  if (GTK_WIDGET_REALIZED (widget))
+    gdk_window_move_resize (widget->window,
+                           allocation->x, allocation->y,
+                           allocation->width, allocation->height);
+
+  child = GTK_BUTTON (widget)->child;
+  if (child && GTK_WIDGET_VISIBLE (child))
+    {
+      child_allocation.x = (GTK_CONTAINER (widget)->border_width +
+                           GTK_WIDGET (widget)->style->klass->xthickness);
+      child_allocation.y = (GTK_CONTAINER (widget)->border_width +
+                           GTK_WIDGET (widget)->style->klass->ythickness);
+      child_allocation.width = (allocation->width - child_allocation.x * 2 -
+                               OPTION_INDICATOR_WIDTH - OPTION_INDICATOR_SPACING * 5 -
+                               CHILD_LEFT_SPACING - CHILD_RIGHT_SPACING);
+      child_allocation.height = (allocation->height - child_allocation.y * 2 -
+                                CHILD_TOP_SPACING - CHILD_BOTTOM_SPACING);
+      child_allocation.x += CHILD_LEFT_SPACING;
+      child_allocation.y += CHILD_RIGHT_SPACING;
+
+      gtk_widget_size_allocate (child, &child_allocation);
+    }
+}
+
+static void
+gtk_option_menu_paint (GtkWidget    *widget,
+                      GdkRectangle *area)
+{
+  GdkRectangle restrict_area;
+  GdkRectangle new_area;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_OPTION_MENU (widget));
+  g_return_if_fail (area != NULL);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      restrict_area.x = GTK_CONTAINER (widget)->border_width;
+      restrict_area.y = GTK_CONTAINER (widget)->border_width;
+      restrict_area.width = widget->allocation.width - restrict_area.x * 2;
+      restrict_area.height = widget->allocation.height - restrict_area.y * 2;
+
+      if (gdk_rectangle_intersect (area, &restrict_area, &new_area))
+       {
+         gtk_style_set_background (widget->style, widget->window, GTK_WIDGET_STATE (widget));
+         gdk_window_clear_area (widget->window,
+                                new_area.x, new_area.y,
+                                new_area.width, new_area.height);
+
+         gtk_draw_shadow (widget->style, widget->window,
+                          GTK_WIDGET_STATE (widget), GTK_SHADOW_OUT,
+                          restrict_area.x, restrict_area.y,
+                          restrict_area.width, restrict_area.height);
+
+         gtk_draw_shadow (widget->style, widget->window,
+                          GTK_WIDGET_STATE (widget), GTK_SHADOW_OUT,
+                          restrict_area.x + restrict_area.width - restrict_area.x -
+                          OPTION_INDICATOR_WIDTH - OPTION_INDICATOR_SPACING * 4,
+                          restrict_area.y + (restrict_area.height - OPTION_INDICATOR_HEIGHT) / 2,
+                          OPTION_INDICATOR_WIDTH, OPTION_INDICATOR_HEIGHT);
+       }
+    }
+}
+
+static void
+gtk_option_menu_draw (GtkWidget    *widget,
+                     GdkRectangle *area)
+{
+  GtkWidget *child;
+  GdkRectangle child_area;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_OPTION_MENU (widget));
+  g_return_if_fail (area != NULL);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      gtk_option_menu_paint (widget, area);
+
+      child = GTK_BUTTON (widget)->child;
+      if (child && gtk_widget_intersect (child, area, &child_area))
+       gtk_widget_draw (child, &child_area);
+    }
+}
+
+static gint
+gtk_option_menu_expose (GtkWidget      *widget,
+                       GdkEventExpose *event)
+{
+  GtkWidget *child;
+  GdkEventExpose child_event;
+  gint remove_child;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_OPTION_MENU (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      gtk_option_menu_paint (widget, &event->area);
+
+      remove_child = FALSE;
+      child = GTK_BUTTON (widget)->child;
+
+      if (!child)
+       {
+         if (!GTK_OPTION_MENU (widget)->menu)
+           return FALSE;
+         gtk_option_menu_update_contents (GTK_OPTION_MENU (widget));
+         child = GTK_BUTTON (widget)->child;
+         if (!child)
+           return FALSE;
+         remove_child = TRUE;
+       }
+
+      child_event = *event;
+
+      if (GTK_WIDGET_NO_WINDOW (child) &&
+         gtk_widget_intersect (child, &event->area, &child_event.area))
+       gtk_widget_event (child, (GdkEvent*) &child_event);
+
+      if (remove_child)
+       gtk_option_menu_remove_contents (GTK_OPTION_MENU (widget));
+    }
+
+  return FALSE;
+}
+
+static gint
+gtk_option_menu_button_press (GtkWidget      *widget,
+                             GdkEventButton *event)
+{
+  GtkOptionMenu *option_menu;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_OPTION_MENU (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if ((event->type == GDK_BUTTON_PRESS) &&
+      (event->button == 1))
+    {
+      option_menu = GTK_OPTION_MENU (widget);
+      gtk_option_menu_remove_contents (option_menu);
+      gtk_menu_popup (GTK_MENU (option_menu->menu), NULL, NULL,
+                     gtk_option_menu_position, option_menu,
+                     event->button, event->time);
+    }
+
+  return FALSE;
+}
+
+static void
+gtk_option_menu_deactivate (GtkMenuShell  *menu_shell,
+                           GtkOptionMenu *option_menu)
+{
+  g_return_if_fail (menu_shell != NULL);
+  g_return_if_fail (option_menu != NULL);
+  g_return_if_fail (GTK_IS_OPTION_MENU (option_menu));
+
+  gtk_option_menu_update_contents (option_menu);
+}
+
+static void
+gtk_option_menu_update_contents (GtkOptionMenu *option_menu)
+{
+  GtkWidget *child;
+
+  g_return_if_fail (option_menu != NULL);
+  g_return_if_fail (GTK_IS_OPTION_MENU (option_menu));
+
+  if (option_menu->menu)
+    {
+      gtk_option_menu_remove_contents (option_menu);
+
+      option_menu->menu_item = gtk_menu_get_active (GTK_MENU (option_menu->menu));
+      if (option_menu->menu_item)
+       {
+         child = GTK_BIN (option_menu->menu_item)->child;
+         if (child)
+           {
+             gtk_container_block_resize (GTK_CONTAINER (option_menu));
+             if (GTK_WIDGET (option_menu)->state != child->state)
+               gtk_widget_set_state (child, GTK_WIDGET (option_menu)->state);
+             gtk_widget_reparent (child, GTK_WIDGET (option_menu));
+             gtk_container_unblock_resize (GTK_CONTAINER (option_menu));
+           }
+
+         gtk_widget_size_allocate (GTK_WIDGET (option_menu),
+                                   &(GTK_WIDGET (option_menu)->allocation));
+
+         if (GTK_WIDGET_DRAWABLE (option_menu))
+           gtk_widget_queue_draw (GTK_WIDGET (option_menu));
+       }
+    }
+}
+
+static void
+gtk_option_menu_remove_contents (GtkOptionMenu *option_menu)
+{
+  g_return_if_fail (option_menu != NULL);
+  g_return_if_fail (GTK_IS_OPTION_MENU (option_menu));
+
+  if (GTK_BUTTON (option_menu)->child)
+    {
+      gtk_container_block_resize (GTK_CONTAINER (option_menu));
+      if (GTK_WIDGET (option_menu->menu_item)->state != GTK_BUTTON (option_menu)->child->state)
+       gtk_widget_set_state (GTK_BUTTON (option_menu)->child,
+                             GTK_WIDGET (option_menu->menu_item)->state);
+      GTK_WIDGET_UNSET_FLAGS (GTK_BUTTON (option_menu)->child, GTK_MAPPED | GTK_REALIZED);
+      gtk_widget_reparent (GTK_BUTTON (option_menu)->child, option_menu->menu_item);
+      gtk_container_unblock_resize (GTK_CONTAINER (option_menu));
+      option_menu->menu_item = NULL;
+    }
+}
+
+static void
+gtk_option_menu_calc_size (GtkOptionMenu *option_menu)
+{
+  GtkWidget *child;
+  GList *children;
+
+  g_return_if_fail (option_menu != NULL);
+  g_return_if_fail (GTK_IS_OPTION_MENU (option_menu));
+
+  option_menu->width = 0;
+  option_menu->height = 0;
+
+  if (option_menu->menu)
+    {
+      children = GTK_MENU_SHELL (option_menu->menu)->children;
+      while (children)
+       {
+         child = children->data;
+         children = children->next;
+
+         if (GTK_WIDGET_VISIBLE (child))
+           {
+             gtk_widget_size_request (child, &child->requisition);
+
+             option_menu->width = MAX (option_menu->width, child->requisition.width);
+             option_menu->height = MAX (option_menu->height, child->requisition.height);
+           }
+       }
+    }
+}
+
+static void
+gtk_option_menu_position (GtkMenu  *menu,
+                         gint     *x,
+                         gint     *y,
+                         gpointer  user_data)
+{
+  GtkOptionMenu *option_menu;
+  GtkWidget *active;
+  GtkWidget *child;
+  GList *children;
+  gint shift_menu;
+  gint screen_width;
+  gint screen_height;
+  gint menu_xpos;
+  gint menu_ypos;
+  gint width;
+  gint height;
+
+  g_return_if_fail (user_data != NULL);
+  g_return_if_fail (GTK_IS_OPTION_MENU (user_data));
+
+  option_menu = GTK_OPTION_MENU (user_data);
+
+  width = GTK_WIDGET (menu)->allocation.width;
+  height = GTK_WIDGET (menu)->allocation.height;
+
+  active = gtk_menu_get_active (GTK_MENU (option_menu->menu));
+  children = GTK_MENU_SHELL (option_menu->menu)->children;
+  gdk_window_get_origin (GTK_WIDGET (option_menu)->window, &menu_xpos, &menu_ypos);
+
+  menu_ypos += GTK_WIDGET (option_menu)->allocation.height / 2 - 2;
+
+  if (active != NULL)
+    menu_ypos -= active->requisition.height / 2;
+
+  while (children)
+    {
+      child = children->data;
+
+      if (active == child)
+       break;
+
+      menu_ypos -= child->allocation.height;
+      children = children->next;
+    }
+
+  screen_width = gdk_screen_width ();
+  screen_height = gdk_screen_height ();
+
+  shift_menu = FALSE;
+  if (menu_ypos < 0)
+    {
+      menu_ypos = 0;
+      shift_menu = TRUE;
+    }
+  else if ((menu_ypos + height) > screen_height)
+    {
+      menu_ypos -= ((menu_ypos + height) - screen_height);
+      shift_menu = TRUE;
+    }
+
+  if (shift_menu)
+    {
+      if ((menu_xpos + GTK_WIDGET (option_menu)->allocation.width + width) <= screen_width)
+       menu_xpos += GTK_WIDGET (option_menu)->allocation.width;
+      else
+       menu_xpos -= width;
+    }
+
+  if (menu_xpos < 0)
+    menu_xpos = 0;
+  else if ((menu_xpos + width) > screen_width)
+    menu_xpos -= ((menu_xpos + width) - screen_width);
+
+  *x = menu_xpos;
+  *y = menu_ypos;
+}
diff --git a/gtk/gtkoptionmenu.h b/gtk/gtkoptionmenu.h
new file mode 100644 (file)
index 0000000..bbddf23
--- /dev/null
@@ -0,0 +1,71 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_OPTION_MENU_H__
+#define __GTK_OPTION_MENU_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkbutton.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_OPTION_MENU(obj)          GTK_CHECK_CAST (obj, gtk_option_menu_get_type (), GtkOptionMenu)
+#define GTK_OPTION_MENU_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_option_menu_get_type (), GtkOptionMenuClass)
+#define GTK_IS_OPTION_MENU(obj)       GTK_CHECK_TYPE (obj, gtk_option_menu_get_type ())
+
+
+typedef struct _GtkOptionMenu       GtkOptionMenu;
+typedef struct _GtkOptionMenuClass  GtkOptionMenuClass;
+
+struct _GtkOptionMenu
+{
+  GtkButton button;
+
+  GtkWidget *menu;
+  GtkWidget *menu_item;
+
+  guint16 width;
+  guint16 height;
+};
+
+struct _GtkOptionMenuClass
+{
+  GtkButtonClass parent_class;
+};
+
+
+guint      gtk_option_menu_get_type    (void);
+GtkWidget* gtk_option_menu_new         (void);
+GtkWidget* gtk_option_menu_get_menu    (GtkOptionMenu *option_menu);
+void       gtk_option_menu_set_menu    (GtkOptionMenu *option_menu,
+                                       GtkWidget     *menu);
+void       gtk_option_menu_remove_menu (GtkOptionMenu *option_menu);
+void       gtk_option_menu_set_history (GtkOptionMenu *option_menu,
+                                       gint           index);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_OPTION_MENU_H__ */
diff --git a/gtk/gtkpaned.c b/gtk/gtkpaned.c
new file mode 100644 (file)
index 0000000..d6b53db
--- /dev/null
@@ -0,0 +1,452 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkpaned.h"
+
+
+static void gtk_paned_class_init (GtkPanedClass    *klass);
+static void gtk_paned_init       (GtkPaned         *paned);
+static void gtk_paned_destroy    (GtkObject      *object);
+static void gtk_paned_realize    (GtkWidget *widget);
+static void gtk_paned_map        (GtkWidget      *widget);
+static void gtk_paned_unmap      (GtkWidget      *widget);
+static void gtk_paned_unrealize  (GtkWidget *widget);
+static gint gtk_paned_expose     (GtkWidget      *widget,
+                               GdkEventExpose *event);
+static void gtk_paned_add        (GtkContainer   *container,
+                               GtkWidget      *widget);
+static void gtk_paned_remove     (GtkContainer   *container,
+                               GtkWidget      *widget);
+static void gtk_paned_foreach    (GtkContainer   *container,
+                               GtkCallback     callback,
+                               gpointer        callback_data);
+
+
+static GtkContainerClass *parent_class = NULL;
+
+
+guint
+gtk_paned_get_type ()
+{
+  static guint paned_type = 0;
+
+  if (!paned_type)
+    {
+      GtkTypeInfo paned_info =
+      {
+       "GtkPaned",
+       sizeof (GtkPaned),
+       sizeof (GtkPanedClass),
+       (GtkClassInitFunc) gtk_paned_class_init,
+       (GtkObjectInitFunc) gtk_paned_init,
+       (GtkArgFunc) NULL,
+      };
+
+      paned_type = gtk_type_unique (gtk_container_get_type (), &paned_info);
+    }
+
+  return paned_type;
+}
+
+static void
+gtk_paned_class_init (GtkPanedClass *class)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+  GtkContainerClass *container_class;
+
+  object_class = (GtkObjectClass*) class;
+  widget_class = (GtkWidgetClass*) class;
+  container_class = (GtkContainerClass*) class;
+
+  parent_class = gtk_type_class (gtk_container_get_type ());
+
+  object_class->destroy = gtk_paned_destroy;
+
+  widget_class->realize = gtk_paned_realize;
+  widget_class->map = gtk_paned_map;
+  widget_class->unmap = gtk_paned_unmap;
+  widget_class->unrealize = gtk_paned_unrealize;
+  widget_class->expose_event = gtk_paned_expose;
+
+  container_class->add = gtk_paned_add;
+  container_class->remove = gtk_paned_remove;
+  container_class->foreach = gtk_paned_foreach;
+}
+
+static void
+gtk_paned_init (GtkPaned *paned)
+{
+  GTK_WIDGET_SET_FLAGS (paned, GTK_NO_WINDOW);
+
+  paned->child1 = NULL;
+  paned->child2 = NULL;
+  paned->handle = NULL;
+  paned->xor_gc = NULL;
+
+  paned->handle_size = 10;
+  paned->gutter_size = 6;
+  paned->position_set = FALSE;
+  paned->in_drag = FALSE;
+
+  paned->handle_xpos = -1;
+  paned->handle_ypos = -1;
+}
+
+
+static void
+gtk_paned_destroy (GtkObject *object)
+{
+  GtkPaned *paned;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_PANED (object));
+
+  paned = GTK_PANED (object);
+
+  if (paned->child1)
+    {
+      paned->child1->parent = NULL;
+      gtk_object_unref (GTK_OBJECT (paned->child1));
+      gtk_widget_destroy (paned->child1);
+    }
+  if (paned->child2)
+    {
+      paned->child2->parent = NULL;
+      gtk_object_unref (GTK_OBJECT (paned->child2));
+      gtk_widget_destroy (paned->child2);
+    }
+
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+gtk_paned_realize (GtkWidget *widget)
+{
+  GtkPaned *paned;
+  GdkWindowAttr attributes;
+  gint attributes_mask;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_PANED (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+  paned = GTK_PANED (widget);
+
+  attributes.x = paned->handle_xpos;
+  attributes.y = paned->handle_ypos;
+  attributes.width = paned->handle_size;
+  attributes.height = paned->handle_size;
+  attributes.wclass = GDK_INPUT_OUTPUT;
+  attributes.window_type = GDK_WINDOW_CHILD;
+  attributes.visual = gtk_widget_get_visual (widget);
+  attributes.colormap = gtk_widget_get_colormap (widget);
+  attributes.cursor = gdk_cursor_new(GDK_CROSS);
+  attributes.event_mask = gtk_widget_get_events (widget);
+  attributes.event_mask |= (GDK_EXPOSURE_MASK |
+                           GDK_BUTTON_PRESS_MASK |
+                           GDK_BUTTON_RELEASE_MASK |
+                           GDK_POINTER_MOTION_MASK |
+                           GDK_POINTER_MOTION_HINT_MASK);
+
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP |
+    GDK_WA_CURSOR;
+
+  paned->handle = gdk_window_new (widget->parent->window, &attributes, attributes_mask);
+  gdk_window_set_user_data (paned->handle, widget);
+  gdk_window_show (paned->handle);
+  gdk_window_raise (paned->handle);
+
+  widget->window = widget->parent->window;
+  widget->style = gtk_style_attach (widget->style, widget->window);
+
+  gtk_style_set_background (widget->style, paned->handle, GTK_STATE_NORMAL);
+}
+
+static void
+gtk_paned_map (GtkWidget *widget)
+{
+  GtkPaned *paned;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_PANED (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
+  paned = GTK_PANED (widget);
+
+  gdk_window_show (paned->handle);
+  gtk_widget_queue_draw (widget);
+
+  if (paned->child1 &&
+      GTK_WIDGET_VISIBLE (paned->child1) &&
+      !GTK_WIDGET_MAPPED (paned->child1))
+    gtk_widget_map (paned->child1);
+  if (paned->child2 &&
+      GTK_WIDGET_VISIBLE (paned->child2) &&
+      !GTK_WIDGET_MAPPED (paned->child2))
+    gtk_widget_map (paned->child2);
+}
+
+static void
+gtk_paned_unmap (GtkWidget *widget)
+{
+  GtkPaned *paned;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_PANED (widget));
+
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
+  paned = GTK_PANED (widget);
+
+  gdk_window_clear_area (widget->window,
+                        widget->allocation.x,
+                        widget->allocation.y,
+                        widget->allocation.width,
+                        widget->allocation.height);
+  gdk_window_hide (paned->handle);
+
+  if (paned->child1 &&
+      GTK_WIDGET_VISIBLE (paned->child1) &&
+      GTK_WIDGET_MAPPED (paned->child1))
+    gtk_widget_unmap (paned->child1);
+  if (paned->child2 &&
+      GTK_WIDGET_VISIBLE (paned->child2) &&
+      GTK_WIDGET_MAPPED (paned->child2))
+    gtk_widget_unmap (paned->child2);
+}
+
+static void
+gtk_paned_unrealize (GtkWidget *widget)
+{
+  GtkPaned *paned;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_PANED (widget));
+
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED);
+  paned = GTK_PANED (widget);
+
+  gtk_style_detach (widget->style);
+
+  if (paned->xor_gc)
+    gdk_gc_destroy (paned->xor_gc);
+  if (paned->handle)
+    gdk_window_destroy (paned->handle);
+
+  paned->handle = NULL;
+  widget->window = NULL;
+}
+
+static gint
+gtk_paned_expose (GtkWidget      *widget,
+                 GdkEventExpose *event)
+{
+  GtkPaned *paned;
+  GdkEventExpose child_event;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_PANED (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      paned = GTK_PANED (widget);
+
+      /* An expose event for the handle */
+      if (event->window == paned->handle)
+       {
+         gdk_window_set_background (paned->handle,
+                                    &widget->style->bg[widget->state]);
+         gdk_window_clear (paned->handle);
+         gtk_draw_shadow (widget->style, paned->handle,
+                          GTK_WIDGET_STATE(widget),
+                          GTK_SHADOW_OUT, 0, 0,
+                          paned->handle_size, paned->handle_size);
+       }
+      else
+       {
+         child_event = *event;
+         if (paned->child1 &&
+             GTK_WIDGET_NO_WINDOW (paned->child1) &&
+             gtk_widget_intersect (paned->child1, &event->area, &child_event.area))
+           gtk_widget_event (paned->child1, (GdkEvent*) &child_event);
+
+         if (paned->child2 &&
+             GTK_WIDGET_NO_WINDOW (paned->child2) &&
+             gtk_widget_intersect (paned->child2, &event->area, &child_event.area))
+           gtk_widget_event (paned->child2, (GdkEvent*) &child_event);
+
+         /* redraw the groove if necessary */
+         child_event.area = paned->groove_rectangle;
+         if (gtk_widget_intersect (widget, &event->area, &child_event.area))
+           gtk_widget_draw (widget, &child_event.area);
+       }
+    }
+  return FALSE;
+}
+
+void
+gtk_paned_add1 (GtkPaned     *paned,
+               GtkWidget    *widget)
+{
+  g_return_if_fail (widget != NULL);
+
+  if (!paned->child1)
+    {
+      gtk_widget_set_parent (widget, GTK_WIDGET (paned));
+
+      if (GTK_WIDGET_VISIBLE (widget->parent))
+       {
+         if (GTK_WIDGET_REALIZED (widget->parent) &&
+             !GTK_WIDGET_REALIZED (widget))
+           gtk_widget_realize (widget);
+         
+         if (GTK_WIDGET_MAPPED (widget->parent) &&
+             !GTK_WIDGET_MAPPED (widget))
+           gtk_widget_map (widget);
+       }
+
+      paned->child1 = widget;
+
+      if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (paned))
+        gtk_widget_queue_resize (widget);
+    }
+}
+
+void
+gtk_paned_add2 (GtkPaned  *paned,
+               GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+
+  if (!paned->child2)
+    {
+      gtk_widget_set_parent (widget, GTK_WIDGET (paned));
+
+      if (GTK_WIDGET_VISIBLE (widget->parent))
+       {
+         if (GTK_WIDGET_REALIZED (widget->parent) &&
+             !GTK_WIDGET_REALIZED (widget))
+           gtk_widget_realize (widget);
+         
+         if (GTK_WIDGET_MAPPED (widget->parent) &&
+             !GTK_WIDGET_MAPPED (widget))
+           gtk_widget_map (widget);
+       }
+
+      paned->child2 = widget;
+
+      if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (paned))
+        gtk_widget_queue_resize (widget);
+    }
+}
+
+static void
+gtk_paned_add (GtkContainer *container,
+              GtkWidget    *widget)
+{
+  GtkPaned *paned;
+
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_PANED (container));
+  g_return_if_fail (widget != NULL);
+
+  paned = GTK_PANED (container);
+
+  if (!paned->child1)
+    gtk_paned_add1 (GTK_PANED (container),widget);
+  else if (!paned->child2)
+    gtk_paned_add2 (GTK_PANED (container),widget);
+}
+
+static void
+gtk_paned_remove (GtkContainer *container,
+                 GtkWidget    *widget)
+{
+  GtkPaned *paned;
+
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_PANED (container));
+  g_return_if_fail (widget != NULL);
+
+  paned = GTK_PANED (container);
+
+  if (paned->child1 == widget)
+    {
+      gtk_widget_unparent (widget);
+
+      paned->child1 = NULL;
+
+      if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
+        gtk_widget_queue_resize (GTK_WIDGET (container));
+    }
+  else if (paned->child2 == widget)
+    {
+      gtk_widget_unparent (widget);
+
+      paned->child2 = NULL;
+
+      if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
+        gtk_widget_queue_resize (GTK_WIDGET (container));
+    }
+}
+
+static void
+gtk_paned_foreach (GtkContainer *container,
+                GtkCallback   callback,
+                gpointer      callback_data)
+{
+  GtkPaned *paned;
+
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_PANED (container));
+  g_return_if_fail (callback != NULL);
+
+  paned = GTK_PANED (container);
+
+  if (paned->child1)
+    (* callback) (paned->child1, callback_data);
+  if (paned->child2)
+    (* callback) (paned->child2, callback_data);
+}
+
+void
+gtk_paned_handle_size (GtkPaned *paned, guint16 size)
+{
+  gint x,y;
+
+  if (paned->handle)
+    {
+      gdk_window_get_geometry (paned->handle, &x, &y, NULL, NULL, NULL);
+      gdk_window_move_resize (paned->handle,
+                              x + paned->handle_size / 2 - size / 2,
+                              y + paned->handle_size / 2 - size / 2,
+                              size, size);
+    }
+  
+  paned->handle_size = size;
+}
+
+void
+gtk_paned_gutter_size (GtkPaned *paned, guint16 size)
+{
+  paned->gutter_size = size;
+
+  if (GTK_WIDGET_VISIBLE (GTK_WIDGET (paned)))
+    gtk_widget_queue_resize (GTK_WIDGET (paned));
+}
diff --git a/gtk/gtkpaned.h b/gtk/gtkpaned.h
new file mode 100644 (file)
index 0000000..1b25263
--- /dev/null
@@ -0,0 +1,78 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_PANED_H__
+#define __GTK_PANED_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkcontainer.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_PANED(obj)          GTK_CHECK_CAST (obj, gtk_paned_get_type (), GtkPaned)
+#define GTK_PANED_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_paned_get_type (), GtkPanedClass)
+#define GTK_IS_PANED(obj)       GTK_CHECK_TYPE (obj, gtk_paned_get_type ())
+
+
+typedef struct _GtkPaned       GtkPaned;
+typedef struct _GtkPanedClass  GtkPanedClass;
+
+struct _GtkPaned
+{
+  GtkContainer container;
+
+  GtkWidget *child1;
+  GtkWidget *child2;
+
+  GdkWindow *handle;
+  GdkRectangle groove_rectangle;
+  GdkGC *xor_gc;
+
+  guint16 handle_size;
+  guint16 gutter_size;
+  
+  gint child1_size;
+  guint position_set : 1;
+  guint in_drag : 1;
+
+  gint16 handle_xpos;
+  gint16 handle_ypos;
+};
+
+struct _GtkPanedClass
+{
+  GtkContainerClass parent_class;
+};
+
+
+guint gtk_paned_get_type   (void);
+void gtk_paned_add1 (GtkPaned *paned, GtkWidget *child);
+void gtk_paned_add2 (GtkPaned *paned, GtkWidget *child);
+void gtk_paned_handle_size (GtkPaned *paned, guint16 size);
+void gtk_paned_gutter_size (GtkPaned *paned, guint16 size);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_PANED_H__ */
diff --git a/gtk/gtkpixmap.c b/gtk/gtkpixmap.c
new file mode 100644 (file)
index 0000000..ae640f8
--- /dev/null
@@ -0,0 +1,176 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkcontainer.h"
+#include "gtkpixmap.h"
+
+
+static void gtk_pixmap_class_init (GtkPixmapClass  *klass);
+static void gtk_pixmap_init       (GtkPixmap       *pixmap);
+static gint gtk_pixmap_expose     (GtkWidget       *widget,
+                                  GdkEventExpose  *event);
+
+
+guint
+gtk_pixmap_get_type ()
+{
+  static guint pixmap_type = 0;
+
+  if (!pixmap_type)
+    {
+      GtkTypeInfo pixmap_info =
+      {
+       "GtkPixmap",
+       sizeof (GtkPixmap),
+       sizeof (GtkPixmapClass),
+       (GtkClassInitFunc) gtk_pixmap_class_init,
+       (GtkObjectInitFunc) gtk_pixmap_init,
+       (GtkArgFunc) NULL,
+      };
+
+      pixmap_type = gtk_type_unique (gtk_misc_get_type (), &pixmap_info);
+    }
+
+  return pixmap_type;
+}
+
+static void
+gtk_pixmap_class_init (GtkPixmapClass *class)
+{
+  GtkWidgetClass *widget_class;
+
+  widget_class = (GtkWidgetClass*) class;
+
+  widget_class->expose_event = gtk_pixmap_expose;
+}
+
+static void
+gtk_pixmap_init (GtkPixmap *pixmap)
+{
+  GTK_WIDGET_SET_FLAGS (pixmap, GTK_NO_WINDOW);
+
+  pixmap->pixmap = NULL;
+  pixmap->mask = NULL;
+}
+
+GtkWidget*
+gtk_pixmap_new (GdkPixmap *val,
+               GdkBitmap *mask)
+{
+  GtkPixmap *pixmap;
+
+  g_return_val_if_fail (val != NULL, NULL);
+
+  pixmap = gtk_type_new (gtk_pixmap_get_type ());
+
+  gtk_pixmap_set (pixmap, val, mask);
+
+  return GTK_WIDGET (pixmap);
+}
+
+void
+gtk_pixmap_set (GtkPixmap *pixmap,
+               GdkPixmap *val,
+               GdkBitmap *mask)
+{
+  gint width;
+  gint height;
+
+  g_return_if_fail (pixmap != NULL);
+  g_return_if_fail (GTK_IS_PIXMAP (pixmap));
+  g_return_if_fail (val != NULL);
+
+  pixmap->pixmap = val;
+  pixmap->mask = mask;
+
+  if (pixmap->pixmap)
+    {
+      gdk_window_get_size (pixmap->pixmap, &width, &height);
+      GTK_WIDGET (pixmap)->requisition.width = width + GTK_MISC (pixmap)->xpad * 2;
+      GTK_WIDGET (pixmap)->requisition.height = height + GTK_MISC (pixmap)->ypad * 2;
+    }
+  else
+    {
+      GTK_WIDGET (pixmap)->requisition.width = 0;
+      GTK_WIDGET (pixmap)->requisition.height = 0;
+    }
+
+  if (GTK_WIDGET_VISIBLE (pixmap))
+    gtk_widget_queue_resize (GTK_WIDGET (pixmap));
+}
+
+void
+gtk_pixmap_get (GtkPixmap  *pixmap,
+               GdkPixmap **val,
+               GdkBitmap **mask)
+{
+  g_return_if_fail (pixmap != NULL);
+  g_return_if_fail (GTK_IS_PIXMAP (pixmap));
+
+  if (val)
+    *val = pixmap->pixmap;
+  if (mask)
+    *mask = pixmap->mask;
+}
+
+
+static gint
+gtk_pixmap_expose (GtkWidget      *widget,
+                  GdkEventExpose *event)
+{
+  GtkPixmap *pixmap;
+  GtkMisc *misc;
+  gint x, y;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_PIXMAP (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      pixmap = GTK_PIXMAP (widget);
+      misc = GTK_MISC (widget);
+
+      x = (widget->allocation.x * (1.0 - misc->xalign) +
+          (widget->allocation.x + widget->allocation.width
+           - (widget->requisition.width - misc->xpad * 2)) *
+          misc->xalign) + 0.5;
+      y = (widget->allocation.y * (1.0 - misc->yalign) +
+          (widget->allocation.y + widget->allocation.height
+           - (widget->requisition.height - misc->ypad * 2)) *
+          misc->yalign) + 0.5;
+
+      if (pixmap->mask)
+       {
+         gdk_gc_set_clip_mask (widget->style->black_gc, pixmap->mask);
+         gdk_gc_set_clip_origin (widget->style->black_gc, x, y);
+       }
+
+      gdk_draw_pixmap (widget->window,
+                      widget->style->black_gc,
+                      pixmap->pixmap,
+                      0, 0, x, y, -1, -1);
+
+      if (pixmap->mask)
+       {
+         gdk_gc_set_clip_mask (widget->style->black_gc, NULL);
+         gdk_gc_set_clip_origin (widget->style->black_gc, 0, 0);
+       }
+    }
+
+  return FALSE;
+}
diff --git a/gtk/gtkpixmap.h b/gtk/gtkpixmap.h
new file mode 100644 (file)
index 0000000..970d4f4
--- /dev/null
@@ -0,0 +1,69 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_PIXMAP_H__
+#define __GTK_PIXMAP_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkmisc.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_PIXMAP(obj)          GTK_CHECK_CAST (obj, gtk_pixmap_get_type (), GtkPixmap)
+#define GTK_PIXMAP_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_pixmap_get_type (), GtkPixmapClass)
+#define GTK_IS_PIXMAP(obj)       GTK_CHECK_TYPE (obj, gtk_pixmap_get_type ())
+
+
+typedef struct _GtkPixmap       GtkPixmap;
+typedef struct _GtkPixmapClass  GtkPixmapClass;
+
+struct _GtkPixmap
+{
+  GtkMisc misc;
+
+  GdkPixmap *pixmap;
+  GdkBitmap *mask;
+};
+
+struct _GtkPixmapClass
+{
+  GtkMiscClass parent_class;
+};
+
+
+guint      gtk_pixmap_get_type   (void);
+GtkWidget* gtk_pixmap_new        (GdkPixmap  *pixmap,
+                                 GdkBitmap  *mask);
+void       gtk_pixmap_set        (GtkPixmap  *pixmap,
+                                 GdkPixmap  *val,
+                                 GdkBitmap  *mask);
+void       gtk_pixmap_get        (GtkPixmap  *pixmap,
+                                 GdkPixmap **val,
+                                 GdkBitmap **mask);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_PIXMAP_H__ */
diff --git a/gtk/gtkpreview.c b/gtk/gtkpreview.c
new file mode 100644 (file)
index 0000000..4246a32
--- /dev/null
@@ -0,0 +1,1571 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <math.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include "gdk/gdkx.h"
+#include "gtkpreview.h"
+#include "gtksignal.h"
+
+
+#define IMAGE_SIZE            256
+#define PREVIEW_CLASS(w)      GTK_PREVIEW_CLASS (GTK_OBJECT (w)->klass)
+#define COLOR_COMPOSE(r,g,b)  (lookup_red[r] | lookup_green[g] | lookup_blue[b])
+
+
+typedef struct _GtkPreviewProp  GtkPreviewProp;
+typedef void (*GtkTransferFunc) (guchar *dest, guchar *src, gint count);
+
+struct _GtkPreviewProp
+{
+  guint16 ref_count;
+  guint16 nred_shades;
+  guint16 ngreen_shades;
+  guint16 nblue_shades;
+  guint16 ngray_shades;
+};
+
+
+static void   gtk_preview_class_init    (GtkPreviewClass  *klass);
+static void   gtk_preview_init          (GtkPreview       *preview);
+static void   gtk_preview_destroy       (GtkObject        *object);
+static void   gtk_preview_realize       (GtkWidget        *widget);
+static void   gtk_preview_unrealize     (GtkWidget        *widget);
+static gint   gtk_preview_expose        (GtkWidget        *widget,
+                                        GdkEventExpose   *event);
+static void   gtk_preview_make_buffer   (GtkPreview       *preview);
+static void   gtk_preview_get_visuals   (GtkPreviewClass  *klass);
+static void   gtk_preview_get_cmaps     (GtkPreviewClass  *klass);
+static void   gtk_preview_dither_init   (GtkPreviewClass  *klass);
+static void   gtk_fill_lookup_array     (gulong           *array,
+                                        int               depth,
+                                        int               shift,
+                                        int               prec);
+static void   gtk_trim_cmap             (GtkPreviewClass  *klass);
+static void   gtk_create_8_bit          (GtkPreviewClass  *klass);
+
+static void   gtk_color_8               (guchar           *src,
+                                        guchar           *data,
+                                        gint              x,
+                                        gint              y,
+                                        gulong            width);
+static void   gtk_color_16              (guchar           *src,
+                                        guchar           *data,
+                                        gulong            width);
+static void   gtk_color_24              (guchar           *src,
+                                        guchar           *data,
+                                        gulong            width);
+static void   gtk_grayscale_8           (guchar           *src,
+                                        guchar           *data,
+                                        gint              x,
+                                        gint              y,
+                                        gulong            width);
+static void   gtk_grayscale_16          (guchar           *src,
+                                        guchar           *data,
+                                        gulong            width);
+static void   gtk_grayscale_24          (guchar           *src,
+                                        guchar           *data,
+                                        gulong            width);
+
+static gint   gtk_get_preview_prop      (guint            *nred,
+                                        guint            *nblue,
+                                        guint            *ngreen,
+                                        guint            *ngray);
+static void   gtk_set_preview_prop      (guint             nred,
+                                        guint             ngreen,
+                                        guint             nblue,
+                                        guint             ngray);
+
+/* transfer functions:
+ *  destination byte order/source bpp/destination bpp
+ */
+static void   gtk_lsbmsb_1_1            (guchar           *dest,
+                                        guchar           *src,
+                                        gint              count);
+static void   gtk_lsb_2_2               (guchar           *dest,
+                                        guchar           *src,
+                                        gint              count);
+static void   gtk_msb_2_2               (guchar           *dest,
+                                        guchar           *src,
+                                        gint              count);
+static void   gtk_lsb_3_3               (guchar           *dest,
+                                        guchar           *src,
+                                        gint              count);
+static void   gtk_msb_3_3               (guchar           *dest,
+                                        guchar           *src,
+                                        gint              count);
+static void   gtk_lsb_3_4               (guchar           *dest,
+                                        guchar           *src,
+                                        gint              count);
+static void   gtk_msb_3_4               (guchar           *dest,
+                                        guchar           *src,
+                                        gint              count);
+
+
+static GtkWidgetClass *parent_class = NULL;
+static GtkPreviewClass *preview_class = NULL;
+static GtkPreviewInfo *preview_info = NULL;
+static gint install_cmap = FALSE;
+
+
+guint
+gtk_preview_get_type ()
+{
+  static guint preview_type = 0;
+
+  if (!preview_type)
+    {
+      GtkTypeInfo preview_info =
+      {
+        "GtkPreview",
+        sizeof (GtkPreview),
+        sizeof (GtkPreviewClass),
+        (GtkClassInitFunc) gtk_preview_class_init,
+        (GtkObjectInitFunc) gtk_preview_init,
+       (GtkArgFunc) NULL,
+      };
+
+      preview_type = gtk_type_unique (gtk_widget_get_type (), &preview_info);
+    }
+
+  return preview_type;
+}
+
+static void
+gtk_preview_class_init (GtkPreviewClass *klass)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+
+  object_class = (GtkObjectClass*) klass;
+  widget_class = (GtkWidgetClass*) klass;
+
+  parent_class = gtk_type_class (gtk_widget_get_type ());
+  preview_class = klass;
+
+  object_class->destroy = gtk_preview_destroy;
+
+  widget_class->realize = gtk_preview_realize;
+  widget_class->unrealize = gtk_preview_unrealize;
+  widget_class->expose_event = gtk_preview_expose;
+
+  if (preview_info)
+    klass->info = *preview_info;
+  else
+    {
+      klass->info.visual = NULL;
+      klass->info.cmap = NULL;
+
+      klass->info.color_pixels = NULL;
+      klass->info.gray_pixels = NULL;
+      klass->info.reserved_pixels = NULL;
+
+      klass->info.lookup_red = NULL;
+      klass->info.lookup_green = NULL;
+      klass->info.lookup_blue = NULL;
+
+      klass->info.dither_red = NULL;
+      klass->info.dither_green = NULL;
+      klass->info.dither_blue = NULL;
+      klass->info.dither_gray = NULL;
+      klass->info.dither_matrix = NULL;
+
+      klass->info.nred_shades = 6;
+      klass->info.ngreen_shades = 6;
+      klass->info.nblue_shades = 4;
+      klass->info.ngray_shades = 24;
+      klass->info.nreserved = 0;
+
+      klass->info.bpp = 0;
+      klass->info.cmap_alloced = FALSE;
+      klass->info.gamma = 1.0;
+    }
+
+  klass->image = NULL;
+
+  gtk_preview_get_visuals (klass);
+  gtk_preview_get_cmaps (klass);
+  gtk_preview_dither_init (klass);
+}
+
+static void
+gtk_preview_init (GtkPreview *preview)
+{
+  GTK_WIDGET_SET_FLAGS (preview, GTK_BASIC);
+
+  preview->buffer = NULL;
+  preview->buffer_width = 0;
+  preview->buffer_height = 0;
+  preview->expand = FALSE;
+}
+
+void
+gtk_preview_uninit ()
+{
+  GtkPreviewProp *prop;
+  GdkAtom property;
+
+  if (preview_class && !install_cmap &&
+      (preview_class->info.visual->type != GDK_VISUAL_TRUE_COLOR) &&
+      (preview_class->info.visual->type != GDK_VISUAL_DIRECT_COLOR))
+    {
+      property = gdk_atom_intern ("GTK_PREVIEW_INFO", FALSE);
+
+      if (gdk_property_get (NULL, property, property,
+                           0, sizeof (GtkPreviewProp), FALSE,
+                           NULL, NULL, NULL, (guchar**) &prop))
+       {
+         prop->ref_count = ntohs (prop->ref_count) - 1;
+         if (prop->ref_count == 0)
+           {
+             gdk_property_delete (NULL, property);
+           }
+         else
+           {
+             prop->ref_count = htons (prop->ref_count);
+             gdk_property_change (NULL, property, property, 16,
+                                  GDK_PROP_MODE_REPLACE,
+                                  (guchar*) prop, 5);
+           }
+       }
+    }
+}
+
+GtkWidget*
+gtk_preview_new (GtkPreviewType type)
+{
+  GtkPreview *preview;
+
+  preview = gtk_type_new (gtk_preview_get_type ());
+  preview->type = type;
+
+  return GTK_WIDGET (preview);
+}
+
+void
+gtk_preview_size (GtkPreview *preview,
+                 gint        width,
+                 gint        height)
+{
+  g_return_if_fail (preview != NULL);
+  g_return_if_fail (GTK_IS_PREVIEW (preview));
+
+  if ((width != GTK_WIDGET (preview)->requisition.width) ||
+      (height != GTK_WIDGET (preview)->requisition.height))
+    {
+      GTK_WIDGET (preview)->requisition.width = width;
+      GTK_WIDGET (preview)->requisition.height = height;
+
+      if (preview->buffer)
+       g_free (preview->buffer);
+      preview->buffer = NULL;
+    }
+}
+
+void
+gtk_preview_put (GtkPreview   *preview,
+                GdkWindow    *window,
+                GdkGC        *gc,
+                gint          srcx,
+                gint          srcy,
+                gint          destx,
+                gint          desty,
+                gint          width,
+                gint          height)
+{
+  GtkWidget *widget;
+  GdkImage *image;
+  GdkRectangle r1, r2, r3;
+  GtkTransferFunc transfer_func;
+  guchar *image_mem;
+  guchar *src, *dest;
+  gint x, xe, x2;
+  gint y, ye, y2;
+  guint dest_rowstride;
+  guint src_bpp;
+  guint dest_bpp;
+  gint i;
+
+  g_return_if_fail (preview != NULL);
+  g_return_if_fail (GTK_IS_PREVIEW (preview));
+  g_return_if_fail (window != NULL);
+
+  if (!preview->buffer)
+    return;
+
+  widget = GTK_WIDGET (preview);
+
+  r1.x = srcx;
+  r1.y = srcy;
+  r1.width = preview->buffer_width;
+  r1.height = preview->buffer_height;
+
+  r2.x = destx;
+  r2.y = desty;
+  r2.width = width;
+  r2.height = height;
+
+  if (!gdk_rectangle_intersect (&r1, &r2, &r3))
+    return;
+
+  x2 = r3.x + r3.width;
+  y2 = r3.y + r3.height;
+
+  if (!preview_class->image)
+    preview_class->image = gdk_image_new (GDK_IMAGE_FASTEST,
+                                         preview_class->info.visual,
+                                         IMAGE_SIZE, IMAGE_SIZE);
+  image = preview_class->image;
+  src_bpp = preview_class->info.bpp;
+
+  image_mem = image->mem;
+  dest_bpp = image->bpp;
+  dest_rowstride = image->bpl;
+
+  transfer_func = NULL;
+
+  switch (dest_bpp)
+    {
+    case 1:
+      switch (src_bpp)
+       {
+       case 1:
+         transfer_func = gtk_lsbmsb_1_1;
+         break;
+       }
+      break;
+    case 2:
+      switch (src_bpp)
+       {
+       case 2:
+         if (image->byte_order == GDK_MSB_FIRST)
+           transfer_func = gtk_msb_2_2;
+         else
+           transfer_func = gtk_lsb_2_2;
+         break;
+       case 3:
+         break;
+       }
+      break;
+    case 3:
+      switch (src_bpp)
+       {
+       case 3:
+         if (image->byte_order == GDK_MSB_FIRST)
+           transfer_func = gtk_msb_3_3;
+         else
+           transfer_func = gtk_lsb_3_3;
+         break;
+       }
+      break;
+    case 4:
+      switch (src_bpp)
+       {
+       case 3:
+         if (image->byte_order == GDK_MSB_FIRST)
+           transfer_func = gtk_msb_3_4;
+         else
+           transfer_func = gtk_lsb_3_4;
+         break;
+       }
+      break;
+    }
+
+  if (!transfer_func)
+    {
+      g_warning ("unsupported byte order/src bpp/dest bpp combination: %s:%d:%d",
+                (image->byte_order == GDK_MSB_FIRST) ? "msb" : "lsb", src_bpp, dest_bpp);
+      return;
+    }
+
+  for (y = r3.y; y < y2; y += IMAGE_SIZE)
+    {
+      for (x = r3.x; x < x2; x += IMAGE_SIZE)
+       {
+         xe = x + IMAGE_SIZE;
+         if (xe > x2)
+           xe = x2;
+
+         ye = y + IMAGE_SIZE;
+         if (ye > y2)
+           ye = y2;
+
+         for (i = y; i < ye; i++)
+           {
+             src = preview->buffer + (((gulong) (i - r1.y) * (gulong) preview->buffer_width) +
+                                      (x - r1.x)) * (gulong) src_bpp;
+             dest = image_mem + ((gulong) (i - y) * dest_rowstride);
+
+             if (xe > x)
+               (* transfer_func) (dest, src, xe - x);
+           }
+
+         gdk_draw_image (window, gc,
+                         image, 0, 0, x, y,
+                         xe - x, ye - y);
+         gdk_flush ();
+       }
+    }
+}
+
+void
+gtk_preview_put_row (GtkPreview *preview,
+                    guchar     *src,
+                    guchar     *dest,
+                    gint        x,
+                    gint        y,
+                    gint        w)
+{
+  g_return_if_fail (preview != NULL);
+  g_return_if_fail (GTK_IS_PREVIEW (preview));
+  g_return_if_fail (src != NULL);
+  g_return_if_fail (dest != NULL);
+
+  switch (preview->type)
+    {
+    case GTK_PREVIEW_COLOR:
+      switch (preview_class->info.visual->depth)
+       {
+       case 8:
+         gtk_color_8 (src, dest, x, y, w);
+         break;
+       case 15:
+       case 16:
+         gtk_color_16 (src, dest, w);
+         break;
+       case 24:
+       case 32:
+         gtk_color_24 (src, dest, w);
+         break;
+       }
+      break;
+    case GTK_PREVIEW_GRAYSCALE:
+      switch (preview_class->info.visual->depth)
+       {
+       case 8:
+         gtk_grayscale_8 (src, dest, x, y, w);
+         break;
+       case 15:
+       case 16:
+         gtk_grayscale_16 (src, dest, w);
+         break;
+       case 24:
+       case 32:
+         gtk_grayscale_24 (src, dest, w);
+         break;
+       }
+      break;
+    }
+}
+
+void
+gtk_preview_draw_row (GtkPreview *preview,
+                     guchar     *data,
+                     gint        x,
+                     gint        y,
+                     gint        w)
+{
+  guchar *dest;
+
+  g_return_if_fail (preview != NULL);
+  g_return_if_fail (GTK_IS_PREVIEW (preview));
+  g_return_if_fail (data != NULL);
+
+  if ((w <= 0) || (y < 0))
+    return;
+
+  g_return_if_fail (data != NULL);
+
+  gtk_preview_make_buffer (preview);
+
+  if (y >= preview->buffer_height)
+    return;
+
+  switch (preview->type)
+    {
+    case GTK_PREVIEW_COLOR:
+      switch (preview_class->info.visual->depth)
+       {
+       case 8:
+         dest = preview->buffer + ((gulong) y * (gulong) preview->buffer_width + (gulong) x);
+         gtk_color_8 (data, dest, x, y, w);
+         break;
+       case 15:
+       case 16:
+         dest = preview->buffer + ((gulong) y * (gulong) preview->buffer_width + (gulong) x) * 2;
+         gtk_color_16 (data, dest, w);
+         break;
+       case 24:
+       case 32:
+         dest = preview->buffer + ((gulong) y * (gulong) preview->buffer_width + (gulong) x) * 3;
+         gtk_color_24 (data, dest, w);
+         break;
+       }
+      break;
+    case GTK_PREVIEW_GRAYSCALE:
+      switch (preview_class->info.visual->depth)
+       {
+       case 8:
+         dest = preview->buffer + ((gulong) y * (gulong) preview->buffer_width + (gulong) x);
+         gtk_grayscale_8 (data, dest, x, y, w);
+         break;
+       case 15:
+       case 16:
+         dest = preview->buffer + ((gulong) y * (gulong) preview->buffer_width + (gulong) x) * 2;
+         gtk_grayscale_16 (data, dest, w);
+         break;
+       case 24:
+       case 32:
+         dest = preview->buffer + ((gulong) y * (gulong) preview->buffer_width + (gulong) x) * 3;
+         gtk_grayscale_24 (data, dest, w);
+         break;
+       }
+      break;
+    }
+}
+
+void
+gtk_preview_set_expand (GtkPreview *preview,
+                       gint        expand)
+{
+  g_return_if_fail (preview != NULL);
+  g_return_if_fail (GTK_IS_PREVIEW (preview));
+
+  preview->expand = (expand != FALSE);
+}
+
+void
+gtk_preview_set_gamma (double _gamma)
+{
+  g_return_if_fail (preview_class == NULL);
+
+  if (!preview_info)
+    {
+      preview_info = g_new0 (GtkPreviewInfo, 1);
+      preview_info->nred_shades = 6;
+      preview_info->ngreen_shades = 6;
+      preview_info->nblue_shades = 4;
+      preview_info->ngray_shades = 24;
+    }
+
+  preview_info->gamma = _gamma;
+}
+
+void
+gtk_preview_set_color_cube (guint nred_shades,
+                           guint ngreen_shades,
+                           guint nblue_shades,
+                           guint ngray_shades)
+{
+  g_return_if_fail (preview_class == NULL);
+
+  if (!preview_info)
+    {
+      preview_info = g_new0 (GtkPreviewInfo, 1);
+      preview_info->gamma = 1.0;
+    }
+
+  preview_info->nred_shades = nred_shades;
+  preview_info->ngreen_shades = ngreen_shades;
+  preview_info->nblue_shades = nblue_shades;
+  preview_info->ngray_shades = ngray_shades;
+}
+
+void
+gtk_preview_set_install_cmap (gint _install_cmap)
+{
+  /* g_return_if_fail (preview_class == NULL); */
+
+  install_cmap = _install_cmap;
+}
+
+void
+gtk_preview_set_reserved (gint nreserved)
+{
+  if (!preview_info)
+    preview_info = g_new0 (GtkPreviewInfo, 1);
+
+  preview_info->nreserved = nreserved;
+}
+
+GdkVisual*
+gtk_preview_get_visual ()
+{
+  if (!preview_class)
+    preview_class = gtk_type_class (gtk_preview_get_type ());
+
+  return preview_class->info.visual;
+}
+
+GdkColormap*
+gtk_preview_get_cmap ()
+{
+  if (!preview_class)
+    preview_class = gtk_type_class (gtk_preview_get_type ());
+
+  return preview_class->info.cmap;
+}
+
+GtkPreviewInfo*
+gtk_preview_get_info ()
+{
+  if (!preview_class)
+    preview_class = gtk_type_class (gtk_preview_get_type ());
+
+  return &preview_class->info;
+}
+
+
+static void
+gtk_preview_destroy (GtkObject *object)
+{
+  GtkPreview *preview;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_PREVIEW (object));
+
+  preview = GTK_PREVIEW (object);
+  if (preview->buffer)
+    g_free (preview->buffer);
+  preview->type = (GtkPreviewType) -1;
+
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+gtk_preview_realize (GtkWidget *widget)
+{
+  GtkPreview *preview;
+  GdkWindowAttr attributes;
+  gint attributes_mask;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_PREVIEW (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+  preview = GTK_PREVIEW (widget);
+
+  attributes.window_type = GDK_WINDOW_CHILD;
+  attributes.x = widget->allocation.x;
+  attributes.y = widget->allocation.y;
+  attributes.width = widget->allocation.width;
+  attributes.height = widget->allocation.height;
+  attributes.wclass = GDK_INPUT_OUTPUT;
+  attributes.visual = gtk_widget_get_visual (widget);
+  attributes.colormap = gtk_widget_get_colormap (widget);
+  attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK;
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+
+  widget->window = gdk_window_new (widget->parent->window, &attributes, attributes_mask);
+  gdk_window_set_user_data (widget->window, widget);
+
+  widget->style = gtk_style_attach (widget->style, widget->window);
+  gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
+}
+
+static void
+gtk_preview_unrealize (GtkWidget *widget)
+{
+  GtkPreview *preview;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_PREVIEW (widget));
+
+  preview = GTK_PREVIEW (widget);
+
+  if (GTK_WIDGET_CLASS (parent_class)->unrealize)
+    (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
+}
+
+static gint
+gtk_preview_expose (GtkWidget      *widget,
+                   GdkEventExpose *event)
+{
+  GtkPreview *preview;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_PREVIEW (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      preview = GTK_PREVIEW (widget);
+
+      gtk_preview_put (GTK_PREVIEW (widget),
+                      widget->window, widget->style->black_gc,
+                      (widget->allocation.width - preview->buffer_width) / 2,
+                      (widget->allocation.height - preview->buffer_height) / 2,
+                      event->area.x, event->area.y,
+                      event->area.width, event->area.height);
+    }
+
+  return FALSE;
+}
+
+static void
+gtk_preview_make_buffer (GtkPreview *preview)
+{
+  GtkWidget *widget;
+  gint width;
+  gint height;
+
+  g_return_if_fail (preview != NULL);
+  g_return_if_fail (GTK_IS_PREVIEW (preview));
+
+  widget = GTK_WIDGET (preview);
+
+  if (preview->expand &&
+      (widget->allocation.width != 0) &&
+      (widget->allocation.height != 0))
+    {
+      width = widget->allocation.width;
+      height = widget->allocation.height;
+    }
+  else
+    {
+      width = widget->requisition.width;
+      height = widget->requisition.height;
+    }
+
+  if (!preview->buffer ||
+      (preview->buffer_width != width) ||
+      (preview->buffer_height != height))
+    {
+      if (preview->buffer)
+       g_free (preview->buffer);
+
+      preview->buffer_width = width;
+      preview->buffer_height = height;
+
+      preview->buffer = g_new0 (guchar,
+                               preview->buffer_width *
+                               preview->buffer_height *
+                               preview_class->info.bpp);
+    }
+}
+
+static void
+gtk_preview_get_visuals (GtkPreviewClass *klass)
+{
+  static GdkVisualType types[] =
+  {
+    GDK_VISUAL_TRUE_COLOR,
+    GDK_VISUAL_DIRECT_COLOR,
+    GDK_VISUAL_TRUE_COLOR,
+    GDK_VISUAL_DIRECT_COLOR,
+    GDK_VISUAL_TRUE_COLOR,
+    GDK_VISUAL_DIRECT_COLOR,
+    GDK_VISUAL_TRUE_COLOR,
+    GDK_VISUAL_DIRECT_COLOR,
+    GDK_VISUAL_PSEUDO_COLOR
+  };
+  static gint depths[] = { 24, 24, 32, 32, 16, 16, 15, 15, 8 };
+  static gint nvisual_types = sizeof (types) / sizeof (types[0]);
+
+  int i;
+
+  g_return_if_fail (klass != NULL);
+
+  if (!klass->info.visual)
+    for (i = 0; i < nvisual_types; i++)
+      if ((klass->info.visual = gdk_visual_get_best_with_both (depths[i], types[i])))
+       {
+         if ((klass->info.visual->type == GDK_VISUAL_TRUE_COLOR) ||
+             (klass->info.visual->type == GDK_VISUAL_DIRECT_COLOR))
+           {
+             klass->info.lookup_red = g_new (gulong, 256);
+             klass->info.lookup_green = g_new (gulong, 256);
+             klass->info.lookup_blue = g_new (gulong, 256);
+
+             gtk_fill_lookup_array (klass->info.lookup_red,
+                                    klass->info.visual->depth,
+                                    klass->info.visual->red_shift,
+                                    8 - klass->info.visual->red_prec);
+             gtk_fill_lookup_array (klass->info.lookup_green,
+                                    klass->info.visual->depth,
+                                    klass->info.visual->green_shift,
+                                    8 - klass->info.visual->green_prec);
+             gtk_fill_lookup_array (klass->info.lookup_blue,
+                                    klass->info.visual->depth,
+                                    klass->info.visual->blue_shift,
+                                    8 - klass->info.visual->blue_prec);
+           }
+         break;
+       }
+
+  if (!klass->info.visual)
+    {
+      g_warning ("unable to find a suitable visual for color image display.\n");
+      return;
+    }
+
+  switch (klass->info.visual->depth)
+    {
+    case 8:
+      klass->info.bpp = 1;
+      break;
+    case 15:
+    case 16:
+      klass->info.bpp = 2;
+      break;
+    case 24:
+    case 32:
+      klass->info.bpp = 3;
+      break;
+    }
+}
+
+static void
+gtk_preview_get_cmaps (GtkPreviewClass *klass)
+{
+  g_return_if_fail (klass != NULL);
+  g_return_if_fail (klass->info.visual != NULL);
+
+  if ((klass->info.visual->type != GDK_VISUAL_TRUE_COLOR) &&
+      (klass->info.visual->type != GDK_VISUAL_DIRECT_COLOR))
+    {
+      if (install_cmap)
+       {
+         klass->info.cmap = gdk_colormap_new (klass->info.visual, FALSE);
+         klass->info.cmap_alloced = install_cmap;
+
+         gtk_trim_cmap (klass);
+         gtk_create_8_bit (klass);
+       }
+      else
+       {
+         guint nred;
+         guint ngreen;
+         guint nblue;
+         guint ngray;
+         gint set_prop;
+
+         klass->info.cmap = gdk_colormap_get_system ();
+
+         set_prop = TRUE;
+         if (gtk_get_preview_prop (&nred, &ngreen, &nblue, &ngray))
+           {
+             set_prop = FALSE;
+
+             klass->info.nred_shades = nred;
+             klass->info.ngreen_shades = ngreen;
+             klass->info.nblue_shades = nblue;
+             klass->info.ngray_shades = ngray;
+
+             if (klass->info.nreserved)
+               {
+                 klass->info.reserved_pixels = g_new (gulong, klass->info.nreserved);
+                 if (!gdk_colors_alloc (klass->info.cmap, 0, NULL, 0,
+                                        klass->info.reserved_pixels,
+                                        klass->info.nreserved))
+                   {
+                     g_free (klass->info.reserved_pixels);
+                     klass->info.reserved_pixels = NULL;
+                   }
+               }
+           }
+         else
+           {
+             gtk_trim_cmap (klass);
+           }
+
+         gtk_create_8_bit (klass);
+
+         if (set_prop)
+           gtk_set_preview_prop (klass->info.nred_shades,
+                                 klass->info.ngreen_shades,
+                                 klass->info.nblue_shades,
+                                 klass->info.ngray_shades);
+       }
+    }
+  else
+    {
+      if (klass->info.visual == gdk_visual_get_system ())
+       klass->info.cmap = gdk_colormap_get_system ();
+      else
+       klass->info.cmap = gdk_colormap_new (klass->info.visual, FALSE);
+      klass->info.cmap_alloced = TRUE;
+
+      klass->info.nred_shades = 0;
+      klass->info.ngreen_shades = 0;
+      klass->info.nblue_shades = 0;
+      klass->info.ngray_shades = 0;
+    }
+}
+
+static void
+gtk_preview_dither_init (GtkPreviewClass *klass)
+{
+  int i, j, k;
+  unsigned char low_shade, high_shade;
+  unsigned short index;
+  long red_mult, green_mult;
+  double red_matrix_width;
+  double green_matrix_width;
+  double blue_matrix_width;
+  double gray_matrix_width;
+  double red_colors_per_shade;
+  double green_colors_per_shade;
+  double blue_colors_per_shade;
+  double gray_colors_per_shade;
+  gulong *gray_pixels;
+  gint shades_r, shades_g, shades_b, shades_gray;
+  GtkDitherInfo *red_ordered_dither;
+  GtkDitherInfo *green_ordered_dither;
+  GtkDitherInfo *blue_ordered_dither;
+  GtkDitherInfo *gray_ordered_dither;
+  guchar ***dither_matrix;
+  guchar DM[8][8] =
+  {
+    { 0,  32, 8,  40, 2,  34, 10, 42 },
+    { 48, 16, 56, 24, 50, 18, 58, 26 },
+    { 12, 44, 4,  36, 14, 46, 6,  38 },
+    { 60, 28, 52, 20, 62, 30, 54, 22 },
+    { 3,  35, 11, 43, 1,  33, 9,  41 },
+    { 51, 19, 59, 27, 49, 17, 57, 25 },
+    { 15, 47, 7,  39, 13, 45, 5,  37 },
+    { 63, 31, 55, 23, 61, 29, 53, 21 }
+  };
+
+  if (klass->info.visual->type != GDK_VISUAL_PSEUDO_COLOR)
+    return;
+
+  shades_r = klass->info.nred_shades;
+  shades_g = klass->info.ngreen_shades;
+  shades_b = klass->info.nblue_shades;
+  shades_gray = klass->info.ngray_shades;
+
+  red_mult = shades_g * shades_b;
+  green_mult = shades_b;
+
+  red_colors_per_shade = 255.0 / (shades_r - 1);
+  red_matrix_width = red_colors_per_shade / 64;
+
+  green_colors_per_shade = 255.0 / (shades_g - 1);
+  green_matrix_width = green_colors_per_shade / 64;
+
+  blue_colors_per_shade = 255.0 / (shades_b - 1);
+  blue_matrix_width = blue_colors_per_shade / 64;
+
+  gray_colors_per_shade = 255.0 / (shades_gray - 1);
+  gray_matrix_width = gray_colors_per_shade / 64;
+
+  /*  alloc the ordered dither arrays for accelerated dithering  */
+
+  klass->info.dither_red = g_new (GtkDitherInfo, 256);
+  klass->info.dither_green = g_new (GtkDitherInfo, 256);
+  klass->info.dither_blue = g_new (GtkDitherInfo, 256);
+  klass->info.dither_gray = g_new (GtkDitherInfo, 256);
+
+  red_ordered_dither = klass->info.dither_red;
+  green_ordered_dither = klass->info.dither_green;
+  blue_ordered_dither = klass->info.dither_blue;
+  gray_ordered_dither = klass->info.dither_gray;
+
+  dither_matrix = g_new (guchar**, 8);
+  for (i = 0; i < 8; i++)
+    {
+      dither_matrix[i] = g_new (guchar*, 8);
+      for (j = 0; j < 8; j++)
+       dither_matrix[i][j] = g_new (guchar, 65);
+    }
+
+  klass->info.dither_matrix = dither_matrix;
+
+  /*  setup the ordered_dither_matrices  */
+
+  for (i = 0; i < 8; i++)
+    for (j = 0; j < 8; j++)
+      for (k = 0; k <= 64; k++)
+       dither_matrix[i][j][k] = (DM[i][j] < k) ? 1 : 0;
+
+  /*  setup arrays containing three bytes of information for red, green, & blue  */
+  /*  the arrays contain :
+   *    1st byte:    low end shade value
+   *    2nd byte:    high end shade value
+   *    3rd & 4th bytes:    ordered dither matrix index
+   */
+
+  gray_pixels = klass->info.gray_pixels;
+
+  for (i = 0; i < 256; i++)
+    {
+
+      /*  setup the red information  */
+      {
+       low_shade = (unsigned char) (i / red_colors_per_shade);
+       if (low_shade == (shades_r - 1))
+         low_shade--;
+       high_shade = low_shade + 1;
+
+       index = (unsigned short)
+         (((double) i - low_shade * red_colors_per_shade) /
+          red_matrix_width);
+
+       low_shade *= red_mult;
+       high_shade *= red_mult;
+
+       red_ordered_dither[i].s[1] = index;
+       red_ordered_dither[i].c[0] = low_shade;
+       red_ordered_dither[i].c[1] = high_shade;
+      }
+
+
+      /*  setup the green information  */
+      {
+       low_shade = (unsigned char) (i / green_colors_per_shade);
+       if (low_shade == (shades_g - 1))
+         low_shade--;
+       high_shade = low_shade + 1;
+
+       index = (unsigned short)
+         (((double) i - low_shade * green_colors_per_shade) /
+          green_matrix_width);
+
+       low_shade *= green_mult;
+       high_shade *= green_mult;
+
+       green_ordered_dither[i].s[1] = index;
+       green_ordered_dither[i].c[0] = low_shade;
+       green_ordered_dither[i].c[1] = high_shade;
+      }
+
+
+      /*  setup the blue information  */
+      {
+       low_shade = (unsigned char) (i / blue_colors_per_shade);
+       if (low_shade == (shades_b - 1))
+         low_shade--;
+       high_shade = low_shade + 1;
+
+       index = (unsigned short)
+         (((double) i - low_shade * blue_colors_per_shade) /
+          blue_matrix_width);
+
+       blue_ordered_dither[i].s[1] = index;
+       blue_ordered_dither[i].c[0] = low_shade;
+       blue_ordered_dither[i].c[1] = high_shade;
+      }
+
+
+      /*  setup the gray information */
+      {
+       low_shade = (unsigned char) (i / gray_colors_per_shade);
+       if (low_shade == (shades_gray - 1))
+         low_shade--;
+       high_shade = low_shade + 1;
+
+       index = (unsigned short)
+         (((double) i - low_shade * gray_colors_per_shade) /
+          gray_matrix_width);
+
+       gray_ordered_dither[i].s[1] = index;
+       gray_ordered_dither[i].c[0] = gray_pixels[low_shade];
+       gray_ordered_dither[i].c[1] = gray_pixels[high_shade];
+      }
+    }
+}
+
+static void
+gtk_fill_lookup_array (gulong *array,
+                      int     depth,
+                      int     shift,
+                      int     prec)
+{
+  double one_over_gamma;
+  double ind;
+  int val;
+  int i;
+
+  if (preview_class->info.gamma != 0.0)
+    one_over_gamma = 1.0 / preview_class->info.gamma;
+  else
+    one_over_gamma = 1.0;
+
+  for (i = 0; i < 256; i++)
+    {
+      if (one_over_gamma == 1.0)
+        array[i] = ((i >> prec) << shift);
+      else
+        {
+          ind = (double) i / 255.0;
+          val = (int) (255 * pow (ind, one_over_gamma));
+          array[i] = ((val >> prec) << shift);
+        }
+    }
+}
+
+static void
+gtk_trim_cmap (GtkPreviewClass *klass)
+{
+  gulong pixels[256];
+  guint nred;
+  guint ngreen;
+  guint nblue;
+  guint ngray;
+  guint nreserved;
+  guint total;
+  guint tmp;
+  gint success;
+
+  nred = klass->info.nred_shades;
+  ngreen = klass->info.ngreen_shades;
+  nblue = klass->info.nblue_shades;
+  ngray = klass->info.ngray_shades;
+  nreserved = klass->info.nreserved;
+
+  success = FALSE;
+  while (!success)
+    {
+      total = nred * ngreen * nblue + ngray + nreserved;
+
+      if (total <= 256)
+       {
+         if ((nred < 2) || (ngreen < 2) || (nblue < 2) || (ngray < 2))
+           success = TRUE;
+         else
+           {
+             success = gdk_colors_alloc (klass->info.cmap, 0, NULL, 0, pixels, total);
+             if (success)
+               {
+                 if (nreserved > 0)
+                   {
+                     klass->info.reserved_pixels = g_new (gulong, nreserved);
+                     memcpy (klass->info.reserved_pixels, pixels, sizeof (gulong) * nreserved);
+                     gdk_colors_free (klass->info.cmap, &pixels[nreserved],
+                                      total - nreserved, 0);
+                   }
+                 else
+                   {
+                     gdk_colors_free (klass->info.cmap, pixels, total, 0);
+                   }
+               }
+           }
+       }
+
+      if (!success)
+       {
+         if ((nblue >= nred) && (nblue >= ngreen))
+           nblue = nblue - 1;
+         else if ((nred >= ngreen) && (nred >= nblue))
+           nred = nred - 1;
+         else
+           {
+             tmp = log (ngray) / log (2);
+
+             if (ngreen >= tmp)
+               ngreen = ngreen - 1;
+             else
+               ngray -= 1;
+           }
+       }
+    }
+
+  if ((nred < 2) || (ngreen < 2) || (nblue < 2) || (ngray < 2))
+    {
+      g_print ("Unable to allocate sufficient colormap entries.\n");
+      g_print ("Try exiting other color intensive applications.\n");
+      return;
+    }
+
+  /*  If any of the shade values has changed, issue a warning  */
+  if ((nred != klass->info.nred_shades) ||
+      (ngreen != klass->info.ngreen_shades) ||
+      (nblue != klass->info.nblue_shades) ||
+      (ngray != klass->info.ngray_shades))
+    {
+      g_print ("Not enough colors to satisfy requested color cube.\n");
+      g_print ("Reduced color cube shades from\n");
+      g_print ("[%d of Red, %d of Green, %d of Blue, %d of Gray] ==> [%d of Red, %d of Green, %d of Blue, %d of Gray]\n",
+               klass->info.nred_shades, klass->info.ngreen_shades,
+              klass->info.nblue_shades, klass->info.ngray_shades,
+              nred, ngreen, nblue, ngray);
+    }
+
+  klass->info.nred_shades = nred;
+  klass->info.ngreen_shades = ngreen;
+  klass->info.nblue_shades = nblue;
+  klass->info.ngray_shades = ngray;
+}
+
+static void
+gtk_create_8_bit (GtkPreviewClass *klass)
+{
+  unsigned int r, g, b;
+  unsigned int rv, gv, bv;
+  unsigned int dr, dg, db, dgray;
+  GdkColor color;
+  gulong *pixels;
+  double one_over_gamma;
+  int i;
+
+  if (!klass->info.color_pixels)
+    klass->info.color_pixels = g_new (gulong, 256);
+
+  if (!klass->info.gray_pixels)
+    klass->info.gray_pixels = g_new (gulong, 256);
+
+  if (klass->info.gamma != 0.0)
+    one_over_gamma = 1.0 / klass->info.gamma;
+  else
+    one_over_gamma = 1.0;
+
+  dr = klass->info.nred_shades - 1;
+  dg = klass->info.ngreen_shades - 1;
+  db = klass->info.nblue_shades - 1;
+  dgray = klass->info.ngray_shades - 1;
+
+  pixels = klass->info.color_pixels;
+
+  for (r = 0, i = 0; r <= dr; r++)
+    for (g = 0; g <= dg; g++)
+      for (b = 0; b <= db; b++, i++)
+        {
+          rv = (unsigned int) ((r * klass->info.visual->colormap_size) / dr);
+          gv = (unsigned int) ((g * klass->info.visual->colormap_size) / dg);
+          bv = (unsigned int) ((b * klass->info.visual->colormap_size) / db);
+          color.red = ((int) (255 * pow ((double) rv / 256.0, one_over_gamma))) * 257;
+          color.green = ((int) (255 * pow ((double) gv / 256.0, one_over_gamma))) * 257;
+          color.blue = ((int) (255 * pow ((double) bv / 256.0, one_over_gamma))) * 257;
+
+         if (!gdk_color_alloc (klass->info.cmap, &color))
+           {
+             g_error ("could not initialize 8-bit combined colormap");
+             return;
+           }
+
+         pixels[i] = color.pixel;
+        }
+
+  pixels = klass->info.gray_pixels;
+
+  for (i = 0; i < (int) klass->info.ngray_shades; i++)
+    {
+      color.red = (i * klass->info.visual->colormap_size) / dgray;
+      color.red = ((int) (255 * pow ((double) color.red / 256.0, one_over_gamma))) * 257;
+      color.green = color.red;
+      color.blue = color.red;
+
+      if (!gdk_color_alloc (klass->info.cmap, &color))
+       {
+         g_error ("could not initialize 8-bit combined colormap");
+         return;
+       }
+
+      pixels[i] = color.pixel;
+    }
+}
+
+
+static void
+gtk_color_8 (guchar *src,
+            guchar *dest,
+            gint    x,
+            gint    y,
+            gulong  width)
+{
+  gulong *colors;
+  GtkDitherInfo *dither_red;
+  GtkDitherInfo *dither_green;
+  GtkDitherInfo *dither_blue;
+  GtkDitherInfo r, g, b;
+  guchar **dither_matrix;
+  guchar *matrix;
+
+  colors = preview_class->info.color_pixels;
+  dither_red = preview_class->info.dither_red;
+  dither_green = preview_class->info.dither_green;
+  dither_blue = preview_class->info.dither_blue;
+  dither_matrix = preview_class->info.dither_matrix[y & 0x7];
+
+  while (width--)
+    {
+      r = dither_red[src[0]];
+      g = dither_green[src[1]];
+      b = dither_blue[src[2]];
+      src += 3;
+
+      matrix = dither_matrix[x++ & 0x7];
+      *dest++ = colors[(r.c[matrix[r.s[1]]] +
+                       g.c[matrix[g.s[1]]] +
+                       b.c[matrix[b.s[1]]])];
+    }
+}
+
+static void
+gtk_color_16 (guchar *src,
+             guchar *dest,
+             gulong  width)
+{
+  gulong *lookup_red;
+  gulong *lookup_green;
+  gulong *lookup_blue;
+  gulong val;
+
+  lookup_red = preview_class->info.lookup_red;
+  lookup_green = preview_class->info.lookup_green;
+  lookup_blue = preview_class->info.lookup_blue;
+
+  while (width--)
+    {
+      val = COLOR_COMPOSE (src[0], src[1], src[2]);
+      dest[0] = val;
+      dest[1] = val >> 8;
+      dest += 2;
+      src += 3;
+    }
+}
+
+static void
+gtk_color_24 (guchar *src,
+             guchar *dest,
+             gulong  width)
+{
+  gulong *lookup_red;
+  gulong *lookup_green;
+  gulong *lookup_blue;
+  gulong val;
+
+  lookup_red = preview_class->info.lookup_red;
+  lookup_green = preview_class->info.lookup_green;
+  lookup_blue = preview_class->info.lookup_blue;
+
+  while (width--)
+    {
+      val = COLOR_COMPOSE (src[0], src[1], src[2]);
+      dest[0] = val;
+      dest[1] = val >> 8;
+      dest[2] = val >> 16;
+      dest += 3;
+      src += 3;
+    }
+}
+
+static void
+gtk_grayscale_8 (guchar *src,
+                guchar *dest,
+                gint    x,
+                gint    y,
+                gulong  width)
+{
+  GtkDitherInfo *dither_gray;
+  GtkDitherInfo gray;
+  guchar **dither_matrix;
+  guchar *matrix;
+
+  dither_gray = preview_class->info.dither_gray;
+  dither_matrix = preview_class->info.dither_matrix[y & 0x7];
+
+  while (width--)
+    {
+      gray = dither_gray[*src++];
+      matrix = dither_matrix[x++ & 0x7];
+      *dest++ = gray.c[matrix[gray.s[1]]];
+    }
+}
+
+static void
+gtk_grayscale_16 (guchar *src,
+                 guchar *dest,
+                 gulong  width)
+{
+  gulong *lookup_red;
+  gulong *lookup_green;
+  gulong *lookup_blue;
+  gulong val;
+
+  lookup_red = preview_class->info.lookup_red;
+  lookup_green = preview_class->info.lookup_green;
+  lookup_blue = preview_class->info.lookup_blue;
+
+  while (width--)
+    {
+      val = COLOR_COMPOSE (*src, *src, *src);
+      dest[0] = val;
+      dest[1] = val >> 8;
+      dest += 2;
+      src += 1;
+    }
+}
+
+static void
+gtk_grayscale_24 (guchar  *src,
+                 guchar  *dest,
+                 gulong   width)
+{
+  gulong *lookup_red;
+  gulong *lookup_green;
+  gulong *lookup_blue;
+  gulong val;
+
+  lookup_red = preview_class->info.lookup_red;
+  lookup_green = preview_class->info.lookup_green;
+  lookup_blue = preview_class->info.lookup_blue;
+
+  while (width--)
+    {
+      val = COLOR_COMPOSE (*src, *src, *src);
+      dest[0] = val;
+      dest[1] = val >> 8;
+      dest[2] = val >> 16;
+      dest += 3;
+      src += 1;
+    }
+}
+
+
+static gint
+gtk_get_preview_prop (guint *nred,
+                     guint *ngreen,
+                     guint *nblue,
+                     guint *ngray)
+{
+  GtkPreviewProp *prop;
+  GdkAtom property;
+
+  property = gdk_atom_intern ("GTK_PREVIEW_INFO", FALSE);
+
+  if (gdk_property_get (NULL, property, property,
+                       0, sizeof (GtkPreviewProp), FALSE,
+                       NULL, NULL, NULL, (guchar**) &prop))
+    {
+      *nred = ntohs (prop->nred_shades);
+      *ngreen = ntohs (prop->ngreen_shades);
+      *nblue = ntohs (prop->nblue_shades);
+      *ngray = ntohs (prop->ngray_shades);
+
+      prop->ref_count = htons (ntohs (prop->ref_count) + 1);
+      gdk_property_change (NULL, property, property, 16,
+                          GDK_PROP_MODE_REPLACE,
+                          (guchar*) prop, 5);
+
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+static void
+gtk_set_preview_prop (guint nred,
+                     guint ngreen,
+                     guint nblue,
+                     guint ngray)
+{
+  GtkPreviewProp prop;
+  GdkAtom property;
+
+  property = gdk_atom_intern ("GTK_PREVIEW_INFO", FALSE);
+
+  prop.ref_count = htons (1);
+  prop.nred_shades = htons (nred);
+  prop.ngreen_shades = htons (ngreen);
+  prop.nblue_shades = htons (nblue);
+  prop.ngray_shades = htons (ngray);
+
+  gdk_property_change (NULL, property, property, 16,
+                      GDK_PROP_MODE_REPLACE,
+                      (guchar*) &prop, 5);
+}
+
+
+static void
+gtk_lsbmsb_1_1 (guchar *dest,
+               guchar *src,
+               gint    count)
+{
+  memcpy (dest, src, count);
+}
+
+static void
+gtk_lsb_2_2 (guchar *dest,
+            guchar *src,
+            gint    count)
+{
+  memcpy (dest, src, count * 2);
+}
+
+static void
+gtk_msb_2_2 (guchar *dest,
+            guchar *src,
+            gint    count)
+{
+  while (count--)
+    {
+      dest[0] = src[1];
+      dest[1] = src[0];
+      dest += 2;
+      src += 2;
+    }
+}
+
+static void
+gtk_lsb_3_3 (guchar *dest,
+            guchar *src,
+            gint    count)
+{
+  memcpy (dest, src, count * 3);
+}
+
+static void
+gtk_msb_3_3 (guchar *dest,
+            guchar *src,
+            gint    count)
+{
+  while (count--)
+    {
+      dest[0] = src[2];
+      dest[1] = src[1];
+      dest[2] = src[0];
+      dest += 3;
+      src += 3;
+    }
+}
+
+static void
+gtk_lsb_3_4 (guchar *dest,
+            guchar *src,
+            gint    count)
+{
+  while (count--)
+    {
+      dest[0] = src[0];
+      dest[1] = src[1];
+      dest[2] = src[2];
+      dest += 4;
+      src += 3;
+    }
+}
+
+static void
+gtk_msb_3_4 (guchar *dest,
+            guchar *src,
+            gint    count)
+{
+  while (count--)
+    {
+      dest[1] = src[2];
+      dest[2] = src[1];
+      dest[3] = src[0];
+      dest += 4;
+      src += 3;
+    }
+}
diff --git a/gtk/gtkpreview.h b/gtk/gtkpreview.h
new file mode 100644 (file)
index 0000000..2fe6ad5
--- /dev/null
@@ -0,0 +1,144 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_PREVIEW_H__
+#define __GTK_PREVIEW_H__
+
+
+#include <gtk/gtkwidget.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_PREVIEW(obj)          GTK_CHECK_CAST (obj, gtk_preview_get_type (), GtkPreview)
+#define GTK_PREVIEW_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_preview_get_type (), GtkPreviewClass)
+#define GTK_IS_PREVIEW(obj)       GTK_CHECK_TYPE (obj, gtk_preview_get_type ())
+
+
+typedef struct _GtkPreview       GtkPreview;
+typedef struct _GtkPreviewInfo   GtkPreviewInfo;
+typedef union  _GtkDitherInfo    GtkDitherInfo;
+typedef struct _GtkPreviewClass  GtkPreviewClass;
+
+struct _GtkPreview
+{
+  GtkWidget widget;
+
+  guchar *buffer;
+  guint16 buffer_width;
+  guint16 buffer_height;
+
+  guint type : 1;
+  guint expand : 1;
+};
+
+struct _GtkPreviewInfo
+{
+  GdkVisual *visual;
+  GdkColormap *cmap;
+
+  gulong *color_pixels;
+  gulong *gray_pixels;
+  gulong *reserved_pixels;
+
+  gulong *lookup_red;
+  gulong *lookup_green;
+  gulong *lookup_blue;
+
+  GtkDitherInfo *dither_red;
+  GtkDitherInfo *dither_green;
+  GtkDitherInfo *dither_blue;
+  GtkDitherInfo *dither_gray;
+  guchar ***dither_matrix;
+
+  guint nred_shades;
+  guint ngreen_shades;
+  guint nblue_shades;
+  guint ngray_shades;
+  guint nreserved;
+
+  guint bpp;
+  gint cmap_alloced;
+  gdouble gamma;
+};
+
+union _GtkDitherInfo
+{
+  gushort s[2];
+  guchar c[4];
+};
+
+struct _GtkPreviewClass
+{
+  GtkWidgetClass parent_class;
+
+  GtkPreviewInfo info;
+
+  GdkImage *image;
+};
+
+
+guint           gtk_preview_get_type           (void);
+void            gtk_preview_uninit             (void);
+GtkWidget*      gtk_preview_new                (GtkPreviewType   type);
+void            gtk_preview_size               (GtkPreview      *preview,
+                                               gint             width,
+                                               gint             height);
+void            gtk_preview_put                (GtkPreview      *preview,
+                                               GdkWindow       *window,
+                                               GdkGC           *gc,
+                                               gint             srcx,
+                                               gint             srcy,
+                                               gint             destx,
+                                               gint             desty,
+                                               gint             width,
+                                               gint             height);
+void            gtk_preview_put_row            (GtkPreview      *preview,
+                                               guchar          *src,
+                                               guchar          *dest,
+                                               gint             x,
+                                               gint             y,
+                                               gint             w);
+void            gtk_preview_draw_row           (GtkPreview      *preview,
+                                               guchar          *data,
+                                               gint             x,
+                                               gint             y,
+                                               gint             w);
+void            gtk_preview_set_expand         (GtkPreview      *preview,
+                                               gint             expand);
+
+void            gtk_preview_set_gamma          (double           gamma);
+void            gtk_preview_set_color_cube     (guint            nred_shades,
+                                               guint            ngreen_shades,
+                                               guint            nblue_shades,
+                                               guint            ngray_shades);
+void            gtk_preview_set_install_cmap   (gint             install_cmap);
+void            gtk_preview_set_reserved       (gint             nreserved);
+GdkVisual*      gtk_preview_get_visual         (void);
+GdkColormap*    gtk_preview_get_cmap           (void);
+GtkPreviewInfo* gtk_preview_get_info           (void);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_PREVIEW_H__ */
diff --git a/gtk/gtkprogressbar.c b/gtk/gtkprogressbar.c
new file mode 100644 (file)
index 0000000..8db560b
--- /dev/null
@@ -0,0 +1,259 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkprogressbar.h"
+
+
+#define MIN_WIDTH   200
+#define MIN_HEIGHT  20
+
+
+static void gtk_progress_bar_class_init    (GtkProgressBarClass *klass);
+static void gtk_progress_bar_init          (GtkProgressBar      *pbar);
+static void gtk_progress_bar_realize       (GtkWidget           *widget);
+static void gtk_progress_bar_size_allocate (GtkWidget           *widget,
+                                           GtkAllocation       *allocation);
+static gint gtk_progress_bar_expose        (GtkWidget           *widget,
+                                           GdkEventExpose      *event);
+static void gtk_progress_bar_make_pixmap   (GtkProgressBar      *pbar);
+static void gtk_progress_bar_paint         (GtkProgressBar      *pbar);
+
+
+guint
+gtk_progress_bar_get_type ()
+{
+  static guint progress_bar_type = 0;
+
+  if (!progress_bar_type)
+    {
+      GtkTypeInfo progress_bar_info =
+      {
+       "GtkProgressBar",
+       sizeof (GtkProgressBar),
+       sizeof (GtkProgressBarClass),
+       (GtkClassInitFunc) gtk_progress_bar_class_init,
+       (GtkObjectInitFunc) gtk_progress_bar_init,
+       (GtkArgFunc) NULL,
+      };
+
+      progress_bar_type = gtk_type_unique (gtk_widget_get_type (), &progress_bar_info);
+    }
+
+  return progress_bar_type;
+}
+
+static void
+gtk_progress_bar_class_init (GtkProgressBarClass *class)
+{
+  GtkWidgetClass *widget_class;
+
+  widget_class = (GtkWidgetClass*) class;
+
+  widget_class->realize = gtk_progress_bar_realize;
+  widget_class->size_allocate = gtk_progress_bar_size_allocate;
+  widget_class->expose_event = gtk_progress_bar_expose;
+}
+
+static void
+gtk_progress_bar_init (GtkProgressBar *pbar)
+{
+  GTK_WIDGET_SET_FLAGS (pbar, GTK_BASIC);
+
+  GTK_WIDGET (pbar)->requisition.width = MIN_WIDTH;
+  GTK_WIDGET (pbar)->requisition.height = MIN_HEIGHT;
+  pbar->offscreen_pixmap = NULL;
+  pbar->percentage = 0;
+}
+
+
+GtkWidget*
+gtk_progress_bar_new ()
+{
+  return GTK_WIDGET (gtk_type_new (gtk_progress_bar_get_type ()));
+}
+
+void
+gtk_progress_bar_update (GtkProgressBar *pbar,
+                        gfloat          percentage)
+{
+  g_return_if_fail (pbar != NULL);
+  g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
+
+  if (percentage < 0.0)
+    percentage = 0.0;
+  else if (percentage > 1.0)
+    percentage = 1.0;
+
+  if (pbar->percentage != percentage)
+    {
+      pbar->percentage = percentage;
+      gtk_progress_bar_paint (pbar);
+      gtk_widget_queue_draw (GTK_WIDGET (pbar));
+    }
+}
+
+static void
+gtk_progress_bar_realize (GtkWidget *widget)
+{
+  GtkProgressBar *pbar;
+  GdkWindowAttr attributes;
+  gint attributes_mask;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_PROGRESS_BAR (widget));
+
+  pbar = GTK_PROGRESS_BAR (widget);
+  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+
+  attributes.window_type = GDK_WINDOW_CHILD;
+  attributes.x = widget->allocation.x;
+  attributes.y = widget->allocation.y;
+  attributes.width = widget->allocation.width;
+  attributes.height = widget->allocation.height;
+  attributes.wclass = GDK_INPUT_OUTPUT;
+  attributes.visual = gtk_widget_get_visual (widget);
+  attributes.colormap = gtk_widget_get_colormap (widget);
+  attributes.event_mask = gtk_widget_get_events (widget);
+  attributes.event_mask |= GDK_EXPOSURE_MASK;
+
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+
+  widget->window = gdk_window_new (widget->parent->window, &attributes, attributes_mask);
+  gdk_window_set_user_data (widget->window, pbar);
+
+  widget->style = gtk_style_attach (widget->style, widget->window);
+  gtk_style_set_background (widget->style, widget->window, GTK_STATE_ACTIVE);
+
+  gtk_progress_bar_make_pixmap (pbar);
+}
+
+static void
+gtk_progress_bar_size_allocate (GtkWidget     *widget,
+                               GtkAllocation *allocation)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_PROGRESS_BAR (widget));
+  g_return_if_fail (allocation != NULL);
+
+  widget->allocation = *allocation;
+
+  if (GTK_WIDGET_REALIZED (widget))
+    {
+      gdk_window_move_resize (widget->window,
+                             allocation->x, allocation->y,
+                             allocation->width, allocation->height);
+
+      gtk_progress_bar_make_pixmap (GTK_PROGRESS_BAR (widget));
+    }
+}
+
+static gint
+gtk_progress_bar_expose (GtkWidget      *widget,
+                        GdkEventExpose *event)
+{
+  GtkProgressBar *pbar;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_PROGRESS_BAR (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      pbar = GTK_PROGRESS_BAR (widget);
+
+      gdk_draw_pixmap (widget->window,
+                      widget->style->black_gc,
+                      pbar->offscreen_pixmap,
+                      0, 0, 0, 0,
+                      widget->allocation.width,
+                      widget->allocation.height);
+    }
+
+  return FALSE;
+}
+
+static void
+gtk_progress_bar_make_pixmap (GtkProgressBar *pbar)
+{
+  GtkWidget *widget;
+
+  g_return_if_fail (pbar != NULL);
+  g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
+
+  if (GTK_WIDGET_REALIZED (pbar))
+    {
+      widget = GTK_WIDGET (pbar);
+
+      if (pbar->offscreen_pixmap)
+       gdk_pixmap_destroy (pbar->offscreen_pixmap);
+
+      pbar->offscreen_pixmap = gdk_pixmap_new (widget->window,
+                                              widget->allocation.width,
+                                              widget->allocation.height,
+                                              -1);
+
+      gtk_progress_bar_paint (pbar);
+    }
+}
+
+static void
+gtk_progress_bar_paint (GtkProgressBar *pbar)
+{
+  GtkWidget *widget;
+  int amount;
+
+  g_return_if_fail (pbar != NULL);
+  g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
+
+  if (pbar->offscreen_pixmap)
+    {
+      widget = GTK_WIDGET (pbar);
+
+      gtk_draw_shadow (widget->style,
+                      pbar->offscreen_pixmap,
+                      GTK_STATE_NORMAL, GTK_SHADOW_IN, 0, 0,
+                      widget->allocation.width,
+                      widget->allocation.height);
+
+      gdk_draw_rectangle (pbar->offscreen_pixmap,
+                         widget->style->bg_gc[GTK_STATE_ACTIVE], TRUE,
+                         widget->style->klass->xthickness,
+                         widget->style->klass->ythickness,
+                         widget->allocation.width - widget->style->klass->xthickness * 2,
+                         widget->allocation.height - widget->style->klass->ythickness * 2);
+
+
+      amount = pbar->percentage * (widget->allocation.width - widget->style->klass->xthickness * 2);
+      if (amount > 0)
+       {
+         gdk_draw_rectangle (pbar->offscreen_pixmap,
+                             widget->style->bg_gc[GTK_STATE_PRELIGHT], TRUE,
+                             widget->style->klass->xthickness,
+                             widget->style->klass->ythickness,
+                             amount,
+                             widget->allocation.height - widget->style->klass->ythickness * 2);
+
+         gtk_draw_shadow (widget->style,
+                          pbar->offscreen_pixmap,
+                          GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
+                          widget->style->klass->xthickness,
+                          widget->style->klass->ythickness,
+                          amount,
+                          widget->allocation.height - widget->style->klass->ythickness * 2);
+       }
+    }
+}
diff --git a/gtk/gtkprogressbar.h b/gtk/gtkprogressbar.h
new file mode 100644 (file)
index 0000000..e831dfb
--- /dev/null
@@ -0,0 +1,64 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_PROGRESS_BAR_H__
+#define __GTK_PROGRESS_BAR_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkwidget.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_PROGRESS_BAR(obj)          GTK_CHECK_CAST (obj, gtk_progress_bar_get_type (), GtkProgressBar)
+#define GTK_PROGRESS_BAR_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_progress_bar_get_type (), GtkProgressBarClass)
+#define GTK_IS_PROGRESS_BAR(obj)       GTK_CHECK_TYPE (obj, gtk_progress_bar_get_type ())
+
+
+typedef struct _GtkProgressBar       GtkProgressBar;
+typedef struct _GtkProgressBarClass  GtkProgressBarClass;
+
+struct _GtkProgressBar
+{
+  GtkWidget widget;
+
+  GdkPixmap *offscreen_pixmap;
+  gfloat percentage;
+};
+
+struct _GtkProgressBarClass
+{
+  GtkWidgetClass parent_class;
+};
+
+
+guint      gtk_progress_bar_get_type (void);
+GtkWidget* gtk_progress_bar_new      (void);
+void       gtk_progress_bar_update   (GtkProgressBar *pbar,
+                                     gfloat          percentage);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_PROGRESS_BAR_H__ */
diff --git a/gtk/gtkradiobutton.c b/gtk/gtkradiobutton.c
new file mode 100644 (file)
index 0000000..0c52836
--- /dev/null
@@ -0,0 +1,321 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtklabel.h"
+#include "gtkradiobutton.h"
+#include "gtksignal.h"
+
+
+#define CHECK_BUTTON_CLASS(w)  GTK_CHECK_BUTTON_CLASS (GTK_OBJECT (w)->klass)
+
+
+static void gtk_radio_button_class_init     (GtkRadioButtonClass  *klass);
+static void gtk_radio_button_init           (GtkRadioButton       *radio_button);
+static void gtk_radio_button_destroy        (GtkObject            *object);
+static void gtk_radio_button_clicked        (GtkButton            *button);
+static void gtk_radio_button_draw_indicator (GtkCheckButton       *check_button,
+                                            GdkRectangle         *area);
+
+
+static GtkCheckButtonClass *parent_class = NULL;
+
+
+guint
+gtk_radio_button_get_type ()
+{
+  static guint radio_button_type = 0;
+
+  if (!radio_button_type)
+    {
+      GtkTypeInfo radio_button_info =
+      {
+       "GtkRadioButton",
+       sizeof (GtkRadioButton),
+       sizeof (GtkRadioButtonClass),
+       (GtkClassInitFunc) gtk_radio_button_class_init,
+       (GtkObjectInitFunc) gtk_radio_button_init,
+       (GtkArgFunc) NULL,
+      };
+
+      radio_button_type = gtk_type_unique (gtk_check_button_get_type (), &radio_button_info);
+    }
+
+  return radio_button_type;
+}
+
+static void
+gtk_radio_button_class_init (GtkRadioButtonClass *class)
+{
+  GtkObjectClass *object_class;
+  GtkButtonClass *button_class;
+  GtkCheckButtonClass *check_button_class;
+
+  object_class = (GtkObjectClass*) class;
+  button_class = (GtkButtonClass*) class;
+  check_button_class = (GtkCheckButtonClass*) class;
+
+  parent_class = gtk_type_class (gtk_check_button_get_type ());
+
+  object_class->destroy = gtk_radio_button_destroy;
+
+  button_class->clicked = gtk_radio_button_clicked;
+
+  check_button_class->draw_indicator = gtk_radio_button_draw_indicator;
+}
+
+static void
+gtk_radio_button_init (GtkRadioButton *radio_button)
+{
+  radio_button->group = NULL;
+}
+
+GtkWidget*
+gtk_radio_button_new (GSList *group)
+{
+  GtkRadioButton *radio_button;
+  GtkRadioButton *tmp_button;
+  GSList *tmp_list;
+
+  radio_button = gtk_type_new (gtk_radio_button_get_type ());
+
+  tmp_list = group;
+  radio_button->group = g_slist_prepend (group, radio_button);
+
+  if (tmp_list)
+    {
+      while (tmp_list)
+       {
+         tmp_button = tmp_list->data;
+         tmp_list = tmp_list->next;
+
+         tmp_button->group = radio_button->group;
+       }
+    }
+  else
+    {
+      GTK_TOGGLE_BUTTON (radio_button)->active = TRUE;
+      gtk_widget_set_state (GTK_WIDGET (radio_button), GTK_STATE_ACTIVE);
+    }
+
+  return GTK_WIDGET (radio_button);
+}
+
+GtkWidget*
+gtk_radio_button_new_with_label (GSList      *group,
+                                const gchar *label)
+{
+  GtkWidget *radio_button;
+  GtkWidget *label_widget;
+
+  radio_button = gtk_radio_button_new (group);
+  label_widget = gtk_label_new (label);
+  gtk_misc_set_alignment (GTK_MISC (label_widget), 0.0, 0.5);
+
+  gtk_container_add (GTK_CONTAINER (radio_button), label_widget);
+  gtk_widget_show (label_widget);
+
+  return radio_button;
+}
+
+GtkWidget*
+gtk_radio_button_new_from_widget (GtkRadioButton *group)
+{
+  GSList *l = NULL;
+  if (group)
+    l = gtk_radio_button_group (group);
+  return gtk_radio_button_new (l);
+}
+
+
+GtkWidget*
+gtk_radio_button_new_with_label_from_widget (GtkRadioButton *group,
+                                            const gchar    *label)
+{
+  GSList *l = NULL;
+  if (group)
+    l = gtk_radio_button_group (group);
+  return gtk_radio_button_new_with_label (l, label);
+}
+
+GSList*
+gtk_radio_button_group (GtkRadioButton *radio_button)
+{
+  g_return_val_if_fail (radio_button != NULL, NULL);
+  g_return_val_if_fail (GTK_IS_RADIO_BUTTON (radio_button), NULL);
+
+  return radio_button->group;
+}
+
+
+static void
+gtk_radio_button_destroy (GtkObject *object)
+{
+  GtkRadioButton *radio_button;
+  GtkRadioButton *tmp_button;
+  GSList *tmp_list;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_RADIO_BUTTON (object));
+
+  radio_button = GTK_RADIO_BUTTON (object);
+
+  radio_button->group = g_slist_remove (radio_button->group, radio_button);
+  tmp_list = radio_button->group;
+
+  while (tmp_list)
+    {
+      tmp_button = tmp_list->data;
+      tmp_list = tmp_list->next;
+
+      tmp_button->group = radio_button->group;
+    }
+
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+gtk_radio_button_clicked (GtkButton *button)
+{
+  GtkToggleButton *toggle_button;
+  GtkRadioButton *radio_button;
+  GtkToggleButton *tmp_button;
+  GtkStateType new_state;
+  GSList *tmp_list;
+  gint toggled;
+
+  g_return_if_fail (button != NULL);
+  g_return_if_fail (GTK_IS_RADIO_BUTTON (button));
+
+  radio_button = GTK_RADIO_BUTTON (button);
+  toggle_button = GTK_TOGGLE_BUTTON (button);
+  toggled = FALSE;
+
+  if (toggle_button->active)
+    {
+      tmp_button = NULL;
+      tmp_list = radio_button->group;
+
+      while (tmp_list)
+       {
+         tmp_button = tmp_list->data;
+         tmp_list = tmp_list->next;
+
+         if (tmp_button->active && (tmp_button != toggle_button))
+           break;
+
+         tmp_button = NULL;
+       }
+
+      if (!tmp_button)
+       {
+         new_state = (button->in_button ? GTK_STATE_PRELIGHT : GTK_STATE_ACTIVE);
+       }
+      else
+       {
+         toggled = TRUE;
+         toggle_button->active = !toggle_button->active;
+         new_state = (button->in_button ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL);
+       }
+    }
+  else
+    {
+      toggled = TRUE;
+      toggle_button->active = !toggle_button->active;
+
+      tmp_list = radio_button->group;
+      while (tmp_list)
+       {
+         tmp_button = tmp_list->data;
+         tmp_list = tmp_list->next;
+
+         if (tmp_button->active && (tmp_button != toggle_button))
+           {
+             gtk_button_clicked (GTK_BUTTON (tmp_button));
+             break;
+           }
+       }
+
+      new_state = (button->in_button ? GTK_STATE_PRELIGHT : GTK_STATE_ACTIVE);
+    }
+
+  if (GTK_WIDGET_STATE (button) != new_state)
+    gtk_widget_set_state (GTK_WIDGET (button), new_state);
+  if (toggled)
+    gtk_toggle_button_toggled (toggle_button);
+  gtk_widget_queue_draw (GTK_WIDGET (button));
+}
+
+static void
+gtk_radio_button_draw_indicator (GtkCheckButton *check_button,
+                                GdkRectangle   *area)
+{
+  GtkWidget *widget;
+  GtkButton *button;
+  GtkToggleButton *toggle_button;
+  GtkStateType state_type;
+  GtkShadowType shadow_type;
+  GdkPoint pts[4];
+  gint width, height;
+  gint x, y;
+
+  g_return_if_fail (check_button != NULL);
+  g_return_if_fail (GTK_IS_RADIO_BUTTON (check_button));
+
+  if (GTK_WIDGET_VISIBLE (check_button) && GTK_WIDGET_MAPPED (check_button))
+    {
+      widget = GTK_WIDGET (check_button);
+      button = GTK_BUTTON (check_button);
+      toggle_button = GTK_TOGGLE_BUTTON (check_button);
+
+      state_type = GTK_WIDGET_STATE (widget);
+      if ((state_type != GTK_STATE_NORMAL) &&
+         (state_type != GTK_STATE_PRELIGHT))
+       state_type = GTK_STATE_NORMAL;
+
+      gtk_style_set_background (widget->style, widget->window, state_type);
+      gdk_window_clear_area (widget->window, area->x, area->y, area->width, area->height);
+
+      x = CHECK_BUTTON_CLASS (widget)->indicator_spacing + GTK_CONTAINER (widget)->border_width;
+      y = (widget->allocation.height - CHECK_BUTTON_CLASS (widget)->indicator_size) / 2;
+      width = CHECK_BUTTON_CLASS (widget)->indicator_size;
+      height = CHECK_BUTTON_CLASS (widget)->indicator_size;
+
+      if (GTK_WIDGET_STATE (widget) == GTK_STATE_ACTIVE)
+       shadow_type = GTK_SHADOW_IN;
+      else if ((GTK_WIDGET_STATE (widget) == GTK_STATE_PRELIGHT) && toggle_button->active)
+       shadow_type = GTK_SHADOW_IN;
+      else
+       shadow_type = GTK_SHADOW_OUT;
+
+      pts[0].x = x + width / 2;
+      pts[0].y = y;
+      pts[1].x = x + width;
+      pts[1].y = y + height / 2;
+      pts[2].x = pts[0].x;
+      pts[2].y = y + height;
+      pts[3].x = x;
+      pts[3].y = pts[1].y;
+
+      gdk_draw_polygon (widget->window,
+                       widget->style->bg_gc[GTK_WIDGET_STATE (widget)],
+                       TRUE, pts, 4);
+      gtk_draw_diamond (widget->style, widget->window,
+                       GTK_WIDGET_STATE (widget), shadow_type,
+                       x, y, width, height);
+    }
+}
diff --git a/gtk/gtkradiobutton.h b/gtk/gtkradiobutton.h
new file mode 100644 (file)
index 0000000..bf346c2
--- /dev/null
@@ -0,0 +1,69 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_RADIO_BUTTON_H__
+#define __GTK_RADIO_BUTTON_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkcheckbutton.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_RADIO_BUTTON(obj)          GTK_CHECK_CAST (obj, gtk_radio_button_get_type (), GtkRadioButton)
+#define GTK_RADIO_BUTTON_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_radio_button_get_type (), GtkRadioButtonClass)
+#define GTK_IS_RADIO_BUTTON(obj)       GTK_CHECK_TYPE (obj, gtk_radio_button_get_type ())
+
+
+typedef struct _GtkRadioButton       GtkRadioButton;
+typedef struct _GtkRadioButtonClass  GtkRadioButtonClass;
+
+struct _GtkRadioButton
+{
+  GtkCheckButton check_button;
+
+  GSList *group;
+};
+
+struct _GtkRadioButtonClass
+{
+  GtkCheckButtonClass parent_class;
+};
+
+
+guint       gtk_radio_button_get_type        (void);
+GtkWidget*  gtk_radio_button_new             (GSList         *group);
+GtkWidget*  gtk_radio_button_new_from_widget (GtkRadioButton *group);
+GtkWidget*  gtk_radio_button_new_with_label  (GSList         *group,
+                                             const gchar    *label);
+GtkWidget*  gtk_radio_button_new_interp     (GtkRadioButton *group);
+GtkWidget*  gtk_radio_button_new_with_label_interp
+                                            (GtkRadioButton *group,
+                                            const gchar    *label);
+GSList*     gtk_radio_button_group           (GtkRadioButton *radio_button);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_RADIO_BUTTON_H__ */
diff --git a/gtk/gtkradiomenuitem.c b/gtk/gtkradiomenuitem.c
new file mode 100644 (file)
index 0000000..edfcff6
--- /dev/null
@@ -0,0 +1,240 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtklabel.h"
+#include "gtkradiomenuitem.h"
+
+
+static void gtk_radio_menu_item_class_init     (GtkRadioMenuItemClass *klass);
+static void gtk_radio_menu_item_init           (GtkRadioMenuItem      *radio_menu_item);
+static void gtk_radio_menu_item_activate       (GtkMenuItem           *menu_item);
+static void gtk_radio_menu_item_draw_indicator (GtkCheckMenuItem      *check_menu_item,
+                                               GdkRectangle          *area);
+
+
+guint
+gtk_radio_menu_item_get_type ()
+{
+  static guint radio_menu_item_type = 0;
+
+  if (!radio_menu_item_type)
+    {
+      GtkTypeInfo radio_menu_item_info =
+      {
+        "GtkRadioMenuItem",
+        sizeof (GtkRadioMenuItem),
+        sizeof (GtkRadioMenuItemClass),
+        (GtkClassInitFunc) gtk_radio_menu_item_class_init,
+        (GtkObjectInitFunc) gtk_radio_menu_item_init,
+        (GtkArgFunc) NULL,
+      };
+
+      radio_menu_item_type = gtk_type_unique (gtk_check_menu_item_get_type (), &radio_menu_item_info);
+    }
+
+  return radio_menu_item_type;
+}
+
+GtkWidget*
+gtk_radio_menu_item_new (GSList *group)
+{
+  GtkRadioMenuItem *radio_menu_item;
+  GtkRadioMenuItem *tmp_menu_item;
+  GSList *tmp_list;
+
+  radio_menu_item = gtk_type_new (gtk_radio_menu_item_get_type ());
+
+  tmp_list = group;
+  radio_menu_item->group = g_slist_prepend (group, radio_menu_item);
+
+  if (tmp_list)
+    {
+      while (tmp_list)
+       {
+         tmp_menu_item = tmp_list->data;
+         tmp_list = tmp_list->next;
+
+         tmp_menu_item->group = radio_menu_item->group;
+       }
+    }
+  else
+    {
+      GTK_CHECK_MENU_ITEM (radio_menu_item)->active = TRUE;
+    }
+
+  return GTK_WIDGET (radio_menu_item);
+}
+
+GtkWidget*
+gtk_radio_menu_item_new_with_label (GSList *group,
+                                   const gchar *label)
+{
+  GtkWidget *radio_menu_item;
+  GtkWidget *label_widget;
+
+  radio_menu_item = gtk_radio_menu_item_new (group);
+  label_widget = gtk_label_new (label);
+  gtk_misc_set_alignment (GTK_MISC (label_widget), 0.0, 0.5);
+
+  gtk_container_add (GTK_CONTAINER (radio_menu_item), label_widget);
+  gtk_widget_show (label_widget);
+
+  return radio_menu_item;
+}
+
+GSList*
+gtk_radio_menu_item_group (GtkRadioMenuItem *radio_menu_item)
+{
+  g_return_val_if_fail (radio_menu_item != NULL, NULL);
+  g_return_val_if_fail (GTK_IS_RADIO_MENU_ITEM (radio_menu_item), NULL);
+
+  return radio_menu_item->group;
+}
+
+
+static void
+gtk_radio_menu_item_class_init (GtkRadioMenuItemClass *klass)
+{
+  GtkMenuItemClass *menu_item_class;
+  GtkCheckMenuItemClass *check_menu_item_class;
+
+  menu_item_class = (GtkMenuItemClass*) klass;
+  check_menu_item_class = (GtkCheckMenuItemClass*) klass;
+
+  menu_item_class->activate = gtk_radio_menu_item_activate;
+
+  check_menu_item_class->draw_indicator = gtk_radio_menu_item_draw_indicator;
+}
+
+static void
+gtk_radio_menu_item_init (GtkRadioMenuItem *radio_menu_item)
+{
+  radio_menu_item->group = NULL;
+}
+
+static void
+gtk_radio_menu_item_activate (GtkMenuItem *menu_item)
+{
+  GtkRadioMenuItem *radio_menu_item;
+  GtkCheckMenuItem *check_menu_item;
+  GtkCheckMenuItem *tmp_menu_item;
+  GSList *tmp_list;
+  gint toggled;
+
+  g_return_if_fail (menu_item != NULL);
+  g_return_if_fail (GTK_IS_RADIO_MENU_ITEM (menu_item));
+
+  radio_menu_item = GTK_RADIO_MENU_ITEM (menu_item);
+  check_menu_item = GTK_CHECK_MENU_ITEM (menu_item);
+  toggled = FALSE;
+
+  if (check_menu_item->active)
+    {
+      tmp_menu_item = NULL;
+      tmp_list = radio_menu_item->group;
+
+      while (tmp_list)
+       {
+         tmp_menu_item = tmp_list->data;
+         tmp_list = tmp_list->next;
+
+         if (tmp_menu_item->active && (tmp_menu_item != check_menu_item))
+           break;
+
+         tmp_menu_item = NULL;
+       }
+
+      if (tmp_menu_item)
+       {
+         toggled = TRUE;
+         check_menu_item->active = !check_menu_item->active;
+       }
+    }
+  else
+    {
+      toggled = TRUE;
+      check_menu_item->active = !check_menu_item->active;
+
+      tmp_list = radio_menu_item->group;
+      while (tmp_list)
+       {
+         tmp_menu_item = tmp_list->data;
+         tmp_list = tmp_list->next;
+
+         if (tmp_menu_item->active && (tmp_menu_item != check_menu_item))
+           {
+             gtk_menu_item_activate (GTK_MENU_ITEM (tmp_menu_item));
+             break;
+           }
+       }
+    }
+
+  if (toggled)
+    gtk_check_menu_item_toggled (check_menu_item);
+  gtk_widget_queue_draw (GTK_WIDGET (radio_menu_item));
+}
+
+static void
+gtk_radio_menu_item_draw_indicator (GtkCheckMenuItem *check_menu_item,
+                                   GdkRectangle     *area)
+{
+  GtkWidget *widget;
+  GtkStateType state_type;
+  GtkShadowType shadow_type;
+  GdkPoint pts[4];
+  gint width, height;
+  gint x, y;
+
+  g_return_if_fail (check_menu_item != NULL);
+  g_return_if_fail (GTK_IS_RADIO_MENU_ITEM (check_menu_item));
+
+  if (GTK_WIDGET_DRAWABLE (check_menu_item))
+    {
+      widget = GTK_WIDGET (check_menu_item);
+
+      width = 8;
+      height = 8;
+      x = (GTK_CONTAINER (check_menu_item)->border_width +
+          widget->style->klass->xthickness + 2);
+      y = (widget->allocation.height - height) / 2;
+
+      gdk_window_clear_area (widget->window, x, y, width, height);
+
+      if (check_menu_item->active ||
+         (GTK_WIDGET_STATE (check_menu_item) == GTK_STATE_PRELIGHT))
+       {
+         state_type = GTK_WIDGET_STATE (widget);
+         shadow_type = GTK_SHADOW_IN;
+
+         pts[0].x = x + width / 2;
+         pts[0].y = y;
+         pts[1].x = x + width;
+         pts[1].y = y + height / 2;
+         pts[2].x = pts[0].x;
+         pts[2].y = y + height;
+         pts[3].x = x;
+         pts[3].y = pts[1].y;
+
+         gdk_draw_polygon (widget->window,
+                           widget->style->bg_gc[state_type],
+                           TRUE, pts, 4);
+         gtk_draw_diamond (widget->style, widget->window,
+                           state_type, shadow_type,
+                           x, y, width, height);
+       }
+    }
+}
diff --git a/gtk/gtkradiomenuitem.h b/gtk/gtkradiomenuitem.h
new file mode 100644 (file)
index 0000000..28abafc
--- /dev/null
@@ -0,0 +1,64 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_RADIO_MENU_ITEM_H__
+#define __GTK_RADIO_MENU_ITEM_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkcheckmenuitem.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_RADIO_MENU_ITEM(obj)          GTK_CHECK_CAST (obj, gtk_radio_menu_item_get_type (), GtkRadioMenuItem)
+#define GTK_RADIO_MENU_ITEM_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_radio_menu_item_get_type (), GtkRadioMenuItemClass)
+#define GTK_IS_RADIO_MENU_ITEM(obj)       GTK_CHECK_TYPE (obj, gtk_radio_menu_item_get_type ())
+
+
+typedef struct _GtkRadioMenuItem       GtkRadioMenuItem;
+typedef struct _GtkRadioMenuItemClass  GtkRadioMenuItemClass;
+
+struct _GtkRadioMenuItem
+{
+  GtkCheckMenuItem check_menu_item;
+
+  GSList *group;
+};
+
+struct _GtkRadioMenuItemClass
+{
+  GtkCheckMenuItemClass parent_class;
+};
+
+
+guint      gtk_radio_menu_item_get_type       (void);
+GtkWidget* gtk_radio_menu_item_new            (GSList           *group);
+GtkWidget* gtk_radio_menu_item_new_with_label (GSList           *group,
+                                              const gchar      *label);
+GSList*    gtk_radio_menu_item_group          (GtkRadioMenuItem *radio_menu_item);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_RADIO_MENU_ITEM_H__ */
diff --git a/gtk/gtkrange.c b/gtk/gtkrange.c
new file mode 100644 (file)
index 0000000..f00bbf6
--- /dev/null
@@ -0,0 +1,1369 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdio.h>
+#include "gtkmain.h"
+#include "gtkrange.h"
+#include "gtksignal.h"
+
+
+#define SCROLL_TIMER_LENGTH  20
+#define SCROLL_INITIAL_DELAY 100
+#define SCROLL_DELAY_LENGTH  300
+
+#define RANGE_CLASS(w)  GTK_RANGE_CLASS (GTK_OBJECT (w)->klass)
+
+
+static void gtk_range_class_init               (GtkRangeClass    *klass);
+static void gtk_range_init                     (GtkRange         *range);
+static void gtk_range_destroy                  (GtkObject        *object);
+static void gtk_range_draw                     (GtkWidget        *widget,
+                                               GdkRectangle     *area);
+static void gtk_range_draw_focus               (GtkWidget        *widget);
+static void gtk_range_unrealize                (GtkWidget        *widget);
+static gint gtk_range_expose                   (GtkWidget        *widget,
+                                               GdkEventExpose   *event);
+static gint gtk_range_button_press             (GtkWidget        *widget,
+                                               GdkEventButton   *event);
+static gint gtk_range_button_release           (GtkWidget        *widget,
+                                               GdkEventButton   *event);
+static gint gtk_range_motion_notify            (GtkWidget        *widget,
+                                               GdkEventMotion   *event);
+static gint gtk_range_key_press                (GtkWidget         *widget,
+                                               GdkEventKey       *event);
+static gint gtk_range_enter_notify             (GtkWidget        *widget,
+                                               GdkEventCrossing *event);
+static gint gtk_range_leave_notify             (GtkWidget        *widget,
+                                               GdkEventCrossing *event);
+static gint gtk_range_focus_in                 (GtkWidget        *widget,
+                                               GdkEventFocus    *event);
+static gint gtk_range_focus_out                (GtkWidget        *widget,
+                                               GdkEventFocus    *event);
+static void gtk_real_range_draw_trough         (GtkRange         *range);
+static void gtk_real_range_draw_slider         (GtkRange         *range);
+static gint gtk_real_range_timer               (GtkRange         *range);
+static gint gtk_range_scroll                   (GtkRange         *range);
+
+static void gtk_range_add_timer                (GtkRange         *range);
+static void gtk_range_remove_timer             (GtkRange         *range);
+
+static void gtk_range_adjustment_changed       (GtkAdjustment    *adjustment,
+                                               gpointer          data);
+static void gtk_range_adjustment_value_changed (GtkAdjustment    *adjustment,
+                                               gpointer          data);
+
+static void gtk_range_trough_hdims             (GtkRange         *range,
+                                               gint             *left,
+                                               gint             *right);
+static void gtk_range_trough_vdims             (GtkRange         *range,
+                                               gint             *top,
+                                               gint             *bottom);
+
+static GtkWidgetClass *parent_class = NULL;
+
+
+guint
+gtk_range_get_type ()
+{
+  static guint range_type = 0;
+
+  if (!range_type)
+    {
+      GtkTypeInfo range_info =
+      {
+       "GtkRange",
+       sizeof (GtkRange),
+       sizeof (GtkRangeClass),
+       (GtkClassInitFunc) gtk_range_class_init,
+       (GtkObjectInitFunc) gtk_range_init,
+       (GtkArgFunc) NULL,
+      };
+
+      range_type = gtk_type_unique (gtk_widget_get_type (), &range_info);
+    }
+
+  return range_type;
+}
+
+static void
+gtk_range_class_init (GtkRangeClass *class)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+
+  object_class = (GtkObjectClass*) class;
+  widget_class = (GtkWidgetClass*) class;
+
+  parent_class = gtk_type_class (gtk_widget_get_type ());
+
+  object_class->destroy = gtk_range_destroy;
+
+  widget_class->draw = gtk_range_draw;
+  widget_class->draw_focus = gtk_range_draw_focus;
+  widget_class->unrealize = gtk_range_unrealize;
+  widget_class->expose_event = gtk_range_expose;
+  widget_class->button_press_event = gtk_range_button_press;
+  widget_class->button_release_event = gtk_range_button_release;
+  widget_class->motion_notify_event = gtk_range_motion_notify;
+  widget_class->key_press_event = gtk_range_key_press;
+  widget_class->enter_notify_event = gtk_range_enter_notify;
+  widget_class->leave_notify_event = gtk_range_leave_notify;
+  widget_class->focus_in_event = gtk_range_focus_in;
+  widget_class->focus_out_event = gtk_range_focus_out;
+
+  class->slider_width = 11;
+  class->stepper_size = 11;
+  class->stepper_slider_spacing = 1;
+  class->min_slider_size = 7;
+  class->trough = 1;
+  class->slider = 2;
+  class->step_forw = 3;
+  class->step_back = 4;
+  class->draw_background = NULL;
+  class->draw_trough = gtk_real_range_draw_trough;
+  class->draw_slider = gtk_real_range_draw_slider;
+  class->draw_step_forw = NULL;
+  class->draw_step_back = NULL;
+  class->trough_click = NULL;
+  class->trough_keys = NULL;
+  class->motion = NULL;
+  class->timer = gtk_real_range_timer;
+}
+
+static void
+gtk_range_init (GtkRange *range)
+{
+  range->trough = NULL;
+  range->slider = NULL;
+  range->step_forw = NULL;
+  range->step_back = NULL;
+
+  range->x_click_point = 0;
+  range->y_click_point = 0;
+  range->button = 0;
+  range->digits = -1;
+  range->policy = GTK_UPDATE_CONTINUOUS;
+  range->scroll_type = GTK_SCROLL_NONE;
+  range->in_child = 0;
+  range->click_child = 0;
+  range->need_timer = FALSE;
+  range->timer = 0;
+  range->old_value = 0.0;
+  range->old_lower = 0.0;
+  range->old_upper = 0.0;
+  range->old_page_size = 0.0;
+  range->adjustment = NULL;
+}
+
+GtkAdjustment*
+gtk_range_get_adjustment (GtkRange *range)
+{
+  g_return_val_if_fail (range != NULL, NULL);
+  g_return_val_if_fail (GTK_IS_RANGE (range), NULL);
+
+  return range->adjustment;
+}
+
+void
+gtk_range_set_update_policy (GtkRange      *range,
+                            GtkUpdateType  policy)
+{
+  g_return_if_fail (range != NULL);
+  g_return_if_fail (GTK_IS_RANGE (range));
+
+  range->policy = policy;
+}
+
+void
+gtk_range_set_adjustment (GtkRange      *range,
+                         GtkAdjustment *adjustment)
+{
+  g_return_if_fail (range != NULL);
+  g_return_if_fail (GTK_IS_RANGE (range));
+
+  if (range->adjustment)
+    {
+      gtk_signal_disconnect_by_data (GTK_OBJECT (range->adjustment), (gpointer) range);
+      gtk_object_unref (GTK_OBJECT (range->adjustment));
+    }
+
+  range->adjustment = adjustment;
+  gtk_object_ref (GTK_OBJECT (range->adjustment));
+
+  gtk_signal_connect (GTK_OBJECT (adjustment), "changed",
+                     (GtkSignalFunc) gtk_range_adjustment_changed,
+                     (gpointer) range);
+  gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
+                     (GtkSignalFunc) gtk_range_adjustment_value_changed,
+                     (gpointer) range);
+
+  range->old_value = adjustment->value;
+  range->old_lower = adjustment->lower;
+  range->old_upper = adjustment->upper;
+  range->old_page_size = adjustment->page_size;
+
+  gtk_range_adjustment_changed (range->adjustment, (gpointer) range);
+}
+
+void
+gtk_range_draw_background (GtkRange *range)
+{
+  g_return_if_fail (range != NULL);
+  g_return_if_fail (GTK_IS_RANGE (range));
+
+  if (range->trough && RANGE_CLASS (range)->draw_background)
+    (* RANGE_CLASS (range)->draw_background) (range);
+}
+
+void
+gtk_range_draw_trough (GtkRange *range)
+{
+  g_return_if_fail (range != NULL);
+  g_return_if_fail (GTK_IS_RANGE (range));
+
+  if (range->trough && RANGE_CLASS (range)->draw_trough)
+    (* RANGE_CLASS (range)->draw_trough) (range);
+}
+
+void
+gtk_range_draw_slider (GtkRange *range)
+{
+  g_return_if_fail (range != NULL);
+  g_return_if_fail (GTK_IS_RANGE (range));
+
+  if (range->slider && RANGE_CLASS (range)->draw_slider)
+    (* RANGE_CLASS (range)->draw_slider) (range);
+}
+
+void
+gtk_range_draw_step_forw (GtkRange *range)
+{
+  g_return_if_fail (range != NULL);
+  g_return_if_fail (GTK_IS_RANGE (range));
+
+  if (range->step_forw && RANGE_CLASS (range)->draw_step_forw)
+    (* RANGE_CLASS (range)->draw_step_forw) (range);
+}
+
+void
+gtk_range_draw_step_back (GtkRange *range)
+{
+  g_return_if_fail (range != NULL);
+  g_return_if_fail (GTK_IS_RANGE (range));
+
+  if (range->step_back && RANGE_CLASS (range)->draw_step_back)
+    (* RANGE_CLASS (range)->draw_step_back) (range);
+}
+
+void
+gtk_range_slider_update (GtkRange *range)
+{
+  g_return_if_fail (range != NULL);
+  g_return_if_fail (GTK_IS_RANGE (range));
+
+  if (RANGE_CLASS (range)->slider_update)
+    (* RANGE_CLASS (range)->slider_update) (range);
+}
+
+gint
+gtk_range_trough_click (GtkRange *range,
+                       gint      x,
+                       gint      y)
+{
+  g_return_val_if_fail (range != NULL, GTK_TROUGH_NONE);
+  g_return_val_if_fail (GTK_IS_RANGE (range), GTK_TROUGH_NONE);
+
+  if (RANGE_CLASS (range)->trough_click)
+    return (* RANGE_CLASS (range)->trough_click) (range, x, y);
+
+  return GTK_TROUGH_NONE;
+}
+
+void
+gtk_range_default_hslider_update (GtkRange *range)
+{
+  gint left;
+  gint right;
+  gint x;
+
+  g_return_if_fail (range != NULL);
+  g_return_if_fail (GTK_IS_RANGE (range));
+
+  if (GTK_WIDGET_REALIZED (range))
+    {
+      gtk_range_trough_hdims (range, &left, &right);
+      x = left;
+
+      if (range->adjustment->value < range->adjustment->lower)
+       {
+         range->adjustment->value = range->adjustment->lower;
+         gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
+       }
+      else if (range->adjustment->value > range->adjustment->upper)
+       {
+         range->adjustment->value = range->adjustment->upper;
+         gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
+       }
+
+      if (range->adjustment->lower != (range->adjustment->upper - range->adjustment->page_size))
+       x += ((right - left) * (range->adjustment->value - range->adjustment->lower) /
+             (range->adjustment->upper - range->adjustment->lower - range->adjustment->page_size));
+
+      if (x < left)
+       x = left;
+      else if (x > right)
+       x = right;
+
+      gdk_window_move (range->slider, x, GTK_WIDGET (range)->style->klass->ythickness);
+    }
+}
+
+void
+gtk_range_default_vslider_update (GtkRange *range)
+{
+  gint top;
+  gint bottom;
+  gint y;
+
+  g_return_if_fail (range != NULL);
+  g_return_if_fail (GTK_IS_RANGE (range));
+
+  if (GTK_WIDGET_REALIZED (range))
+    {
+      gtk_range_trough_vdims (range, &top, &bottom);
+      y = top;
+
+      if (range->adjustment->value < range->adjustment->lower)
+       {
+         range->adjustment->value = range->adjustment->lower;
+         gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
+       }
+      else if (range->adjustment->value > range->adjustment->upper)
+       {
+         range->adjustment->value = range->adjustment->upper;
+         gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
+       }
+
+      if (range->adjustment->lower != (range->adjustment->upper - range->adjustment->page_size))
+       y += ((bottom - top) * (range->adjustment->value - range->adjustment->lower) /
+             (range->adjustment->upper - range->adjustment->lower - range->adjustment->page_size));
+
+      if (y < top)
+       y = top;
+      else if (y > bottom)
+       y = bottom;
+
+      gdk_window_move (range->slider, GTK_WIDGET (range)->style->klass->ythickness, y);
+    }
+}
+
+gint
+gtk_range_default_htrough_click (GtkRange *range,
+                                gint      x,
+                                gint      y)
+{
+  gint xthickness;
+  gint ythickness;
+  gint trough_width;
+  gint trough_height;
+  gint slider_x;
+
+  g_return_val_if_fail (range != NULL, GTK_TROUGH_NONE);
+  g_return_val_if_fail (GTK_IS_RANGE (range), GTK_TROUGH_NONE);
+
+  xthickness = GTK_WIDGET (range)->style->klass->xthickness;
+  ythickness = GTK_WIDGET (range)->style->klass->ythickness;
+
+  if ((x > xthickness) && (y > ythickness))
+    {
+      gdk_window_get_size (range->trough, &trough_width, &trough_height);
+
+      if ((x < (trough_width - xthickness) && (y < (trough_height - ythickness))))
+       {
+         gdk_window_get_position (range->slider, &slider_x, NULL);
+
+         if (x < slider_x)
+           return GTK_TROUGH_START;
+         else
+           return GTK_TROUGH_END;
+       }
+    }
+
+  return GTK_TROUGH_NONE;
+}
+
+gint
+gtk_range_default_vtrough_click (GtkRange *range,
+                                gint      x,
+                                gint      y)
+{
+  gint xthickness;
+  gint ythickness;
+  gint trough_width;
+  gint trough_height;
+  gint slider_y;
+
+  g_return_val_if_fail (range != NULL, GTK_TROUGH_NONE);
+  g_return_val_if_fail (GTK_IS_RANGE (range), GTK_TROUGH_NONE);
+
+  xthickness = GTK_WIDGET (range)->style->klass->xthickness;
+  ythickness = GTK_WIDGET (range)->style->klass->ythickness;
+
+  if ((x > xthickness) && (y > ythickness))
+    {
+      gdk_window_get_size (range->trough, &trough_width, &trough_height);
+
+      if ((x < (trough_width - xthickness) && (y < (trough_height - ythickness))))
+       {
+         gdk_window_get_position (range->slider, NULL, &slider_y);
+
+         if (y < slider_y)
+           return GTK_TROUGH_START;
+         else
+           return GTK_TROUGH_END;
+       }
+    }
+
+  return GTK_TROUGH_NONE;
+}
+
+void
+gtk_range_default_hmotion (GtkRange *range,
+                          gint      xdelta,
+                          gint      ydelta)
+{
+  gdouble old_value;
+  gint left, right;
+  gint slider_x, slider_y;
+  gint new_pos;
+
+  g_return_if_fail (range != NULL);
+  g_return_if_fail (GTK_IS_RANGE (range));
+
+  range = GTK_RANGE (range);
+
+  gdk_window_get_position (range->slider, &slider_x, &slider_y);
+  gtk_range_trough_hdims (range, &left, &right);
+
+  if (left == right)
+    return;
+
+  new_pos = slider_x + xdelta;
+
+  if (new_pos < left)
+    new_pos = left;
+  else if (new_pos > right)
+    new_pos = right;
+
+  old_value = range->adjustment->value;
+  range->adjustment->value = ((range->adjustment->upper -
+                              range->adjustment->lower -
+                              range->adjustment->page_size) *
+                             (new_pos - left) / (right - left) +
+                             range->adjustment->lower);
+
+  if (range->digits >= 0)
+    {
+      char buffer[64];
+
+      sprintf (buffer, "%0.*f", range->digits, range->adjustment->value);
+      sscanf (buffer, "%f", &range->adjustment->value);
+    }
+
+  if (old_value != range->adjustment->value)
+    {
+      if (range->policy == GTK_UPDATE_CONTINUOUS)
+       {
+         gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
+       }
+      else
+       {
+         gtk_range_slider_update (range);
+         gtk_range_draw_background (range);
+
+         if (range->policy == GTK_UPDATE_DELAYED)
+           {
+             gtk_range_remove_timer (range);
+             range->timer = gtk_timeout_add (SCROLL_DELAY_LENGTH,
+                                             (GtkFunction) RANGE_CLASS (range)->timer,
+                                             (gpointer) range);
+           }
+       }
+    }
+}
+
+void
+gtk_range_default_vmotion (GtkRange *range,
+                          gint      xdelta,
+                          gint      ydelta)
+{
+  gdouble old_value;
+  gint top, bottom;
+  gint slider_x, slider_y;
+  gint new_pos;
+
+  g_return_if_fail (range != NULL);
+  g_return_if_fail (GTK_IS_RANGE (range));
+
+  range = GTK_RANGE (range);
+
+  gdk_window_get_position (range->slider, &slider_x, &slider_y);
+  gtk_range_trough_vdims (range, &top, &bottom);
+
+  if (bottom == top)
+    return;
+
+  new_pos = slider_y + ydelta;
+
+  if (new_pos < top)
+    new_pos = top;
+  else if (new_pos > bottom)
+    new_pos = bottom;
+
+  old_value = range->adjustment->value;
+  range->adjustment->value = ((range->adjustment->upper -
+                              range->adjustment->lower -
+                              range->adjustment->page_size) *
+                             (new_pos - top) / (bottom - top) +
+                             range->adjustment->lower);
+
+  if (range->digits >= 0)
+    {
+      char buffer[64];
+
+      sprintf (buffer, "%0.*f", range->digits, range->adjustment->value);
+      sscanf (buffer, "%f", &range->adjustment->value);
+    }
+
+  if (old_value != range->adjustment->value)
+    {
+      if (range->policy == GTK_UPDATE_CONTINUOUS)
+       {
+         gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
+       }
+      else
+       {
+         gtk_range_slider_update (range);
+         gtk_range_draw_background (range);
+
+         if (range->policy == GTK_UPDATE_DELAYED)
+           {
+             gtk_range_remove_timer (range);
+             range->timer = gtk_timeout_add (SCROLL_DELAY_LENGTH,
+                                             (GtkFunction) RANGE_CLASS (range)->timer,
+                                             (gpointer) range);
+           }
+       }
+    }
+}
+
+gfloat
+gtk_range_calc_value (GtkRange *range,
+                     gint      position)
+{
+  return 0.0;
+}
+
+
+static void
+gtk_range_destroy (GtkObject *object)
+{
+  GtkRange *range;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_RANGE (object));
+
+  range = GTK_RANGE (object);
+
+  if (range->adjustment)
+    gtk_object_unref (GTK_OBJECT (range->adjustment));
+
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+gtk_range_draw (GtkWidget    *widget,
+               GdkRectangle *area)
+{
+  GtkRange *range;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_RANGE (widget));
+  g_return_if_fail (area != NULL);
+
+  if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget))
+    {
+      range = GTK_RANGE (widget);
+
+      gtk_range_draw_background (range);
+      gtk_range_draw_trough (range);
+      gtk_range_draw_slider (range);
+      gtk_range_draw_step_forw (range);
+      gtk_range_draw_step_back (range);
+    }
+}
+
+static void
+gtk_range_draw_focus (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_RANGE (widget));
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    gtk_range_draw_trough (GTK_RANGE (widget));
+}
+
+static void
+gtk_range_unrealize (GtkWidget *widget)
+{
+  GtkRange *range;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_RANGE (widget));
+
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED);
+  range = GTK_RANGE (widget);
+
+  gtk_style_detach (widget->style);
+
+  if (range->slider)
+    gdk_window_destroy (range->slider);
+  if (range->trough)
+    gdk_window_destroy (range->trough);
+  if (range->step_forw)
+    gdk_window_destroy (range->step_forw);
+  if (range->step_back)
+    gdk_window_destroy (range->step_back);
+  if (widget->window)
+    gdk_window_destroy (widget->window);
+
+  range->slider = NULL;
+  range->trough = NULL;
+  range->step_forw = NULL;
+  range->step_back = NULL;
+  widget->window = NULL;
+}
+
+static gint
+gtk_range_expose (GtkWidget      *widget,
+                 GdkEventExpose *event)
+{
+  GtkRange *range;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  range = GTK_RANGE (widget);
+
+  if (event->window == range->trough)
+    {
+      gtk_range_draw_trough (range);
+    }
+  else if (event->window == widget->window)
+    {
+      gtk_range_draw_background (range);
+    }
+  else if (event->window == range->slider)
+    {
+      gtk_range_draw_slider (range);
+    }
+  else if (event->window == range->step_forw)
+    {
+      gtk_range_draw_step_forw (range);
+    }
+  else if (event->window == range->step_back)
+    {
+      gtk_range_draw_step_back (range);
+    }
+  return FALSE;
+}
+
+static gint
+gtk_range_button_press (GtkWidget      *widget,
+                       GdkEventButton *event)
+{
+  GtkRange *range;
+  gint trough_part;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (!GTK_WIDGET_HAS_FOCUS (widget))
+    gtk_widget_grab_focus (widget);
+
+  range = GTK_RANGE (widget);
+  if (!range->button)
+    {
+      gtk_grab_add (widget);
+
+      range->button = event->button;
+      range->x_click_point = event->x;
+      range->y_click_point = event->y;
+
+      if (event->window == range->trough)
+       {
+         range->click_child = RANGE_CLASS (range)->trough;
+
+         trough_part = gtk_range_trough_click (range, event->x, event->y);
+
+         range->scroll_type = GTK_SCROLL_NONE;
+         if (trough_part == GTK_TROUGH_START)
+           range->scroll_type = GTK_SCROLL_PAGE_BACKWARD;
+         else if (trough_part == GTK_TROUGH_END)
+           range->scroll_type = GTK_SCROLL_PAGE_FORWARD;
+
+         if (range->scroll_type != GTK_SCROLL_NONE)
+           {
+             gtk_range_scroll (range);
+             gtk_range_add_timer (range);
+           }
+       }
+      else if (event->window == range->slider)
+       {
+         range->click_child = RANGE_CLASS (range)->slider;
+         range->scroll_type = GTK_SCROLL_NONE;
+       }
+      else if (event->window == range->step_forw)
+       {
+         range->click_child = RANGE_CLASS (range)->step_forw;
+         range->scroll_type = GTK_SCROLL_STEP_FORWARD;
+
+         gtk_range_scroll (range);
+         gtk_range_add_timer (range);
+         gtk_range_draw_step_forw (range);
+       }
+      else if (event->window == range->step_back)
+       {
+         range->click_child = RANGE_CLASS (range)->step_back;
+         range->scroll_type = GTK_SCROLL_STEP_BACKWARD;
+
+         gtk_range_scroll (range);
+         gtk_range_add_timer (range);
+         gtk_range_draw_step_back (range);
+       }
+    }
+
+  return FALSE;
+}
+
+static gint
+gtk_range_button_release (GtkWidget      *widget,
+                         GdkEventButton *event)
+{
+  GtkRange *range;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  range = GTK_RANGE (widget);
+
+  if (range->button == event->button)
+    {
+      gtk_grab_remove (widget);
+
+      range->button = 0;
+      range->x_click_point = -1;
+      range->y_click_point = -1;
+
+      if (range->click_child == RANGE_CLASS (range)->slider)
+       {
+         if (range->policy == GTK_UPDATE_DELAYED)
+           gtk_range_remove_timer (range);
+
+         if ((range->policy != GTK_UPDATE_CONTINUOUS) &&
+             (range->old_value != range->adjustment->value))
+           gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
+       }
+      else if ((range->click_child == RANGE_CLASS (range)->trough) ||
+              (range->click_child == RANGE_CLASS (range)->step_forw) ||
+              (range->click_child == RANGE_CLASS (range)->step_back))
+       {
+         gtk_range_remove_timer (range);
+
+         if ((range->policy != GTK_UPDATE_CONTINUOUS) &&
+             (range->old_value != range->adjustment->value))
+           gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
+
+         if (range->click_child == RANGE_CLASS (range)->step_forw)
+           {
+             range->click_child = 0;
+             gtk_range_draw_step_forw (range);
+           }
+         else if (range->click_child == RANGE_CLASS (range)->step_back)
+           {
+             range->click_child = 0;
+             gtk_range_draw_step_back (range);
+           }
+       }
+
+      range->click_child = 0;
+    }
+
+  return FALSE;
+}
+
+static gint
+gtk_range_motion_notify (GtkWidget      *widget,
+                        GdkEventMotion *event)
+{
+  GtkRange *range;
+  GdkModifierType mods;
+  gint x, y, mask;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  range = GTK_RANGE (widget);
+
+  if (range->click_child == RANGE_CLASS (range)->slider)
+    {
+      x = event->x;
+      y = event->y;
+
+      if (event->is_hint || (event->window != range->slider))
+       gdk_window_get_pointer (range->slider, &x, &y, &mods);
+
+      switch (range->button)
+       {
+       case 1:
+         mask = GDK_BUTTON1_MASK;
+         break;
+       case 2:
+         mask = GDK_BUTTON2_MASK;
+         break;
+       case 3:
+         mask = GDK_BUTTON3_MASK;
+         break;
+       default:
+         mask = 0;
+         break;
+       }
+
+      if (mods & mask)
+       {
+         if (RANGE_CLASS (range)->motion)
+           (* RANGE_CLASS (range)->motion) (range, x - range->x_click_point, y - range->y_click_point);
+       }
+    }
+
+  return FALSE;
+}
+
+static gint
+gtk_range_key_press (GtkWidget   *widget,
+                    GdkEventKey *event)
+{
+  GtkRange *range;
+  gint return_val;
+  GtkScrollType scroll = GTK_SCROLL_NONE;
+  GtkTroughType pos = GTK_TROUGH_NONE;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  range = GTK_RANGE (widget);
+  return_val = FALSE;
+
+  if (RANGE_CLASS (range)->trough_keys)
+    return_val = (* RANGE_CLASS (range)->trough_keys) (range, event, &scroll, &pos);
+
+  if (return_val)
+    {
+      if (scroll != GTK_SCROLL_NONE)
+       {
+         range->scroll_type = scroll;
+         gtk_range_scroll (range);
+         if (range->old_value != range->adjustment->value)
+           {
+             gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
+             switch (range->scroll_type)
+               {
+               case GTK_SCROLL_STEP_BACKWARD:
+                 gtk_range_draw_step_back (range);
+                 break;
+               case GTK_SCROLL_STEP_FORWARD:
+                 gtk_range_draw_step_forw (range);
+                 break;
+               }
+           }
+       }
+      if (pos != GTK_TROUGH_NONE)
+       {
+         if (pos == GTK_TROUGH_START)
+           range->adjustment->value = range->adjustment->lower;
+         else
+           range->adjustment->value =
+             range->adjustment->upper - range->adjustment->page_size;
+
+         if (range->old_value != range->adjustment->value)
+           {
+             gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment),
+                                      "value_changed");
+
+             gtk_range_slider_update (range);
+             gtk_range_draw_background (range);
+           }
+       }
+    }
+  return return_val;
+}
+
+static gint
+gtk_range_enter_notify (GtkWidget        *widget,
+                       GdkEventCrossing *event)
+{
+  GtkRange *range;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  range = GTK_RANGE (widget);
+
+  if (event->window == range->trough)
+    {
+      range->in_child = RANGE_CLASS (range)->trough;
+    }
+  else if (event->window == range->slider)
+    {
+      range->in_child = RANGE_CLASS (range)->slider;
+
+      if ((range->click_child == 0) ||
+         (range->click_child == RANGE_CLASS (range)->trough))
+       gtk_range_draw_slider (range);
+    }
+  else if (event->window == range->step_forw)
+    {
+      range->in_child = RANGE_CLASS (range)->step_forw;
+
+      if ((range->click_child == 0) ||
+         (range->click_child == RANGE_CLASS (range)->trough))
+       gtk_range_draw_step_forw (range);
+    }
+  else if (event->window == range->step_back)
+    {
+      range->in_child = RANGE_CLASS (range)->step_back;
+
+      if ((range->click_child == 0) ||
+         (range->click_child == RANGE_CLASS (range)->trough))
+       gtk_range_draw_step_back (range);
+    }
+
+  return FALSE;
+}
+
+static gint
+gtk_range_leave_notify (GtkWidget        *widget,
+                       GdkEventCrossing *event)
+{
+  GtkRange *range;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  range = GTK_RANGE (widget);
+
+  range->in_child = 0;
+
+  if (event->window == range->trough)
+    {
+    }
+  else if (event->window == range->slider)
+    {
+      if ((range->click_child == 0) ||
+         (range->click_child == RANGE_CLASS (range)->trough))
+       gtk_range_draw_slider (range);
+    }
+  else if (event->window == range->step_forw)
+    {
+      if ((range->click_child == 0) ||
+         (range->click_child == RANGE_CLASS (range)->trough))
+       gtk_range_draw_step_forw (range);
+    }
+  else if (event->window == range->step_back)
+    {
+      if ((range->click_child == 0) ||
+         (range->click_child == RANGE_CLASS (range)->trough))
+       gtk_range_draw_step_back (range);
+    }
+
+  return FALSE;
+}
+
+static gint
+gtk_range_focus_in (GtkWidget     *widget,
+                   GdkEventFocus *event)
+{
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
+  gtk_widget_draw_focus (widget);
+
+  return FALSE;
+}
+
+static gint
+gtk_range_focus_out (GtkWidget     *widget,
+                    GdkEventFocus *event)
+{
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
+  gtk_widget_draw_focus (widget);
+
+  return FALSE;
+}
+
+static void
+gtk_real_range_draw_trough (GtkRange *range)
+{
+  g_return_if_fail (range != NULL);
+  g_return_if_fail (GTK_IS_RANGE (range));
+
+  if (range->trough)
+    {
+      gtk_draw_shadow (GTK_WIDGET (range)->style, range->trough,
+                       GTK_STATE_NORMAL, GTK_SHADOW_IN,
+                       0, 0, -1, -1);
+
+      if (GTK_WIDGET_HAS_FOCUS (range))
+        gdk_draw_rectangle (GTK_WIDGET (range)->window,
+                            GTK_WIDGET (range)->style->black_gc,
+                            FALSE, 0, 0,
+                            GTK_WIDGET (range)->allocation.width - 1,
+                            GTK_WIDGET (range)->allocation.height - 1);
+      else if (range->trough != GTK_WIDGET (range)->window)
+        gdk_draw_rectangle (GTK_WIDGET (range)->window,
+                            GTK_WIDGET (range)->style->bg_gc[GTK_STATE_NORMAL],
+                            FALSE, 0, 0,
+                            GTK_WIDGET (range)->allocation.width - 1,
+                            GTK_WIDGET (range)->allocation.height - 1);
+    }
+}
+
+static void
+gtk_real_range_draw_slider (GtkRange *range)
+{
+  GtkStateType state_type;
+
+  g_return_if_fail (range != NULL);
+  g_return_if_fail (GTK_IS_RANGE (range));
+
+  if (range->slider)
+    {
+      if ((range->in_child == RANGE_CLASS (range)->slider) ||
+         (range->click_child == RANGE_CLASS (range)->slider))
+       state_type = GTK_STATE_PRELIGHT;
+      else
+       state_type = GTK_STATE_NORMAL;
+
+      gtk_style_set_background (GTK_WIDGET (range)->style, range->slider, state_type);
+      gdk_window_clear (range->slider);
+
+      gtk_draw_shadow (GTK_WIDGET (range)->style, range->slider,
+                      state_type, GTK_SHADOW_OUT,
+                      0, 0, -1, -1);
+    }
+}
+
+static gint
+gtk_real_range_timer (GtkRange *range)
+{
+  gint return_val;
+
+  g_return_val_if_fail (range != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_RANGE (range), FALSE);
+
+  return_val = TRUE;
+  if (range->click_child == RANGE_CLASS (range)->slider)
+    {
+      if (range->policy == GTK_UPDATE_DELAYED)
+       gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
+      return_val = FALSE;
+    }
+  else
+    {
+      if (!range->timer)
+       {
+         return_val = FALSE;
+         if (range->need_timer)
+           range->timer = gtk_timeout_add (SCROLL_TIMER_LENGTH,
+                                           (GtkFunction) RANGE_CLASS (range)->timer,
+                                           (gpointer) range);
+         else
+           return FALSE;
+         range->need_timer = FALSE;
+       }
+
+      if (gtk_range_scroll (range))
+       return return_val;
+    }
+
+  return return_val;
+}
+
+static gint
+gtk_range_scroll (GtkRange *range)
+{
+  gfloat new_value;
+  gint return_val;
+
+  g_return_val_if_fail (range != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_RANGE (range), FALSE);
+
+  new_value = range->adjustment->value;
+  return_val = TRUE;
+
+  switch (range->scroll_type)
+    {
+    case GTK_SCROLL_NONE:
+      break;
+
+    case GTK_SCROLL_STEP_BACKWARD:
+      new_value -= range->adjustment->step_increment;
+      if (new_value <= range->adjustment->lower)
+       {
+         new_value = range->adjustment->lower;
+         return_val = FALSE;
+         range->timer = 0;
+       }
+      break;
+
+    case GTK_SCROLL_STEP_FORWARD:
+      new_value += range->adjustment->step_increment;
+      if (new_value >= (range->adjustment->upper - range->adjustment->page_size))
+       {
+         new_value = range->adjustment->upper - range->adjustment->page_size;
+         return_val = FALSE;
+         range->timer = 0;
+       }
+      break;
+
+    case GTK_SCROLL_PAGE_BACKWARD:
+      new_value -= range->adjustment->page_increment;
+      if (new_value <= range->adjustment->lower)
+       {
+         new_value = range->adjustment->lower;
+         return_val = FALSE;
+         range->timer = 0;
+       }
+      break;
+
+    case GTK_SCROLL_PAGE_FORWARD:
+      new_value += range->adjustment->page_increment;
+      if (new_value >= (range->adjustment->upper - range->adjustment->page_size))
+       {
+         new_value = range->adjustment->upper - range->adjustment->page_size;
+         return_val = FALSE;
+         range->timer = 0;
+       }
+      break;
+    }
+
+  if (new_value != range->adjustment->value)
+    {
+      range->adjustment->value = new_value;
+
+      if ((range->policy == GTK_UPDATE_CONTINUOUS) ||
+         (!return_val && (range->policy == GTK_UPDATE_DELAYED)))
+       {
+         gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
+       }
+      else
+       {
+         gtk_range_slider_update (range);
+         gtk_range_draw_background (range);
+       }
+    }
+
+  return return_val;
+}
+
+
+static void
+gtk_range_add_timer (GtkRange *range)
+{
+  g_return_if_fail (range != NULL);
+  g_return_if_fail (GTK_IS_RANGE (range));
+
+  if (!range->timer)
+    {
+      range->need_timer = TRUE;
+      range->timer = gtk_timeout_add (SCROLL_INITIAL_DELAY,
+                                     (GtkFunction) RANGE_CLASS (range)->timer,
+                                     (gpointer) range);
+    }
+}
+
+static void
+gtk_range_remove_timer (GtkRange *range)
+{
+  g_return_if_fail (range != NULL);
+  g_return_if_fail (GTK_IS_RANGE (range));
+
+  if (range->timer)
+    {
+      gtk_timeout_remove (range->timer);
+      range->timer = 0;
+    }
+  range->need_timer = FALSE;
+}
+
+static void
+gtk_range_adjustment_changed (GtkAdjustment *adjustment,
+                             gpointer       data)
+{
+  GtkRange *range;
+
+  g_return_if_fail (adjustment != NULL);
+  g_return_if_fail (data != NULL);
+
+  range = GTK_RANGE (data);
+
+  if (((range->old_lower != adjustment->lower) ||
+       (range->old_upper != adjustment->upper) ||
+       (range->old_page_size != adjustment->page_size)) &&
+      (range->old_value == adjustment->value))
+    {
+      if ((adjustment->lower == adjustment->upper) ||
+         (range->old_lower == (range->old_upper - range->old_page_size)))
+       {
+         adjustment->value = adjustment->lower;
+         gtk_signal_emit_by_name (GTK_OBJECT (adjustment), "value_changed");
+       }
+    }
+
+  if ((range->old_value != adjustment->value) ||
+      (range->old_lower != adjustment->lower) ||
+      (range->old_upper != adjustment->upper) ||
+      (range->old_page_size != adjustment->page_size))
+    {
+      gtk_range_slider_update (range);
+      gtk_range_draw_background (range);
+
+      range->old_value = adjustment->value;
+      range->old_lower = adjustment->lower;
+      range->old_upper = adjustment->upper;
+      range->old_page_size = adjustment->page_size;
+    }
+}
+
+static void
+gtk_range_adjustment_value_changed (GtkAdjustment *adjustment,
+                                   gpointer       data)
+{
+  GtkRange *range;
+
+  g_return_if_fail (adjustment != NULL);
+  g_return_if_fail (data != NULL);
+
+  range = GTK_RANGE (data);
+
+  if (range->old_value != adjustment->value)
+    {
+      gtk_range_slider_update (range);
+      gtk_range_draw_background (range);
+
+      range->old_value = adjustment->value;
+    }
+}
+
+
+static void
+gtk_range_trough_hdims (GtkRange *range,
+                       gint     *left,
+                       gint     *right)
+{
+  gint trough_width;
+  gint slider_length;
+  gint tmp_width;
+  gint tleft;
+  gint tright;
+
+  g_return_if_fail (range != NULL);
+
+  gdk_window_get_size (range->trough, &trough_width, NULL);
+  gdk_window_get_size (range->slider, &slider_length, NULL);
+
+  tleft = GTK_WIDGET (range)->style->klass->xthickness;
+  tright = trough_width - slider_length - GTK_WIDGET (range)->style->klass->xthickness;
+
+  if (range->step_back)
+    {
+      gdk_window_get_size (range->step_back, &tmp_width, NULL);
+      tleft += (tmp_width + RANGE_CLASS (range)->stepper_slider_spacing);
+    }
+
+  if (range->step_forw)
+    {
+      gdk_window_get_size (range->step_forw, &tmp_width, NULL);
+      tright -= (tmp_width + RANGE_CLASS (range)->stepper_slider_spacing);
+    }
+
+  if (left)
+    *left = tleft;
+  if (right)
+    *right = tright;
+}
+
+static void
+gtk_range_trough_vdims (GtkRange *range,
+                       gint     *top,
+                       gint     *bottom)
+{
+  gint trough_height;
+  gint slider_length;
+  gint tmp_height;
+  gint ttop;
+  gint tbottom;
+
+  g_return_if_fail (range != NULL);
+
+  gdk_window_get_size (range->trough, NULL, &trough_height);
+  gdk_window_get_size (range->slider, NULL, &slider_length);
+
+  ttop = GTK_WIDGET (range)->style->klass->xthickness;
+  tbottom = trough_height - slider_length - GTK_WIDGET (range)->style->klass->ythickness;
+
+  if (range->step_back)
+    {
+      gdk_window_get_size (range->step_back, NULL, &tmp_height);
+      ttop += (tmp_height + RANGE_CLASS (range)->stepper_slider_spacing);
+    }
+
+  if (range->step_forw)
+    {
+      gdk_window_get_size (range->step_forw, NULL, &tmp_height);
+      tbottom -= (tmp_height + RANGE_CLASS (range)->stepper_slider_spacing);
+    }
+
+  if (top)
+    *top = ttop;
+  if (bottom)
+    *bottom = tbottom;
+}
diff --git a/gtk/gtkrange.h b/gtk/gtkrange.h
new file mode 100644 (file)
index 0000000..47ff50a
--- /dev/null
@@ -0,0 +1,144 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_RANGE_H__
+#define __GTK_RANGE_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkadjustment.h>
+#include <gtk/gtkwidget.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_RANGE(obj)          GTK_CHECK_CAST (obj, gtk_range_get_type (), GtkRange)
+#define GTK_RANGE_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_range_get_type (), GtkRangeClass)
+#define GTK_IS_RANGE(obj)       GTK_CHECK_TYPE (obj, gtk_range_get_type ())
+
+
+typedef struct _GtkRange        GtkRange;
+typedef struct _GtkRangeClass   GtkRangeClass;
+
+struct _GtkRange
+{
+  GtkWidget widget;
+
+  GdkWindow *trough;
+  GdkWindow *slider;
+  GdkWindow *step_forw;
+  GdkWindow *step_back;
+
+  gint16 x_click_point;
+  gint16 y_click_point;
+
+  guint8 button;
+  gint8 digits;
+  guint policy : 2;
+  guint scroll_type : 3;
+  guint in_child : 3;
+  guint click_child : 3;
+  guint need_timer : 1;
+
+  guint32 timer;
+
+  gfloat old_value;
+  gfloat old_lower;
+  gfloat old_upper;
+  gfloat old_page_size;
+
+  GtkAdjustment *adjustment;
+};
+
+struct _GtkRangeClass
+{
+  GtkWidgetClass parent_class;
+
+  gint slider_width;
+  gint stepper_size;
+  gint stepper_slider_spacing;
+  gint min_slider_size;
+
+  guint8 trough;
+  guint8 slider;
+  guint8 step_forw;
+  guint8 step_back;
+
+  void (* draw_background) (GtkRange *range);
+  void (* draw_trough)     (GtkRange *range);
+  void (* draw_slider)     (GtkRange *range);
+  void (* draw_step_forw)  (GtkRange *range);
+  void (* draw_step_back)  (GtkRange *range);
+  void (* slider_update)   (GtkRange *range);
+  gint (* trough_click)    (GtkRange *range,
+                           gint      x,
+                           gint      y);
+  gint (* trough_keys)     (GtkRange *range,
+                           GdkEventKey *key,
+                           GtkScrollType *scroll,
+                           GtkTroughType *trough);
+  void (* motion)          (GtkRange *range,
+                           gint      xdelta,
+                           gint      ydelta);
+  gint (* timer)           (GtkRange *range);
+};
+
+
+guint          gtk_range_get_type               (void);
+GtkAdjustment* gtk_range_get_adjustment         (GtkRange      *range);
+void           gtk_range_set_update_policy      (GtkRange      *range,
+                                                GtkUpdateType  policy);
+void           gtk_range_set_adjustment         (GtkRange      *range,
+                                                GtkAdjustment *adjustment);
+
+void           gtk_range_draw_background        (GtkRange      *range);
+void           gtk_range_draw_trough            (GtkRange      *range);
+void           gtk_range_draw_slider            (GtkRange      *range);
+void           gtk_range_draw_step_forw         (GtkRange      *range);
+void           gtk_range_draw_step_back         (GtkRange      *range);
+void           gtk_range_slider_update          (GtkRange      *range);
+gint           gtk_range_trough_click           (GtkRange      *range,
+                                                gint           x,
+                                                gint           y);
+
+void           gtk_range_default_hslider_update (GtkRange      *range);
+void           gtk_range_default_vslider_update (GtkRange      *range);
+gint           gtk_range_default_htrough_click  (GtkRange      *range,
+                                                gint           x,
+                                                gint           y);
+gint           gtk_range_default_vtrough_click  (GtkRange      *range,
+                                                gint           x,
+                                                gint           y);
+void           gtk_range_default_hmotion        (GtkRange      *range,
+                                                gint           xdelta,
+                                                gint           ydelta);
+void           gtk_range_default_vmotion        (GtkRange      *range,
+                                                gint           xdelta,
+                                                gint           ydelta);
+gfloat         gtk_range_calc_value             (GtkRange      *range,
+                                                gint           position);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_RANGE_H__ */
diff --git a/gtk/gtkrc.c b/gtk/gtkrc.c
new file mode 100644 (file)
index 0000000..86bc201
--- /dev/null
@@ -0,0 +1,1489 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "gtkrc.h"
+
+
+enum {
+  TOKEN_EOF,
+  TOKEN_LEFT_CURLY,
+  TOKEN_RIGHT_CURLY,
+  TOKEN_LEFT_BRACE,
+  TOKEN_RIGHT_BRACE,
+  TOKEN_EQUAL_SIGN,
+  TOKEN_COMMA,
+  TOKEN_INTEGER,
+  TOKEN_FLOAT,
+  TOKEN_STRING,
+  TOKEN_SYMBOL,
+  TOKEN_ACTIVE,
+  TOKEN_BASE,
+  TOKEN_BG,
+  TOKEN_BG_PIXMAP,
+  TOKEN_FG,
+  TOKEN_FONT,
+  TOKEN_FONTSET,
+  TOKEN_INSENSITIVE,
+  TOKEN_NORMAL,
+  TOKEN_PIXMAP_PATH,
+  TOKEN_PRELIGHT,
+  TOKEN_SELECTED,
+  TOKEN_STYLE,
+  TOKEN_TEXT,
+  TOKEN_WIDGET,
+  TOKEN_WIDGET_CLASS
+};
+
+enum {
+  PARSE_OK,
+  PARSE_ERROR,
+  PARSE_SYNTAX
+};
+
+enum {
+  PARSE_START,
+  PARSE_COMMENT,
+  PARSE_STRING,
+  PARSE_SYMBOL,
+  PARSE_NUMBER
+};
+
+
+typedef struct _GtkRcStyle  GtkRcStyle;
+typedef struct _GtkRcSet    GtkRcSet;
+
+struct _GtkRcStyle
+{
+  int initialize;
+  char *name;
+  char *font_name;
+  char *fontset_name;
+  char *bg_pixmap_name[5];
+  GtkStyle *style;
+};
+
+struct _GtkRcSet
+{
+  char *set;
+  GtkRcStyle *rc_style;
+};
+
+
+static guint       gtk_rc_style_hash               (const char *name);
+static gint        gtk_rc_style_compare            (const char *a,
+                                                   const char *b);
+static GtkRcStyle* gtk_rc_style_find               (const char *name);
+static GtkRcStyle* gtk_rc_styles_match             (GSList *sets,
+                                                   const char   *path);
+static gint        gtk_rc_style_match              (const char *set,
+                                                   const char *path);
+static void        gtk_rc_style_init               (GtkRcStyle *rc_style);
+static gint        gtk_rc_get_token                (void);
+static gint        gtk_rc_simple_token             (char ch);
+static gint        gtk_rc_symbol_token             (const char *sym);
+static gint        gtk_rc_get_next_token           (void);
+static gint        gtk_rc_peek_next_token          (void);
+static gint        gtk_rc_parse_statement          (void);
+static gint        gtk_rc_parse_style              (void);
+static gint        gtk_rc_parse_style_option       (GtkRcStyle   *rc_style);
+static gint        gtk_rc_parse_base               (GtkStyle     *style);
+static gint        gtk_rc_parse_bg                 (GtkStyle     *style);
+static gint        gtk_rc_parse_fg                 (GtkStyle     *style);
+static gint        gtk_rc_parse_bg_pixmap          (GtkRcStyle   *rc_style);
+static gint        gtk_rc_parse_font               (GtkRcStyle   *rc_style);
+static gint       gtk_rc_parse_fontset            (GtkRcStyle   *rc_style);
+static gint        gtk_rc_parse_state              (GtkStateType *state);
+static gint        gtk_rc_parse_color              (GdkColor     *color);
+static gint        gtk_rc_parse_pixmap_path        (void);
+static void        gtk_rc_parse_pixmap_path_string (gchar *pix_path);
+static char*       gtk_rc_find_pixmap_in_path      (gchar *pixmap_file);
+static gint        gtk_rc_parse_widget_style       (void);
+static gint        gtk_rc_parse_widget_class_style (void);
+static char*       gtk_rc_widget_path              (GtkWidget *widget);
+static char*       gtk_rc_widget_class_path        (GtkWidget *widget);
+
+
+static struct
+{
+  char *name;
+  int token;
+} symbols[] =
+  {
+    { "ACTIVE", TOKEN_ACTIVE },
+    { "base", TOKEN_BASE },
+    { "bg", TOKEN_BG },
+    { "bg_pixmap", TOKEN_BG_PIXMAP },
+    { "fg", TOKEN_FG },
+    { "font", TOKEN_FONT },
+    { "fontset", TOKEN_FONTSET },
+    { "INSENSITIVE", TOKEN_INSENSITIVE },
+    { "NORMAL", TOKEN_NORMAL },
+    { "pixmap_path", TOKEN_PIXMAP_PATH },
+    { "PRELIGHT", TOKEN_PRELIGHT },
+    { "SELECTED", TOKEN_SELECTED },
+    { "style", TOKEN_STYLE },
+    { "text", TOKEN_TEXT },
+    { "widget", TOKEN_WIDGET },
+    { "widget_class", TOKEN_WIDGET_CLASS },
+  };
+
+static int nsymbols = sizeof (symbols) / sizeof (symbols[0]);
+
+static struct
+{
+  char ch;
+  int token;
+} simple_tokens[] =
+  {
+    { '{', TOKEN_LEFT_CURLY },
+    { '}', TOKEN_RIGHT_CURLY },
+    { '[', TOKEN_LEFT_BRACE },
+    { ']', TOKEN_RIGHT_BRACE },
+    { '=', TOKEN_EQUAL_SIGN },
+    { ',', TOKEN_COMMA },
+  };
+
+static int nsimple_tokens = sizeof (simple_tokens) / sizeof (simple_tokens[0]);
+
+static FILE *input_fp = NULL;
+static char *buffer = NULL;
+static char *tokenbuf = NULL;
+static int position = 0;
+static int linenum = 1;
+static int buffer_size = 1024;
+static int tokenbuf_size = 1024;
+
+static int done;
+static int cur_token;
+static int next_token;
+
+static char *token_str;
+static double token_float;
+static int token_int;
+
+static GHashTable *rc_style_ht = NULL;
+static GSList *widget_sets = NULL;
+static GSList *widget_class_sets = NULL;
+
+#define GTK_RC_MAX_PIXMAP_PATHS 128
+static gchar *pixmap_path[GTK_RC_MAX_PIXMAP_PATHS];
+
+
+void
+gtk_rc_init ()
+{
+  rc_style_ht = g_hash_table_new ((GHashFunc) gtk_rc_style_hash,
+                                 (GCompareFunc) gtk_rc_style_compare);
+}
+
+void
+gtk_rc_parse (const char *filename)
+{
+  input_fp = fopen (filename, "r");
+  if (!input_fp)
+         return;
+
+  buffer = g_new (char, buffer_size + tokenbuf_size);
+  tokenbuf = buffer + buffer_size;
+  position = 0;
+  linenum = 1;
+
+  cur_token = -1;
+  next_token = -1;
+  done = FALSE;
+
+  while (!done)
+    {
+      if (gtk_rc_parse_statement () != PARSE_OK)
+       {
+         g_warning ("rc file parse error: \"%s\" line %d",
+                    filename, linenum);
+         done = TRUE;
+       }
+    }
+
+  fclose (input_fp);
+
+  g_free (buffer);
+
+  buffer = NULL;
+  tokenbuf = NULL;
+  position = 0;
+  linenum = 1;
+}
+
+GtkStyle*
+gtk_rc_get_style (GtkWidget *widget)
+{
+  GtkRcStyle *rc_style;
+  char *path;
+
+  if (widget_sets)
+    {
+      path = gtk_rc_widget_path (widget);
+      if (path)
+       {
+         rc_style = gtk_rc_styles_match (widget_sets, path);
+         g_free (path);
+
+         if (rc_style)
+           {
+             gtk_rc_style_init (rc_style);
+             return rc_style->style;
+           }
+       }
+    }
+
+  if (widget_class_sets)
+    {
+      path = gtk_rc_widget_class_path (widget);
+      if (path)
+       {
+         rc_style = gtk_rc_styles_match (widget_class_sets, path);
+         g_free (path);
+
+         if (rc_style)
+           {
+             gtk_rc_style_init (rc_style);
+             return rc_style->style;
+           }
+       }
+    }
+
+  return widget->style;
+}
+
+void
+gtk_rc_add_widget_name_style (GtkStyle *style,
+                             const char     *pattern)
+{
+  GtkRcStyle *rc_style;
+  GtkRcSet *rc_set;
+  int i;
+
+  gtk_style_ref (style);
+
+  rc_style = g_new (GtkRcStyle, 1);
+  rc_style->initialize = FALSE;
+  rc_style->name = NULL;
+  rc_style->font_name = NULL;
+  rc_style->fontset_name = NULL;
+
+  for (i = 0; i < 5; i++)
+    rc_style->bg_pixmap_name[i] = NULL;
+
+  rc_style->style = style;
+
+  rc_set = g_new (GtkRcSet, 1);
+  rc_set->set = g_strdup (pattern);
+  rc_set->rc_style = rc_style;
+
+  widget_sets = g_slist_append (widget_sets, rc_set);
+}
+
+void
+gtk_rc_add_widget_class_style (GtkStyle *style,
+                              const char     *pattern)
+{
+  GtkRcStyle *rc_style;
+  GtkRcSet *rc_set;
+  int i;
+
+  gtk_style_ref (style);
+
+  rc_style = g_new (GtkRcStyle, 1);
+  rc_style->initialize = FALSE;
+  rc_style->name = NULL;
+  rc_style->font_name = NULL;
+  rc_style->fontset_name = NULL;
+
+  for (i = 0; i < 5; i++)
+    rc_style->bg_pixmap_name[i] = NULL;
+
+  rc_style->style = style;
+
+  rc_set = g_new (GtkRcSet, 1);
+  rc_set->set = g_strdup (pattern);
+  rc_set->rc_style = rc_style;
+
+  widget_class_sets = g_slist_append (widget_class_sets, rc_set);
+}
+
+
+static guint
+gtk_rc_style_hash (const char *name)
+{
+  guint result;
+
+  result = 0;
+  while (*name)
+    result += (result << 3) + *name++;
+
+  return result;
+}
+
+static gint
+gtk_rc_style_compare (const char *a,
+                     const char *b)
+{
+  return (strcmp (a, b) == 0);
+}
+
+static GtkRcStyle*
+gtk_rc_style_find (const char *name)
+{
+  GtkRcStyle *rc_style;
+
+  rc_style = g_hash_table_lookup (rc_style_ht, (gpointer) name);
+
+  return rc_style;
+}
+
+static GtkRcStyle*
+gtk_rc_styles_match (GSList       *sets,
+                    const char   *path)
+{
+  GtkRcSet *rc_set;
+
+  while (sets)
+    {
+      rc_set = sets->data;
+      sets = sets->next;
+
+      if (gtk_rc_style_match (rc_set->set, path))
+       return rc_set->rc_style;
+    }
+
+  return NULL;
+}
+
+static gint
+gtk_rc_style_match (const char *set,
+                   const char *path)
+{
+  char ch;
+
+  while (1)
+    {
+      ch = *set++;
+      if (ch == '\0')
+       return (*path == '\0');
+
+      switch (ch)
+       {
+       case '*':
+         while (*set == '*')
+           set++;
+
+         ch = *set++;
+         if (ch == '\0')
+           return TRUE;
+
+         while (*path)
+           {
+             while (*path && (ch != *path))
+               path++;
+
+             if (!(*path))
+               return FALSE;
+
+             path++;
+             if (gtk_rc_style_match (set, path))
+               return TRUE;
+           }
+         break;
+
+       case '?':
+         break;
+
+       default:
+         if (ch == *path)
+           path++;
+         else
+           return FALSE;
+         break;
+       }
+    }
+
+  return TRUE;
+}
+
+static void
+gtk_rc_style_init (GtkRcStyle *rc_style)
+{
+  GdkFont *old_font;
+  gint i;
+
+  if (rc_style->initialize)
+    {
+      rc_style->initialize = FALSE;
+
+      if (rc_style->fontset_name)
+       {
+         old_font = rc_style->style->font;
+         rc_style->style->font = gdk_fontset_load (rc_style->fontset_name);
+         if (rc_style->style->font)
+           gdk_fontset_free (old_font);
+         else
+           rc_style->style->font = old_font;
+       }
+      else if (rc_style->font_name)
+       {
+         old_font = rc_style->style->font;
+         rc_style->style->font = gdk_font_load (rc_style->font_name);
+         if (rc_style->style->font)
+           gdk_font_free (old_font);
+         else
+           rc_style->style->font = old_font;
+       }
+
+      for (i = 0; i < 5; i++)
+       if (rc_style->bg_pixmap_name[i])
+         {
+           if (strcmp (rc_style->bg_pixmap_name[i], "<parent>") == 0)
+             rc_style->style->bg_pixmap[i] = (GdkPixmap*) GDK_PARENT_RELATIVE;
+           else
+             rc_style->style->bg_pixmap[i] = gdk_pixmap_create_from_xpm (NULL, NULL,
+                                                                         &rc_style->style->bg[i],
+                                                                         rc_style->bg_pixmap_name[i]);
+         }
+    }
+}
+
+static gint
+gtk_rc_get_token ()
+{
+  int tokenpos;
+  int state;
+  int count;
+  int token;
+  int hex_number = FALSE;
+  int float_number = FALSE;
+  char ch;
+
+  tokenpos = 0;
+  state = PARSE_START;
+
+  while (1)
+    {
+      if (position >= (buffer_size - 1))
+       position = 0;
+      if (!position || (buffer[position] == '\0'))
+       {
+         count = fread (buffer, sizeof (char), buffer_size - 1, input_fp);
+         if ((count == 0) && feof (input_fp))
+           return TOKEN_EOF;
+         buffer[count] = '\0';
+       }
+
+      ch = buffer[position++];
+      if (ch == '\n')
+       linenum += 1;
+
+      switch (state)
+       {
+       case PARSE_START:
+         token = gtk_rc_simple_token (ch);
+
+         if (token)
+           return token;
+         else if (ch == '#')
+           state = PARSE_COMMENT;
+         else if (ch == '"')
+           state = PARSE_STRING;
+         else if ((ch == ' ') || (ch == '\t') || (ch == '\n'))
+           break;
+         else if (ch == '.')
+           {
+             hex_number = FALSE;
+             float_number = TRUE;
+             tokenbuf[tokenpos++] = ch;
+             state = PARSE_NUMBER;
+           }
+         else if ((ch == '$') || (ch == '#'))
+           {
+             hex_number = TRUE;
+             float_number = FALSE;
+             state = PARSE_NUMBER;
+           }
+         else if (isdigit (ch))
+           {
+             hex_number = FALSE;
+             float_number = FALSE;
+             tokenbuf[tokenpos++] = ch;
+             state = PARSE_NUMBER;
+           }
+         else
+           {
+             tokenbuf[tokenpos++] = ch;
+             state = PARSE_SYMBOL;
+           }
+         break;
+
+       case PARSE_COMMENT:
+         if (ch == '\n')
+           state = PARSE_START;
+         break;
+
+       case PARSE_STRING:
+         if (ch != '"')
+           {
+             tokenbuf[tokenpos++] = ch;
+           }
+         else
+           {
+             tokenbuf[tokenpos] = '\0';
+             token_str = tokenbuf;
+             return TOKEN_STRING;
+           }
+         break;
+
+       case PARSE_SYMBOL:
+         if ((ch != ' ') && (ch != '\t') && (ch != '\n') &&
+             (gtk_rc_simple_token (ch) == 0))
+           {
+             tokenbuf[tokenpos++] = ch;
+           }
+         else
+           {
+             position -= 1;
+             tokenbuf[tokenpos] = '\0';
+             token_str = tokenbuf;
+             return gtk_rc_symbol_token (tokenbuf);
+           }
+         break;
+
+       case PARSE_NUMBER:
+         if (isdigit (ch) || (hex_number && isxdigit (ch)))
+           {
+             tokenbuf[tokenpos++] = ch;
+           }
+         else if (!hex_number && !float_number && (ch == '.'))
+           {
+             float_number = TRUE;
+             tokenbuf[tokenpos++] = ch;
+           }
+         else if (!float_number &&
+                  (ch == 'x') && (tokenpos == 1) &&
+                  (tokenbuf[0] == '0'))
+           {
+             hex_number = TRUE;
+             tokenpos = 0;
+           }
+         else
+           {
+             position -= 1;
+             tokenbuf[tokenpos] = '\0';
+             if (float_number)
+               {
+                 sscanf (tokenbuf, "%lf", &token_float);
+                 return TOKEN_FLOAT;
+               }
+             else
+               {
+                 sscanf (tokenbuf, (hex_number ? "%x" : "%d"), &token_int);
+                 return TOKEN_INTEGER;
+               }
+           }
+         break;
+       }
+    }
+}
+
+static gint
+gtk_rc_simple_token (char ch)
+{
+  gint i;
+
+  for (i = 0; i < nsimple_tokens; i++)
+    if (simple_tokens[i].ch == ch)
+      return simple_tokens[i].token;
+
+  return 0;
+}
+
+static gint
+gtk_rc_symbol_token (const char *sym)
+{
+  gint i;
+
+  for (i = 0; i < nsymbols; i++)
+    if (strcmp (symbols[i].name, sym) == 0)
+      return symbols[i].token;
+
+  return TOKEN_STRING;
+}
+
+static gint
+gtk_rc_get_next_token ()
+{
+  if (next_token != -1)
+    {
+      cur_token = next_token;
+      next_token = -1;
+    }
+  else
+    {
+      cur_token = gtk_rc_get_token ();
+    }
+
+  return cur_token;
+}
+
+static gint
+gtk_rc_peek_next_token ()
+{
+  if (next_token == -1)
+    next_token = gtk_rc_get_token ();
+
+  return next_token;
+}
+
+static gint
+gtk_rc_parse_statement ()
+{
+  gint token;
+  gint error;
+
+  token = gtk_rc_peek_next_token ();
+  if (!token)
+    {
+      done = TRUE;
+      return PARSE_OK;
+    }
+
+  error = gtk_rc_parse_style ();
+  if (error != PARSE_SYNTAX)
+    return error;
+
+  error = gtk_rc_parse_pixmap_path ();
+  if (error != PARSE_SYNTAX)
+    return error;
+
+  error = gtk_rc_parse_widget_style ();
+  if (error != PARSE_SYNTAX)
+    return error;
+
+  error = gtk_rc_parse_widget_class_style ();
+
+  return error;
+}
+
+static gint
+gtk_rc_parse_style ()
+{
+  GtkRcStyle *rc_style;
+  GtkRcStyle *parent_style;
+  gint token;
+  gint error;
+  gint insert;
+  gint i;
+
+  token = gtk_rc_peek_next_token ();
+  if (!token)
+    return PARSE_ERROR;
+  if (token != TOKEN_STYLE)
+    return PARSE_SYNTAX;
+  token = gtk_rc_get_next_token ();
+
+  token = gtk_rc_get_next_token ();
+  if (!token || (token != TOKEN_STRING))
+    return PARSE_ERROR;
+
+  insert = FALSE;
+  rc_style = g_hash_table_lookup (rc_style_ht, token_str);
+
+  if (!rc_style)
+    {
+      insert = TRUE;
+      rc_style = g_new (GtkRcStyle, 1);
+      rc_style->initialize = TRUE;
+      rc_style->name = g_strdup (token_str);
+      rc_style->font_name = NULL;
+      rc_style->fontset_name = NULL;
+
+      for (i = 0; i < 5; i++)
+       rc_style->bg_pixmap_name[i] = NULL;
+
+      rc_style->style = gtk_style_new ();
+      gtk_style_ref (rc_style->style);
+    }
+
+  token = gtk_rc_peek_next_token ();
+  if (token == TOKEN_EQUAL_SIGN)
+    {
+      token = gtk_rc_get_next_token ();
+
+      token = gtk_rc_get_next_token ();
+      if (!token || (token != TOKEN_STRING))
+       {
+         if (insert)
+           {
+             gtk_style_unref (rc_style->style);
+             g_free (rc_style);
+           }
+         return PARSE_ERROR;
+       }
+
+      parent_style = g_hash_table_lookup (rc_style_ht, token_str);
+      if (parent_style)
+       {
+         for (i = 0; i < 5; i++)
+           {
+             rc_style->style->fg[i] = parent_style->style->fg[i];
+             rc_style->style->bg[i] = parent_style->style->bg[i];
+             rc_style->style->light[i] = parent_style->style->light[i];
+             rc_style->style->dark[i] = parent_style->style->dark[i];
+             rc_style->style->mid[i] = parent_style->style->mid[i];
+             rc_style->style->text[i] = parent_style->style->text[i];
+             rc_style->style->base[i] = parent_style->style->base[i];
+           }
+
+         rc_style->style->black = parent_style->style->black;
+         rc_style->style->white = parent_style->style->white;
+
+         if (rc_style->fontset_name)
+           {
+             g_free (rc_style->fontset_name);
+             rc_style->fontset_name = g_strdup (parent_style->fontset_name);
+           }
+         else if (rc_style->font_name)
+           {
+             g_free (rc_style->font_name);
+             rc_style->font_name = g_strdup (parent_style->font_name);
+           }
+
+         for (i = 0; i < 5; i++)
+           {
+             if (rc_style->bg_pixmap_name[i])
+               g_free (rc_style->bg_pixmap_name[i]);
+             rc_style->bg_pixmap_name[i] = g_strdup (parent_style->bg_pixmap_name[i]);
+           }
+       }
+    }
+
+  token = gtk_rc_get_next_token ();
+  if (!token || (token != TOKEN_LEFT_CURLY))
+    {
+      if (insert)
+       {
+         gtk_style_unref (rc_style->style);
+         g_free (rc_style);
+       }
+      return PARSE_ERROR;
+    }
+
+  while (1)
+    {
+      error = gtk_rc_parse_style_option (rc_style);
+      if (error == PARSE_SYNTAX)
+       break;
+      if (error == PARSE_ERROR)
+       {
+         if (insert)
+           {
+             gtk_style_unref (rc_style->style);
+             g_free (rc_style);
+           }
+         return error;
+       }
+    }
+
+  token = gtk_rc_get_next_token ();
+  if (!token || (token != TOKEN_RIGHT_CURLY))
+    {
+      if (insert)
+       {
+         if (rc_style->fontset_name)
+           g_free (rc_style->fontset_name);
+         else if (rc_style->font_name)
+           g_free (rc_style->font_name);
+
+         for (i = 0; i < 5; i++)
+           if (rc_style->bg_pixmap_name[i])
+             g_free (rc_style->bg_pixmap_name[i]);
+
+         gtk_style_unref (rc_style->style);
+         g_free (rc_style);
+       }
+      return PARSE_ERROR;
+    }
+
+  if (insert)
+    g_hash_table_insert (rc_style_ht, rc_style->name, rc_style);
+
+  return PARSE_OK;
+}
+
+static gint
+gtk_rc_parse_style_option (GtkRcStyle *rc_style)
+{
+  gint token;
+  gint error;
+
+  token = gtk_rc_peek_next_token ();
+  if (!token)
+    return PARSE_ERROR;
+
+  error = gtk_rc_parse_base (rc_style->style);
+  if (error != PARSE_SYNTAX)
+    return error;
+
+  error = gtk_rc_parse_bg (rc_style->style);
+  if (error != PARSE_SYNTAX)
+    return error;
+
+  error = gtk_rc_parse_fg (rc_style->style);
+  if (error != PARSE_SYNTAX)
+    return error;
+
+  error = gtk_rc_parse_bg_pixmap (rc_style);
+  if (error != PARSE_SYNTAX)
+    return error;
+
+  error = gtk_rc_parse_font (rc_style);
+  if (error != PARSE_SYNTAX)
+    return error;
+
+  error = gtk_rc_parse_fontset (rc_style);
+
+  return error;
+}
+
+static gint
+gtk_rc_parse_base (GtkStyle *style)
+{
+  GtkStateType state;
+  gint token;
+  gint error;
+
+  token = gtk_rc_peek_next_token ();
+  if (!token)
+    return PARSE_ERROR;
+  if (token != TOKEN_BASE)
+    return PARSE_SYNTAX;
+  token = gtk_rc_get_next_token ();
+
+  error = gtk_rc_parse_state (&state);
+  if (error != PARSE_OK)
+    return error;
+
+  token = gtk_rc_get_next_token ();
+  if (!token || (token != TOKEN_EQUAL_SIGN))
+    return PARSE_ERROR;
+
+  error = gtk_rc_parse_color (&style->base[state]);
+
+  return error;
+}
+
+static gint
+gtk_rc_parse_bg (GtkStyle *style)
+{
+  GtkStateType state;
+  gint token;
+  gint error;
+
+  token = gtk_rc_peek_next_token ();
+  if (!token)
+    return PARSE_ERROR;
+  if (token != TOKEN_BG)
+    return PARSE_SYNTAX;
+  token = gtk_rc_get_next_token ();
+
+  error = gtk_rc_parse_state (&state);
+  if (error != PARSE_OK)
+    return error;
+
+  token = gtk_rc_get_next_token ();
+  if (!token || (token != TOKEN_EQUAL_SIGN))
+    return PARSE_ERROR;
+
+  error = gtk_rc_parse_color (&style->bg[state]);
+
+  return error;
+}
+
+static gint
+gtk_rc_parse_fg (GtkStyle *style)
+{
+  GtkStateType state;
+  gint token;
+  gint error;
+
+  token = gtk_rc_peek_next_token ();
+  if (!token)
+    return PARSE_ERROR;
+  if (token != TOKEN_FG)
+    return PARSE_SYNTAX;
+  token = gtk_rc_get_next_token ();
+
+  error = gtk_rc_parse_state (&state);
+  if (error != PARSE_OK)
+    return error;
+
+  token = gtk_rc_get_next_token ();
+  if (!token || (token != TOKEN_EQUAL_SIGN))
+    return PARSE_ERROR;
+
+  error = gtk_rc_parse_color (&style->fg[state]);
+
+  return error;
+}
+
+static gint
+gtk_rc_parse_bg_pixmap (GtkRcStyle *rc_style)
+{
+  GtkStateType state;
+  gint token;
+  gint error;
+  gchar *pixmap_file;
+
+  token = gtk_rc_peek_next_token ();
+  if (!token)
+    return PARSE_ERROR;
+  if (token != TOKEN_BG_PIXMAP)
+    return PARSE_SYNTAX;
+  token = gtk_rc_get_next_token ();
+
+  error = gtk_rc_parse_state (&state);
+  if (error != PARSE_OK)
+    return error;
+
+  token = gtk_rc_get_next_token ();
+  if (!token || (token != TOKEN_EQUAL_SIGN))
+    return PARSE_ERROR;
+
+  token = gtk_rc_get_next_token ();
+  if (!token || (token != TOKEN_STRING))
+    return PARSE_ERROR;
+
+  if (strcmp (token_str, "<parent>"))
+    pixmap_file = gtk_rc_find_pixmap_in_path (token_str);
+  else
+    pixmap_file = g_strdup(token_str);
+
+  if (pixmap_file)
+    {
+      if (rc_style->bg_pixmap_name[state])
+       g_free (rc_style->bg_pixmap_name[state]);
+      rc_style->bg_pixmap_name[state] = pixmap_file;
+    }
+
+  return PARSE_OK;
+}
+
+static char*
+gtk_rc_find_pixmap_in_path (gchar *pixmap_file)
+{
+  gint i;
+  FILE *fp;
+  gchar *buf;
+
+  for (i = 0; (i < GTK_RC_MAX_PIXMAP_PATHS) && (pixmap_path[i] != NULL); i++)
+    {
+      buf = g_malloc (strlen (pixmap_path[i]) + strlen (pixmap_file) + 2);
+      sprintf (buf, "%s%c%s", pixmap_path[i], '/', pixmap_file);
+
+      fp = fopen (buf, "r");
+      if (fp)
+       {
+         fclose (fp);
+         return buf;
+       }
+
+      g_free (buf);
+    }
+
+  g_warning ("Unable to locate image file in pixmap_path: \"%s\" line %d",
+            pixmap_file, linenum);
+
+  return NULL;
+}
+
+static gint
+gtk_rc_parse_font (GtkRcStyle *rc_style)
+{
+  gint token;
+
+  token = gtk_rc_peek_next_token ();
+  if (!token)
+    return PARSE_ERROR;
+  if (token != TOKEN_FONT)
+    return PARSE_SYNTAX;
+  token = gtk_rc_get_next_token ();
+
+  token = gtk_rc_get_next_token ();
+  if (!token || (token != TOKEN_EQUAL_SIGN))
+    return PARSE_ERROR;
+
+  token = gtk_rc_get_next_token ();
+  if (!token || (token != TOKEN_STRING))
+    return PARSE_ERROR;
+
+  if (rc_style->font_name)
+    g_free (rc_style->font_name);
+  rc_style->font_name = g_strdup (token_str);
+
+  return PARSE_OK;
+}
+
+static gint
+gtk_rc_parse_fontset (GtkRcStyle *rc_style)
+{
+  gint token;
+
+  token = gtk_rc_peek_next_token ();
+  if (!token)
+    return PARSE_ERROR;
+  if (token != TOKEN_FONTSET)
+    return PARSE_SYNTAX;
+  token = gtk_rc_get_next_token ();
+
+  token = gtk_rc_get_next_token ();
+  if (!token || (token != TOKEN_EQUAL_SIGN))
+    return PARSE_ERROR;
+
+  token = gtk_rc_get_next_token ();
+  if (!token || (token != TOKEN_STRING))
+    return PARSE_ERROR;
+
+  if (rc_style->fontset_name)
+    g_free (rc_style->fontset_name);
+  rc_style->fontset_name = g_strdup (token_str);
+
+  return PARSE_OK;
+}
+
+static gint
+gtk_rc_parse_state (GtkStateType *state)
+{
+  gint token;
+
+  token = gtk_rc_peek_next_token ();
+  if (!token)
+    return PARSE_ERROR;
+  if (token != TOKEN_LEFT_BRACE)
+    return PARSE_SYNTAX;
+  token = gtk_rc_get_next_token ();
+
+  token = gtk_rc_get_next_token ();
+  if (token == TOKEN_ACTIVE)
+    *state = GTK_STATE_ACTIVE;
+  else if (token == TOKEN_INSENSITIVE)
+    *state = GTK_STATE_INSENSITIVE;
+  else if (token == TOKEN_NORMAL)
+    *state = GTK_STATE_NORMAL;
+  else if (token == TOKEN_PRELIGHT)
+    *state = GTK_STATE_PRELIGHT;
+  else if (token == TOKEN_SELECTED)
+    *state = GTK_STATE_SELECTED;
+  else
+    return PARSE_ERROR;
+
+  token = gtk_rc_get_next_token ();
+  if (!token || (token != TOKEN_RIGHT_BRACE))
+    return PARSE_ERROR;
+
+  return PARSE_OK;
+}
+
+static gint
+gtk_rc_parse_color (GdkColor *color)
+{
+  gint token;
+  gint length;
+  gint temp;
+  gchar buf[9];
+  gint i, j;
+
+  token = gtk_rc_peek_next_token ();
+  if (!token)
+    return PARSE_ERROR;
+
+  switch (token)
+    {
+    case TOKEN_LEFT_CURLY:
+      token = gtk_rc_get_next_token ();
+
+      token = gtk_rc_get_next_token ();
+      if (!token || ((token != TOKEN_INTEGER) && (token != TOKEN_FLOAT)))
+       return PARSE_ERROR;
+
+      if (token == TOKEN_FLOAT)
+       token_int = token_float * 65535.0;
+      if (token_int < 0)
+       token_int = 0;
+      if (token_int > 65535)
+       token_int = 65535;
+
+      color->red = token_int;
+
+      token = gtk_rc_get_next_token ();
+      if (!token || (token != TOKEN_COMMA))
+       return PARSE_ERROR;
+
+      token = gtk_rc_get_next_token ();
+      if (!token || ((token != TOKEN_INTEGER) && (token != TOKEN_FLOAT)))
+       return PARSE_ERROR;
+
+      if (token == TOKEN_FLOAT)
+       token_int = token_float * 65535.0;
+      if (token_int < 0)
+       token_int = 0;
+      if (token_int > 65535)
+       token_int = 65535;
+
+      color->green = token_int;
+
+      token = gtk_rc_get_next_token ();
+      if (!token || (token != TOKEN_COMMA))
+       return PARSE_ERROR;
+
+      token = gtk_rc_get_next_token ();
+      if (!token || ((token != TOKEN_INTEGER) && (token != TOKEN_FLOAT)))
+       return PARSE_ERROR;
+
+      if (token == TOKEN_FLOAT)
+       token_int = token_float * 65535.0;
+      if (token_int < 0)
+       token_int = 0;
+      if (token_int > 65535)
+       token_int = 65535;
+
+      color->blue = token_int;
+
+      token = gtk_rc_get_next_token ();
+      if (!token || (token != TOKEN_RIGHT_CURLY))
+       return PARSE_ERROR;
+      break;
+
+    case TOKEN_STRING:
+      token = gtk_rc_get_next_token ();
+
+      if (token_str[0] != '#')
+       return PARSE_ERROR;
+
+      length = strlen (token_str) - 1;
+      if (((length % 3) != 0) || (length > 12))
+       return PARSE_ERROR;
+      length /= 3;
+
+      for (i = 0, j = 1; i < length; i++, j++)
+       buf[i] = token_str[j];
+      buf[i] = '\0';
+
+      sscanf (buf, "%x", &temp);
+      color->red = temp;
+
+      for (i = 0; i < length; i++, j++)
+       buf[i] = token_str[j];
+      buf[i] = '\0';
+
+      sscanf (buf, "%x", &temp);
+      color->green = temp;
+
+      for (i = 0; i < length; i++, j++)
+       buf[i] = token_str[j];
+      buf[i] = '\0';
+
+      sscanf (buf, "%x", &temp);
+      color->blue = temp;
+
+      if (length == 1)
+       {
+         color->red *= 4369;
+         color->green *= 4369;
+         color->blue *= 4369;
+       }
+      else if (length == 2)
+       {
+         color->red *= 257;
+         color->green *= 257;
+         color->blue *= 257;
+       }
+      else if (length == 3)
+       {
+         color->red *= 16;
+         color->green *= 16;
+         color->blue *= 16;
+       }
+      break;
+
+    default:
+      return PARSE_SYNTAX;
+    }
+
+  return PARSE_OK;
+}
+
+static gint
+gtk_rc_parse_pixmap_path ()
+{
+  gint token;
+
+  token = gtk_rc_peek_next_token ();
+  if (!token)
+    return PARSE_ERROR;
+  if (token != TOKEN_PIXMAP_PATH)
+    return PARSE_SYNTAX;
+  token = gtk_rc_get_next_token ();
+
+  token = gtk_rc_get_next_token ();
+
+  if (!token || (token != TOKEN_STRING))
+    return PARSE_ERROR;
+
+  gtk_rc_parse_pixmap_path_string(token_str);
+
+  return PARSE_OK;
+}
+
+static void gtk_rc_parse_pixmap_path_string(gchar *pix_path)
+{
+  gchar *buf;
+  gint end_offset;
+  gint start_offset = 0;
+  gint path_len;
+  gint path_num;
+
+  /* free the old one, or just add to the old one ? */
+  for (path_num=0; pixmap_path[path_num]; path_num++)
+    {
+      g_free(pixmap_path[path_num]);
+      pixmap_path[path_num] = NULL;
+    }
+
+  path_num = 0;
+
+  path_len = strlen(pix_path);
+
+  buf = g_strdup(pix_path);
+
+  for(end_offset = 0; end_offset <= path_len; end_offset++)
+    {
+      if ( (buf[end_offset] == ':') || (end_offset == path_len) )
+       {
+         buf[end_offset] = '\0';
+         pixmap_path[path_num] = g_strdup(buf + start_offset);
+         path_num++;
+         pixmap_path[path_num] = NULL;
+         start_offset = end_offset + 1;
+         g_free(buf);
+         buf = g_strdup(pix_path);
+       }
+    }
+  g_free(buf);
+}
+
+static gint
+gtk_rc_parse_widget_style ()
+{
+  GtkRcSet *rc_set;
+  gint token;
+
+  token = gtk_rc_peek_next_token ();
+  if (!token)
+    return PARSE_ERROR;
+  if (token != TOKEN_WIDGET)
+    return PARSE_SYNTAX;
+  token = gtk_rc_get_next_token ();
+
+  token = gtk_rc_get_next_token ();
+  if (!token || (token != TOKEN_STRING))
+    return PARSE_ERROR;
+
+  rc_set = g_new (GtkRcSet, 1);
+  rc_set->set = g_strdup (token_str);
+
+  token = gtk_rc_get_next_token ();
+  if (!token || (token != TOKEN_STYLE))
+    {
+      g_free (rc_set->set);
+      g_free (rc_set);
+      return PARSE_ERROR;
+    }
+
+  token = gtk_rc_get_next_token ();
+  if (!token || (token != TOKEN_STRING))
+    {
+      g_free (rc_set->set);
+      g_free (rc_set);
+      return PARSE_ERROR;
+    }
+
+  rc_set->rc_style = gtk_rc_style_find (token_str);
+  if (!rc_set->rc_style)
+    {
+      g_free (rc_set->set);
+      g_free (rc_set);
+      return PARSE_ERROR;
+    }
+
+  widget_sets = g_slist_append (widget_sets, rc_set);
+
+  return PARSE_OK;
+}
+
+static gint
+gtk_rc_parse_widget_class_style ()
+{
+  GtkRcSet *rc_set;
+  gint token;
+
+  token = gtk_rc_peek_next_token ();
+  if (!token)
+    return PARSE_ERROR;
+  if (token != TOKEN_WIDGET_CLASS)
+    return PARSE_SYNTAX;
+  token = gtk_rc_get_next_token ();
+
+  token = gtk_rc_get_next_token ();
+  if (!token || (token != TOKEN_STRING))
+    return PARSE_ERROR;
+
+  rc_set = g_new (GtkRcSet, 1);
+  rc_set->set = g_strdup (token_str);
+
+  token = gtk_rc_get_next_token ();
+  if (!token || (token != TOKEN_STYLE))
+    {
+      g_free (rc_set->set);
+      g_free (rc_set);
+      return PARSE_ERROR;
+    }
+
+  token = gtk_rc_get_next_token ();
+  if (!token || (token != TOKEN_STRING))
+    {
+      g_free (rc_set->set);
+      g_free (rc_set);
+      return PARSE_ERROR;
+    }
+
+  rc_set->rc_style = gtk_rc_style_find (token_str);
+  if (!rc_set->rc_style)
+    {
+      g_free (rc_set->set);
+      g_free (rc_set);
+      return PARSE_ERROR;
+    }
+
+  widget_class_sets = g_slist_append (widget_class_sets, rc_set);
+
+  return PARSE_OK;
+}
+
+static char*
+gtk_rc_widget_path (GtkWidget *widget)
+{
+  GtkWidget *tmp_widget;
+  char *path;
+  char *name;
+  int pathlength;
+  int namelength;
+
+  path = NULL;
+  pathlength = 0;
+
+  tmp_widget = widget;
+  while (tmp_widget)
+    {
+      name = gtk_widget_get_name (tmp_widget);
+      pathlength += strlen (name);
+
+      tmp_widget = tmp_widget->parent;
+
+      if (tmp_widget)
+       pathlength += 1;
+    }
+
+  path = g_new (char, pathlength + 1);
+  path[pathlength] = '\0';
+
+  tmp_widget = widget;
+  while (tmp_widget)
+    {
+      name = gtk_widget_get_name (tmp_widget);
+      namelength = strlen (name);
+
+      strncpy (&path[pathlength - namelength], name, namelength);
+      pathlength -= namelength;
+
+      tmp_widget = tmp_widget->parent;
+
+      if (tmp_widget)
+       {
+         pathlength -= 1;
+         path[pathlength] = '.';
+       }
+    }
+
+  return path;
+}
+
+static char*
+gtk_rc_widget_class_path (GtkWidget *widget)
+{
+  GtkWidget *tmp_widget;
+  char *path;
+  char *name;
+  int pathlength;
+  int namelength;
+
+  path = NULL;
+  pathlength = 0;
+
+  tmp_widget = widget;
+  while (tmp_widget)
+    {
+      name = gtk_type_name (GTK_WIDGET_TYPE (tmp_widget));
+      pathlength += strlen (name);
+
+      tmp_widget = tmp_widget->parent;
+
+      if (tmp_widget)
+       pathlength += 1;
+    }
+
+  path = g_new (char, pathlength + 1);
+  path[pathlength] = '\0';
+
+  tmp_widget = widget;
+  while (tmp_widget)
+    {
+      name = gtk_type_name (GTK_WIDGET_TYPE (tmp_widget));
+      namelength = strlen (name);
+
+      strncpy (&path[pathlength - namelength], name, namelength);
+      pathlength -= namelength;
+
+      tmp_widget = tmp_widget->parent;
+
+      if (tmp_widget)
+       {
+         pathlength -= 1;
+         path[pathlength] = '.';
+       }
+    }
+
+  return path;
+}
diff --git a/gtk/gtkrc.h b/gtk/gtkrc.h
new file mode 100644 (file)
index 0000000..8c761bb
--- /dev/null
@@ -0,0 +1,45 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_RC_H__
+#define __GTK_RC_H__
+
+
+#include <gtk/gtkstyle.h>
+#include <gtk/gtkwidget.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+void      gtk_rc_init                   (void);
+void      gtk_rc_parse                  (const char  *filename);
+GtkStyle* gtk_rc_get_style              (GtkWidget   *widget);
+void      gtk_rc_add_widget_name_style  (GtkStyle    *style,
+                                        const char  *pattern);
+void      gtk_rc_add_widget_class_style (GtkStyle    *style,
+                                        const char  *pattern);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_RC_H__ */
diff --git a/gtk/gtkruler.c b/gtk/gtkruler.c
new file mode 100644 (file)
index 0000000..dad0e11
--- /dev/null
@@ -0,0 +1,305 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkruler.h"
+
+
+static void gtk_ruler_class_init    (GtkRulerClass  *klass);
+static void gtk_ruler_init          (GtkRuler       *ruler);
+static void gtk_ruler_realize       (GtkWidget      *widget);
+static void gtk_ruler_unrealize     (GtkWidget      *widget);
+static void gtk_ruler_size_allocate (GtkWidget      *widget,
+                                    GtkAllocation  *allocation);
+static gint gtk_ruler_expose        (GtkWidget      *widget,
+                                    GdkEventExpose *event);
+static void gtk_ruler_make_pixmap   (GtkRuler       *ruler);
+
+
+static GtkRulerMetric ruler_metrics[] =
+{
+  {"Pixels", "Pi", 1.0, { 1, 2, 5, 10, 25, 50, 100, 250, 500, 1000 }, { 1, 5, 10, 50, 100 }},
+  {"Inches", "In", 72.0, { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 }, { 1, 2, 4, 8, 16 }},
+  {"Centimeters", "Cn", 28.35, { 1, 2, 5, 10, 25, 50, 100, 250, 500, 1000 }, { 1, 5, 10, 50, 100 }},
+};
+
+
+guint
+gtk_ruler_get_type ()
+{
+  static guint ruler_type = 0;
+
+  if (!ruler_type)
+    {
+      GtkTypeInfo ruler_info =
+      {
+       "GtkRuler",
+       sizeof (GtkRuler),
+       sizeof (GtkRulerClass),
+       (GtkClassInitFunc) gtk_ruler_class_init,
+       (GtkObjectInitFunc) gtk_ruler_init,
+       (GtkArgFunc) NULL,
+      };
+
+      ruler_type = gtk_type_unique (gtk_widget_get_type (), &ruler_info);
+    }
+
+  return ruler_type;
+}
+
+static void
+gtk_ruler_class_init (GtkRulerClass *class)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+
+  object_class = (GtkObjectClass*) class;
+  widget_class = (GtkWidgetClass*) class;
+
+  widget_class->realize = gtk_ruler_realize;
+  widget_class->unrealize = gtk_ruler_unrealize;
+  widget_class->size_allocate = gtk_ruler_size_allocate;
+  widget_class->expose_event = gtk_ruler_expose;
+
+  class->draw_ticks = NULL;
+  class->draw_pos = NULL;
+}
+
+static void
+gtk_ruler_init (GtkRuler *ruler)
+{
+  ruler->backing_store = NULL;
+  ruler->non_gr_exp_gc = NULL;
+  ruler->xsrc = 0;
+  ruler->ysrc = 0;
+  ruler->slider_size = 0;
+  ruler->lower = 0;
+  ruler->upper = 0;
+  ruler->position = 0;
+  ruler->max_size = 0;
+
+  gtk_ruler_set_metric (ruler, GTK_PIXELS);
+}
+
+void
+gtk_ruler_set_metric (GtkRuler      *ruler,
+                     GtkMetricType  metric)
+{
+  g_return_if_fail (ruler != NULL);
+  g_return_if_fail (GTK_IS_RULER (ruler));
+
+  ruler->metric = &ruler_metrics[metric];
+
+  if (GTK_WIDGET_DRAWABLE (ruler))
+    gtk_widget_queue_draw (GTK_WIDGET (ruler));
+}
+
+void
+gtk_ruler_set_range (GtkRuler *ruler,
+                    gfloat    lower,
+                    gfloat    upper,
+                    gfloat    position,
+                    gfloat    max_size)
+{
+  g_return_if_fail (ruler != NULL);
+  g_return_if_fail (GTK_IS_RULER (ruler));
+
+  ruler->lower = lower;
+  ruler->upper = upper;
+  ruler->position = position;
+  ruler->max_size = max_size;
+
+  if (GTK_WIDGET_DRAWABLE (ruler))
+    gtk_widget_queue_draw (GTK_WIDGET (ruler));
+}
+
+void
+gtk_ruler_draw_ticks (GtkRuler *ruler)
+{
+  g_return_if_fail (ruler != NULL);
+  g_return_if_fail (GTK_IS_RULER (ruler));
+
+  if (GTK_RULER_CLASS (GTK_OBJECT (ruler)->klass)->draw_ticks)
+    (* GTK_RULER_CLASS (GTK_OBJECT (ruler)->klass)->draw_ticks) (ruler);
+}
+
+void
+gtk_ruler_draw_pos (GtkRuler *ruler)
+{
+  g_return_if_fail (ruler != NULL);
+  g_return_if_fail (GTK_IS_RULER (ruler));
+
+  if (GTK_RULER_CLASS (GTK_OBJECT (ruler)->klass)->draw_pos)
+    (* GTK_RULER_CLASS (GTK_OBJECT (ruler)->klass)->draw_pos) (ruler);
+}
+
+
+static void
+gtk_ruler_realize (GtkWidget *widget)
+{
+  GtkRuler *ruler;
+  GdkWindowAttr attributes;
+  gint attributes_mask;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_RULER (widget));
+
+  ruler = GTK_RULER (widget);
+  GTK_WIDGET_SET_FLAGS (ruler, GTK_REALIZED);
+
+  attributes.window_type = GDK_WINDOW_CHILD;
+  attributes.x = widget->allocation.x;
+  attributes.y = widget->allocation.y;
+  attributes.width = widget->allocation.width;
+  attributes.height = widget->allocation.height;
+  attributes.wclass = GDK_INPUT_OUTPUT;
+  attributes.visual = gtk_widget_get_visual (widget);
+  attributes.colormap = gtk_widget_get_colormap (widget);
+  attributes.event_mask = gtk_widget_get_events (widget);
+  attributes.event_mask |= (GDK_EXPOSURE_MASK |
+                           GDK_POINTER_MOTION_MASK |
+                           GDK_POINTER_MOTION_HINT_MASK);
+
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+
+  widget->window = gdk_window_new (widget->parent->window, &attributes, attributes_mask);
+  gdk_window_set_user_data (widget->window, ruler);
+
+  widget->style = gtk_style_attach (widget->style, widget->window);
+  gtk_style_set_background (widget->style, widget->window, GTK_STATE_ACTIVE);
+
+  gtk_ruler_make_pixmap (ruler);
+}
+
+static void
+gtk_ruler_unrealize (GtkWidget *widget)
+{
+  GtkRuler *ruler;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_RULER (widget));
+
+  ruler = GTK_RULER (widget);
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED | GTK_MAPPED);
+
+  gtk_style_detach (widget->style);
+  gdk_window_destroy (widget->window);
+  widget->window = NULL;
+
+  if (ruler->backing_store)
+    gdk_pixmap_destroy (ruler->backing_store);
+  if (ruler->non_gr_exp_gc)
+    gdk_gc_destroy (ruler->non_gr_exp_gc);
+
+  ruler->backing_store = NULL;
+  ruler->non_gr_exp_gc = NULL;
+}
+
+static void
+gtk_ruler_size_allocate (GtkWidget     *widget,
+                        GtkAllocation *allocation)
+{
+  GtkRuler *ruler;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_RULER (widget));
+
+  ruler = GTK_RULER (widget);
+  widget->allocation = *allocation;
+
+  if (GTK_WIDGET_REALIZED (widget))
+    {
+      gdk_window_move_resize (widget->window,
+                             allocation->x, allocation->y,
+                             allocation->width, allocation->height);
+
+      gtk_ruler_make_pixmap (ruler);
+    }
+}
+
+static gint
+gtk_ruler_expose (GtkWidget      *widget,
+                 GdkEventExpose *event)
+{
+  GtkRuler *ruler;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_RULER (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      ruler = GTK_RULER (widget);
+
+      gdk_draw_rectangle (ruler->backing_store,
+                         widget->style->bg_gc[GTK_STATE_NORMAL],
+                         TRUE, 0, 0,
+                         widget->allocation.width,
+                         widget->allocation.height);
+
+      gtk_ruler_draw_ticks (ruler);
+
+      gtk_draw_shadow (widget->style, ruler->backing_store,
+                      GTK_STATE_NORMAL, GTK_SHADOW_OUT, 0, 0,
+                      widget->allocation.width,
+                      widget->allocation.height);
+
+      gdk_draw_pixmap (widget->window,
+                      ruler->non_gr_exp_gc,
+                      ruler->backing_store,
+                      0, 0, 0, 0,
+                      widget->allocation.width,
+                      widget->allocation.height);
+
+      gtk_ruler_draw_pos (ruler);
+    }
+
+  return FALSE;
+}
+
+static void
+gtk_ruler_make_pixmap (GtkRuler *ruler)
+{
+  GtkWidget *widget;
+  gint width;
+  gint height;
+
+  widget = GTK_WIDGET (ruler);
+
+  if (ruler->backing_store)
+    {
+      gdk_window_get_size (ruler->backing_store, &width, &height);
+      if ((width == widget->allocation.width) &&
+         (height == widget->allocation.height))
+       return;
+
+      gdk_pixmap_destroy (ruler->backing_store);
+    }
+
+  ruler->backing_store = gdk_pixmap_new (widget->window,
+                                        widget->allocation.width,
+                                        widget->allocation.height,
+                                        -1);
+
+  ruler->xsrc = 0;
+  ruler->ysrc = 0;
+
+  if (!ruler->non_gr_exp_gc)
+    {
+      ruler->non_gr_exp_gc = gdk_gc_new (widget->window);
+      gdk_gc_set_exposures (ruler->non_gr_exp_gc, FALSE);
+    }
+}
diff --git a/gtk/gtkruler.h b/gtk/gtkruler.h
new file mode 100644 (file)
index 0000000..c74b203
--- /dev/null
@@ -0,0 +1,91 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_RULER_H__
+#define __GTK_RULER_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkwidget.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_RULER(obj)          GTK_CHECK_CAST (obj, gtk_ruler_get_type (), GtkRuler)
+#define GTK_RULER_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_ruler_get_type (), GtkRulerClass)
+#define GTK_IS_RULER(obj)       GTK_CHECK_TYPE (obj, gtk_ruler_get_type ())
+
+
+typedef struct _GtkRuler        GtkRuler;
+typedef struct _GtkRulerClass   GtkRulerClass;
+typedef struct _GtkRulerMetric  GtkRulerMetric;
+
+struct _GtkRuler
+{
+  GtkWidget widget;
+
+  GdkPixmap *backing_store;
+  GdkGC *non_gr_exp_gc;
+  GtkRulerMetric *metric;
+  gint xsrc, ysrc;
+  gint slider_size;
+
+  gfloat lower;
+  gfloat upper;
+  gfloat position;
+  gfloat max_size;
+};
+
+struct _GtkRulerClass
+{
+  GtkWidgetClass parent_class;
+
+  void (* draw_ticks) (GtkRuler *ruler);
+  void (* draw_pos)   (GtkRuler *ruler);
+};
+
+struct _GtkRulerMetric
+{
+  gchar *metric_name;
+  gchar *abbrev;
+  gfloat pixels_per_unit;
+  gfloat ruler_scale[10];
+  gint subdivide[5];        /* five possible modes of subdivision */
+};
+
+
+guint gtk_ruler_get_type   (void);
+void  gtk_ruler_set_metric (GtkRuler       *ruler,
+                           GtkMetricType   metric);
+void  gtk_ruler_set_range  (GtkRuler       *ruler,
+                           gfloat          lower,
+                           gfloat          upper,
+                           gfloat          position,
+                           gfloat          max_size);
+void  gtk_ruler_draw_ticks (GtkRuler       *ruler);
+void  gtk_ruler_draw_pos   (GtkRuler       *ruler);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_RULER_H__ */
diff --git a/gtk/gtkscale.c b/gtk/gtkscale.c
new file mode 100644 (file)
index 0000000..ba2f186
--- /dev/null
@@ -0,0 +1,229 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <math.h>
+#include "gtkcontainer.h"
+#include "gtkscale.h"
+
+
+#define SCALE_CLASS(w)  GTK_SCALE_CLASS (GTK_OBJECT (w)->klass)
+
+
+static void gtk_scale_class_init      (GtkScaleClass *klass);
+static void gtk_scale_init            (GtkScale      *scale);
+static void gtk_scale_destroy         (GtkObject     *object);
+static void gtk_scale_draw_background (GtkRange      *range);
+
+
+static GtkRangeClass *parent_class = NULL;
+
+
+guint
+gtk_scale_get_type ()
+{
+  static guint scale_type = 0;
+
+  if (!scale_type)
+    {
+      GtkTypeInfo scale_info =
+      {
+       "GtkScale",
+       sizeof (GtkScale),
+       sizeof (GtkScaleClass),
+       (GtkClassInitFunc) gtk_scale_class_init,
+       (GtkObjectInitFunc) gtk_scale_init,
+       (GtkArgFunc) NULL,
+      };
+
+      scale_type = gtk_type_unique (gtk_range_get_type (), &scale_info);
+    }
+
+  return scale_type;
+}
+
+static void
+gtk_scale_class_init (GtkScaleClass *class)
+{
+  GtkObjectClass *object_class;
+  GtkRangeClass *range_class;
+
+  object_class = (GtkObjectClass*) class;
+  range_class = (GtkRangeClass*) class;
+
+  parent_class = gtk_type_class (gtk_range_get_type ());
+
+  object_class->destroy = gtk_scale_destroy;
+
+  range_class->draw_background = gtk_scale_draw_background;
+
+  class->slider_length = 31;
+  class->value_spacing = 2;
+  class->draw_value = NULL;
+}
+
+static void
+gtk_scale_init (GtkScale *scale)
+{
+  GTK_WIDGET_SET_FLAGS (scale, GTK_CAN_FOCUS);
+  GTK_RANGE (scale)->digits = 1;
+  scale->draw_value = TRUE;
+  scale->value_pos = GTK_POS_TOP;
+}
+
+void
+gtk_scale_set_digits (GtkScale *scale,
+                     gint      digits)
+{
+  g_return_if_fail (scale != NULL);
+  g_return_if_fail (GTK_IS_SCALE (scale));
+
+  if (GTK_RANGE (scale)->digits != digits)
+    {
+      GTK_RANGE (scale)->digits = digits;
+
+      if (GTK_WIDGET_VISIBLE (scale) && GTK_WIDGET_MAPPED (scale))
+       gtk_widget_queue_resize (GTK_WIDGET (scale));
+    }
+}
+
+void
+gtk_scale_set_draw_value (GtkScale *scale,
+                         gint      draw_value)
+{
+  g_return_if_fail (scale != NULL);
+  g_return_if_fail (GTK_IS_SCALE (scale));
+
+  if (scale->draw_value != draw_value)
+    {
+      scale->draw_value = (draw_value != 0);
+
+      if (GTK_WIDGET_VISIBLE (scale) && GTK_WIDGET_MAPPED (scale))
+       gtk_widget_queue_resize (GTK_WIDGET (scale));
+    }
+}
+
+void
+gtk_scale_set_value_pos (GtkScale        *scale,
+                        GtkPositionType  pos)
+{
+  g_return_if_fail (scale != NULL);
+  g_return_if_fail (GTK_IS_SCALE (scale));
+
+  if (scale->value_pos != pos)
+    {
+      scale->value_pos = pos;
+
+      if (GTK_WIDGET_VISIBLE (scale) && GTK_WIDGET_MAPPED (scale))
+       gtk_widget_queue_resize (GTK_WIDGET (scale));
+    }
+}
+
+gint
+gtk_scale_value_width (GtkScale *scale)
+{
+  GtkRange *range;
+  gchar buffer[128];
+  gfloat value;
+  gint temp;
+  gint return_val;
+  gint digits;
+  gint i, j;
+
+  g_return_val_if_fail (scale != NULL, 0);
+  g_return_val_if_fail (GTK_IS_SCALE (scale), 0);
+
+  return_val = 0;
+  if (scale->draw_value)
+    {
+      range = GTK_RANGE (scale);
+
+      value = ABS (range->adjustment->lower);
+      if (value == 0) value = 1;
+      digits = log10 (value) + 1;
+      if (digits > 13)
+       digits = 13;
+
+      i = 0;
+      if (range->adjustment->lower < 0)
+        buffer[i++] = '-';
+      for (j = 0; j < digits; j++)
+        buffer[i++] = '0';
+      if (GTK_RANGE (scale)->digits)
+        buffer[i++] = '.';
+      for (j = 0; j < GTK_RANGE (scale)->digits; j++)
+        buffer[i++] = '0';
+      buffer[i] = '\0';
+
+      return_val = gdk_string_measure (GTK_WIDGET (scale)->style->font, buffer);
+
+      value = ABS (range->adjustment->upper);
+      if (value == 0) value = 1;
+      digits = log10 (value) + 1;
+      if (digits > 13)
+        digits = 13;
+
+      i = 0;
+      if (range->adjustment->lower < 0)
+        buffer[i++] = '-';
+      for (j = 0; j < digits; j++)
+        buffer[i++] = '0';
+      if (GTK_RANGE (scale)->digits)
+        buffer[i++] = '.';
+      for (j = 0; j < GTK_RANGE (scale)->digits; j++)
+        buffer[i++] = '0';
+      buffer[i] = '\0';
+
+      temp = gdk_string_measure (GTK_WIDGET (scale)->style->font, buffer);
+      return_val = MAX (return_val, temp);
+    }
+
+  return return_val;
+}
+
+void
+gtk_scale_draw_value (GtkScale *scale)
+{
+  g_return_if_fail (scale != NULL);
+  g_return_if_fail (GTK_IS_SCALE (scale));
+
+  if (SCALE_CLASS (scale)->draw_value)
+    (* SCALE_CLASS (scale)->draw_value) (scale);
+}
+
+
+static void
+gtk_scale_destroy (GtkObject *object)
+{
+  GtkRange *range;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_SCALE (object));
+
+  range = GTK_RANGE (object);
+
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+gtk_scale_draw_background (GtkRange *range)
+{
+  g_return_if_fail (range != NULL);
+  g_return_if_fail (GTK_IS_SCALE (range));
+
+  gtk_scale_draw_value (GTK_SCALE (range));
+}
diff --git a/gtk/gtkscale.h b/gtk/gtkscale.h
new file mode 100644 (file)
index 0000000..6fe2e49
--- /dev/null
@@ -0,0 +1,75 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_SCALE_H__
+#define __GTK_SCALE_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkrange.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_SCALE(obj)          GTK_CHECK_CAST (obj, gtk_scale_get_type (), GtkScale)
+#define GTK_SCALE_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_scale_get_type (), GtkScaleClass)
+#define GTK_IS_SCALE(obj)       GTK_CHECK_TYPE (obj, gtk_scale_get_type ())
+
+
+typedef struct _GtkScale        GtkScale;
+typedef struct _GtkScaleClass   GtkScaleClass;
+
+struct _GtkScale
+{
+  GtkRange range;
+
+  guint draw_value : 1;
+  guint value_pos : 2;
+};
+
+struct _GtkScaleClass
+{
+  GtkRangeClass parent_class;
+
+  gint slider_length;
+  gint value_spacing;
+
+  void (* draw_value) (GtkScale *scale);
+};
+
+
+guint  gtk_scale_get_type       (void);
+void   gtk_scale_set_digits     (GtkScale        *scale,
+                                gint             digits);
+void   gtk_scale_set_draw_value (GtkScale        *scale,
+                                gint             draw_value);
+void   gtk_scale_set_value_pos  (GtkScale        *scale,
+                                GtkPositionType  pos);
+gint   gtk_scale_value_width    (GtkScale        *scale);
+
+void   gtk_scale_draw_value     (GtkScale        *scale);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_SCALE_H__ */
diff --git a/gtk/gtkscrollbar.c b/gtk/gtkscrollbar.c
new file mode 100644 (file)
index 0000000..3f5088b
--- /dev/null
@@ -0,0 +1,54 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkscrollbar.h"
+
+static void gtk_scrollbar_class_init (GtkScrollbarClass *klass);
+static void gtk_scrollbar_init       (GtkScrollbar      *scrollbar);
+
+guint
+gtk_scrollbar_get_type ()
+{
+  static guint scrollbar_type = 0;
+
+  if (!scrollbar_type)
+    {
+      GtkTypeInfo scrollbar_info =
+      {
+       "GtkScrollbar",
+       sizeof (GtkScrollbar),
+       sizeof (GtkScrollbarClass),
+       (GtkClassInitFunc) gtk_scrollbar_class_init,
+       (GtkObjectInitFunc) gtk_scrollbar_init,
+       (GtkArgFunc) NULL,
+      };
+
+      scrollbar_type = gtk_type_unique (gtk_range_get_type (), &scrollbar_info);
+    }
+
+  return scrollbar_type;
+}
+
+static void
+gtk_scrollbar_class_init (GtkScrollbarClass *class)
+{
+}
+
+static void
+gtk_scrollbar_init (GtkScrollbar *scrollbar)
+{
+}
diff --git a/gtk/gtkscrollbar.h b/gtk/gtkscrollbar.h
new file mode 100644 (file)
index 0000000..14aadad
--- /dev/null
@@ -0,0 +1,58 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_SCROLLBAR_H__
+#define __GTK_SCROLLBAR_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkrange.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_SCROLLBAR(obj)          GTK_CHECK_CAST (obj, gtk_scrollbar_get_type (), GtkScrollbar)
+#define GTK_SCROLLBAR_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_scrollbar_get_type (), GtkScrollbarClass)
+#define GTK_IS_SCROLLBAR(obj)       GTK_CHECK_TYPE (obj, gtk_scrollbar_get_type ())
+
+
+typedef struct _GtkScrollbar        GtkScrollbar;
+typedef struct _GtkScrollbarClass   GtkScrollbarClass;
+
+struct _GtkScrollbar
+{
+  GtkRange range;
+};
+
+struct _GtkScrollbarClass
+{
+  GtkRangeClass parent_class;
+};
+
+
+guint  gtk_scrollbar_get_type (void);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_SCROLLBAR_H__ */
diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c
new file mode 100644 (file)
index 0000000..79cc67a
--- /dev/null
@@ -0,0 +1,510 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkscrolledwindow.h"
+#include "gtksignal.h"
+
+
+#define SCROLLBAR_SPACING  5
+
+
+static void gtk_scrolled_window_class_init         (GtkScrolledWindowClass *klass);
+static void gtk_scrolled_window_init               (GtkScrolledWindow      *scrolled_window);
+static void gtk_scrolled_window_destroy            (GtkObject              *object);
+static void gtk_scrolled_window_map                (GtkWidget              *widget);
+static void gtk_scrolled_window_unmap              (GtkWidget              *widget);
+static void gtk_scrolled_window_draw               (GtkWidget              *widget,
+                                                   GdkRectangle           *area);
+static void gtk_scrolled_window_size_request       (GtkWidget              *widget,
+                                                   GtkRequisition         *requisition);
+static void gtk_scrolled_window_size_allocate      (GtkWidget              *widget,
+                                                   GtkAllocation          *allocation);
+static void gtk_scrolled_window_add                (GtkContainer           *container,
+                                                   GtkWidget              *widget);
+static void gtk_scrolled_window_remove             (GtkContainer           *container,
+                                                   GtkWidget              *widget);
+static void gtk_scrolled_window_foreach            (GtkContainer           *container,
+                                                   GtkCallback             callback,
+                                                   gpointer                callback_data);
+static void gtk_scrolled_window_viewport_allocate  (GtkWidget              *widget,
+                                                   GtkAllocation          *allocation);
+static void gtk_scrolled_window_adjustment_changed (GtkAdjustment          *adjustment,
+                                                   gpointer                data);
+
+
+static GtkContainerClass *parent_class = NULL;
+
+
+guint
+gtk_scrolled_window_get_type ()
+{
+  static guint scrolled_window_type = 0;
+
+  if (!scrolled_window_type)
+    {
+      GtkTypeInfo scrolled_window_info =
+      {
+       "GtkScrolledWindow",
+       sizeof (GtkScrolledWindow),
+       sizeof (GtkScrolledWindowClass),
+       (GtkClassInitFunc) gtk_scrolled_window_class_init,
+       (GtkObjectInitFunc) gtk_scrolled_window_init,
+       (GtkArgFunc) NULL,
+      };
+
+      scrolled_window_type = gtk_type_unique (gtk_container_get_type (), &scrolled_window_info);
+    }
+
+  return scrolled_window_type;
+}
+
+static void
+gtk_scrolled_window_class_init (GtkScrolledWindowClass *class)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+  GtkContainerClass *container_class;
+
+  object_class = (GtkObjectClass*) class;
+  widget_class = (GtkWidgetClass*) class;
+  container_class = (GtkContainerClass*) class;
+
+  parent_class = gtk_type_class (gtk_container_get_type ());
+
+  object_class->destroy = gtk_scrolled_window_destroy;
+
+  widget_class->map = gtk_scrolled_window_map;
+  widget_class->unmap = gtk_scrolled_window_unmap;
+  widget_class->draw = gtk_scrolled_window_draw;
+  widget_class->size_request = gtk_scrolled_window_size_request;
+  widget_class->size_allocate = gtk_scrolled_window_size_allocate;
+
+  container_class->add = gtk_scrolled_window_add;
+  container_class->remove = gtk_scrolled_window_remove;
+  container_class->foreach = gtk_scrolled_window_foreach;
+}
+
+static void
+gtk_scrolled_window_init (GtkScrolledWindow *scrolled_window)
+{
+  GTK_WIDGET_SET_FLAGS (scrolled_window, GTK_NO_WINDOW);
+
+  scrolled_window->hscrollbar = NULL;
+  scrolled_window->vscrollbar = NULL;
+  scrolled_window->hscrollbar_policy = GTK_POLICY_ALWAYS;
+  scrolled_window->vscrollbar_policy = GTK_POLICY_ALWAYS;
+}
+
+GtkWidget*
+gtk_scrolled_window_new (GtkAdjustment *hadjustment,
+                        GtkAdjustment *vadjustment)
+{
+  GtkScrolledWindow *scrolled_window;
+
+  scrolled_window = gtk_type_new (gtk_scrolled_window_get_type ());
+
+  scrolled_window->viewport = gtk_viewport_new (hadjustment, vadjustment);
+  hadjustment = gtk_viewport_get_hadjustment (GTK_VIEWPORT (scrolled_window->viewport));
+  vadjustment = gtk_viewport_get_vadjustment (GTK_VIEWPORT (scrolled_window->viewport));
+
+  gtk_signal_connect (GTK_OBJECT (hadjustment), "changed",
+                     (GtkSignalFunc) gtk_scrolled_window_adjustment_changed,
+                     (gpointer) scrolled_window);
+  gtk_signal_connect (GTK_OBJECT (vadjustment), "changed",
+                     (GtkSignalFunc) gtk_scrolled_window_adjustment_changed,
+                     (gpointer) scrolled_window);
+
+  scrolled_window->hscrollbar = gtk_hscrollbar_new (hadjustment);
+  scrolled_window->vscrollbar = gtk_vscrollbar_new (vadjustment);
+
+  gtk_widget_set_parent (scrolled_window->viewport, GTK_WIDGET (scrolled_window));
+  gtk_widget_set_parent (scrolled_window->hscrollbar, GTK_WIDGET (scrolled_window));
+  gtk_widget_set_parent (scrolled_window->vscrollbar, GTK_WIDGET (scrolled_window));
+
+  gtk_widget_show (scrolled_window->viewport);
+  gtk_widget_show (scrolled_window->hscrollbar);
+  gtk_widget_show (scrolled_window->vscrollbar);
+
+  return GTK_WIDGET (scrolled_window);
+}
+
+GtkAdjustment*
+gtk_scrolled_window_get_hadjustment (GtkScrolledWindow *scrolled_window)
+{
+  g_return_val_if_fail (scrolled_window != NULL, NULL);
+  g_return_val_if_fail (GTK_IS_SCROLLED_WINDOW (scrolled_window), NULL);
+
+  return gtk_range_get_adjustment (GTK_RANGE (scrolled_window->hscrollbar));
+}
+
+GtkAdjustment*
+gtk_scrolled_window_get_vadjustment (GtkScrolledWindow *scrolled_window)
+{
+  g_return_val_if_fail (scrolled_window != NULL, NULL);
+  g_return_val_if_fail (GTK_IS_SCROLLED_WINDOW (scrolled_window), NULL);
+
+  return gtk_range_get_adjustment (GTK_RANGE (scrolled_window->vscrollbar));
+}
+
+void
+gtk_scrolled_window_set_policy (GtkScrolledWindow *scrolled_window,
+                               GtkPolicyType      hscrollbar_policy,
+                               GtkPolicyType      vscrollbar_policy)
+{
+  g_return_if_fail (scrolled_window != NULL);
+  g_return_if_fail (GTK_IS_SCROLLED_WINDOW (scrolled_window));
+
+  if ((scrolled_window->hscrollbar_policy != hscrollbar_policy) ||
+      (scrolled_window->vscrollbar_policy != vscrollbar_policy))
+    {
+      scrolled_window->hscrollbar_policy = hscrollbar_policy;
+      scrolled_window->vscrollbar_policy = vscrollbar_policy;
+
+      if (GTK_WIDGET (scrolled_window)->parent)
+       gtk_widget_queue_resize (GTK_WIDGET (scrolled_window));
+    }
+}
+
+
+static void
+gtk_scrolled_window_destroy (GtkObject *object)
+{
+  GtkScrolledWindow *scrolled_window;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_SCROLLED_WINDOW (object));
+
+  scrolled_window = GTK_SCROLLED_WINDOW (object);
+
+  gtk_widget_destroy (scrolled_window->viewport);
+  gtk_widget_destroy (scrolled_window->hscrollbar);
+  gtk_widget_destroy (scrolled_window->vscrollbar);
+
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+gtk_scrolled_window_map (GtkWidget *widget)
+{
+  GtkScrolledWindow *scrolled_window;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_SCROLLED_WINDOW (widget));
+
+  if (!GTK_WIDGET_MAPPED (widget))
+    {
+      GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
+      scrolled_window = GTK_SCROLLED_WINDOW (widget);
+
+      if (GTK_WIDGET_VISIBLE (scrolled_window->viewport) &&
+         !GTK_WIDGET_MAPPED (scrolled_window->viewport))
+       gtk_widget_map (scrolled_window->viewport);
+
+      if (GTK_WIDGET_VISIBLE (scrolled_window->hscrollbar) &&
+         !GTK_WIDGET_MAPPED (scrolled_window->hscrollbar))
+       gtk_widget_map (scrolled_window->hscrollbar);
+
+      if (GTK_WIDGET_VISIBLE (scrolled_window->vscrollbar) &&
+         !GTK_WIDGET_MAPPED (scrolled_window->vscrollbar))
+       gtk_widget_map (scrolled_window->vscrollbar);
+    }
+}
+
+static void
+gtk_scrolled_window_unmap (GtkWidget *widget)
+{
+  GtkScrolledWindow *scrolled_window;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_SCROLLED_WINDOW (widget));
+
+  if (GTK_WIDGET_MAPPED (widget))
+    {
+      GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
+      scrolled_window = GTK_SCROLLED_WINDOW (widget);
+
+      if (GTK_WIDGET_MAPPED (scrolled_window->viewport))
+       gtk_widget_unmap (scrolled_window->viewport);
+
+      if (GTK_WIDGET_MAPPED (scrolled_window->hscrollbar))
+       gtk_widget_unmap (scrolled_window->hscrollbar);
+
+      if (GTK_WIDGET_MAPPED (scrolled_window->vscrollbar))
+       gtk_widget_unmap (scrolled_window->vscrollbar);
+    }
+}
+
+static void
+gtk_scrolled_window_draw (GtkWidget    *widget,
+                         GdkRectangle *area)
+{
+  GtkScrolledWindow *scrolled_window;
+  GdkRectangle child_area;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_SCROLLED_WINDOW (widget));
+  g_return_if_fail (area != NULL);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      scrolled_window = GTK_SCROLLED_WINDOW (widget);
+
+      if (gtk_widget_intersect (scrolled_window->viewport, area, &child_area))
+       gtk_widget_draw (scrolled_window->viewport, &child_area);
+
+      if (gtk_widget_intersect (scrolled_window->hscrollbar, area, &child_area))
+       gtk_widget_draw (scrolled_window->hscrollbar, &child_area);
+
+      if (gtk_widget_intersect (scrolled_window->vscrollbar, area, &child_area))
+       gtk_widget_draw (scrolled_window->vscrollbar, &child_area);
+    }
+}
+
+static void
+gtk_scrolled_window_size_request (GtkWidget      *widget,
+                                 GtkRequisition *requisition)
+{
+  GtkScrolledWindow *scrolled_window;
+  gint extra_height;
+  gint extra_width;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_SCROLLED_WINDOW (widget));
+  g_return_if_fail (requisition != NULL);
+
+  scrolled_window = GTK_SCROLLED_WINDOW (widget);
+
+  requisition->width = 0;
+  requisition->height = 0;
+
+  if (GTK_WIDGET_VISIBLE (scrolled_window->viewport))
+    {
+      gtk_widget_size_request (scrolled_window->viewport, &scrolled_window->viewport->requisition);
+
+      requisition->width += scrolled_window->viewport->requisition.width;
+      requisition->height += scrolled_window->viewport->requisition.height;
+    }
+
+  extra_width = 0;
+  extra_height = 0;
+
+  if ((scrolled_window->hscrollbar_policy == GTK_POLICY_AUTOMATIC) ||
+      GTK_WIDGET_VISIBLE (scrolled_window->hscrollbar))
+    {
+      gtk_widget_size_request (scrolled_window->hscrollbar,
+                              &scrolled_window->hscrollbar->requisition);
+
+      requisition->width = MAX (requisition->width, scrolled_window->hscrollbar->requisition.width);
+      extra_height = SCROLLBAR_SPACING + scrolled_window->hscrollbar->requisition.height;
+    }
+
+  if ((scrolled_window->vscrollbar_policy == GTK_POLICY_AUTOMATIC) ||
+      GTK_WIDGET_VISIBLE (scrolled_window->vscrollbar))
+    {
+      gtk_widget_size_request (scrolled_window->vscrollbar,
+                              &scrolled_window->vscrollbar->requisition);
+
+      requisition->height = MAX (requisition->height, scrolled_window->vscrollbar->requisition.height);
+      extra_width = SCROLLBAR_SPACING + scrolled_window->vscrollbar->requisition.width;
+    }
+
+  requisition->width += GTK_CONTAINER (widget)->border_width * 2 + extra_width;
+  requisition->height += GTK_CONTAINER (widget)->border_width * 2 + extra_height;
+}
+
+static void
+gtk_scrolled_window_size_allocate (GtkWidget     *widget,
+                                  GtkAllocation *allocation)
+{
+  GtkScrolledWindow *scrolled_window;
+  GtkAllocation viewport_allocation;
+  GtkAllocation child_allocation;
+  guint previous_hvis;
+  guint previous_vvis;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_SCROLLED_WINDOW (widget));
+  g_return_if_fail (allocation != NULL);
+
+  scrolled_window = GTK_SCROLLED_WINDOW (widget);
+  widget->allocation = *allocation;
+
+  gtk_scrolled_window_viewport_allocate (widget, &viewport_allocation);
+
+  gtk_container_disable_resize (GTK_CONTAINER (scrolled_window));
+
+  if (GTK_WIDGET_VISIBLE (scrolled_window->viewport))
+    {
+      do {
+       gtk_scrolled_window_viewport_allocate (widget, &viewport_allocation);
+
+       child_allocation.x = viewport_allocation.x + allocation->x;
+       child_allocation.y = viewport_allocation.y + allocation->y;
+       child_allocation.width = viewport_allocation.width;
+       child_allocation.height = viewport_allocation.height;
+
+       previous_hvis = GTK_WIDGET_VISIBLE (scrolled_window->hscrollbar);
+       previous_vvis = GTK_WIDGET_VISIBLE (scrolled_window->vscrollbar);
+
+       gtk_widget_size_allocate (scrolled_window->viewport, &child_allocation);
+      } while ((previous_hvis != GTK_WIDGET_VISIBLE (scrolled_window->hscrollbar)) ||
+              (previous_vvis != GTK_WIDGET_VISIBLE (scrolled_window->vscrollbar)));
+    }
+
+  if (GTK_WIDGET_VISIBLE (scrolled_window->hscrollbar))
+    {
+      child_allocation.x = viewport_allocation.x;
+      child_allocation.y = viewport_allocation.y + viewport_allocation.height + SCROLLBAR_SPACING;
+      child_allocation.width = viewport_allocation.width;
+      child_allocation.height = scrolled_window->hscrollbar->requisition.height;
+      child_allocation.x += allocation->x;
+      child_allocation.y += allocation->y;
+
+      gtk_widget_size_allocate (scrolled_window->hscrollbar, &child_allocation);
+    }
+
+  if (GTK_WIDGET_VISIBLE (scrolled_window->vscrollbar))
+    {
+      child_allocation.x = viewport_allocation.x + viewport_allocation.width + SCROLLBAR_SPACING;
+      child_allocation.y = viewport_allocation.y;
+      child_allocation.width = scrolled_window->vscrollbar->requisition.width;
+      child_allocation.height = viewport_allocation.height;
+      child_allocation.x += allocation->x;
+      child_allocation.y += allocation->y;
+
+      gtk_widget_size_allocate (scrolled_window->vscrollbar, &child_allocation);
+    }
+
+  gtk_container_enable_resize (GTK_CONTAINER (scrolled_window));
+}
+
+static void
+gtk_scrolled_window_add (GtkContainer *container,
+                        GtkWidget    *widget)
+{
+  GtkScrolledWindow *scrolled_window;
+
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_SCROLLED_WINDOW (container));
+  g_return_if_fail (widget != NULL);
+
+  scrolled_window = GTK_SCROLLED_WINDOW (container);
+  gtk_container_add (GTK_CONTAINER (scrolled_window->viewport), widget);
+}
+
+static void
+gtk_scrolled_window_remove (GtkContainer *container,
+                           GtkWidget    *widget)
+{
+  GtkScrolledWindow *scrolled_window;
+
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_SCROLLED_WINDOW (container));
+  g_return_if_fail (widget != NULL);
+
+  scrolled_window = GTK_SCROLLED_WINDOW (container);
+  gtk_container_remove (GTK_CONTAINER (scrolled_window->viewport), widget);
+}
+
+static void
+gtk_scrolled_window_foreach (GtkContainer *container,
+                            GtkCallback   callback,
+                            gpointer      callback_data)
+{
+  GtkScrolledWindow *scrolled_window;
+
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_SCROLLED_WINDOW (container));
+  g_return_if_fail (callback != NULL);
+
+  scrolled_window = GTK_SCROLLED_WINDOW (container);
+
+  (* callback) (scrolled_window->viewport, callback_data);
+}
+
+static void
+gtk_scrolled_window_viewport_allocate (GtkWidget     *widget,
+                                      GtkAllocation *allocation)
+{
+  GtkScrolledWindow *scrolled_window;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (allocation != NULL);
+
+  scrolled_window = GTK_SCROLLED_WINDOW (widget);
+
+  allocation->x = GTK_CONTAINER (widget)->border_width;
+  allocation->y = GTK_CONTAINER (widget)->border_width;
+  allocation->width = widget->allocation.width - allocation->x * 2;
+  allocation->height = widget->allocation.height - allocation->y * 2;
+
+  if (GTK_WIDGET_VISIBLE (scrolled_window->vscrollbar))
+    allocation->width -= scrolled_window->vscrollbar->requisition.width + SCROLLBAR_SPACING;
+  if (GTK_WIDGET_VISIBLE (scrolled_window->hscrollbar))
+    allocation->height -= scrolled_window->hscrollbar->requisition.height + SCROLLBAR_SPACING;
+}
+
+static void
+gtk_scrolled_window_adjustment_changed (GtkAdjustment *adjustment,
+                                       gpointer       data)
+{
+  GtkScrolledWindow *scrolled_win;
+  GtkWidget *scrollbar;
+  gint hide_scrollbar;
+  gint policy;
+
+  g_return_if_fail (adjustment != NULL);
+  g_return_if_fail (data != NULL);
+
+  scrolled_win = GTK_SCROLLED_WINDOW (data);
+
+  if (adjustment == gtk_range_get_adjustment (GTK_RANGE (scrolled_win->hscrollbar)))
+    {
+      scrollbar = scrolled_win->hscrollbar;
+      policy = scrolled_win->hscrollbar_policy;
+    }
+  else if (adjustment == gtk_range_get_adjustment (GTK_RANGE (scrolled_win->vscrollbar)))
+    {
+      scrollbar = scrolled_win->vscrollbar;
+      policy = scrolled_win->vscrollbar_policy;
+    }
+  else
+    {
+      g_warning ("could not determine which adjustment scrollbar received change signal for");
+      return;
+    }
+
+  if (policy == GTK_POLICY_AUTOMATIC)
+    {
+      hide_scrollbar = FALSE;
+
+      if ((adjustment->upper - adjustment->lower) <= adjustment->page_size)
+       hide_scrollbar = TRUE;
+
+      if (hide_scrollbar)
+       {
+         if (GTK_WIDGET_VISIBLE (scrollbar))
+           gtk_widget_hide (scrollbar);
+       }
+      else
+       {
+         if (!GTK_WIDGET_VISIBLE (scrollbar))
+           gtk_widget_show (scrollbar);
+       }
+    }
+}
diff --git a/gtk/gtkscrolledwindow.h b/gtk/gtkscrolledwindow.h
new file mode 100644 (file)
index 0000000..34a01ef
--- /dev/null
@@ -0,0 +1,74 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_SCROLLED_WINDOW_H__
+#define __GTK_SCROLLED_WINDOW_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkhscrollbar.h>
+#include <gtk/gtkvscrollbar.h>
+#include <gtk/gtkviewport.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_SCROLLED_WINDOW(obj)          GTK_CHECK_CAST (obj, gtk_scrolled_window_get_type (), GtkScrolledWindow)
+#define GTK_SCROLLED_WINDOW_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_scrolled_window_get_type (), GtkScrolledWindowClass)
+#define GTK_IS_SCROLLED_WINDOW(obj)       GTK_CHECK_TYPE (obj, gtk_scrolled_window_get_type ())
+
+
+typedef struct _GtkScrolledWindow       GtkScrolledWindow;
+typedef struct _GtkScrolledWindowClass  GtkScrolledWindowClass;
+
+struct _GtkScrolledWindow
+{
+  GtkContainer container;
+
+  GtkWidget *viewport;
+  GtkWidget *hscrollbar;
+  GtkWidget *vscrollbar;
+
+  guint8 hscrollbar_policy;
+  guint8 vscrollbar_policy;
+};
+
+struct _GtkScrolledWindowClass
+{
+  GtkContainerClass parent_class;
+};
+
+
+guint          gtk_scrolled_window_get_type        (void);
+GtkWidget*     gtk_scrolled_window_new             (GtkAdjustment     *hadjustment,
+                                                   GtkAdjustment     *vadjustment);
+GtkAdjustment* gtk_scrolled_window_get_hadjustment (GtkScrolledWindow *scrolled_window);
+GtkAdjustment* gtk_scrolled_window_get_vadjustment (GtkScrolledWindow *scrolled_window);
+void           gtk_scrolled_window_set_policy      (GtkScrolledWindow *scrolled_window,
+                                                   GtkPolicyType      hscrollbar_policy,
+                                                   GtkPolicyType      vscrollbar_policy);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_SCROLLED_WINDOW_H__ */
diff --git a/gtk/gtkselection.c b/gtk/gtkselection.c
new file mode 100644 (file)
index 0000000..ca6f574
--- /dev/null
@@ -0,0 +1,1388 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* This file implements most of the work of the ICCM selection protocol.
+ * The code was written after an intensive study of the equivalent part
+ * of John Ousterhout's Tk toolkit, and does many things in much the 
+ * same way.
+ *
+ * The one thing in the ICCM that isn't fully supported here (or in Tk)
+ * is side effects targets. For these to be handled properly, MULTIPLE
+ * targets need to be done in the order specified. This cannot be
+ * guaranteed with the way we do things, since if we are doing INCR
+ * transfers, the order will depend on the timing of the requestor.
+ *
+ * By Owen Taylor <owt1@cornell.edu>          8/16/97
+ */
+
+/* Terminology note: when not otherwise specified, the term "incr" below
+ * refers to the _sending_ part of the INCR protocol. The receiving
+ * portion is referred to just as "retrieval". (Terminology borrowed
+ * from Tk, because there is no good opposite to "retrieval" in English.
+ * "send" can't be made into a noun gracefully and we're already using
+ * "emission" for something else ....)
+ */
+
+/* The MOTIF entry widget seems to ask for the TARGETS target, then
+   (regardless of the reply) ask for the TEXT target. It's slightly
+   possible though that it somehow thinks we are responding negatively
+   to the TARGETS request, though I don't really think so ... */
+
+#include <stdarg.h>
+#include <gdk/gdkx.h>
+/* we need this for gdk_window_lookup() */
+#include "gtkmain.h"
+#include "gtkselection.h"
+#include "gtksignal.h"
+
+/* #define DEBUG_SELECTION */
+
+/* Maximum size of a sent chunk, in bytes. Also the default size of
+   our buffers */
+#define GTK_SELECTION_MAX_SIZE 4000
+
+enum {
+  INCR,
+  MULTIPLE,
+  TARGETS,
+  TIMESTAMP,
+  LAST_ATOM
+};
+
+typedef struct _GtkSelectionInfo GtkSelectionInfo;
+typedef struct _GtkIncrConversion GtkIncrConversion;
+typedef struct _GtkIncrInfo GtkIncrInfo;
+typedef struct _GtkRetrievalInfo GtkRetrievalInfo;
+typedef struct _GtkSelectionHandler GtkSelectionHandler;
+
+struct _GtkSelectionInfo
+{
+  GdkAtom    selection;
+  GtkWidget *widget;           /* widget that owns selection */
+  guint32    time;             /* time used to acquire selection */
+};
+
+struct _GtkIncrConversion 
+{
+  GdkAtom           target;    /* Requested target */
+  GdkAtom           property;  /* Property to store in */
+  GtkSelectionData  data;      /* The data being supplied */
+  gint             offset;     /* Current offset in sent selection.
+                                *  -1 => All done
+                                *  -2 => Only the final (empty) portion
+                                *        left to send */
+};
+
+struct _GtkIncrInfo
+{
+  GtkWidget *widget;           /* Selection owner */
+  GdkWindow *requestor;                /* Requestor window - we create a GdkWindow
+                                  so we can receive events */
+  GdkAtom    selection;                /* Selection we're sending */
+
+  GtkIncrConversion *conversions; /* Information about requested conversions -
+                                  * With MULTIPLE requests (benighted 1980's
+                                  * hardware idea), there can be more than
+                                  * one */
+  gint num_conversions;
+  gint num_incrs;              /* number of remaining INCR style transactions */
+  guint32 idle_time;
+};
+
+
+struct _GtkRetrievalInfo
+{
+  GtkWidget *widget;
+  GdkAtom selection;           /* Selection being retrieved. */
+  GdkAtom target;              /* Form of selection that we requested */
+  guint32 idle_time;           /* Number of seconds since we last heard
+                                  from selection owner */
+  guchar   *buffer;            /* Buffer in which to accumulate results */
+  gint     offset;             /* Current offset in buffer, -1 indicates
+                                  not yet started */
+};
+
+struct _GtkSelectionHandler
+{
+  GdkAtom selection;           /* selection thats handled */
+  GdkAtom target;              /* target thats handled */
+  GtkSelectionFunction function; /* callback function */
+  GtkRemoveFunction remove_func; /* called when callback is removed */
+  gpointer data;                /* callback data */
+};
+
+/* Local Functions */
+static void gtk_selection_init                   (void);
+static gint gtk_selection_incr_timeout           (GtkIncrInfo *info);
+static gint gtk_selection_retrieval_timeout      (GtkRetrievalInfo *info);
+static void gtk_selection_retrieval_report       (GtkRetrievalInfo *info,
+                                                 GdkAtom type, gint format, 
+                                                 guchar *buffer, gint length);
+static GtkSelectionHandler *gtk_selection_find_handler (GtkWidget *widget,
+                                                       GdkAtom    selection,
+                                                       GdkAtom    target);
+static void gtk_selection_default_handler        (GtkWidget       *widget,
+                                                 GtkSelectionData *data);
+
+/* Local Data */
+static gint initialize = TRUE;
+static GList *current_retrievals = NULL;
+static GList *current_incrs = NULL;
+static GList *current_selections = NULL;
+
+static GdkAtom gtk_selection_atoms[LAST_ATOM];
+static const char *gtk_selection_handler_key = "selection_handlers";
+
+/*************************************************************
+ * gtk_selection_owner_set:
+ *     Claim ownership of a selection.
+ *   arguments:
+ *     widget:         new selection owner
+ *     selection:      which selection
+ *     time:           time (use GDK_CURRENT_TIME only if necessary)
+ *
+ *   results:
+ *************************************************************/
+
+gint
+gtk_selection_owner_set (GtkWidget *widget,
+                        GdkAtom    selection,
+                        guint32    time)
+{
+  GList *tmp_list;
+  GtkWidget *old_owner;
+  GtkSelectionInfo *selection_info;
+  GdkWindow *window;
+
+  if (widget == NULL)
+    window = NULL;
+  else
+    {
+      if (!GTK_WIDGET_REALIZED (widget))
+       gtk_widget_realize (widget);
+      
+      window = widget->window;
+    }
+
+  tmp_list = current_selections;
+  while (tmp_list)
+    {
+      selection_info = (GtkSelectionInfo *)tmp_list->data;
+      
+      if (selection_info->selection == selection)
+       break;
+      
+      tmp_list = tmp_list->next;
+    }
+
+  if (tmp_list == NULL)
+    selection_info = NULL;
+  else
+    if (selection_info->widget == widget)
+      return TRUE;
+      
+  if (gdk_selection_owner_set (window, selection, time, TRUE))
+    {
+      old_owner = NULL;
+      
+      if (widget == NULL)
+       {
+         if (selection_info)
+           {
+             old_owner = selection_info->widget;
+             current_selections = g_list_remove_link (current_selections,
+                                                      tmp_list);
+             g_list_free (tmp_list);
+             g_free (selection_info);
+           }
+       }
+      else
+       {
+         if (selection_info == NULL)
+           {
+             selection_info = g_new (GtkSelectionInfo, 1);
+             selection_info->selection = selection;
+             selection_info->widget = widget;
+             selection_info->time = time;
+             current_selections = g_list_append (current_selections, 
+                                                 selection_info);
+           }
+         else
+           {
+             old_owner = selection_info->widget;
+             selection_info->widget = widget;
+             selection_info->time = time;
+           }
+       }
+      /* If another widget in the application lost the selection,
+       *  send it a GDK_SELECTION_CLEAR event, unless we're setting
+       *  the owner to None, in which case an event will be sent */
+      if (old_owner && (widget != NULL))
+       {
+         GdkEventSelection event;
+         
+         event.type = GDK_SELECTION_CLEAR;
+         event.window = old_owner->window;
+         event.selection = selection;
+         event.time = time;
+
+         gtk_widget_event (widget, (GdkEvent *) &event);
+       }
+      return TRUE;
+    }
+  else
+    return FALSE;
+}
+
+/*************************************************************
+ * gtk_selection_add_handler:
+ *     Add a handler for a specified selection/target pair
+ *
+ *   arguments:
+ *     widget:     The widget the handler applies to
+ *     selection:
+ *     target:
+ *     format:     Format in which this handler will return data
+ *     function:   Callback function (can be NULL)
+ *     data:       User data for callback
+ *
+ *   results:
+ *************************************************************/
+
+void
+gtk_selection_add_handler (GtkWidget           *widget, 
+                          GdkAtom              selection,
+                          GdkAtom              target,
+                          GtkSelectionFunction function,
+                          GtkRemoveFunction    remove_func,
+                          gpointer             data)
+{
+  GList *selection_handlers;
+  GList *tmp_list;
+  GtkSelectionHandler *handler;
+
+  g_return_if_fail (widget != NULL);
+  if (initialize)
+    gtk_selection_init ();
+  
+  selection_handlers = gtk_object_get_data (GTK_OBJECT (widget),
+                                           gtk_selection_handler_key);
+
+  /* Reuse old handler structure, if present */
+  tmp_list = selection_handlers;
+  while (tmp_list)
+    {
+      handler = (GtkSelectionHandler *)tmp_list->data;
+      if ((handler->selection == selection) && (handler->target == target))
+       {
+         if (handler->remove_func)
+           (*handler->remove_func)(handler->data);
+         if (function)
+           {
+             handler->function = function;
+             handler->remove_func = remove_func;
+             handler->data = data;
+           }
+         else
+           {
+             selection_handlers = g_list_remove_link (selection_handlers, 
+                                                      tmp_list);
+             g_list_free (tmp_list);
+             g_free (handler);
+           }
+         return;
+       }
+      tmp_list = tmp_list->next;
+    }
+
+  if (tmp_list == NULL && function)
+    {
+      handler = g_new (GtkSelectionHandler, 1);
+      handler->selection = selection;
+      handler->target = target;
+      handler->function = function;
+      handler->remove_func = remove_func;
+      handler->data = data;
+      selection_handlers = g_list_append (selection_handlers, handler);
+    }
+  
+  gtk_object_set_data (GTK_OBJECT (widget), gtk_selection_handler_key,
+                      selection_handlers);
+}
+
+/*************************************************************
+ * gtk_selection_remove_all:
+ *     Removes all handlers and unsets ownership of all 
+ *     selections for a widget. Called when widget is being
+ *     destroyed
+ *     
+ *   arguments:
+ *     widget:   The widget
+ *   results:
+ *************************************************************/
+
+void
+gtk_selection_remove_all (GtkWidget *widget)
+{
+  GList *tmp_list;
+  GList *next;
+  GtkSelectionInfo *selection_info;
+  GList *selection_handlers;
+  GtkSelectionHandler *handler;
+
+  /* Remove pending requests/incrs for this widget */
+
+  tmp_list = current_incrs;
+  while (tmp_list)
+    {
+      next = tmp_list->next;
+      if (((GtkIncrInfo *)tmp_list->data)->widget == widget)
+       {
+         current_incrs = g_list_remove_link (current_incrs, tmp_list);
+         /* structure will be freed in timeout */
+         g_list_free (tmp_list);
+       }
+      tmp_list = next;
+    }
+
+  tmp_list = current_retrievals;
+  while (tmp_list)
+    {
+      next = tmp_list->next;
+      if (((GtkRetrievalInfo *)tmp_list->data)->widget == widget)
+       {
+         current_retrievals = g_list_remove_link (current_retrievals, 
+                                                  tmp_list);
+         /* structure will be freed in timeout */
+         g_list_free (tmp_list);
+       }
+      tmp_list = next;
+    }
+  
+  /* Disclaim ownership of any selections */
+
+  tmp_list = current_selections;
+  while (tmp_list)
+    {
+      next = tmp_list->next;
+      selection_info = (GtkSelectionInfo *)tmp_list->data;
+      
+      if (selection_info->widget == widget)
+       {       
+         gdk_selection_owner_set (NULL, 
+                                  selection_info->selection,
+                                  GDK_CURRENT_TIME, FALSE);
+         current_selections = g_list_remove_link (current_selections, 
+                                                  tmp_list);
+         g_list_free (tmp_list);
+         g_free (selection_info);
+       }
+      
+      tmp_list = next;
+    }
+
+  /* Now remove all handlers */
+
+  selection_handlers = gtk_object_get_data (GTK_OBJECT (widget),
+                                           gtk_selection_handler_key);
+
+  tmp_list = selection_handlers;
+  while (tmp_list)
+    {
+      next = tmp_list->next;
+      handler = (GtkSelectionHandler *)tmp_list->data;
+
+      if (handler->remove_func)
+       (*handler->remove_func)(handler->data);
+
+      g_free (handler);
+
+      tmp_list = next;
+    }
+
+  g_list_free (selection_handlers);
+}
+
+/*************************************************************
+ * gtk_selection_convert:
+ *     Request the contents of a selection. When received, 
+ *     a "selection_received" signal will be generated.
+ *
+ *   arguments:
+ *     widget:     The widget which acts as requestor
+ *     selection:  Which selection to get
+ *     target:     Form of information desired (e.g., STRING)
+ *     time:       Time of request (usually of triggering event)
+ *                 In emergency, you could use GDK_CURRENT_TIME
+ *
+ *   results:
+ *     TRUE if requested succeeded. FALSE if we could not process
+ *     request. (e.g., there was already a request in process for
+ *     this widget). 
+ *************************************************************/
+
+gint
+gtk_selection_convert (GtkWidget *widget, 
+                      GdkAtom    selection, 
+                      GdkAtom    target,
+                      guint32    time)
+{
+  GtkRetrievalInfo *info;
+  GList *tmp_list;
+  GdkWindow *owner_window;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+
+  if (initialize)
+    gtk_selection_init ();
+  
+  if (!GTK_WIDGET_REALIZED (widget))
+    gtk_widget_realize (widget);
+
+  /* Check to see if there are already any retrievals in progress for
+     this widget. If we changed GDK to use the selection for the 
+     window property in which to store the retrieved information, then
+     we could support multiple retrievals for different selections.
+     This might be useful for DND. */
+
+  tmp_list = current_retrievals;
+  while (tmp_list)
+    {
+      info = (GtkRetrievalInfo *)tmp_list->data;
+      if (info->widget == widget)
+       return FALSE;
+      tmp_list = tmp_list->next;
+    }
+
+  info = g_new (GtkRetrievalInfo, 1);
+
+  info->widget = widget;
+  info->selection = selection;
+  info->target = target;
+  info->buffer = NULL;
+  info->offset = -1;
+
+  /* Check if this process has current owner. If so, call handler
+     procedure directly to avoid deadlocks with INCR. */
+
+  owner_window = gdk_selection_owner_get (selection);
+  
+  if (owner_window != NULL)
+    {
+      GtkWidget *owner_widget;
+      GtkSelectionHandler *handler;
+      GtkSelectionData selection_data;
+
+      selection_data.selection = selection;
+      selection_data.target = target;
+      selection_data.data = NULL;
+      selection_data.length = -1;
+
+      gdk_window_get_user_data (owner_window, (gpointer *)&owner_widget);
+
+      if (owner_widget != NULL)
+       {
+         handler = gtk_selection_find_handler (owner_widget, selection, target);
+         if (handler)
+           (* handler->function)(owner_widget,
+                                 &selection_data,
+                                 handler->data);
+         else                  /* try the default handler */
+           gtk_selection_default_handler (owner_widget,
+                                          &selection_data);
+
+         gtk_selection_retrieval_report (info,
+                                         selection_data.type, 
+                                         selection_data.format,
+                                         selection_data.data,
+                                         selection_data.length);
+
+         g_free (selection_data.data);
+         
+         g_free (info);
+         return TRUE;
+       }
+    }
+  
+  /* Otherwise, we need to go through X */
+
+  current_retrievals = g_list_append (current_retrievals, info);
+  gdk_selection_convert (widget->window, selection, target, time);
+  gtk_timeout_add (1000, (GtkFunction) gtk_selection_retrieval_timeout, info);
+
+  return TRUE;
+}
+
+/*************************************************************
+ * gtk_selection_data_set:
+ *     Store new data into a GtkSelectionData object. Should
+ *     _only_ by called from a selection handler callback.
+ *     Null terminates the stored data.
+ *   arguments:
+ *     type:   the type of selection data
+ *     format:  format (number of bits in a unit)
+ *     data:    pointer to the data (will be copied)
+ *     length:  length of the data
+ *   results:
+ *************************************************************/
+
+void 
+gtk_selection_data_set (GtkSelectionData *selection_data,
+                       GdkAtom           type,
+                       gint              format,
+                       guchar           *data,
+                       gint              length)
+{
+  if (selection_data->data)
+    g_free (selection_data->data);
+
+  selection_data->type = type;
+  selection_data->format = format;
+
+  if (data)
+    {
+      selection_data->data = g_new (guchar, length+1);
+      memcpy (selection_data->data, data, length);
+      selection_data->data[length] = 0;
+    }
+  else
+    selection_data->data = NULL;
+
+  selection_data->length = length;
+}
+
+/*************************************************************
+ * gtk_selection_init:
+ *     Initialize local variables
+ *   arguments:
+ *     
+ *   results:
+ *************************************************************/
+
+static void
+gtk_selection_init (void)
+{
+  gtk_selection_atoms[INCR] = gdk_atom_intern ("INCR", FALSE);
+  gtk_selection_atoms[MULTIPLE] = gdk_atom_intern ("MULTIPLE", FALSE);
+  gtk_selection_atoms[TIMESTAMP] = gdk_atom_intern ("TIMESTAMP", FALSE);
+  gtk_selection_atoms[TARGETS] = gdk_atom_intern ("TARGETS", FALSE);
+}
+
+/*************************************************************
+ * gtk_selection_clear:
+ *     Handler for "selection_clear_event"
+ *   arguments:
+ *     widget:
+ *     event:
+ *   results:
+ *************************************************************/
+
+gint
+gtk_selection_clear (GtkWidget *widget,
+                    GdkEventSelection *event)
+{
+  /* FIXME: there can be a problem if we change the selection
+     via gtk_selection_owner_set after another client claims 
+     the selection, but before we get the notification event.
+     Tk filters based on serial #'s, which aren't retained by
+     GTK. Filtering based on time's will be inherently 
+     somewhat unreliable. */
+
+  GList *tmp_list;
+  GtkSelectionInfo *selection_info;
+
+  tmp_list = current_selections;
+  while (tmp_list)
+    {
+      selection_info = (GtkSelectionInfo *)tmp_list->data;
+      
+      if ((selection_info->selection == event->selection) &&
+         (selection_info->widget == widget))
+       break;
+      
+      tmp_list = tmp_list->next;
+    }
+    
+  if (tmp_list == NULL || selection_info->time > event->time)
+    return TRUE;
+
+  current_selections = g_list_remove_link (current_selections, tmp_list);
+  g_list_free (tmp_list);
+  g_free (selection_info);
+
+  return TRUE;
+}
+
+
+/*************************************************************
+ * gtk_selection_request:
+ *     Handler for "selection_request_event" 
+ *   arguments:
+ *     widget:
+ *     event:
+ *   results:
+ *************************************************************/
+
+gint
+gtk_selection_request (GtkWidget *widget,
+                      GdkEventSelection *event)
+{
+  GtkIncrInfo *info;
+  GtkSelectionHandler *handler;
+  GList *tmp_list;
+  guchar *mult_atoms;
+  int i;
+
+  /* Check if we own selection */
+
+  tmp_list = current_selections;
+  while (tmp_list)
+    {
+      GtkSelectionInfo *selection_info = (GtkSelectionInfo *)tmp_list->data;
+
+      if ((selection_info->selection == event->selection) &&
+         (selection_info->widget == widget))
+       break;
+
+      tmp_list = tmp_list->next;
+    }
+
+  if (tmp_list == NULL)
+    return FALSE;
+  
+  info = g_new(GtkIncrInfo, 1);
+
+  info->widget = widget;
+  info->selection = event->selection;
+  info->num_incrs = 0;
+
+  /* Create GdkWindow structure for the requestor */
+
+  info->requestor = gdk_window_lookup (event->requestor);
+  if (!info->requestor)
+    info->requestor = gdk_window_foreign_new (event->requestor);
+  
+  /* Determine conversions we need to perform */
+
+  if (event->target == gtk_selection_atoms[MULTIPLE])
+    {
+      GdkAtom  type;
+      gint     format;
+      gint     length;
+
+      mult_atoms = NULL;
+      if (!gdk_property_get (info->requestor, event->property, GDK_SELECTION_TYPE_ATOM,
+                            0, GTK_SELECTION_MAX_SIZE, FALSE,
+                            &type, &format, &length, &mult_atoms) ||
+         type != GDK_SELECTION_TYPE_ATOM || format != 8*sizeof(GdkAtom))
+       {
+         gdk_selection_send_notify (event->requestor, event->selection,
+                                    event->target, GDK_NONE, event->time);
+         g_free (mult_atoms);
+         g_free (info);
+         return TRUE;
+       }
+
+      info->num_conversions = length / (2*sizeof (GdkAtom));
+      info->conversions = g_new (GtkIncrConversion, info->num_conversions);
+
+      for (i=0; i<info->num_conversions; i++)
+       {
+         info->conversions[i].target = ((GdkAtom *)mult_atoms)[2*i];
+         info->conversions[i].property = ((GdkAtom *)mult_atoms)[2*i+1];
+       }
+    }
+  else                         /* only a single conversion */
+    {
+      info->conversions = g_new (GtkIncrConversion, 1);
+      info->num_conversions = 1;
+      info->conversions[0].target = event->target;
+      info->conversions[0].property = event->property;
+      mult_atoms = (guchar *)info->conversions;
+    }
+
+  /* Loop through conversions and determine which of these are big
+     enough to require doing them via INCR */
+  for (i=0; i<info->num_conversions; i++)
+    {
+      GtkSelectionData data;
+      gint items;
+
+      data.selection = event->selection;
+      data.target = info->conversions[i].target;
+      data.data = NULL;
+      data.length = -1;
+
+#ifdef DEBUG_SELECTION
+      g_print("Selection %ld, target %ld (%s) requested by 0x%x (property = %ld)\n",
+             event->selection, info->conversions[i].target,
+             gdk_atom_name(info->conversions[i].target),
+             event->requestor, event->property);
+#endif
+  
+      handler = gtk_selection_find_handler (widget, event->selection,
+                                           info->conversions[i].target);
+      if (handler)
+       (* handler->function)(widget, &data, handler->data);
+      else
+       gtk_selection_default_handler (widget, &data);
+
+      if (data.length < 0)
+       {
+         ((GdkAtom *)mult_atoms)[2*i+1] = GDK_NONE;
+         info->conversions[i].property = GDK_NONE;
+         continue;
+       }
+
+      g_return_val_if_fail ((data.format >= 8) 
+                           && (data.format % 8 == 0), FALSE)
+
+      items = (data.length + data.format/8 - 1) / (data.format/8);
+
+      if (data.length > GTK_SELECTION_MAX_SIZE)
+       {
+         /* Sending via INCR */
+         
+         info->conversions[i].offset = 0;
+         info->conversions[i].data = data;
+         info->num_incrs++;
+         
+         gdk_property_change (info->requestor, 
+                              info->conversions[i].property,
+                              gtk_selection_atoms[INCR],
+                              8*sizeof (GdkAtom),
+                              GDK_PROP_MODE_REPLACE,
+                              (guchar *)&items, 1);
+       }
+      else
+       {
+         info->conversions[i].offset = -1;
+
+         gdk_property_change (info->requestor, 
+                              info->conversions[i].property,
+                              data.type,
+                              data.format,
+                              GDK_PROP_MODE_REPLACE,
+                              data.data, items);
+
+         g_free (data.data);
+       }
+    }
+
+  /* If we have some INCR's, we need to send the rest of the data in
+     a callback */
+
+  if (info->num_incrs > 0)
+    {
+      /* FIXME: this could be dangerous if window doesn't still
+        exist */
+
+#ifdef DEBUG_SELECTION
+      g_print("Starting INCR...\n");
+#endif
+
+      gdk_window_set_events (info->requestor,
+                            gdk_window_get_events (info->requestor) |
+                            GDK_PROPERTY_CHANGE_MASK);
+      current_incrs = g_list_append (current_incrs, info);
+      gtk_timeout_add (1000, (GtkFunction)gtk_selection_incr_timeout, info);
+    }
+
+  /* If it was a MULTIPLE request, set the property to indicate which
+     conversions succeeded */
+  if (event->target == gtk_selection_atoms[MULTIPLE])
+    {
+      gdk_property_change (info->requestor, event->property,
+                          GDK_SELECTION_TYPE_ATOM, 8*sizeof(GdkAtom), 
+                          GDK_PROP_MODE_REPLACE,
+                          mult_atoms, info->num_conversions);
+      g_free (mult_atoms);
+    }
+
+  gdk_selection_send_notify (event->requestor, event->selection, event->target,
+                            event->property, event->time);
+
+  if (info->num_incrs == 0)
+    {
+      g_free (info->conversions);
+      g_free (info);
+    }
+
+  return TRUE;
+}
+
+/*************************************************************
+ * gtk_selection_incr_event:
+ *     Called whenever an PropertyNotify event occurs for an 
+ *     GdkWindow with user_data == NULL. These will be notifications
+ *     that a window we are sending the selection to via the
+ *     INCR protocol has deleted a property and is ready for
+ *     more data.
+ *
+ *   arguments:
+ *     window:  the requestor window
+ *     event:   the property event structure
+ *
+ *   results:
+ *************************************************************/
+
+gint
+gtk_selection_incr_event (GdkWindow        *window,
+                         GdkEventProperty *event)
+{
+  GList *tmp_list;
+  GtkIncrInfo *info;
+  gint num_bytes;
+  guchar *buffer;
+
+  int i;
+  
+  if (event->state != GDK_PROPERTY_DELETE)
+    return FALSE;
+
+#ifdef DEBUG_SELECTION
+  g_print("PropertyDelete, property %ld\n", event->atom);
+#endif
+
+  /* Now find the appropriate ongoing INCR */
+  tmp_list = current_incrs;
+  while (tmp_list)
+    {
+      info = (GtkIncrInfo *)tmp_list->data;
+      if (info->requestor == event->window)
+       break;
+      
+      tmp_list = tmp_list->next;
+    }
+
+  if (tmp_list == NULL)
+    return FALSE;
+
+  /* Find out which target this is for */
+  for (i=0; i<info->num_conversions; i++)
+    {
+      if (info->conversions[i].property == event->atom &&
+         info->conversions[i].offset != -1)
+       {
+         info->idle_time = 0;
+         
+         if (info->conversions[i].offset == -2) /* only the last 0-length
+                                                   piece*/
+           {
+             num_bytes = 0;
+             buffer = NULL;
+           }
+         else
+           {
+             num_bytes = info->conversions[i].data.length -
+               info->conversions[i].offset;
+             buffer = info->conversions[i].data.data + 
+               info->conversions[i].offset;
+
+             if (num_bytes > GTK_SELECTION_MAX_SIZE)
+               {
+                 num_bytes = GTK_SELECTION_MAX_SIZE;
+                 info->conversions[i].offset += GTK_SELECTION_MAX_SIZE;
+               }
+             else
+               info->conversions[i].offset = -2;
+           }
+#ifdef DEBUG_SELECTION
+         g_print("INCR: put %d bytes (offset = %d) into window 0x%lx , property %ld\n",
+                 num_bytes, info->conversions[i].offset, 
+                 GDK_WINDOW_XWINDOW(info->requestor), event->atom);
+#endif
+         gdk_property_change (info->requestor, event->atom,
+                              info->conversions[i].data.type,
+                              info->conversions[i].data.format,
+                              GDK_PROP_MODE_REPLACE,
+                              buffer, 
+                              (num_bytes + info->conversions[i].data.format/8 - 1) / 
+                              (info->conversions[i].data.format/8));
+
+         if (info->conversions[i].offset == -2)
+           {
+             g_free (info->conversions[i].data.data);
+             info->conversions[i].data.data = NULL;
+           }
+         
+         if (num_bytes == 0)
+           {
+             info->num_incrs--;
+             info->conversions[i].offset = -1;
+           }
+       }
+      break;
+    }
+
+  /* Check if we're finished with all the targets */
+
+  if (info->num_incrs == 0)
+    {
+      current_incrs = g_list_remove_link (current_incrs, tmp_list);
+      g_list_free (tmp_list);
+      /* Let the timeout free it */
+    }
+  
+  return TRUE;
+}
+
+/*************************************************************
+ * gtk_selection_incr_timeout:
+ *     Timeout callback for the sending portion of the INCR
+ *     protocol
+ *   arguments:
+ *     info:    Information about this incr
+ *   results:
+ *************************************************************/
+
+static gint
+gtk_selection_incr_timeout (GtkIncrInfo *info)
+{
+  GList *tmp_list;
+  
+  /* Determine if retrieval has finished by checking if it still in
+     list of pending retrievals */
+
+  tmp_list = current_incrs;
+  while (tmp_list)
+    {
+      if (info == (GtkIncrInfo *)tmp_list->data)
+       break;
+      tmp_list = tmp_list->next;
+    }
+  
+  /* If retrieval is finished */
+  if (!tmp_list || info->idle_time >= 5)
+    {
+      if (tmp_list && info->idle_time >= 5)
+       {
+         current_incrs = g_list_remove_link (current_incrs, tmp_list);
+         g_list_free (tmp_list);
+       }
+      
+      g_free (info->conversions);
+      /* FIXME: we should check if requestor window is still in use,
+        and if not, remove it? */
+        
+      g_free (info);
+      
+      return FALSE;            /* remove timeout */
+    }
+  else
+    {
+      info->idle_time++;
+      
+      return TRUE;             /* timeout will happen again */
+    }
+}
+
+/*************************************************************
+ * gtk_selection_notify:
+ *     Handler for "selection_notify_event" signals on windows
+ *     where a retrieval is currently in process. The selection
+ *     owner has responded to our conversion request.
+ *   arguments:
+ *     widget:          Widget getting signal
+ *     event:           Selection event structure
+ *     info:            Information about this retrieval
+ *   results:
+ *     was event handled?
+ *************************************************************/
+
+gint
+gtk_selection_notify (GtkWidget        *widget,
+                     GdkEventSelection *event)
+{
+  GList *tmp_list;
+  GtkRetrievalInfo *info;
+  guchar  *buffer;
+  gint length;
+  GdkAtom type;
+  gint    format;
+  
+#ifdef DEBUG_SELECTION
+  g_print("Initial receipt of selection %ld, target %ld (property = %ld)\n",
+         event->selection, event->target, event->property);
+#endif
+  
+  tmp_list = current_retrievals;
+  while (tmp_list)
+    {
+      info = (GtkRetrievalInfo *)tmp_list->data;
+      if (info->widget == widget && info->selection == event->selection)
+       break;
+      tmp_list = tmp_list->next;
+    }
+
+  if (!tmp_list)               /* no retrieval in progress */
+    return FALSE;
+
+  if (event->property == GDK_NONE)
+    {
+      current_retrievals = g_list_remove_link (current_retrievals, tmp_list);
+      g_list_free (tmp_list);
+      /* structure will be freed in timeout */
+      gtk_selection_retrieval_report (info,
+                                     GDK_NONE, 0, NULL, -1);
+
+      return TRUE;
+    }
+  
+  length = gdk_selection_property_get (widget->window, &buffer, 
+                                      &type, &format);
+
+  if (type == gtk_selection_atoms[INCR])
+    {
+      /* The remainder of the selection will come through PropertyNotify
+        events */
+
+      info->idle_time = 0;
+      info->offset = 0;                /* Mark as OK to proceed */
+      gdk_window_set_events (widget->window,
+                            gdk_window_get_events (widget->window)
+                            | GDK_PROPERTY_CHANGE_MASK);
+    }
+  else
+    {
+      /* We don't delete the info structure - that will happen in timeout */
+      current_retrievals = g_list_remove_link (current_retrievals, tmp_list);
+      g_list_free (tmp_list);
+
+      info->offset = length;
+      gtk_selection_retrieval_report (info,
+                                     type, format, 
+                                     buffer, length);
+    }
+
+  gdk_property_delete (widget->window, event->property);
+
+  g_free (buffer);
+
+  return TRUE;
+}
+
+/*************************************************************
+ * gtk_selection_property_notify:
+ *     Handler for "property_notify_event" signals on windows
+ *     where a retrieval is currently in process. The selection
+ *     owner has added more data.
+ *   arguments:
+ *     widget:          Widget getting signal
+ *     event:           Property event structure
+ *     info:            Information about this retrieval
+ *   results:
+ *     was event handled?
+ *************************************************************/
+
+gint
+gtk_selection_property_notify (GtkWidget        *widget,
+                              GdkEventProperty *event)
+{
+  GList *tmp_list;
+  GtkRetrievalInfo *info;
+  guchar *new_buffer;
+  int length;
+  GdkAtom type;
+  gint    format;
+
+  if ((event->state != GDK_PROPERTY_NEW_VALUE) ||  /* property was deleted */
+      (event->atom != gdk_selection_property)) /* not the right property */
+    return FALSE;
+
+#ifdef DEBUG_SELECTION
+  g_print("PropertyNewValue, property %ld\n",
+         event->atom);
+#endif
+  
+  tmp_list = current_retrievals;
+  while (tmp_list)
+    {
+      info = (GtkRetrievalInfo *)tmp_list->data;
+      if (info->widget == widget)
+       break;
+      tmp_list = tmp_list->next;
+    }
+
+  if (!tmp_list)               /* No retrieval in progress */
+    return FALSE;
+
+  if (info->offset < 0)                /* We haven't got the SelectionNotify
+                                  for this retrieval yet */
+    return FALSE;
+
+  info->idle_time = 0;
+  
+  length = gdk_selection_property_get (widget->window, &new_buffer, 
+                                      &type, &format);
+  gdk_property_delete (widget->window, event->atom);
+
+  /* We could do a lot better efficiency-wise by paying attention to
+     what length was sent in the initial INCR transaction, instead of
+     doing memory allocation at every step. But its only guaranteed to
+     be a _lower bound_ (pretty useless!) */
+
+  if (length == 0 || type == GDK_NONE)         /* final zero length portion */
+    {
+      /* Info structure will be freed in timeout */
+      current_retrievals = g_list_remove_link (current_retrievals, tmp_list);
+      g_list_free (tmp_list);
+      gtk_selection_retrieval_report (info,
+                                     type, format, 
+                                     (type == GDK_NONE) ?  NULL : info->buffer,
+                                     (type == GDK_NONE) ?  -1 : info->offset);
+    }
+  else                         /* append on newly arrived data */
+    {
+      if (!info->buffer)
+       {
+#ifdef DEBUG_SELECTION
+         g_print("Start - Adding %d bytes at offset 0\n",
+                 length);
+#endif
+         info->buffer = new_buffer;
+         info->offset = length;
+       }
+      else
+       {
+
+#ifdef DEBUG_SELECTION
+         g_print("Appending %d bytes at offset %d\n",
+                 length,info->offset);
+#endif
+         /* We copy length+1 bytes to preserve guaranteed null termination */
+         info->buffer = g_realloc (info->buffer, info->offset+length+1);
+         memcpy (info->buffer + info->offset, new_buffer, length+1);
+         info->offset += length;
+         g_free (new_buffer);
+       }
+    }
+
+  return TRUE;
+}
+
+/*************************************************************
+ * gtk_selection_retrieval_timeout:
+ *     Timeout callback while receiving a selection.
+ *   arguments:
+ *     info:   Information about this retrieval
+ *   results:
+ *************************************************************/
+
+static gint
+gtk_selection_retrieval_timeout (GtkRetrievalInfo *info)
+{
+  GList *tmp_list;
+  
+  /* Determine if retrieval has finished by checking if it still in
+     list of pending retrievals */
+
+  tmp_list = current_retrievals;
+  while (tmp_list)
+    {
+      if (info == (GtkRetrievalInfo *)tmp_list->data)
+       break;
+      tmp_list = tmp_list->next;
+    }
+  
+  /* If retrieval is finished */
+  if (!tmp_list || info->idle_time >= 5)
+    {
+      if (tmp_list && info->idle_time >= 5)
+       {
+         current_retrievals = g_list_remove_link (current_retrievals, tmp_list);
+         g_list_free (tmp_list);
+         gtk_selection_retrieval_report (info, GDK_NONE, 0, NULL, -1);
+       }
+      
+      g_free (info->buffer);
+      g_free (info);
+      
+      return FALSE;            /* remove timeout */
+    }
+  else
+    {
+      info->idle_time++;
+      
+      return TRUE;             /* timeout will happen again */
+    }
+
+}
+
+/*************************************************************
+ * gtk_selection_retrieval_report:
+ *     Emits a "selection_received" signal.
+ *   arguments:
+ *     info:      information about the retrieval that completed
+ *     buffer:    buffer containing data (NULL => errror)
+ *   results:
+ *************************************************************/
+
+static void
+gtk_selection_retrieval_report (GtkRetrievalInfo *info,
+                               GdkAtom type, gint format, 
+                               guchar *buffer, gint length)
+{
+  GtkSelectionData data;
+
+  data.selection = info->selection;
+  data.target = info->target;
+  data.type = type;
+  data.format = format;
+
+  data.length = length;
+  data.data = buffer;
+
+  gtk_signal_emit_by_name (GTK_OBJECT(info->widget),
+                          "selection_received", &data);
+}
+
+/*************************************************************
+ * gtk_selection_find_handler:
+ *     Find handler for specified widget/selection/target
+ *   arguments:
+ *     widget:
+ *     selection:
+ *     target:
+ *   results:
+ *************************************************************/
+
+static GtkSelectionHandler *
+gtk_selection_find_handler (GtkWidget *widget,
+                           GdkAtom    selection,
+                           GdkAtom    target)
+{
+  GList *tmp_list;
+  GtkSelectionHandler *handler;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  
+  tmp_list = gtk_object_get_data (GTK_OBJECT (widget),
+                                 gtk_selection_handler_key);
+
+  while (tmp_list)
+    {
+      handler = (GtkSelectionHandler *)tmp_list->data;
+      if ((handler->selection == selection) && (handler->target == target))
+       return handler;
+      tmp_list = tmp_list->next;
+    }
+
+  return NULL;
+}
+
+
+/*************************************************************
+ * gtk_selection_default_handler:
+ *     Handles some default targets that exist for any widget
+ *     If it can't fit results into buffer, returns -1. This
+ *     won't happen in any conceivable case, since it would
+ *     require 1000 selection targets!
+ *
+ *   arguments:
+ *     widget:      selection owner
+ *     selection:   selection requested
+ *     target:      target requested
+ *     buffer:      buffer to write results into
+ *     length:      size of buffer
+ *     type:        type atom
+ *     format:      length of type's units in bits
+ *     
+ *   results:
+ *     Number of bytes written to buffer, -1 if error
+ *************************************************************/
+
+static void
+gtk_selection_default_handler (GtkWidget        *widget,
+                              GtkSelectionData *data)
+{
+  if (data->target == gtk_selection_atoms[TIMESTAMP])
+    {
+      /* Time which was used to obtain selection */
+      GList *tmp_list;
+      GtkSelectionInfo *selection_info;
+      
+      tmp_list = current_selections;
+      while (tmp_list)
+       {
+         selection_info = (GtkSelectionInfo *)tmp_list->data;
+         if ((selection_info->widget == widget) &&
+             (selection_info->selection == data->selection))
+           {
+             gtk_selection_data_set (data,
+                                     GDK_SELECTION_TYPE_INTEGER,
+                                     sizeof (guint32)*8,
+                                     (guchar *)&selection_info->time,
+                                     sizeof (guint32));
+             return;
+           }
+             
+         tmp_list = tmp_list->next;
+       }
+
+      data->length = -1;
+    }
+  else if (data->target == gtk_selection_atoms[TARGETS])
+    {
+      /* List of all targets supported for this widget/selection pair */
+      GdkAtom *p;
+      gint count;
+      GList *tmp_list;
+      GtkSelectionHandler *handler;
+
+      count = 3;
+      tmp_list = gtk_object_get_data (GTK_OBJECT(widget),
+                                     gtk_selection_handler_key);
+      while (tmp_list)
+       {
+         handler = (GtkSelectionHandler *)tmp_list->data;
+
+         if (handler->selection == data->selection)
+           count++;
+         
+         tmp_list = tmp_list->next;
+       }
+
+      data->type = GDK_SELECTION_TYPE_ATOM;
+      data->format = 8*sizeof (GdkAtom);
+      data->length = count*sizeof (GdkAtom);
+
+      p = g_new (GdkAtom, count);
+      data->data = (guchar *)p;
+
+      *p++ = gtk_selection_atoms[TIMESTAMP];
+      *p++ = gtk_selection_atoms[TARGETS];
+      *p++ = gtk_selection_atoms[MULTIPLE];
+
+      tmp_list = gtk_object_get_data (GTK_OBJECT(widget),
+                                     gtk_selection_handler_key);
+      while (tmp_list)
+       {
+         handler = (GtkSelectionHandler *)tmp_list->data;
+
+         if (handler->selection == data->selection)
+           *p++ = handler->target;
+
+         tmp_list = tmp_list->next;
+       }
+    }
+  else
+    {
+      data->length = -1;
+    }
+}
diff --git a/gtk/gtkselection.h b/gtk/gtkselection.h
new file mode 100644 (file)
index 0000000..18f3dc4
--- /dev/null
@@ -0,0 +1,91 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_SELECTION_H__
+#define __GTK_SELECTION_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkenums.h>
+#include <gtk/gtkwidget.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct _GtkSelectionData GtkSelectioData;
+
+/* a callback function that provides the selection. Arguments are:
+   widget: selection owner
+   offset: offset into selection
+   buffer: buffer into which to store selection 
+   length: length of buffer
+   bytes_after: (sizeof(selection) - offset - length ) (return)
+   data:   callback data */
+
+typedef void (*GtkSelectionFunction) (GtkWidget *widget, 
+                                     GtkSelectionData *selection_data,
+                                     gpointer data);
+
+/* Public interface */
+
+gint gtk_selection_owner_set (GtkWidget          *widget,
+                             GdkAtom              selection,
+                             guint32              time);
+void gtk_selection_add_handler (GtkWidget           *widget, 
+                               GdkAtom              selection,
+                               GdkAtom              target,
+                               GtkSelectionFunction function,
+                               GtkRemoveFunction    remove_func,
+                               gpointer             data);
+gint gtk_selection_convert   (GtkWidget          *widget, 
+                             GdkAtom              selection, 
+                             GdkAtom              target,
+                             guint32              time);
+
+
+void gtk_selection_data_set (GtkSelectionData *selection_data,
+                            GdkAtom           type,
+                            gint              format,
+                            guchar           *data,
+                            gint              length);
+
+/* Called when a widget is destroyed */
+
+void gtk_selection_remove_all      (GtkWidget *widget);
+
+/* Event handlers */
+
+gint gtk_selection_clear           (GtkWidget        *widget,
+                                   GdkEventSelection *event);
+gint gtk_selection_request         (GtkWidget                *widget,
+                                   GdkEventSelection *event);
+gint gtk_selection_incr_event      (GdkWindow         *window,
+                                   GdkEventProperty  *event);
+gint gtk_selection_notify          (GtkWidget         *widget,
+                                   GdkEventSelection *event);
+gint gtk_selection_property_notify (GtkWidget         *widget,
+                                   GdkEventProperty  *event);
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_SELECTION_H__ */
diff --git a/gtk/gtkseparator.c b/gtk/gtkseparator.c
new file mode 100644 (file)
index 0000000..6ad41ad
--- /dev/null
@@ -0,0 +1,57 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkseparator.h"
+
+
+static void gtk_separator_class_init (GtkSeparatorClass *klass);
+static void gtk_separator_init       (GtkSeparator      *separator);
+
+
+guint
+gtk_separator_get_type ()
+{
+  static guint separator_type = 0;
+
+  if (!separator_type)
+    {
+      GtkTypeInfo separator_info =
+      {
+       "GtkSeparator",
+       sizeof (GtkSeparator),
+       sizeof (GtkSeparatorClass),
+       (GtkClassInitFunc) gtk_separator_class_init,
+       (GtkObjectInitFunc) gtk_separator_init,
+       (GtkArgFunc) NULL,
+      };
+
+      separator_type = gtk_type_unique (gtk_widget_get_type (), &separator_info);
+    }
+
+  return separator_type;
+}
+
+static void
+gtk_separator_class_init (GtkSeparatorClass *class)
+{
+}
+
+static void
+gtk_separator_init (GtkSeparator *separator)
+{
+  GTK_WIDGET_SET_FLAGS (separator, GTK_NO_WINDOW | GTK_BASIC);
+}
diff --git a/gtk/gtkseparator.h b/gtk/gtkseparator.h
new file mode 100644 (file)
index 0000000..bfccd33
--- /dev/null
@@ -0,0 +1,58 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_SEPARATOR_H__
+#define __GTK_SEPARATOR_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkwidget.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_SEPARATOR(obj)          GTK_CHECK_CAST (obj, gtk_separator_get_type (), GtkSeparator)
+#define GTK_SEPARATOR_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_separator_get_type (), GtkSeparatorClass)
+#define GTK_IS_SEPARATOR(obj)       GTK_CHECK_TYPE (obj, gtk_separator_get_type ())
+
+
+typedef struct _GtkSeparator       GtkSeparator;
+typedef struct _GtkSeparatorClass  GtkSeparatorClass;
+
+struct _GtkSeparator
+{
+  GtkWidget widget;
+};
+
+struct _GtkSeparatorClass
+{
+  GtkWidgetClass parent_class;
+};
+
+
+guint  gtk_separator_get_type (void);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_SEPARATOR_H__ */
diff --git a/gtk/gtksignal.c b/gtk/gtksignal.c
new file mode 100644 (file)
index 0000000..65efdb9
--- /dev/null
@@ -0,0 +1,1322 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdarg.h>
+#include "gtksignal.h"
+
+
+#define MAX_PARAMS       20
+#define DONE             1
+#define RESTART          2
+
+#define GTK_RUN_TYPE(x)  ((x) & GTK_RUN_MASK)
+
+
+typedef struct _GtkSignal       GtkSignal;
+typedef struct _GtkSignalInfo   GtkSignalInfo;
+typedef struct _GtkHandler      GtkHandler;
+typedef struct _GtkHandlerInfo  GtkHandlerInfo;
+typedef struct _GtkEmission     GtkEmission;
+
+typedef void (*GtkSignalMarshaller0) (GtkObject *object,
+                                     gpointer   data);
+
+struct _GtkSignalInfo
+{
+  gchar *name;
+  gint object_type;
+  gint signal_type;
+};
+
+struct _GtkSignal
+{
+  GtkSignalInfo info;
+  gint function_offset;
+  GtkSignalRunType run_type;
+  GtkSignalMarshaller marshaller;
+  GtkType return_val;
+  GtkType *params;
+  gint nparams;
+};
+
+struct _GtkHandler
+{
+  guint16 id;
+  guint signal_type : 13;
+  guint object_signal : 1;
+  guint blocked : 1;
+  guint after : 1;
+  guint no_marshal : 1;
+  GtkSignalFunc func;
+  gpointer func_data;
+  GtkSignalDestroy destroy_func;
+  GtkHandler *next;
+};
+
+struct _GtkHandlerInfo
+{
+  GtkObject *object;
+  GtkSignalMarshaller marshaller;
+  GtkArg *params;
+  GtkType *param_types;
+  GtkType return_val;
+  GtkSignalRunType run_type;
+  gint nparams;
+  gint signal_type;
+};
+
+struct _GtkEmission
+{
+  GtkObject *object;
+  gint signal_type;
+};
+
+
+static void         gtk_signal_init            (void);
+static guint        gtk_signal_hash            (gint          *key);
+static gint         gtk_signal_compare         (gint          *a,
+                                               gint          *b);
+static guint        gtk_signal_info_hash       (GtkSignalInfo *a);
+static gint         gtk_signal_info_compare    (GtkSignalInfo *a,
+                                               GtkSignalInfo *b);
+static GtkHandler*  gtk_signal_handler_new     (void);
+static void         gtk_signal_handler_destroy (GtkHandler    *handler);
+static void         gtk_signal_handler_insert  (GtkObject     *object,
+                                               GtkHandler    *handler);
+static gint         gtk_signal_real_emit       (GtkObject     *object,
+                                               gint           signal_type,
+                                               va_list        args);
+static GtkHandler*  gtk_signal_get_handlers    (GtkObject     *object,
+                                               gint           signal_type);
+static gint         gtk_signal_connect_by_type (GtkObject     *object,
+                                               gint           signal_type,
+                                               gint           object_signal,
+                                               GtkSignalFunc  func,
+                                               gpointer       func_data,
+                                               GtkSignalDestroy destroy_func,
+                                               gint           after,
+                                               gint           no_marshal);
+static GtkEmission* gtk_emission_new           (void);
+static void         gtk_emission_destroy       (GtkEmission    *emission);
+static void         gtk_emission_add           (GList         **emissions,
+                                               GtkObject      *object,
+                                               gint            signal_type);
+static void         gtk_emission_remove        (GList         **emissions,
+                                               GtkObject      *object,
+                                               gint            signal_type);
+static gint         gtk_emission_check         (GList          *emissions,
+                                               GtkObject      *object,
+                                               gint            signal_type);
+static gint         gtk_handlers_run           (GtkHandler     *handlers,
+                                               GtkHandlerInfo *info,
+                                               gint            after);
+static void         gtk_params_get             (GtkArg         *params,
+                                               gint            nparams,
+                                               GtkType        *param_types,
+                                               GtkType         return_val,
+                                               va_list         args);
+
+
+static gint initialize = TRUE;
+static GHashTable *signal_hash_table = NULL;
+static GHashTable *signal_info_hash_table = NULL;
+static gint next_signal = 1;
+static gint next_handler_id = 1;
+
+static const char *handler_key = "signal_handlers";
+
+static GMemChunk *handler_mem_chunk = NULL;
+static GMemChunk *emission_mem_chunk = NULL;
+
+static GList *current_emissions = NULL;
+static GList *stop_emissions = NULL;
+static GList *restart_emissions = NULL;
+
+static GtkSignalMarshal marshal = NULL;
+static GtkSignalDestroy destroy = NULL;
+
+
+gint
+gtk_signal_new (const gchar         *name,
+               GtkSignalRunType     run_type,
+               gint                 object_type,
+               gint                 function_offset,
+               GtkSignalMarshaller  marshaller,
+               GtkType              return_val,
+               gint                 nparams,
+               ...)
+{
+  GtkType *params;
+  GtkSignal *signal;
+  GtkSignalInfo info;
+  gint *type;
+  gint i;
+  va_list args;
+
+  g_return_val_if_fail (name != NULL, 0);
+  g_return_val_if_fail (marshaller != NULL, 0);
+  g_return_val_if_fail (nparams < 10, 0);
+
+  if (initialize)
+    gtk_signal_init ();
+
+  info.name = (char*)name;
+  info.object_type = object_type;
+
+  type = g_hash_table_lookup (signal_info_hash_table, &info);
+  if (type)
+    {
+      g_warning ("signal \"%s\" already exists in the \"%s\" class ancestry\n",
+                name, gtk_type_name (object_type));
+      return 0;
+    }
+
+  signal = g_new (GtkSignal, 1);
+  signal->info.name = g_strdup(name);
+  signal->info.object_type = object_type;
+  signal->info.signal_type = next_signal++;
+  signal->function_offset = function_offset;
+  signal->run_type = run_type;
+  signal->marshaller = marshaller;
+  signal->return_val = return_val;
+  signal->params = NULL;
+  signal->nparams = nparams;
+
+  g_hash_table_insert (signal_hash_table, &signal->info.signal_type, signal);
+  g_hash_table_insert (signal_info_hash_table, &signal->info, &signal->info.signal_type);
+
+  if (nparams > 0)
+    {
+      signal->params = g_new (GtkType, nparams);
+      params = signal->params;
+
+      va_start (args, nparams);
+
+      for (i = 0; i < nparams; i++)
+       params[i] = va_arg (args, GtkType);
+
+      va_end (args);
+    }
+
+  return signal->info.signal_type;
+}
+
+gint
+gtk_signal_lookup (const gchar *name,
+                  gint         object_type)
+{
+  GtkSignalInfo info;
+  gint *type;
+
+  g_return_val_if_fail (name != NULL, 0);
+
+  if (initialize)
+    gtk_signal_init ();
+
+  info.name = (char*)name;
+
+  while (object_type)
+    {
+      info.object_type = object_type;
+
+      type = g_hash_table_lookup (signal_info_hash_table, &info);
+      if (type)
+       return *type;
+
+      object_type = gtk_type_parent (object_type);
+    }
+
+  return 0;
+}
+
+gchar*
+gtk_signal_name (gint signal_num)
+{
+  GtkSignal *signal;
+
+  signal = g_hash_table_lookup (signal_hash_table, &signal_num);
+  if (signal)
+    return signal->info.name;
+
+  return NULL;
+}
+
+gint
+gtk_signal_emit (GtkObject *object,
+                gint       signal_type,
+                ...)
+{
+  gint return_val;
+
+  va_list args;
+
+  g_return_val_if_fail (object != NULL, FALSE);
+
+  if (initialize)
+    gtk_signal_init ();
+
+  va_start (args, signal_type);
+
+  return_val = gtk_signal_real_emit (object, signal_type, args);
+
+  va_end (args);
+
+  return return_val;
+}
+
+gint
+gtk_signal_emit_by_name (GtkObject       *object,
+                        const gchar     *name,
+                        ...)
+{
+  gint return_val;
+  gint type;
+  va_list args;
+
+  g_return_val_if_fail (object != NULL, FALSE);
+
+  if (initialize)
+    gtk_signal_init ();
+
+  return_val = TRUE;
+  type = gtk_signal_lookup (name, GTK_OBJECT_TYPE (object));
+
+  if (type)
+    {
+      va_start (args, name);
+
+      return_val = gtk_signal_real_emit (object, type, args);
+
+      va_end (args);
+    }
+
+  return return_val;
+}
+
+void
+gtk_signal_emit_stop (GtkObject *object,
+                     gint       signal_type)
+{
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (signal_type >= 1);
+
+  if (initialize)
+    gtk_signal_init ();
+
+  if (gtk_emission_check (current_emissions, object, signal_type))
+    gtk_emission_add (&stop_emissions, object, signal_type);
+}
+
+void
+gtk_signal_emit_stop_by_name (GtkObject       *object,
+                             const gchar     *name)
+{
+  gint type;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (name != NULL);
+
+  if (initialize)
+    gtk_signal_init ();
+
+  type = gtk_signal_lookup (name, GTK_OBJECT_TYPE (object));
+  if (type)
+    gtk_signal_emit_stop (object, type);
+}
+
+gint
+gtk_signal_connect (GtkObject     *object,
+                   const gchar   *name,
+                   GtkSignalFunc  func,
+                   gpointer       func_data)
+{
+  gint type;
+
+  g_return_val_if_fail (object != NULL, 0);
+
+  if (initialize)
+    gtk_signal_init ();
+
+  type = gtk_signal_lookup (name, GTK_OBJECT_TYPE (object));
+  if (!type)
+    {
+      g_warning ("could not find signal type \"%s\" in the \"%s\" class ancestry",
+                name, gtk_type_name (GTK_OBJECT_TYPE (object)));
+      return 0;
+    }
+
+  return gtk_signal_connect_by_type (object, type, FALSE,
+                                    func, func_data, NULL,
+                                    FALSE, FALSE);
+}
+
+gint
+gtk_signal_connect_after (GtkObject     *object,
+                         const gchar   *name,
+                         GtkSignalFunc  func,
+                         gpointer       func_data)
+{
+  gint type;
+
+  g_return_val_if_fail (object != NULL, 0);
+
+  if (initialize)
+    gtk_signal_init ();
+
+  type = gtk_signal_lookup (name, GTK_OBJECT_TYPE (object));
+  if (!type)
+    {
+      g_warning ("could not find signal type \"%s\" in the \"%s\" class ancestry",
+                name, gtk_type_name (GTK_OBJECT_TYPE (object)));
+      return 0;
+    }
+
+  return gtk_signal_connect_by_type (object, type, FALSE,
+                                    func, func_data, NULL,
+                                    TRUE, FALSE);
+}
+
+gint
+gtk_signal_connect_interp (GtkObject         *object,
+                          gchar             *name,
+                          GtkCallbackMarshal func,
+                          gpointer           func_data,
+                          GtkDestroyNotify   destroy_func,
+                          gint               after)
+{
+  gint type;
+
+  g_return_val_if_fail (object != NULL, 0);
+
+  if (initialize)
+    gtk_signal_init ();
+
+  type = gtk_signal_lookup (name, GTK_OBJECT_TYPE (object));
+  if (!type)
+    {
+      g_warning ("could not find signal type \"%s\" in the \"%s\" class ancestry",
+                name, gtk_type_name (GTK_OBJECT_TYPE (object)));
+      return 0;
+    }
+
+  return gtk_signal_connect_by_type (object, type, FALSE,
+                                    (GtkSignalFunc) func, func_data,
+                                    destroy_func, after, TRUE);
+}
+
+gint
+gtk_signal_connect_object (GtkObject     *object,
+                          const gchar   *name,
+                          GtkSignalFunc  func,
+                          GtkObject     *slot_object)
+{
+  gint type;
+
+  g_return_val_if_fail (object != NULL, 0);
+
+  if (initialize)
+    gtk_signal_init ();
+
+  type = gtk_signal_lookup (name, GTK_OBJECT_TYPE (object));
+  if (!type)
+    {
+      g_warning ("could not find signal type \"%s\" in the \"%s\" class ancestry",
+                name, gtk_type_name (GTK_OBJECT_TYPE (object)));
+      return 0;
+    }
+
+  return gtk_signal_connect_by_type (object, type, TRUE,
+                                    func, slot_object, NULL,
+                                    FALSE, FALSE);
+}
+
+gint
+gtk_signal_connect_object_after (GtkObject     *object,
+                                const gchar   *name,
+                                GtkSignalFunc  func,
+                                GtkObject     *slot_object)
+{
+  gint type;
+
+  g_return_val_if_fail (object != NULL, 0);
+
+  if (initialize)
+    gtk_signal_init ();
+
+  type = gtk_signal_lookup (name, GTK_OBJECT_TYPE (object));
+  if (!type)
+    {
+      g_warning ("could not find signal type \"%s\" in the \"%s\" class ancestry",
+                name, gtk_type_name (GTK_OBJECT_TYPE (object)));
+      return 0;
+    }
+
+  return gtk_signal_connect_by_type (object, type, TRUE,
+                                    func, slot_object, NULL,
+                                    TRUE, FALSE);
+}
+
+void
+gtk_signal_disconnect (GtkObject *object,
+                      gint       anid)
+{
+  GtkHandler *tmp;
+  GtkHandler *prev;
+
+  g_return_if_fail (object != NULL);
+
+  if (initialize)
+    gtk_signal_init ();
+
+  prev = NULL;
+  tmp = gtk_object_get_data (object, handler_key);
+
+  while (tmp)
+    {
+      if (tmp->id == anid)
+       {
+         if (prev)
+           prev->next = tmp->next;
+         else
+           gtk_object_set_data (object, handler_key, tmp->next);
+         gtk_signal_handler_destroy (tmp);
+         return;
+       }
+
+      prev = tmp;
+      tmp = tmp->next;
+    }
+
+  g_warning ("could not find handler (%d)", anid);
+}
+
+void
+gtk_signal_disconnect_by_data (GtkObject *object,
+                              gpointer   data)
+{
+  GtkHandler *start;
+  GtkHandler *tmp;
+  GtkHandler *prev;
+  gint found_one;
+
+  g_return_if_fail (object != NULL);
+
+  if (initialize)
+    gtk_signal_init ();
+
+  prev = NULL;
+  start = gtk_object_get_data (object, handler_key);
+  tmp = start;
+  found_one = FALSE;
+
+  while (tmp)
+    {
+      if (tmp->func_data == data)
+       {
+         found_one = TRUE;
+
+         if (prev)
+           prev->next = tmp->next;
+         else
+           start = tmp->next;
+
+         gtk_signal_handler_destroy (tmp);
+
+         if (prev)
+           {
+             tmp = prev->next;
+           }
+         else
+           {
+             prev = NULL;
+             tmp = start;
+           }
+       }
+      else
+       {
+         prev = tmp;
+         tmp = tmp->next;
+       }
+    }
+
+  gtk_object_set_data (object, handler_key, start);
+
+  if (!found_one)
+    g_warning ("could not find handler containing data (0x%0lX)", (long) data);
+}
+
+void
+gtk_signal_handler_block (GtkObject *object,
+                         gint      anid)
+{
+  GtkHandler *tmp;
+
+  g_return_if_fail (object != NULL);
+
+  if (initialize)
+    gtk_signal_init ();
+
+  tmp = gtk_object_get_data (object, handler_key);
+
+  while (tmp)
+    {
+      if (tmp->id == anid)
+       {
+         tmp->blocked = TRUE;
+         return;
+       }
+
+      tmp = tmp->next;
+    }
+
+  g_warning ("could not find handler (%d)", anid);
+}
+
+void
+gtk_signal_handler_block_by_data (GtkObject *object,
+                                 gpointer   data)
+{
+  GtkHandler *tmp;
+  gint found_one;
+
+  g_return_if_fail (object != NULL);
+
+  if (initialize)
+    gtk_signal_init ();
+
+  found_one = FALSE;
+  tmp = gtk_object_get_data (object, handler_key);
+
+  while (tmp)
+    {
+      if (tmp->func_data == data)
+       {
+         tmp->blocked = TRUE;
+         found_one = TRUE;
+       }
+
+      tmp = tmp->next;
+    }
+
+  if (!found_one)
+    g_warning ("could not find handler containing data (0x%0lX)", (long) data);
+}
+
+void
+gtk_signal_handler_unblock (GtkObject *object,
+                           gint       anid)
+{
+  GtkHandler *tmp;
+
+  g_return_if_fail (object != NULL);
+
+  if (initialize)
+    gtk_signal_init ();
+
+  tmp = gtk_object_get_data (object, handler_key);
+
+  while (tmp)
+    {
+      if (tmp->id == anid)
+       {
+         tmp->blocked = FALSE;
+         return;
+       }
+
+      tmp = tmp->next;
+    }
+
+  g_warning ("could not find handler (%d)", anid);
+}
+
+void
+gtk_signal_handler_unblock_by_data (GtkObject *object,
+                                   gpointer   data)
+{
+  GtkHandler *tmp;
+  gint found_one;
+
+  g_return_if_fail (object != NULL);
+
+  if (initialize)
+    gtk_signal_init ();
+
+  found_one = FALSE;
+  tmp = gtk_object_get_data (object, handler_key);
+
+  while (tmp)
+    {
+      if (tmp->func_data == data)
+       {
+         tmp->blocked = FALSE;
+         found_one = TRUE;
+       }
+
+      tmp = tmp->next;
+    }
+
+  if (!found_one)
+    g_warning ("could not find handler containing data (0x%0lX)", (long) data);
+}
+
+void
+gtk_signal_handlers_destroy (GtkObject *object)
+{
+  GtkHandler *list;
+  GtkHandler *handler;
+
+  list = gtk_object_get_data (object, handler_key);
+  if (list)
+    {
+      while (list)
+       {
+         handler = list->next;
+         gtk_signal_handler_destroy (list);
+         list = handler;
+       }
+
+      gtk_object_remove_data (object, handler_key);
+    }
+}
+
+void
+gtk_signal_default_marshaller (GtkObject      *object,
+                              GtkSignalFunc   func,
+                              gpointer        func_data,
+                              GtkArg         *params)
+{
+  GtkSignalMarshaller0 rfunc;
+
+  rfunc = (GtkSignalMarshaller0) func;
+
+  (* rfunc) (object, func_data);
+}
+
+void
+gtk_signal_set_funcs (GtkSignalMarshal marshal_func,
+                     GtkSignalDestroy destroy_func)
+{
+  marshal = marshal_func;
+  destroy = destroy_func;
+}
+
+
+static void
+gtk_signal_init ()
+{
+  if (initialize)
+    {
+      initialize = FALSE;
+      signal_hash_table = g_hash_table_new ((GHashFunc) gtk_signal_hash,
+                                           (GCompareFunc) gtk_signal_compare);
+      signal_info_hash_table = g_hash_table_new ((GHashFunc) gtk_signal_info_hash,
+                                                (GCompareFunc) gtk_signal_info_compare);
+    }
+}
+
+static guint
+gtk_signal_hash (gint *key)
+{
+  return (guint) *key;
+}
+
+static gint
+gtk_signal_compare (gint *a,
+                   gint *b)
+{
+  return (*a == *b);
+}
+
+static guint
+gtk_signal_info_hash (GtkSignalInfo *a)
+{
+  return (g_string_hash (a->name) + a->object_type);
+}
+
+static gint
+gtk_signal_info_compare (GtkSignalInfo *a,
+                        GtkSignalInfo *b)
+{
+  return ((a->object_type == b->object_type) &&
+         g_string_equal (a->name, b->name));
+}
+
+static GtkHandler*
+gtk_signal_handler_new ()
+{
+  GtkHandler *handler;
+
+  if (!handler_mem_chunk)
+    handler_mem_chunk = g_mem_chunk_new ("handler mem chunk", sizeof (GtkHandler),
+                                        1024, G_ALLOC_AND_FREE);
+
+  handler = g_chunk_new (GtkHandler, handler_mem_chunk);
+
+  handler->id = 0;
+  handler->signal_type = 0;
+  handler->object_signal = FALSE;
+  handler->blocked = FALSE;
+  handler->after = FALSE;
+  handler->no_marshal = FALSE;
+  handler->func = NULL;
+  handler->func_data = NULL;
+  handler->destroy_func = NULL;
+  handler->next = NULL;
+
+  return handler;
+}
+
+static void
+gtk_signal_handler_destroy (GtkHandler *handler)
+{
+  if (!handler->func && destroy)
+    (* destroy) (handler->func_data);
+  else if (handler->destroy_func)
+    (* handler->destroy_func) (handler->func_data);
+  g_mem_chunk_free (handler_mem_chunk, handler);
+}
+
+static void
+gtk_signal_handler_insert (GtkObject  *object,
+                          GtkHandler *handler)
+{
+  GtkHandler *start;
+  GtkHandler *tmp;
+  GtkHandler *prev;
+
+  start = gtk_object_get_data (object, handler_key);
+  if (!start)
+    {
+      gtk_object_set_data (object, handler_key, handler);
+    }
+  else
+    {
+      prev = NULL;
+      tmp = start;
+
+      while (tmp)
+       {
+         if (tmp->signal_type < handler->signal_type)
+           {
+             if (prev)
+               prev->next = handler;
+             else
+               gtk_object_set_data (object, handler_key, handler);
+             handler->next = tmp;
+             break;
+           }
+
+         if (!tmp->next)
+           {
+             tmp->next = handler;
+             break;
+           }
+
+         prev = tmp;
+         tmp = tmp->next;
+       }
+    }
+}
+
+static gint
+gtk_signal_real_emit (GtkObject *object,
+                     gint       signal_type,
+                     va_list    args)
+{
+  gint old_value;
+  GtkSignal *signal;
+  GtkHandler *handlers;
+  GtkHandlerInfo info;
+  guchar **signal_func_offset;
+  gint being_destroyed;
+  GtkArg         params[MAX_PARAMS];
+
+  g_return_val_if_fail (object != NULL, FALSE);
+  g_return_val_if_fail (signal_type >= 1, TRUE);
+
+  being_destroyed = GTK_OBJECT_BEING_DESTROYED (object);
+  if (!GTK_OBJECT_NEED_DESTROY (object))
+    {
+      signal = g_hash_table_lookup (signal_hash_table, &signal_type);
+      g_return_val_if_fail (signal != NULL, TRUE);
+      g_return_val_if_fail (gtk_type_is_a (GTK_OBJECT_TYPE (object), signal->info.object_type), TRUE);
+
+      if ((signal->run_type & GTK_RUN_NO_RECURSE) &&
+         gtk_emission_check (current_emissions, object, signal_type))
+       {
+         gtk_emission_add (&restart_emissions, object, signal_type);
+         return TRUE;
+       }
+
+      old_value = GTK_OBJECT_IN_CALL (object);
+      GTK_OBJECT_SET_FLAGS (object, GTK_IN_CALL);
+
+      gtk_params_get (params, signal->nparams, signal->params, signal->return_val, args);
+
+      gtk_emission_add (&current_emissions, object, signal_type);
+
+    restart:
+      if (GTK_RUN_TYPE (signal->run_type) != GTK_RUN_LAST)
+       {
+         signal_func_offset = (guchar**) ((guchar*) object->klass + signal->function_offset);
+         if (*signal_func_offset)
+           (* signal->marshaller) (object, (GtkSignalFunc) *signal_func_offset, NULL, params);
+         if (GTK_OBJECT_NEED_DESTROY (object))
+           goto done;
+       }
+
+      info.object = object;
+      info.marshaller = signal->marshaller;
+      info.params = params;
+      info.param_types = signal->params;
+      info.return_val = signal->return_val;
+      info.nparams = signal->nparams;
+      info.run_type = signal->run_type;
+      info.signal_type = signal_type;
+
+      handlers = gtk_signal_get_handlers (object, signal_type);
+      switch (gtk_handlers_run (handlers, &info, FALSE))
+       {
+       case DONE:
+         goto done;
+       case RESTART:
+         goto restart;
+       }
+
+      if (GTK_RUN_TYPE (signal->run_type) != GTK_RUN_FIRST)
+       {
+         signal_func_offset = (guchar**) ((guchar*) object->klass + signal->function_offset);
+         if (*signal_func_offset)
+           (* signal->marshaller) (object, (GtkSignalFunc) *signal_func_offset, NULL, params);
+         if (being_destroyed || GTK_OBJECT_NEED_DESTROY (object))
+           goto done;
+       }
+
+      switch (gtk_handlers_run (handlers, &info, TRUE))
+       {
+       case DONE:
+         goto done;
+       case RESTART:
+         goto restart;
+       }
+
+    done:
+      gtk_emission_remove (&current_emissions, object, signal_type);
+
+      if (signal->run_type & GTK_RUN_NO_RECURSE)
+       gtk_emission_remove (&restart_emissions, object, signal_type);
+
+      if (!being_destroyed && !old_value)
+       GTK_OBJECT_UNSET_FLAGS (object, GTK_IN_CALL);
+    }
+
+  if (!being_destroyed && GTK_OBJECT_NEED_DESTROY (object) && !GTK_OBJECT_IN_CALL (object))
+    {
+      gtk_object_destroy (object);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+static GtkHandler*
+gtk_signal_get_handlers (GtkObject *object,
+                        gint       signal_type)
+{
+  GtkHandler *handlers;
+
+  g_return_val_if_fail (object != NULL, NULL);
+  g_return_val_if_fail (signal_type >= 1, NULL);
+
+  handlers = gtk_object_get_data (object, handler_key);
+
+  while (handlers)
+    {
+      if (handlers->signal_type == signal_type)
+       return handlers;
+      handlers = handlers->next;
+    }
+
+  return NULL;
+}
+
+static gint
+gtk_signal_connect_by_type (GtkObject       *object,
+                           gint             signal_type,
+                           gint             object_signal,
+                           GtkSignalFunc    func,
+                           gpointer         func_data,
+                           GtkSignalDestroy destroy_func,
+                           gint             after,
+                           gint             no_marshal)
+{
+  GtkHandler *handler;
+  gint *object_signals;
+  gint nsignals;
+  gint found_it;
+  gint i;
+
+  g_return_val_if_fail (object != NULL, 0);
+  g_return_val_if_fail (object->klass != NULL, 0);
+  g_return_val_if_fail (object->klass->signals != NULL, 0);
+
+  /* Search through the signals for this object and make
+   *  sure the one we are adding is valid. If it isn't then
+   *  issue a warning and return.
+   */
+  object_signals = object->klass->signals;
+  nsignals = object->klass->nsignals;
+  found_it = FALSE;
+
+  for (i = 0; i < nsignals; i++)
+    if (object_signals[i] == signal_type)
+      {
+       found_it = TRUE;
+       break;
+      }
+
+  if (!found_it)
+    {
+      g_warning ("could not find signal (%d) in object's list of signals", signal_type);
+      return 0;
+    }
+
+  handler = gtk_signal_handler_new ();
+  handler->id = next_handler_id++;
+  handler->signal_type = signal_type;
+  handler->object_signal = object_signal;
+  handler->func = func;
+  handler->func_data = func_data;
+  handler->destroy_func = destroy_func;
+
+  if (after)
+    handler->after = TRUE;
+  handler->no_marshal = no_marshal;
+
+  gtk_signal_handler_insert (object, handler);
+  return handler->id;
+}
+
+static GtkEmission*
+gtk_emission_new ()
+{
+  GtkEmission *emission;
+
+  if (!emission_mem_chunk)
+    emission_mem_chunk = g_mem_chunk_new ("emission mem chunk", sizeof (GtkEmission),
+                                         1024, G_ALLOC_AND_FREE);
+
+  emission = g_chunk_new (GtkEmission, emission_mem_chunk);
+
+  emission->object = NULL;
+  emission->signal_type = 0;
+
+  return emission;
+}
+
+static void
+gtk_emission_destroy (GtkEmission *emission)
+{
+  g_mem_chunk_free (emission_mem_chunk, emission);
+}
+
+static void
+gtk_emission_add (GList     **emissions,
+                 GtkObject  *object,
+                 gint        signal_type)
+{
+  GtkEmission *emission;
+
+  g_return_if_fail (emissions != NULL);
+  g_return_if_fail (object != NULL);
+
+  emission = gtk_emission_new ();
+  emission->object = object;
+  emission->signal_type = signal_type;
+
+  *emissions = g_list_prepend (*emissions, emission);
+}
+
+static void
+gtk_emission_remove (GList     **emissions,
+                    GtkObject  *object,
+                    gint        signal_type)
+{
+  GtkEmission *emission;
+  GList *tmp;
+
+  g_return_if_fail (emissions != NULL);
+  g_return_if_fail (object != NULL);
+
+  tmp = *emissions;
+  while (tmp)
+    {
+      emission = tmp->data;
+
+      if ((emission->object == object) &&
+         (emission->signal_type == signal_type))
+       {
+         gtk_emission_destroy (emission);
+         *emissions = g_list_remove_link (*emissions, tmp);
+         g_list_free (tmp);
+         break;
+       }
+
+      tmp = tmp->next;
+    }
+}
+
+static gint
+gtk_emission_check (GList     *emissions,
+                   GtkObject *object,
+                   gint       signal_type)
+{
+  GtkEmission *emission;
+  GList *tmp;
+
+  g_return_val_if_fail (object != NULL, FALSE);
+
+  tmp = emissions;
+  while (tmp)
+    {
+      emission = tmp->data;
+      tmp = tmp->next;
+
+      if ((emission->object == object) &&
+         (emission->signal_type == signal_type))
+       return TRUE;
+    }
+  return FALSE;
+}
+
+static gint
+gtk_handlers_run (GtkHandler     *handlers,
+                 GtkHandlerInfo *info,
+                 gint            after)
+{
+  while (handlers && (handlers->signal_type == info->signal_type))
+    {
+      if (!handlers->blocked && (handlers->after == after))
+       {
+         if (handlers->func)
+           {
+             if (handlers->no_marshal)
+               (* (GtkCallbackMarshal)handlers->func) (info->object,
+                                                       handlers->func_data,
+                                                       info->nparams,
+                                                       info->params);
+             else if (handlers->object_signal)
+               (* info->marshaller) (GTK_OBJECT (handlers->func_data),
+                                     handlers->func,
+                                     handlers->func_data,
+                                     info->params);
+             else
+               (* info->marshaller) (info->object,
+                                     handlers->func,
+                                     handlers->func_data,
+                                     info->params);
+           }
+         else if (marshal)
+           (* marshal) (info->object,
+                        handlers->func_data,
+                        info->nparams,
+                        info->params,
+                        info->param_types,
+                        info->return_val);
+
+         if (GTK_OBJECT_NEED_DESTROY (info->object))
+           return DONE;
+         else if (gtk_emission_check (stop_emissions, info->object, info->signal_type))
+           {
+             gtk_emission_remove (&stop_emissions, info->object, info->signal_type);
+
+             if (info->run_type & GTK_RUN_NO_RECURSE)
+               gtk_emission_remove (&restart_emissions, info->object, info->signal_type);
+             return DONE;
+           }
+         else if ((info->run_type & GTK_RUN_NO_RECURSE) &&
+                  gtk_emission_check (restart_emissions, info->object, info->signal_type))
+           {
+             gtk_emission_remove (&restart_emissions, info->object, info->signal_type);
+             return RESTART;
+           }
+       }
+
+      handlers = handlers->next;
+    }
+
+  return 0;
+}
+
+static void
+gtk_params_get (GtkArg         *params,
+               gint            nparams,
+               GtkType        *param_types,
+               GtkType         return_val,
+               va_list         args)
+{
+  int i;
+
+  for (i = 0; i < nparams; i++)
+    {
+      if (param_types[i] != GTK_TYPE_NONE)
+       {
+         params[i].type = param_types[i];
+         params[i].name = NULL;
+       }
+
+      switch (GTK_FUNDAMENTAL_TYPE (param_types[i]))
+       {
+       case GTK_TYPE_INVALID:
+         break;
+       case GTK_TYPE_NONE:
+         break;
+       case GTK_TYPE_CHAR:
+         GTK_VALUE_CHAR(params[i]) = va_arg (args, gint);
+         break;
+       case GTK_TYPE_BOOL:
+         GTK_VALUE_BOOL(params[i]) = va_arg (args, gint);
+         break;
+       case GTK_TYPE_INT:
+         GTK_VALUE_INT(params[i]) = va_arg (args, gint);
+         break;
+       case GTK_TYPE_UINT:
+         GTK_VALUE_UINT(params[i]) = va_arg (args, guint);
+         break;
+       case GTK_TYPE_ENUM:
+         GTK_VALUE_ENUM(params[i]) = va_arg (args, gint);
+         break;
+       case GTK_TYPE_FLAGS:
+         GTK_VALUE_FLAGS(params[i]) = va_arg (args, gint);
+         break;
+       case GTK_TYPE_LONG:
+         GTK_VALUE_LONG(params[i]) = va_arg (args, glong);
+         break;
+       case GTK_TYPE_ULONG:
+         GTK_VALUE_ULONG(params[i]) = va_arg (args, gulong);
+         break;
+       case GTK_TYPE_FLOAT:
+         GTK_VALUE_FLOAT(params[i]) = va_arg (args, gfloat);
+         break;
+       case GTK_TYPE_STRING:
+         GTK_VALUE_STRING(params[i]) = va_arg (args, gchar*);
+         break;
+       case GTK_TYPE_POINTER:
+         GTK_VALUE_POINTER(params[i]) = va_arg (args, gpointer);
+         break;
+       case GTK_TYPE_BOXED:
+         GTK_VALUE_BOXED(params[i]) = va_arg (args, gpointer);
+         break;
+       case GTK_TYPE_SIGNAL:
+         GTK_VALUE_SIGNAL(params[i]).f = va_arg (args, GtkFunction);
+         GTK_VALUE_SIGNAL(params[i]).d = va_arg (args, gpointer);
+         break;
+       case GTK_TYPE_FOREIGN:
+         GTK_VALUE_FOREIGN(params[i]).data = va_arg (args, gpointer);
+         GTK_VALUE_FOREIGN(params[i]).notify = 
+           va_arg (args, GtkDestroyNotify);
+         break;
+       case GTK_TYPE_CALLBACK:
+         GTK_VALUE_CALLBACK(params[i]).marshal = 
+           va_arg (args, GtkCallbackMarshal);
+         GTK_VALUE_CALLBACK(params[i]).data = va_arg (args, gpointer);
+         GTK_VALUE_CALLBACK(params[i]).notify =
+           va_arg (args, GtkDestroyNotify);
+         break;
+       case GTK_TYPE_C_CALLBACK:
+         GTK_VALUE_C_CALLBACK(params[i]).func = va_arg (args, GtkFunction);
+         GTK_VALUE_C_CALLBACK(params[i]).func_data = va_arg (args, gpointer);
+         break;
+       case GTK_TYPE_ARGS:
+         GTK_VALUE_ARGS(params[i]).n_args = va_arg (args, int);
+         GTK_VALUE_ARGS(params[i]).args = va_arg (args, GtkArg*);
+         break;
+       case GTK_TYPE_OBJECT:
+         GTK_VALUE_OBJECT(params[i]) = va_arg (args, GtkObject*);
+         g_assert (GTK_VALUE_OBJECT(params[i]) == NULL ||
+                   GTK_CHECK_TYPE (GTK_VALUE_OBJECT(params[i]),
+                                   params[i].type));
+         break;
+       default:
+         g_error ("unsupported type %s in signal arg",
+                  gtk_type_name (params[i].type));
+         break;
+       }
+    }
+
+  if (return_val != GTK_TYPE_NONE)
+    {
+      params[i].type = return_val;
+      params[i].name = NULL;
+    }
+
+  switch (GTK_FUNDAMENTAL_TYPE (return_val))
+    {
+    case GTK_TYPE_INVALID:
+      break;
+    case GTK_TYPE_NONE:
+      break;
+    case GTK_TYPE_CHAR:
+      params[i].d.pointer_data = va_arg (args, gchar*);
+      break;
+    case GTK_TYPE_BOOL:
+      params[i].d.pointer_data = va_arg (args, gint*);
+      break;
+    case GTK_TYPE_INT:
+      params[i].d.pointer_data = va_arg (args, gint*);
+      break;
+    case GTK_TYPE_UINT:
+      params[i].d.pointer_data = va_arg (args, guint*);
+      break;
+    case GTK_TYPE_ENUM:
+      params[i].d.pointer_data = va_arg (args, gint*);
+      break;
+    case GTK_TYPE_FLAGS:
+      params[i].d.pointer_data = va_arg (args, gint*);
+      break;
+    case GTK_TYPE_LONG:
+      params[i].d.pointer_data = va_arg (args, glong*);
+      break;
+    case GTK_TYPE_ULONG:
+      params[i].d.pointer_data = va_arg (args, gulong*);
+      break;
+    case GTK_TYPE_FLOAT:
+      params[i].d.pointer_data = va_arg (args, gfloat*);
+      break;
+    case GTK_TYPE_STRING:
+      params[i].d.pointer_data = va_arg (args, gchar**);
+      break;
+    case GTK_TYPE_POINTER:
+      params[i].d.pointer_data = va_arg (args, gpointer*);
+      break;
+    case GTK_TYPE_BOXED:
+      params[i].d.pointer_data = va_arg (args, gpointer*);
+      break;
+    case GTK_TYPE_OBJECT:
+      params[i].d.pointer_data = va_arg (args, GtkObject**);
+      break;
+    case GTK_TYPE_SIGNAL:
+    case GTK_TYPE_FOREIGN:
+    case GTK_TYPE_CALLBACK:
+    case GTK_TYPE_C_CALLBACK:
+    case GTK_TYPE_ARGS:
+    default:
+      g_error ("unsupported type %s in signal return",
+              gtk_type_name (return_val));
+      break;
+    }
+}
diff --git a/gtk/gtksignal.h b/gtk/gtksignal.h
new file mode 100644 (file)
index 0000000..68ff999
--- /dev/null
@@ -0,0 +1,124 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_SIGNAL_H__
+#define __GTK_SIGNAL_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkenums.h>
+#include <gtk/gtkobject.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#ifdef offsetof
+#define GTK_SIGNAL_OFFSET(t, f) ((int) offsetof (t, f))
+#else /* offsetof */
+#define GTK_SIGNAL_OFFSET(t, f) ((int) ((char*) &((t*) 0)->f))
+#endif /* offsetof */
+
+#define GTK_SIGNAL_FUNC(f)  ((GtkSignalFunc) f)
+
+
+typedef void (*GtkSignalFunc)       (void);
+typedef void (*GtkSignalMarshaller) (GtkObject      *object,
+                                    GtkSignalFunc   func,
+                                    gpointer        func_data,
+                                    GtkArg         *args);
+typedef void (*GtkSignalMarshal)    (GtkObject      *object,
+                                    gpointer        data,
+                                    gint            nparams,
+                                    GtkArg         *args,
+                                    GtkType        *arg_types,
+                                    GtkType         return_type);
+typedef void (*GtkSignalDestroy)    (gpointer        data);
+
+
+gint   gtk_signal_new                     (const gchar         *name,
+                                          GtkSignalRunType     run_type,
+                                          gint                 object_type,
+                                          gint                 function_offset,
+                                          GtkSignalMarshaller  marshaller,
+                                          GtkType              return_val,
+                                          gint                 nparams,
+                                          ...);
+gint   gtk_signal_lookup                  (const gchar         *name,
+                                          gint                 object_type);
+gchar* gtk_signal_name                    (gint                 signal_num);
+gint   gtk_signal_emit                    (GtkObject           *object,
+                                          gint                 signal_type,
+                                          ...);
+gint   gtk_signal_emit_by_name            (GtkObject           *object,
+                                          const gchar         *name,
+                                          ...);
+void   gtk_signal_emit_stop               (GtkObject           *object,
+                                          gint                 signal_type);
+void   gtk_signal_emit_stop_by_name       (GtkObject           *object,
+                                          const gchar         *name);
+gint   gtk_signal_connect                 (GtkObject           *object,
+                                          const gchar         *name,
+                                          GtkSignalFunc        func,
+                                          gpointer             func_data);
+gint   gtk_signal_connect_after           (GtkObject           *object,
+                                          const gchar         *name,
+                                          GtkSignalFunc        func,
+                                          gpointer             func_data);
+gint   gtk_signal_connect_object          (GtkObject           *object,
+                                          const gchar         *name,
+                                          GtkSignalFunc        func,
+                                          GtkObject           *slot_object);
+gint   gtk_signal_connect_object_after    (GtkObject           *object,
+                                          const gchar         *name,
+                                          GtkSignalFunc        func,
+                                          GtkObject           *slot_object);
+gint   gtk_signal_connect_interp          (GtkObject           *object,
+                                          gchar               *name,
+                                          GtkCallbackMarshal   func,
+                                          gpointer             data,
+                                          GtkDestroyNotify     destroy_func,
+                                          gint                 after);
+void   gtk_signal_disconnect              (GtkObject           *object,
+                                          gint                 anid);
+void   gtk_signal_disconnect_by_data      (GtkObject           *object,
+                                          gpointer             data);
+void   gtk_signal_handler_block           (GtkObject           *object,
+                                          gint                 anid);
+void   gtk_signal_handler_block_by_data   (GtkObject           *object,
+                                          gpointer             data);
+void   gtk_signal_handler_unblock         (GtkObject           *object,
+                                          gint                 anid);
+void   gtk_signal_handler_unblock_by_data (GtkObject           *object,
+                                          gpointer             data);
+void   gtk_signal_handlers_destroy        (GtkObject           *object);
+void   gtk_signal_default_marshaller      (GtkObject           *object,
+                                          GtkSignalFunc        func,
+                                          gpointer             func_data,
+                                          GtkArg              *args);
+void   gtk_signal_set_funcs               (GtkSignalMarshal     marshal_func,
+                                          GtkSignalDestroy     destroy_func);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_SIGNAL_H__ */
diff --git a/gtk/gtkstyle.c b/gtk/gtkstyle.c
new file mode 100644 (file)
index 0000000..ae8c1a5
--- /dev/null
@@ -0,0 +1,1795 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <math.h>
+#include "gtkgc.h"
+#include "gtkstyle.h"
+
+
+#define LIGHTNESS_MULT  1.3
+#define DARKNESS_MULT   0.7
+
+
+typedef struct _GtkStyleKey GtkStyleKey;
+
+struct _GtkStyleKey
+{
+  GdkColor fg[5];
+  GdkColor bg[5];
+  GdkColor text[5];
+  GdkColor base[5];
+
+  GdkPixmap *bg_pixmap[5];
+
+  GdkFont *font;
+
+  gint depth;
+  GdkColormap *colormap;
+  GtkStyleClass *klass;
+};
+
+
+static void         gtk_style_init         (GtkStyle    *style);
+static void         gtk_styles_init        (void);
+static void         gtk_style_remove       (GtkStyle    *style);
+static GtkStyle*    gtk_style_find         (GtkStyle    *style,
+                                           GdkColormap *cmap,
+                                           gint         depth);
+static GtkStyle*    gtk_style_new_from_key (GtkStyleKey *key);
+static GtkStyleKey* gtk_style_key_dup      (GtkStyleKey *key);
+static void         gtk_style_destroy      (GtkStyle    *style);
+static void         gtk_style_key_destroy  (GtkStyleKey *key);
+static guint        gtk_style_key_hash     (GtkStyleKey *key);
+static guint        gtk_style_value_hash   (GtkStyle    *style);
+static gint         gtk_style_key_compare  (GtkStyleKey *a,
+                                           GtkStyleKey *b);
+
+static void gtk_default_draw_hline   (GtkStyle      *style,
+                                     GdkWindow     *window,
+                                     GtkStateType   state_type,
+                                     gint           x1,
+                                     gint           x2,
+                                     gint           y);
+static void gtk_default_draw_vline   (GtkStyle      *style,
+                                     GdkWindow     *window,
+                                     GtkStateType   state_type,
+                                     gint           y1,
+                                     gint           y2,
+                                     gint           x);
+static void gtk_default_draw_shadow  (GtkStyle      *style,
+                                     GdkWindow     *window,
+                                     GtkStateType   state_type,
+                                     GtkShadowType  shadow_type,
+                                     gint           x,
+                                     gint           y,
+                                     gint           width,
+                                     gint           height);
+static void gtk_default_draw_polygon (GtkStyle      *style,
+                                     GdkWindow     *window,
+                                     GtkStateType   state_type,
+                                     GtkShadowType  shadow_type,
+                                     GdkPoint      *points,
+                                     gint           npoints,
+                                     gint           fill);
+static void gtk_default_draw_arrow   (GtkStyle      *style,
+                                     GdkWindow     *window,
+                                     GtkStateType   state_type,
+                                     GtkShadowType  shadow_type,
+                                     GtkArrowType   arrow_type,
+                                     gint           fill,
+                                     gint           x,
+                                     gint           y,
+                                     gint           width,
+                                     gint           height);
+static void gtk_default_draw_diamond (GtkStyle      *style,
+                                     GdkWindow     *window,
+                                     GtkStateType   state_type,
+                                     GtkShadowType  shadow_type,
+                                     gint           x,
+                                     gint           y,
+                                     gint           width,
+                                     gint           height);
+static void gtk_default_draw_oval    (GtkStyle      *style,
+                                     GdkWindow     *window,
+                                     GtkStateType   state_type,
+                                     GtkShadowType  shadow_type,
+                                     gint           x,
+                                     gint           y,
+                                     gint           width,
+                                     gint           height);
+static void gtk_default_draw_string  (GtkStyle      *style,
+                                     GdkWindow     *window,
+                                     GtkStateType   state_type,
+                                     gint           x,
+                                     gint           y,
+                                     const gchar   *string);
+
+static void gtk_style_shade (GdkColor *a, GdkColor *b, gdouble k);
+static void rgb_to_hls (gdouble *r, gdouble *g, gdouble *b);
+static void hls_to_rgb (gdouble *h, gdouble *l, gdouble *s);
+
+
+static GtkStyleClass default_class =
+{
+  2,
+  2,
+  gtk_default_draw_hline,
+  gtk_default_draw_vline,
+  gtk_default_draw_shadow,
+  gtk_default_draw_polygon,
+  gtk_default_draw_arrow,
+  gtk_default_draw_diamond,
+  gtk_default_draw_oval,
+  gtk_default_draw_string,
+};
+
+static GdkColor gtk_default_normal_fg =      { 0,      0,      0,      0 };
+static GdkColor gtk_default_active_fg =      { 0,      0,      0,      0 };
+static GdkColor gtk_default_prelight_fg =    { 0,      0,      0,      0 };
+static GdkColor gtk_default_selected_fg =    { 0, 0xffff, 0xffff, 0xffff };
+static GdkColor gtk_default_insensitive_fg = { 0, 0x7530, 0x7530, 0x7530 };
+
+static GdkColor gtk_default_normal_bg =      { 0, 0xd6d6, 0xd6d6, 0xd6d6 };
+static GdkColor gtk_default_active_bg =      { 0, 0xc350, 0xc350, 0xc350 };
+static GdkColor gtk_default_prelight_bg =    { 0, 0xea60, 0xea60, 0xea60 };
+static GdkColor gtk_default_selected_bg =    { 0,      0,      0, 0x9c40 };
+static GdkColor gtk_default_insensitive_bg = { 0, 0xd6d6, 0xd6d6, 0xd6d6 };
+
+static GdkFont *default_font = NULL;
+
+static gint initialize = TRUE;
+static GCache *style_cache = NULL;
+static GSList *unattached_styles = NULL;
+
+static GMemChunk *key_mem_chunk = NULL;
+
+
+GtkStyle*
+gtk_style_new ()
+{
+  GtkStyle *style;
+  gint i;
+
+  style = g_new (GtkStyle, 1);
+
+  if (!default_font)
+    default_font = gdk_font_load ("-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*");
+
+  style->font = default_font;
+  gdk_font_ref (style->font);
+
+  style->ref_count = 0;
+  style->attach_count = 0;
+  style->colormap = NULL;
+  style->depth = -1;
+  style->klass = &default_class;
+
+  style->black.red = 0;
+  style->black.green = 0;
+  style->black.blue = 0;
+
+  style->white.red = 65535;
+  style->white.green = 65535;
+  style->white.blue = 65535;
+
+  style->black_gc = NULL;
+  style->white_gc = NULL;
+
+  style->fg[GTK_STATE_NORMAL] = gtk_default_normal_fg;
+  style->fg[GTK_STATE_ACTIVE] = gtk_default_active_fg;
+  style->fg[GTK_STATE_PRELIGHT] = gtk_default_prelight_fg;
+  style->fg[GTK_STATE_SELECTED] = gtk_default_selected_fg;
+  style->fg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_fg;
+
+  style->bg[GTK_STATE_NORMAL] = gtk_default_normal_bg;
+  style->bg[GTK_STATE_ACTIVE] = gtk_default_active_bg;
+  style->bg[GTK_STATE_PRELIGHT] = gtk_default_prelight_bg;
+  style->bg[GTK_STATE_SELECTED] = gtk_default_selected_bg;
+  style->bg[GTK_STATE_INSENSITIVE] = gtk_default_insensitive_bg;
+
+  for (i = 0; i < 5; i++)
+    {
+      style->text[i] = style->fg[i];
+      style->base[i] = style->white;
+    }
+
+  for (i = 0; i < 5; i++)
+    style->bg_pixmap[i] = NULL;
+
+  for (i = 0; i < 5; i++)
+    {
+      style->fg_gc[i] = NULL;
+      style->bg_gc[i] = NULL;
+      style->light_gc[i] = NULL;
+      style->dark_gc[i] = NULL;
+      style->mid_gc[i] = NULL;
+      style->text_gc[i] = NULL;
+      style->base_gc[i] = NULL;
+    }
+
+  unattached_styles = g_slist_prepend (unattached_styles, style);
+
+  return style;
+}
+
+GtkStyle*
+gtk_style_attach (GtkStyle  *style,
+                 GdkWindow *window)
+{
+  GtkStyle *new_style;
+  GdkColormap *colormap;
+  gint depth;
+
+  g_return_val_if_fail (style != NULL, NULL);
+  g_return_val_if_fail (window != NULL, NULL);
+
+  colormap = gdk_window_get_colormap (window);
+  gdk_window_get_geometry (window, NULL, NULL, NULL, NULL, &depth);
+
+  new_style = gtk_style_find (style, colormap, depth);
+
+  if (new_style && (new_style != style))
+    {
+      gtk_style_unref (style);
+      style = new_style;
+      gtk_style_ref (style);
+    }
+
+  if (style->attach_count == 0)
+    unattached_styles = g_slist_remove (unattached_styles, style);
+
+  style->attach_count += 1;
+
+  return style;
+}
+
+void
+gtk_style_detach (GtkStyle *style)
+{
+  gint i;
+
+  g_return_if_fail (style != NULL);
+
+  style->attach_count -= 1;
+  if (style->attach_count == 0)
+    {
+      unattached_styles = g_slist_prepend (unattached_styles, style);
+
+      gtk_gc_release (style->black_gc);
+      gtk_gc_release (style->white_gc);
+
+      style->black_gc = NULL;
+      style->white_gc = NULL;
+
+      for (i = 0; i < 5; i++)
+       {
+         gtk_gc_release (style->fg_gc[i]);
+         gtk_gc_release (style->bg_gc[i]);
+         gtk_gc_release (style->light_gc[i]);
+         gtk_gc_release (style->dark_gc[i]);
+         gtk_gc_release (style->mid_gc[i]);
+         gtk_gc_release (style->text_gc[i]);
+         gtk_gc_release (style->base_gc[i]);
+
+         style->fg_gc[i] = NULL;
+         style->bg_gc[i] = NULL;
+         style->light_gc[i] = NULL;
+         style->dark_gc[i] = NULL;
+         style->mid_gc[i] = NULL;
+         style->text_gc[i] = NULL;
+         style->base_gc[i] = NULL;
+       }
+
+      style->depth = -1;
+      style->colormap = NULL;
+    }
+
+  gtk_style_remove (style);
+}
+
+GtkStyle*
+gtk_style_ref (GtkStyle *style)
+{
+  g_return_val_if_fail (style != NULL, NULL);
+
+  style->ref_count += 1;
+  return style;
+}
+
+void
+gtk_style_unref (GtkStyle *style)
+{
+  g_return_if_fail (style != NULL);
+
+  style->ref_count -= 1;
+  if (style->ref_count == 0)
+    gtk_style_destroy (style);
+}
+
+void
+gtk_style_set_background (GtkStyle     *style,
+                         GdkWindow    *window,
+                         GtkStateType  state_type)
+{
+  GdkPixmap *pixmap;
+  gint parent_relative;
+
+  g_return_if_fail (style != NULL);
+  g_return_if_fail (window != NULL);
+
+  if (style->bg_pixmap[state_type])
+    {
+      if (style->bg_pixmap[state_type] == (GdkPixmap*) GDK_PARENT_RELATIVE)
+       {
+         pixmap = NULL;
+         parent_relative = TRUE;
+       }
+      else
+       {
+         pixmap = style->bg_pixmap[state_type];
+         parent_relative = FALSE;
+       }
+
+      gdk_window_set_back_pixmap (window, pixmap, parent_relative);
+    }
+  else
+    gdk_window_set_background (window, &style->bg[state_type]);
+}
+
+
+void
+gtk_draw_hline (GtkStyle     *style,
+               GdkWindow    *window,
+               GtkStateType  state_type,
+               gint          x1,
+               gint          x2,
+               gint          y)
+{
+  g_return_if_fail (style != NULL);
+  g_return_if_fail (style->klass != NULL);
+  g_return_if_fail (style->klass->draw_hline != NULL);
+
+  (*style->klass->draw_hline) (style, window, state_type, x1, x2, y);
+}
+
+
+void
+gtk_draw_vline (GtkStyle     *style,
+               GdkWindow    *window,
+               GtkStateType  state_type,
+               gint          y1,
+               gint          y2,
+               gint          x)
+{
+  g_return_if_fail (style != NULL);
+  g_return_if_fail (style->klass != NULL);
+  g_return_if_fail (style->klass->draw_vline != NULL);
+
+  (*style->klass->draw_vline) (style, window, state_type, y1, y2, x);
+}
+
+
+void
+gtk_draw_shadow (GtkStyle      *style,
+                GdkWindow     *window,
+                GtkStateType   state_type,
+                GtkShadowType  shadow_type,
+                gint           x,
+                gint           y,
+                gint           width,
+                gint           height)
+{
+  g_return_if_fail (style != NULL);
+  g_return_if_fail (style->klass != NULL);
+  g_return_if_fail (style->klass->draw_shadow != NULL);
+
+  (*style->klass->draw_shadow) (style, window, state_type, shadow_type, x, y, width, height);
+}
+
+void
+gtk_draw_polygon (GtkStyle      *style,
+                 GdkWindow     *window,
+                 GtkStateType   state_type,
+                 GtkShadowType  shadow_type,
+                 GdkPoint      *points,
+                 gint           npoints,
+                 gint           fill)
+{
+  g_return_if_fail (style != NULL);
+  g_return_if_fail (style->klass != NULL);
+  g_return_if_fail (style->klass->draw_shadow != NULL);
+
+  (*style->klass->draw_polygon) (style, window, state_type, shadow_type, points, npoints, fill);
+}
+
+void
+gtk_draw_arrow (GtkStyle      *style,
+               GdkWindow     *window,
+               GtkStateType   state_type,
+               GtkShadowType  shadow_type,
+               GtkArrowType   arrow_type,
+               gint           fill,
+               gint           x,
+               gint           y,
+               gint           width,
+               gint           height)
+{
+  g_return_if_fail (style != NULL);
+  g_return_if_fail (style->klass != NULL);
+  g_return_if_fail (style->klass->draw_arrow != NULL);
+
+  (*style->klass->draw_arrow) (style, window, state_type, shadow_type, arrow_type, fill, x, y, width, height);
+}
+
+
+void
+gtk_draw_diamond (GtkStyle      *style,
+                 GdkWindow     *window,
+                 GtkStateType   state_type,
+                 GtkShadowType  shadow_type,
+                 gint           x,
+                 gint           y,
+                 gint           width,
+                 gint           height)
+{
+  g_return_if_fail (style != NULL);
+  g_return_if_fail (style->klass != NULL);
+  g_return_if_fail (style->klass->draw_diamond != NULL);
+
+  (*style->klass->draw_diamond) (style, window, state_type, shadow_type, x, y, width, height);
+}
+
+
+void
+gtk_draw_oval (GtkStyle      *style,
+              GdkWindow     *window,
+              GtkStateType   state_type,
+              GtkShadowType  shadow_type,
+              gint           x,
+              gint           y,
+              gint           width,
+              gint           height)
+{
+  g_return_if_fail (style != NULL);
+  g_return_if_fail (style->klass != NULL);
+  g_return_if_fail (style->klass->draw_oval != NULL);
+
+  (*style->klass->draw_oval) (style, window, state_type, shadow_type, x, y, width, height);
+}
+
+void
+gtk_draw_string (GtkStyle      *style,
+                GdkWindow     *window,
+                GtkStateType   state_type,
+                gint           x,
+                gint           y,
+                const gchar   *string)
+{
+  g_return_if_fail (style != NULL);
+  g_return_if_fail (style->klass != NULL);
+  g_return_if_fail (style->klass->draw_oval != NULL);
+
+  (*style->klass->draw_string) (style, window, state_type, x, y, string);
+}
+
+
+static void
+gtk_style_init (GtkStyle *style)
+{
+  GdkGCValues gc_values;
+  GdkGCValuesMask gc_values_mask;
+  GdkColormap *colormap;
+  gint i;
+
+  g_return_if_fail (style != NULL);
+
+  if (style->attach_count == 0)
+    {
+      for (i = 0; i < 5; i++)
+       {
+         gtk_style_shade (&style->bg[i], &style->light[i], LIGHTNESS_MULT);
+         gtk_style_shade (&style->bg[i], &style->dark[i], DARKNESS_MULT);
+
+         style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
+         style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
+         style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
+       }
+
+      colormap = style->colormap;
+
+      gdk_color_black (colormap, &style->black);
+      gdk_color_white (colormap, &style->white);
+
+      gc_values_mask = GDK_GC_FOREGROUND | GDK_GC_FONT;
+      if (style->font->type == GDK_FONT_FONT)
+       {
+         gc_values.font = style->font;
+       }
+      else if (style->font->type == GDK_FONT_FONTSET)
+       {
+         gc_values.font = default_font;
+       }
+
+      gc_values.foreground = style->black;
+      style->black_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
+
+      gc_values.foreground = style->white;
+      style->white_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
+
+      for (i = 0; i < 5; i++)
+       {
+         if (!gdk_color_alloc (colormap, &style->fg[i]))
+           g_warning ("unable to allocate color: ( %d %d %d )",
+                      style->fg[i].red, style->fg[i].green, style->fg[i].blue);
+         if (!gdk_color_alloc (colormap, &style->bg[i]))
+           g_warning ("unable to allocate color: ( %d %d %d )",
+                      style->bg[i].red, style->bg[i].green, style->bg[i].blue);
+         if (!gdk_color_alloc (colormap, &style->light[i]))
+           g_warning ("unable to allocate color: ( %d %d %d )",
+                      style->light[i].red, style->light[i].green, style->light[i].blue);
+         if (!gdk_color_alloc (colormap, &style->dark[i]))
+           g_warning ("unable to allocate color: ( %d %d %d )",
+                      style->dark[i].red, style->dark[i].green, style->dark[i].blue);
+         if (!gdk_color_alloc (colormap, &style->mid[i]))
+           g_warning ("unable to allocate color: ( %d %d %d )",
+                      style->mid[i].red, style->mid[i].green, style->mid[i].blue);
+         if (!gdk_color_alloc (colormap, &style->text[i]))
+           g_warning ("unable to allocate color: ( %d %d %d )",
+                      style->text[i].red, style->text[i].green, style->text[i].blue);
+         if (!gdk_color_alloc (colormap, &style->base[i]))
+           g_warning ("unable to allocate color: ( %d %d %d )",
+                      style->base[i].red, style->base[i].green, style->base[i].blue);
+
+         gc_values.foreground = style->fg[i];
+         style->fg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
+
+         gc_values.foreground = style->bg[i];
+         style->bg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
+
+         gc_values.foreground = style->light[i];
+         style->light_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
+
+         gc_values.foreground = style->dark[i];
+         style->dark_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
+
+         gc_values.foreground = style->mid[i];
+         style->mid_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
+
+         gc_values.foreground = style->text[i];
+         style->text_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
+
+         gc_values.foreground = style->base[i];
+         style->base_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
+       }
+    }
+}
+
+static void
+gtk_styles_init ()
+{
+  if (initialize)
+    {
+      initialize = FALSE;
+
+      style_cache = g_cache_new ((GCacheNewFunc) gtk_style_new_from_key,
+                                (GCacheDestroyFunc) gtk_style_destroy,
+                                (GCacheDupFunc) gtk_style_key_dup,
+                                (GCacheDestroyFunc) gtk_style_key_destroy,
+                                (GHashFunc) gtk_style_key_hash,
+                                (GHashFunc) gtk_style_value_hash,
+                                (GCompareFunc) gtk_style_key_compare);
+    }
+}
+
+static void
+gtk_style_remove (GtkStyle *style)
+{
+  if (initialize)
+    gtk_styles_init ();
+
+  g_cache_remove (style_cache, style);
+}
+
+static GtkStyle*
+gtk_style_find (GtkStyle    *style,
+               GdkColormap *cmap,
+               gint         depth)
+{
+  GtkStyleKey key;
+  gint i;
+
+  if (initialize)
+    gtk_styles_init ();
+
+  for (i = 0; i < 5; i++)
+    {
+      key.fg[i] = style->fg[i];
+      key.bg[i] = style->bg[i];
+      key.text[i] = style->text[i];
+      key.base[i] = style->base[i];
+      key.bg_pixmap[i] = style->bg_pixmap[i];
+    }
+
+  key.font = style->font;
+  key.klass = style->klass;
+  key.depth = depth;
+  key.colormap = cmap;
+
+  style = g_cache_insert (style_cache, &key);
+
+  return style;
+}
+
+static GtkStyle*
+gtk_style_new_from_key (GtkStyleKey *key)
+{
+  GtkStyle *style;
+  GSList *list;
+  gint i;
+
+  style = NULL;
+  list = unattached_styles;
+
+  while (list)
+    {
+      style = list->data;
+      list = list->next;
+
+      if ((style->depth != -1) && (style->depth != key->depth))
+       {
+         style = NULL;
+         continue;
+       }
+      if (style->colormap && (style->colormap != key->colormap))
+       {
+         style = NULL;
+         continue;
+       }
+      if (style->klass != key->klass)
+       {
+         style = NULL;
+         continue;
+       }
+      if (!gdk_font_equal (style->font, key->font))
+       {
+         style = NULL;
+         continue;
+       }
+
+      for (i = 0; style && (i < 5); i++)
+       {
+         if (style->bg_pixmap[i] != key->bg_pixmap[i])
+           {
+             style = NULL;
+             continue;
+           }
+
+         if ((style->fg[i].red != key->fg[i].red) ||
+             (style->fg[i].green != key->fg[i].green) ||
+             (style->fg[i].blue != key->fg[i].blue))
+           {
+             style = NULL;
+             continue;
+           }
+
+         if ((style->bg[i].red != key->bg[i].red) ||
+             (style->bg[i].green != key->bg[i].green) ||
+             (style->bg[i].blue != key->bg[i].blue))
+           {
+             style = NULL;
+             continue;
+           }
+
+         if ((style->text[i].red != key->text[i].red) ||
+             (style->text[i].green != key->text[i].green) ||
+             (style->text[i].blue != key->text[i].blue))
+           {
+             style = NULL;
+             continue;
+           }
+
+         if ((style->base[i].red != key->base[i].red) ||
+             (style->base[i].green != key->base[i].green) ||
+             (style->base[i].blue != key->base[i].blue))
+           {
+             style = NULL;
+             continue;
+           }
+       }
+
+      if (style)
+       break;
+    }
+
+  if (!style)
+    {
+      style = g_new (GtkStyle, 1);
+
+      style->ref_count = 0;
+      style->attach_count = 0;
+
+      style->font = key->font;
+      gdk_font_ref (style->font);
+
+      style->depth = key->depth;
+      style->colormap = key->colormap;
+      style->klass = key->klass;
+
+      style->black.red = 0;
+      style->black.green = 0;
+      style->black.blue = 0;
+
+      style->white.red = 65535;
+      style->white.green = 65535;
+      style->white.blue = 65535;
+
+      style->black_gc = NULL;
+      style->white_gc = NULL;
+
+      for (i = 0; i < 5; i++)
+       {
+         style->fg[i] = key->fg[i];
+         style->bg[i] = key->bg[i];
+         style->text[i] = key->text[i];
+         style->base[i] = key->base[i];
+       }
+
+      for (i = 0; i < 5; i++)
+       style->bg_pixmap[i] = key->bg_pixmap[i];
+
+      for (i = 0; i < 5; i++)
+       {
+         style->fg_gc[i] = NULL;
+         style->bg_gc[i] = NULL;
+         style->light_gc[i] = NULL;
+         style->dark_gc[i] = NULL;
+         style->mid_gc[i] = NULL;
+         style->text_gc[i] = NULL;
+         style->base_gc[i] = NULL;
+       }
+    }
+
+  if (style->depth == -1)
+    style->depth = key->depth;
+  if (!style->colormap)
+    style->colormap = key->colormap;
+
+  gtk_style_init (style);
+
+  return style;
+}
+
+static GtkStyleKey*
+gtk_style_key_dup (GtkStyleKey *key)
+{
+  GtkStyleKey *new_key;
+
+  if (!key_mem_chunk)
+    key_mem_chunk = g_mem_chunk_new ("key mem chunk", sizeof (GtkStyleKey),
+                                    1024, G_ALLOC_AND_FREE);
+
+  new_key = g_chunk_new (GtkStyleKey, key_mem_chunk);
+
+  *new_key = *key;
+
+  return new_key;
+}
+
+static void
+gtk_style_destroy (GtkStyle *style)
+{
+  gint i;
+
+  if (style->ref_count != 0)
+    return;
+
+  if (style->attach_count > 0)
+    {
+      gtk_gc_release (style->black_gc);
+      gtk_gc_release (style->white_gc);
+
+      for (i = 0; i < 5; i++)
+       {
+         gtk_gc_release (style->fg_gc[i]);
+         gtk_gc_release (style->bg_gc[i]);
+         gtk_gc_release (style->light_gc[i]);
+         gtk_gc_release (style->dark_gc[i]);
+         gtk_gc_release (style->mid_gc[i]);
+         gtk_gc_release (style->text_gc[i]);
+         gtk_gc_release (style->base_gc[i]);
+       }
+    }
+
+  unattached_styles = g_slist_remove (unattached_styles, style);
+
+  if (style->font->type == GDK_FONT_FONT)
+    gdk_font_free (style->font);
+  else if (style->font->type == GDK_FONT_FONTSET)
+    gdk_fontset_free (style->font);
+  else
+    g_error("undefined font type\n");
+
+  g_free (style);
+}
+
+static void
+gtk_style_key_destroy (GtkStyleKey *key)
+{
+  g_mem_chunk_free (key_mem_chunk, key);
+}
+
+static guint
+gtk_style_key_hash (GtkStyleKey *key)
+{
+  guint hash_val;
+  gint i;
+
+  hash_val = 0;
+
+  for (i = 0; i < 5; i++)
+    {
+      hash_val += key->fg[i].red + key->fg[i].green + key->fg[i].blue;
+      hash_val += key->bg[i].red + key->bg[i].green + key->bg[i].blue;
+      hash_val += key->text[i].red + key->text[i].green + key->text[i].blue;
+      hash_val += key->base[i].red + key->base[i].green + key->base[i].blue;
+    }
+
+  hash_val += (guint) gdk_font_id (key->font);
+  hash_val += (guint) key->depth;
+  hash_val += (gulong) key->colormap;
+  hash_val += (gulong) key->klass;
+
+  return hash_val;
+}
+
+static guint
+gtk_style_value_hash (GtkStyle *style)
+{
+  guint hash_val;
+  gint i;
+
+  hash_val = 0;
+
+  for (i = 0; i < 5; i++)
+    {
+      hash_val += style->fg[i].red + style->fg[i].green + style->fg[i].blue;
+      hash_val += style->bg[i].red + style->bg[i].green + style->bg[i].blue;
+      hash_val += style->text[i].red + style->text[i].green + style->text[i].blue;
+      hash_val += style->base[i].red + style->base[i].green + style->base[i].blue;
+    }
+
+  hash_val += (guint) gdk_font_id (style->font);
+  hash_val += (gulong) style->klass;
+
+  return hash_val;
+}
+
+static gint
+gtk_style_key_compare (GtkStyleKey *a,
+                      GtkStyleKey *b)
+{
+  gint i;
+
+  if (a->depth != b->depth)
+    return FALSE;
+  if (a->colormap != b->colormap)
+    return FALSE;
+  if (a->klass != b->klass)
+    return FALSE;
+  if (!gdk_font_equal (a->font, b->font))
+    return FALSE;
+
+  for (i = 0; i < 5; i++)
+    {
+      if (a->bg_pixmap[i] != b->bg_pixmap[i])
+       return FALSE;
+
+      if ((a->fg[i].red != b->fg[i].red) ||
+         (a->fg[i].green != b->fg[i].green) ||
+         (a->fg[i].blue != b->fg[i].blue))
+       return FALSE;
+      if ((a->bg[i].red != b->bg[i].red) ||
+         (a->bg[i].green != b->bg[i].green) ||
+         (a->bg[i].blue != b->bg[i].blue))
+       return FALSE;
+      if ((a->text[i].red != b->text[i].red) ||
+         (a->text[i].green != b->text[i].green) ||
+         (a->text[i].blue != b->text[i].blue))
+       return FALSE;
+      if ((a->base[i].red != b->base[i].red) ||
+         (a->base[i].green != b->base[i].green) ||
+         (a->base[i].blue != b->base[i].blue))
+       return FALSE;
+    }
+
+  return TRUE;
+}
+
+
+static void
+gtk_default_draw_hline (GtkStyle     *style,
+                       GdkWindow    *window,
+                       GtkStateType  state_type,
+                       gint          x1,
+                       gint          x2,
+                       gint          y)
+{
+  gint thickness_light;
+  gint thickness_dark;
+  gint i;
+
+  g_return_if_fail (style != NULL);
+  g_return_if_fail (window != NULL);
+
+  thickness_light = style->klass->ythickness / 2;
+  thickness_dark = style->klass->ythickness - thickness_light;
+
+  for (i = 0; i < thickness_dark; i++)
+    {
+      gdk_draw_line (window, style->light_gc[state_type], x2 - i - 1, y + i, x2, y + i);
+      gdk_draw_line (window, style->dark_gc[state_type], x1, y + i, x2 - i - 1, y + i);
+    }
+
+  y += thickness_dark;
+  for (i = 0; i < thickness_light; i++)
+    {
+      gdk_draw_line (window, style->dark_gc[state_type], x1, y + i, x1 + thickness_light - i - 1, y + i);
+      gdk_draw_line (window, style->light_gc[state_type], x1 + thickness_light - i - 1, y + i, x2, y + i);
+    }
+}
+
+
+static void
+gtk_default_draw_vline (GtkStyle     *style,
+                       GdkWindow    *window,
+                       GtkStateType  state_type,
+                       gint          y1,
+                       gint          y2,
+                       gint          x)
+{
+  gint thickness_light;
+  gint thickness_dark;
+  gint i;
+
+  g_return_if_fail (style != NULL);
+  g_return_if_fail (window != NULL);
+
+  thickness_light = style->klass->xthickness / 2;
+  thickness_dark = style->klass->xthickness - thickness_light;
+
+  for (i = 0; i < thickness_dark; i++)
+    {
+      gdk_draw_line (window, style->light_gc[state_type], x + i, y2 - i - 1, x + i, y2);
+      gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i, y2 - i - 1);
+    }
+
+  x += thickness_dark;
+  for (i = 0; i < thickness_light; i++)
+    {
+      gdk_draw_line (window, style->dark_gc[state_type], x + i, y1, x + i, y1 + thickness_light - i);
+      gdk_draw_line (window, style->light_gc[state_type], x + i, y1 + thickness_light - i, x + i, y2);
+    }
+}
+
+
+static void
+gtk_default_draw_shadow (GtkStyle      *style,
+                        GdkWindow     *window,
+                        GtkStateType   state_type,
+                        GtkShadowType  shadow_type,
+                        gint           x,
+                        gint           y,
+                        gint           width,
+                        gint           height)
+{
+  GdkGC *gc1;
+  GdkGC *gc2;
+  gint thickness_light;
+  gint thickness_dark;
+  gint i;
+
+  g_return_if_fail (style != NULL);
+  g_return_if_fail (window != NULL);
+
+  if ((width == -1) && (height == -1))
+    gdk_window_get_size (window, &width, &height);
+  else if (width == -1)
+    gdk_window_get_size (window, &width, NULL);
+  else if (height == -1)
+    gdk_window_get_size (window, NULL, &height);
+
+  switch (shadow_type)
+    {
+    case GTK_SHADOW_NONE:
+      gc1 = NULL;
+      gc2 = NULL;
+      break;
+    case GTK_SHADOW_IN:
+    case GTK_SHADOW_ETCHED_IN:
+      gc1 = style->light_gc[state_type];
+      gc2 = style->dark_gc[state_type];
+      break;
+    case GTK_SHADOW_OUT:
+    case GTK_SHADOW_ETCHED_OUT:
+      gc1 = style->dark_gc[state_type];
+      gc2 = style->light_gc[state_type];
+      break;
+    }
+
+  switch (shadow_type)
+    {
+    case GTK_SHADOW_NONE:
+      break;
+
+    case GTK_SHADOW_IN:
+      gdk_draw_line (window, gc1,
+                     x, y + height - 1, x + width - 1, y + height - 1);
+      gdk_draw_line (window, gc1,
+                     x + width - 1, y, x + width - 1, y + height - 1);
+
+      gdk_draw_line (window, style->bg_gc[state_type],
+                     x + 1, y + height - 2, x + width - 2, y + height - 2);
+      gdk_draw_line (window, style->bg_gc[state_type],
+                     x + width - 2, y + 1, x + width - 2, y + height - 2);
+
+      gdk_draw_line (window, style->black_gc,
+                     x + 1, y + 1, x + width - 2, y + 1);
+      gdk_draw_line (window, style->black_gc,
+                     x + 1, y + 1, x + 1, y + height - 2);
+
+      gdk_draw_line (window, gc2,
+                     x, y, x + width - 1, y);
+      gdk_draw_line (window, gc2,
+                     x, y, x, y + height - 1);
+      break;
+
+    case GTK_SHADOW_OUT:
+      gdk_draw_line (window, gc1,
+                     x + 1, y + height - 2, x + width - 2, y + height - 2);
+      gdk_draw_line (window, gc1,
+                     x + width - 2, y + 1, x + width - 2, y + height - 2);
+
+      gdk_draw_line (window, gc2,
+                     x, y, x + width - 1, y);
+      gdk_draw_line (window, gc2,
+                     x, y, x, y + height - 1);
+
+      gdk_draw_line (window, style->bg_gc[state_type],
+                     x + 1, y + 1, x + width - 2, y + 1);
+      gdk_draw_line (window, style->bg_gc[state_type],
+                     x + 1, y + 1, x + 1, y + height - 2);
+
+      gdk_draw_line (window, style->black_gc,
+                     x, y + height - 1, x + width - 1, y + height - 1);
+      gdk_draw_line (window, style->black_gc,
+                     x + width - 1, y, x + width - 1, y + height - 1);
+      break;
+
+    case GTK_SHADOW_ETCHED_IN:
+    case GTK_SHADOW_ETCHED_OUT:
+      thickness_light = 1;
+      thickness_dark = 1;
+
+      for (i = 0; i < thickness_dark; i++)
+        {
+          gdk_draw_line (window, gc1,
+                         x + i,
+                         y + height - i - 1,
+                         x + width - i - 1,
+                         y + height - i - 1);
+          gdk_draw_line (window, gc1,
+                         x + width - i - 1,
+                         y + i,
+                         x + width - i - 1,
+                         y + height - i - 1);
+
+          gdk_draw_line (window, gc2,
+                         x + i,
+                         y + i,
+                         x + width - i - 2,
+                         y + i);
+          gdk_draw_line (window, gc2,
+                         x + i,
+                         y + i,
+                         x + i,
+                         y + height - i - 2);
+        }
+
+      for (i = 0; i < thickness_light; i++)
+        {
+          gdk_draw_line (window, gc1,
+                         x + thickness_dark + i,
+                         y + thickness_dark + i,
+                         x + width - thickness_dark - i - 1,
+                         y + thickness_dark + i);
+          gdk_draw_line (window, gc1,
+                         x + thickness_dark + i,
+                         y + thickness_dark + i,
+                         x + thickness_dark + i,
+                         y + height - thickness_dark - i - 1);
+
+          gdk_draw_line (window, gc2,
+                         x + thickness_dark + i,
+                         y + height - thickness_light - i - 1,
+                         x + width - thickness_light - 1,
+                         y + height - thickness_light - i - 1);
+          gdk_draw_line (window, gc2,
+                         x + width - thickness_light - i - 1,
+                         y + thickness_dark + i,
+                         x + width - thickness_light - i - 1,
+                         y + height - thickness_light - 1);
+        }
+      break;
+    }
+}
+
+
+static void
+gtk_default_draw_polygon (GtkStyle      *style,
+                         GdkWindow     *window,
+                         GtkStateType   state_type,
+                         GtkShadowType  shadow_type,
+                         GdkPoint      *points,
+                         gint           npoints,
+                         gint           fill)
+{
+#ifndef M_PI
+#define M_PI    3.14159265358979323846
+#endif /* M_PI */
+#ifndef M_PI_4
+#define M_PI_4  0.78539816339744830962
+#endif /* M_PI_4 */
+
+  static const gdouble pi_over_4 = M_PI_4;
+  static const gdouble pi_3_over_4 = M_PI_4 * 3;
+
+  GdkGC *gc1;
+  GdkGC *gc2;
+  GdkGC *gc3;
+  GdkGC *gc4;
+  gdouble angle;
+  gint xadjust;
+  gint yadjust;
+  gint i;
+
+  g_return_if_fail (style != NULL);
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (points != NULL);
+
+  switch (shadow_type)
+    {
+    case GTK_SHADOW_IN:
+      gc1 = style->bg_gc[state_type];
+      gc2 = style->dark_gc[state_type];
+      gc3 = style->light_gc[state_type];
+      gc4 = style->black_gc;
+      break;
+    case GTK_SHADOW_OUT:
+      gc1 = style->dark_gc[state_type];
+      gc2 = style->light_gc[state_type];
+      gc3 = style->black_gc;
+      gc4 = style->bg_gc[state_type];
+      break;
+    default:
+      return;
+    }
+
+  if (fill)
+    gdk_draw_polygon (window, style->bg_gc[state_type], TRUE, points, npoints);
+
+  npoints -= 1;
+  for (i = 0; i < npoints; i++)
+    {
+      if ((points[i].x == points[i+1].x) &&
+         (points[i].y == points[i+1].y))
+       {
+         angle = 0;
+       }
+      else
+       {
+         angle = atan2 (points[i+1].y - points[i].y,
+                        points[i+1].x - points[i].x);
+       }
+
+      if ((angle > -pi_3_over_4) && (angle < pi_over_4))
+       {
+         while (angle < 0)
+           angle += M_PI;
+         while (angle > M_PI)
+           angle -= M_PI;
+
+         if ((angle > pi_3_over_4) || (angle < pi_over_4))
+           {
+             xadjust = 0;
+             yadjust = 1;
+           }
+         else
+           {
+             xadjust = 1;
+             yadjust = 0;
+           }
+
+         gdk_draw_line (window, gc1,
+                        points[i].x-xadjust, points[i].y-yadjust,
+                        points[i+1].x-xadjust, points[i+1].y-yadjust);
+         gdk_draw_line (window, gc3,
+                        points[i].x, points[i].y,
+                        points[i+1].x, points[i+1].y);
+       }
+    }
+
+  for (i = 0; i < npoints; i++)
+    {
+      if ((points[i].x == points[i+1].x) &&
+         (points[i].y == points[i+1].y))
+       {
+         angle = 0;
+       }
+      else
+       {
+         angle = atan2 (points[i+1].y - points[i].y,
+                        points[i+1].x - points[i].x);
+       }
+
+      if ((angle <= -pi_3_over_4) || (angle >= pi_over_4))
+       {
+         while (angle < 0)
+           angle += M_PI;
+         while (angle > M_PI)
+           angle -= M_PI;
+
+         if ((angle > pi_3_over_4) || (angle < pi_over_4))
+           {
+             xadjust = 0;
+             yadjust = 1;
+           }
+         else
+           {
+             xadjust = 1;
+             yadjust = 0;
+           }
+
+         gdk_draw_line (window, gc4,
+                        points[i].x+xadjust, points[i].y+yadjust,
+                        points[i+1].x+xadjust, points[i+1].y+yadjust);
+         gdk_draw_line (window, gc2,
+                        points[i].x, points[i].y,
+                        points[i+1].x, points[i+1].y);
+       }
+    }
+}
+
+
+static void
+gtk_default_draw_arrow (GtkStyle      *style,
+                       GdkWindow     *window,
+                       GtkStateType   state_type,
+                       GtkShadowType  shadow_type,
+                       GtkArrowType   arrow_type,
+                       gint           fill,
+                       gint           x,
+                       gint           y,
+                       gint           width,
+                       gint           height)
+{
+  GdkGC *gc1;
+  GdkGC *gc2;
+  GdkGC *gc3;
+  GdkGC *gc4;
+  gint half_width;
+  gint half_height;
+  GdkPoint points[3];
+
+  g_return_if_fail (style != NULL);
+  g_return_if_fail (window != NULL);
+
+  switch (shadow_type)
+    {
+    case GTK_SHADOW_IN:
+      gc1 = style->bg_gc[state_type];
+      gc2 = style->dark_gc[state_type];
+      gc3 = style->light_gc[state_type];
+      gc4 = style->black_gc;
+      break;
+    case GTK_SHADOW_OUT:
+      gc1 = style->dark_gc[state_type];
+      gc2 = style->light_gc[state_type];
+      gc3 = style->black_gc;
+      gc4 = style->bg_gc[state_type];
+      break;
+    default:
+      return;
+    }
+
+  if ((width == -1) && (height == -1))
+    gdk_window_get_size (window, &width, &height);
+  else if (width == -1)
+    gdk_window_get_size (window, &width, NULL);
+  else if (height == -1)
+    gdk_window_get_size (window, NULL, &height);
+
+  half_width = width / 2;
+  half_height = height / 2;
+
+  switch (arrow_type)
+    {
+    case GTK_ARROW_UP:
+      if (fill)
+        {
+          points[0].x = x + half_width;
+          points[0].y = y;
+          points[1].x = x;
+          points[1].y = y + height - 1;
+          points[2].x = x + width - 1;
+          points[2].y = y + height - 1;
+
+          gdk_draw_polygon (window, style->bg_gc[state_type], TRUE, points, 3);
+        }
+
+      gdk_draw_line (window, gc1,
+                     x + 1, y + height - 2,
+                     x + width - 2, y + height - 2);
+      gdk_draw_line (window, gc3,
+                     x + 0, y + height - 1,
+                     x + width - 1, y + height - 1);
+
+      gdk_draw_line (window, gc1,
+                     x + width - 2, y + height - 1,
+                     x + half_width, y + 1);
+      gdk_draw_line (window, gc3,
+                     x + width - 1, y + height - 1,
+                     x + half_width, y);
+
+      gdk_draw_line (window, gc4,
+                     x + half_width, y + 1,
+                     x + 1, y + height - 1);
+      gdk_draw_line (window, gc2,
+                     x + half_width, y,
+                     x, y + height - 1);
+      break;
+    case GTK_ARROW_DOWN:
+      if (fill)
+        {
+          points[0].x = x + width - 1;
+          points[0].y = y;
+          points[1].x = x;
+          points[1].y = y;
+          points[2].x = x + half_width;
+          points[2].y = y + height - 1;
+
+          gdk_draw_polygon (window, style->bg_gc[state_type], TRUE, points, 3);
+        }
+
+      gdk_draw_line (window, gc4,
+                     x + width - 2,
+                     y + 1, x + 1, y + 1);
+      gdk_draw_line (window, gc2,
+                     x + width - 1, y,
+                     x, y);
+
+      gdk_draw_line (window, gc4,
+                     x + 1, y,
+                     x + half_width, y + height - 2);
+      gdk_draw_line (window, gc2,
+                     x, y,
+                     x + half_width, y + height - 1);
+
+      gdk_draw_line (window, gc1,
+                     x + half_width, y + height - 2,
+                     x + width - 2, y);
+      gdk_draw_line (window, gc3,
+                     x + half_width, y + height - 1,
+                     x + width - 1, y);
+      break;
+    case GTK_ARROW_LEFT:
+      if (fill)
+        {
+          points[0].x = x;
+          points[0].y = y + half_height;
+          points[1].x = x + width - 1;
+          points[1].y = y + height - 1;
+          points[2].x = x + width - 1;
+          points[2].y = y;
+
+          gdk_draw_polygon (window, style->bg_gc[state_type], TRUE, points, 3);
+        }
+
+      gdk_draw_line (window, gc1,
+                     x + 1, y + half_height,
+                     x + width - 1, y + height - 1);
+      gdk_draw_line (window, gc3,
+                     x, y + half_height,
+                     x + width - 1, y + height - 1);
+
+      gdk_draw_line (window, gc1,
+                     x + width - 2, y + height - 1,
+                     x + width - 2, y + 1);
+      gdk_draw_line (window, gc3,
+                     x + width - 1, y + height - 1,
+                     x + width - 1, y);
+
+      gdk_draw_line (window, gc4,
+                     x + width - 1, y + 1,
+                     x + 1, y + half_width);
+      gdk_draw_line (window, gc2,
+                     x + width - 1, y,
+                     x, y + half_width);
+      break;
+    case GTK_ARROW_RIGHT:
+      if (fill)
+        {
+          points[0].x = x + width - 1;
+          points[0].y = y + half_height;
+          points[1].x = x;
+          points[1].y = y;
+          points[2].x = x;
+          points[2].y = y + height - 1;
+
+          gdk_draw_polygon (window, style->bg_gc[state_type], TRUE, points, 3);
+        }
+
+      gdk_draw_line (window, gc4,
+                     x + width - 1, y + half_height,
+                     x + 1, y + 1);
+      gdk_draw_line (window, gc2,
+                     x + width - 1, y + half_height,
+                     x, y);
+
+      gdk_draw_line (window, gc4,
+                     x + 1, y + 1,
+                     x + 1, y + height - 2);
+      gdk_draw_line (window, gc2,
+                     x, y,
+                     x, y + height - 1);
+
+      gdk_draw_line (window, gc1,
+                     x + 1, y + height - 2,
+                     x + width - 1, y + half_height);
+      gdk_draw_line (window, gc3,
+                     x, y + height - 1,
+                     x + width - 1, y + half_height);
+      break;
+    }
+}
+
+
+static void
+gtk_default_draw_diamond (GtkStyle      *style,
+                         GdkWindow     *window,
+                         GtkStateType   state_type,
+                         GtkShadowType  shadow_type,
+                         gint           x,
+                         gint           y,
+                         gint           width,
+                         gint           height)
+{
+  gint half_width;
+  gint half_height;
+
+  g_return_if_fail (style != NULL);
+  g_return_if_fail (window != NULL);
+
+  if ((width == -1) && (height == -1))
+    gdk_window_get_size (window, &width, &height);
+  else if (width == -1)
+    gdk_window_get_size (window, &width, NULL);
+  else if (height == -1)
+    gdk_window_get_size (window, NULL, &height);
+
+  half_width = width / 2;
+  half_height = height / 2;
+
+  switch (shadow_type)
+    {
+    case GTK_SHADOW_IN:
+      gdk_draw_line (window, style->bg_gc[state_type],
+                     x + 2, y + half_height,
+                     x + half_width, y + height - 2);
+      gdk_draw_line (window, style->bg_gc[state_type],
+                     x + half_width, y + height - 2,
+                     x + width - 2, y + half_height);
+      gdk_draw_line (window, style->light_gc[state_type],
+                     x + 1, y + half_height,
+                     x + half_width, y + height - 1);
+      gdk_draw_line (window, style->light_gc[state_type],
+                     x + half_width, y + height - 1,
+                     x + width - 1, y + half_height);
+      gdk_draw_line (window, style->light_gc[state_type],
+                     x, y + half_height,
+                     x + half_width, y + height);
+      gdk_draw_line (window, style->light_gc[state_type],
+                     x + half_width, y + height,
+                     x + width, y + half_height);
+
+      gdk_draw_line (window, style->black_gc,
+                     x + 2, y + half_height,
+                     x + half_width, y + 2);
+      gdk_draw_line (window, style->black_gc,
+                     x + half_width, y + 2,
+                     x + width - 2, y + half_height);
+      gdk_draw_line (window, style->dark_gc[state_type],
+                     x + 1, y + half_height,
+                     x + half_width, y + 1);
+      gdk_draw_line (window, style->dark_gc[state_type],
+                     x + half_width, y + 1,
+                     x + width - 1, y + half_height);
+      gdk_draw_line (window, style->dark_gc[state_type],
+                     x, y + half_height,
+                     x + half_width, y);
+      gdk_draw_line (window, style->dark_gc[state_type],
+                     x + half_width, y,
+                     x + width, y + half_height);
+      break;
+    case GTK_SHADOW_OUT:
+      gdk_draw_line (window, style->dark_gc[state_type],
+                     x + 2, y + half_height,
+                     x + half_width, y + height - 2);
+      gdk_draw_line (window, style->dark_gc[state_type],
+                     x + half_width, y + height - 2,
+                     x + width - 2, y + half_height);
+      gdk_draw_line (window, style->dark_gc[state_type],
+                     x + 1, y + half_height,
+                     x + half_width, y + height - 1);
+      gdk_draw_line (window, style->dark_gc[state_type],
+                     x + half_width, y + height - 1,
+                     x + width - 1, y + half_height);
+      gdk_draw_line (window, style->black_gc,
+                     x, y + half_height,
+                     x + half_width, y + height);
+      gdk_draw_line (window, style->black_gc,
+                     x + half_width, y + height,
+                     x + width, y + half_height);
+
+      gdk_draw_line (window, style->bg_gc[state_type],
+                     x + 2, y + half_height,
+                     x + half_width, y + 2);
+      gdk_draw_line (window, style->bg_gc[state_type],
+                     x + half_width, y + 2,
+                     x + width - 2, y + half_height);
+      gdk_draw_line (window, style->light_gc[state_type],
+                     x + 1, y + half_height,
+                     x + half_width, y + 1);
+      gdk_draw_line (window, style->light_gc[state_type],
+                     x + half_width, y + 1,
+                     x + width - 1, y + half_height);
+      gdk_draw_line (window, style->light_gc[state_type],
+                     x, y + half_height,
+                     x + half_width, y);
+      gdk_draw_line (window, style->light_gc[state_type],
+                     x + half_width, y,
+                     x + width, y + half_height);
+      break;
+    default:
+      break;
+    }
+}
+
+
+static void
+gtk_default_draw_oval (GtkStyle      *style,
+                      GdkWindow     *window,
+                      GtkStateType   state_type,
+                      GtkShadowType  shadow_type,
+                      gint           x,
+                      gint           y,
+                      gint           width,
+                      gint           height)
+{
+  g_return_if_fail (style != NULL);
+  g_return_if_fail (window != NULL);
+}
+
+static void
+gtk_default_draw_string (GtkStyle      *style,
+                        GdkWindow     *window,
+                        GtkStateType   state_type,
+                        gint           x,
+                        gint           y,
+                        const gchar   *string)
+{
+  g_return_if_fail (style != NULL);
+  g_return_if_fail (window != NULL);
+
+  if (state_type == GTK_STATE_INSENSITIVE)
+    gdk_draw_string (window, style->font, style->white_gc, x + 1, y + 1, string);
+  gdk_draw_string (window, style->font, style->fg_gc[state_type], x, y, string);
+}
+
+
+static void
+gtk_style_shade (GdkColor *a,
+                GdkColor *b,
+                gdouble   k)
+{
+  gdouble red;
+  gdouble green;
+  gdouble blue;
+
+  red = (gdouble) a->red / 65535.0;
+  green = (gdouble) a->green / 65535.0;
+  blue = (gdouble) a->blue / 65535.0;
+
+  rgb_to_hls (&red, &green, &blue);
+
+  green *= k;
+  if (green > 1.0)
+    green = 1.0;
+  else if (green < 0.0)
+    green = 0.0;
+
+  blue *= k;
+  if (blue > 1.0)
+    blue = 1.0;
+  else if (blue < 0.0)
+    blue = 0.0;
+
+  hls_to_rgb (&red, &green, &blue);
+
+  b->red = red * 65535.0;
+  b->green = green * 65535.0;
+  b->blue = blue * 65535.0;
+}
+
+static void
+rgb_to_hls (gdouble *r,
+           gdouble *g,
+           gdouble *b)
+{
+  gdouble min;
+  gdouble max;
+  gdouble red;
+  gdouble green;
+  gdouble blue;
+  gdouble h, l, s;
+  gdouble delta;
+
+  red = *r;
+  green = *g;
+  blue = *b;
+
+  if (red > green)
+    {
+      if (red > blue)
+       max = red;
+      else
+       max = blue;
+
+      if (green < blue)
+       min = green;
+      else
+       min = blue;
+    }
+  else
+    {
+      if (green > blue)
+       max = green;
+      else
+       max = blue;
+
+      if (red < blue)
+       min = red;
+      else
+       min = blue;
+    }
+
+  l = (max + min) / 2;
+  s = 0;
+  h = 0;
+
+  if (max != min)
+    {
+      if (l <= 0.5)
+       s = (max - min) / (max + min);
+      else
+       s = (max - min) / (2 - max - min);
+
+      delta = max -min;
+      if (red == max)
+       h = (green - blue) / delta;
+      else if (green == max)
+       h = 2 + (blue - red) / delta;
+      else if (blue == max)
+       h = 4 + (red - green) / delta;
+
+      h *= 60;
+      if (h < 0.0)
+       h += 360;
+    }
+
+  *r = h;
+  *g = l;
+  *b = s;
+}
+
+static void
+hls_to_rgb (gdouble *h,
+           gdouble *l,
+           gdouble *s)
+{
+  gdouble hue;
+  gdouble lightness;
+  gdouble saturation;
+  gdouble m1, m2;
+  gdouble r, g, b;
+
+  lightness = *l;
+  saturation = *s;
+
+  if (lightness <= 0.5)
+    m2 = lightness * (1 + saturation);
+  else
+    m2 = lightness + saturation - lightness * saturation;
+  m1 = 2 * lightness - m2;
+
+  if (saturation == 0)
+    {
+      *h = lightness;
+      *l = lightness;
+      *s = lightness;
+    }
+  else
+    {
+      hue = *h + 120;
+      while (hue > 360)
+       hue -= 360;
+      while (hue < 0)
+       hue += 360;
+
+      if (hue < 60)
+       r = m1 + (m2 - m1) * hue / 60;
+      else if (hue < 180)
+       r = m2;
+      else if (hue < 240)
+       r = m1 + (m2 - m1) * (240 - hue) / 60;
+      else
+       r = m1;
+
+      hue = *h;
+      while (hue > 360)
+       hue -= 360;
+      while (hue < 0)
+       hue += 360;
+
+      if (hue < 60)
+       g = m1 + (m2 - m1) * hue / 60;
+      else if (hue < 180)
+       g = m2;
+      else if (hue < 240)
+       g = m1 + (m2 - m1) * (240 - hue) / 60;
+      else
+       g = m1;
+
+      hue = *h - 120;
+      while (hue > 360)
+       hue -= 360;
+      while (hue < 0)
+       hue += 360;
+
+      if (hue < 60)
+       b = m1 + (m2 - m1) * hue / 60;
+      else if (hue < 180)
+       b = m2;
+      else if (hue < 240)
+       b = m1 + (m2 - m1) * (240 - hue) / 60;
+      else
+       b = m1;
+
+      *h = r;
+      *l = g;
+      *s = b;
+    }
+}
diff --git a/gtk/gtkstyle.h b/gtk/gtkstyle.h
new file mode 100644 (file)
index 0000000..c0ec337
--- /dev/null
@@ -0,0 +1,217 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_STYLE_H__
+#define __GTK_STYLE_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkenums.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+typedef struct _GtkStyle       GtkStyle;
+typedef struct _GtkStyleClass  GtkStyleClass;
+
+/* This is used for having dynamic style changing stuff */
+/* fg, bg, light, dark, mid, text, base */
+#define GTK_STYLE_NUM_STYLECOLORS() 7*5
+
+struct _GtkStyle
+{
+  GdkColor fg[5];
+  GdkColor bg[5];
+  GdkColor light[5];
+  GdkColor dark[5];
+  GdkColor mid[5];
+  GdkColor text[5];
+  GdkColor base[5];
+
+  GdkColor black;
+  GdkColor white;
+  GdkFont *font;
+
+  GdkGC *fg_gc[5];
+  GdkGC *bg_gc[5];
+  GdkGC *light_gc[5];
+  GdkGC *dark_gc[5];
+  GdkGC *mid_gc[5];
+  GdkGC *text_gc[5];
+  GdkGC *base_gc[5];
+  GdkGC *black_gc;
+  GdkGC *white_gc;
+
+  GdkPixmap *bg_pixmap[5];
+
+  gint ref_count;
+  gint attach_count;
+
+  gint depth;
+  GdkColormap *colormap;
+
+  GtkStyleClass *klass;
+};
+
+struct _GtkStyleClass
+{
+  gint xthickness;
+  gint ythickness;
+
+  void (*draw_hline)   (GtkStyle      *style,
+                       GdkWindow     *window,
+                       GtkStateType   state_type,
+                       gint           x1,
+                       gint           x2,
+                       gint           y);
+  void (*draw_vline)   (GtkStyle      *style,
+                       GdkWindow     *window,
+                       GtkStateType   state_type,
+                       gint           y1,
+                       gint           y2,
+                       gint           x);
+  void (*draw_shadow)  (GtkStyle      *style,
+                       GdkWindow     *window,
+                       GtkStateType   state_type,
+                       GtkShadowType  shadow_type,
+                       gint           x,
+                       gint           y,
+                       gint           width,
+                       gint           height);
+  void (*draw_polygon) (GtkStyle      *style,
+                       GdkWindow     *window,
+                       GtkStateType   state_type,
+                       GtkShadowType  shadow_type,
+                       GdkPoint      *point,
+                       gint           npoints,
+                       gint           fill);
+  void (*draw_arrow)   (GtkStyle      *style,
+                       GdkWindow     *window,
+                       GtkStateType   state_type,
+                       GtkShadowType  shadow_type,
+                       GtkArrowType   arrow_type,
+                       gint           fill,
+                       gint           x,
+                       gint           y,
+                       gint           width,
+                       gint           height);
+  void (*draw_diamond) (GtkStyle      *style,
+                       GdkWindow     *window,
+                       GtkStateType   state_type,
+                       GtkShadowType  shadow_type,
+                       gint           x,
+                       gint           y,
+                       gint           width,
+                       gint           height);
+  void (*draw_oval)    (GtkStyle      *style,
+                       GdkWindow     *window,
+                       GtkStateType   state_type,
+                       GtkShadowType  shadow_type,
+                       gint           x,
+                       gint           y,
+                       gint           width,
+                       gint           height);
+  void (*draw_string)  (GtkStyle      *style,
+                       GdkWindow     *window,
+                       GtkStateType   state_type,
+                       gint           x,
+                       gint           y,
+                       const gchar   *string);
+};
+
+
+GtkStyle* gtk_style_new            (void);
+GtkStyle* gtk_style_attach         (GtkStyle     *style,
+                                   GdkWindow    *window);
+void      gtk_style_detach         (GtkStyle     *style);
+GtkStyle *gtk_style_ref            (GtkStyle     *style);
+void      gtk_style_unref          (GtkStyle     *style);
+void      gtk_style_set_background (GtkStyle     *style,
+                                   GdkWindow    *window,
+                                   GtkStateType  state_type);
+
+
+void gtk_draw_hline   (GtkStyle      *style,
+                      GdkWindow     *window,
+                      GtkStateType   state_type,
+                      gint           x1,
+                      gint           x2,
+                      gint           y);
+void gtk_draw_vline   (GtkStyle      *style,
+                      GdkWindow     *window,
+                      GtkStateType   state_type,
+                      gint           y1,
+                      gint           y2,
+                      gint           x);
+void gtk_draw_shadow  (GtkStyle      *style,
+                      GdkWindow     *window,
+                      GtkStateType   state_type,
+                      GtkShadowType  shadow_type,
+                      gint           x,
+                      gint           y,
+                      gint           width,
+                      gint           height);
+void gtk_draw_polygon (GtkStyle      *style,
+                      GdkWindow     *window,
+                      GtkStateType   state_type,
+                      GtkShadowType  shadow_type,
+                      GdkPoint      *points,
+                      gint           npoints,
+                      gint           fill);
+void gtk_draw_arrow   (GtkStyle      *style,
+                      GdkWindow     *window,
+                      GtkStateType   state_type,
+                      GtkShadowType  shadow_type,
+                      GtkArrowType   arrow_type,
+                      gint           fill,
+                      gint           x,
+                      gint           y,
+                      gint           width,
+                      gint           height);
+void gtk_draw_diamond (GtkStyle      *style,
+                      GdkWindow     *window,
+                      GtkStateType   state_type,
+                      GtkShadowType  shadow_type,
+                      gint           x,
+                      gint           y,
+                      gint           width,
+                      gint           height);
+void gtk_draw_oval    (GtkStyle      *style,
+                      GdkWindow     *window,
+                      GtkStateType   state_type,
+                      GtkShadowType  shadow_type,
+                      gint           x,
+                      gint           y,
+                      gint           width,
+                      gint           height);
+void gtk_draw_string  (GtkStyle      *style,
+                      GdkWindow     *window,
+                      GtkStateType   state_type,
+                      gint           x,
+                      gint           y,
+                      const gchar   *string);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_STYLE_H__ */
diff --git a/gtk/gtktable.c b/gtk/gtktable.c
new file mode 100644 (file)
index 0000000..7711524
--- /dev/null
@@ -0,0 +1,1178 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtktable.h"
+
+
+static void gtk_table_class_init    (GtkTableClass  *klass);
+static void gtk_table_init          (GtkTable       *table);
+static void gtk_table_destroy       (GtkObject      *object);
+static void gtk_table_map           (GtkWidget      *widget);
+static void gtk_table_unmap         (GtkWidget      *widget);
+static void gtk_table_draw          (GtkWidget      *widget,
+                                    GdkRectangle   *area);
+static gint gtk_table_expose        (GtkWidget      *widget,
+                                    GdkEventExpose *event);
+static void gtk_table_size_request  (GtkWidget      *widget,
+                                    GtkRequisition *requisition);
+static void gtk_table_size_allocate (GtkWidget      *widget,
+                                    GtkAllocation  *allocation);
+static void gtk_table_add           (GtkContainer   *container,
+                                    GtkWidget      *widget);
+static void gtk_table_remove        (GtkContainer   *container,
+                                    GtkWidget      *widget);
+static void gtk_table_foreach       (GtkContainer   *container,
+                                    GtkCallback     callback,
+                                    gpointer        callback_data);
+
+static void gtk_table_size_request_init  (GtkTable *table);
+static void gtk_table_size_request_pass1 (GtkTable *table);
+static void gtk_table_size_request_pass2 (GtkTable *table);
+static void gtk_table_size_request_pass3 (GtkTable *table);
+
+static void gtk_table_size_allocate_init  (GtkTable *table);
+static void gtk_table_size_allocate_pass1 (GtkTable *table);
+static void gtk_table_size_allocate_pass2 (GtkTable *table);
+
+
+static GtkContainerClass *parent_class = NULL;
+
+
+guint
+gtk_table_get_type ()
+{
+  static guint table_type = 0;
+
+  if (!table_type)
+    {
+      GtkTypeInfo table_info =
+      {
+       "GtkTable",
+       sizeof (GtkTable),
+       sizeof (GtkTableClass),
+       (GtkClassInitFunc) gtk_table_class_init,
+       (GtkObjectInitFunc) gtk_table_init,
+       (GtkArgFunc) NULL,
+      };
+
+      table_type = gtk_type_unique (gtk_container_get_type (), &table_info);
+    }
+
+  return table_type;
+}
+
+static void
+gtk_table_class_init (GtkTableClass *class)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+  GtkContainerClass *container_class;
+
+  object_class = (GtkObjectClass*) class;
+  widget_class = (GtkWidgetClass*) class;
+  container_class = (GtkContainerClass*) class;
+
+  parent_class = gtk_type_class (gtk_container_get_type ());
+
+  object_class->destroy = gtk_table_destroy;
+
+  widget_class->map = gtk_table_map;
+  widget_class->unmap = gtk_table_unmap;
+  widget_class->draw = gtk_table_draw;
+  widget_class->expose_event = gtk_table_expose;
+  widget_class->size_request = gtk_table_size_request;
+  widget_class->size_allocate = gtk_table_size_allocate;
+
+  container_class->add = gtk_table_add;
+  container_class->remove = gtk_table_remove;
+  container_class->foreach = gtk_table_foreach;
+}
+
+static void
+gtk_table_init (GtkTable *table)
+{
+  GTK_WIDGET_SET_FLAGS (table, GTK_NO_WINDOW | GTK_BASIC);
+
+  table->children = NULL;
+  table->rows = NULL;
+  table->cols = NULL;
+  table->nrows = 0;
+  table->ncols = 0;
+  table->homogeneous = FALSE;
+}
+
+GtkWidget*
+gtk_table_new (gint rows,
+              gint columns,
+              gint homogeneous)
+{
+  GtkTable *table;
+  gint row, col;
+
+  table = gtk_type_new (gtk_table_get_type ());
+
+  table->nrows = rows;
+  table->ncols = columns;
+  table->homogeneous = (homogeneous ? TRUE : FALSE);
+
+  table->rows = g_new (GtkTableRowCol, table->nrows);
+  table->cols = g_new (GtkTableRowCol, table->ncols);
+
+  for (row = 0; row < table->nrows; row++)
+    {
+      table->rows[row].requisition = 0;
+      table->rows[row].allocation = 0;
+      table->rows[row].spacing = 0;
+      table->rows[row].need_expand = 0;
+      table->rows[row].need_shrink = 0;
+      table->rows[row].expand = 0;
+      table->rows[row].shrink = 0;
+    }
+
+  for (col = 0; col < table->ncols; col++)
+    {
+      table->cols[col].requisition = 0;
+      table->cols[col].allocation = 0;
+      table->cols[col].spacing = 0;
+      table->cols[col].need_expand = 0;
+      table->cols[col].need_shrink = 0;
+      table->cols[col].expand = 0;
+      table->cols[col].shrink = 0;
+    }
+
+  return GTK_WIDGET (table);
+}
+
+void
+gtk_table_attach (GtkTable  *table,
+                 GtkWidget *child,
+                 gint       left_attach,
+                 gint       right_attach,
+                 gint       top_attach,
+                 gint       bottom_attach,
+                 gint       xoptions,
+                 gint       yoptions,
+                 gint       xpadding,
+                 gint       ypadding)
+{
+  GtkTableChild *table_child;
+
+  g_return_if_fail (table != NULL);
+  g_return_if_fail (GTK_IS_TABLE (table));
+  g_return_if_fail (child != NULL);
+
+  g_return_if_fail ((left_attach >= 0) && (left_attach < table->ncols));
+  g_return_if_fail ((left_attach < right_attach) && (right_attach <= table->ncols));
+  g_return_if_fail ((top_attach >= 0) && (top_attach < table->nrows));
+  g_return_if_fail ((top_attach < bottom_attach) && (bottom_attach <= table->nrows));
+
+  table_child = g_new (GtkTableChild, 1);
+  table_child->widget = child;
+  table_child->left_attach = left_attach;
+  table_child->right_attach = right_attach;
+  table_child->top_attach = top_attach;
+  table_child->bottom_attach = bottom_attach;
+  table_child->xexpand = (xoptions & GTK_EXPAND) != 0;
+  table_child->xshrink = (xoptions & GTK_SHRINK) != 0;
+  table_child->xfill = (xoptions & GTK_FILL) != 0;
+  table_child->xpadding = xpadding;
+  table_child->yexpand = (yoptions & GTK_EXPAND) != 0;
+  table_child->yshrink = (yoptions & GTK_SHRINK) != 0;
+  table_child->yfill = (yoptions & GTK_FILL) != 0;
+  table_child->ypadding = ypadding;
+
+  table->children = g_list_prepend (table->children, table_child);
+
+  gtk_widget_set_parent (child, GTK_WIDGET (table));
+
+  if (GTK_WIDGET_VISIBLE (GTK_WIDGET (table)))
+    {
+      if (GTK_WIDGET_REALIZED (GTK_WIDGET (table)) &&
+         !GTK_WIDGET_REALIZED (child))
+       gtk_widget_realize (child);
+      
+      if (GTK_WIDGET_MAPPED (GTK_WIDGET (table)) &&
+         !GTK_WIDGET_MAPPED (child))
+       gtk_widget_map (child);
+    }
+
+  if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (table))
+    gtk_widget_queue_resize (child);
+}
+
+void
+gtk_table_attach_defaults (GtkTable  *table,
+                          GtkWidget *widget,
+                          gint       left_attach,
+                          gint       right_attach,
+                          gint       top_attach,
+                          gint       bottom_attach)
+{
+  gtk_table_attach (table, widget,
+                   left_attach, right_attach,
+                   top_attach, bottom_attach,
+                   GTK_EXPAND | GTK_FILL,
+                   GTK_EXPAND | GTK_FILL,
+                   0, 0);
+}
+
+void
+gtk_table_set_row_spacing (GtkTable *table,
+                          gint      row,
+                          gint      spacing)
+{
+  g_return_if_fail (table != NULL);
+  g_return_if_fail (GTK_IS_TABLE (table));
+  g_return_if_fail ((row >= 0) && (row < (table->nrows - 1)));
+
+  if (table->rows[row].spacing != spacing)
+    {
+      table->rows[row].spacing = spacing;
+
+      if (GTK_WIDGET_VISIBLE (table))
+       gtk_widget_queue_resize (GTK_WIDGET (table));
+    }
+}
+
+void
+gtk_table_set_col_spacing (GtkTable *table,
+                          gint      column,
+                          gint      spacing)
+{
+  g_return_if_fail (table != NULL);
+  g_return_if_fail (GTK_IS_TABLE (table));
+  g_return_if_fail ((column >= 0) && (column < (table->ncols - 1)));
+
+  if (table->cols[column].spacing != spacing)
+    {
+      table->cols[column].spacing = spacing;
+
+      if (GTK_WIDGET_VISIBLE (table))
+       gtk_widget_queue_resize (GTK_WIDGET (table));
+    }
+}
+
+void
+gtk_table_set_row_spacings (GtkTable *table,
+                           gint      spacing)
+{
+  gint row;
+
+  g_return_if_fail (table != NULL);
+  g_return_if_fail (GTK_IS_TABLE (table));
+
+  for (row = 0; row < table->nrows - 1; row++)
+    table->rows[row].spacing = spacing;
+
+  if (GTK_WIDGET_VISIBLE (table))
+    gtk_widget_queue_resize (GTK_WIDGET (table));
+}
+
+void
+gtk_table_set_col_spacings (GtkTable *table,
+                           gint      spacing)
+{
+  gint col;
+
+  g_return_if_fail (table != NULL);
+  g_return_if_fail (GTK_IS_TABLE (table));
+
+  for (col = 0; col < table->ncols - 1; col++)
+    table->cols[col].spacing = spacing;
+
+  if (GTK_WIDGET_VISIBLE (table))
+    gtk_widget_queue_resize (GTK_WIDGET (table));
+}
+
+
+static void
+gtk_table_destroy (GtkObject *object)
+{
+  GtkTable *table;
+  GtkTableChild *child;
+  GList *children;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_TABLE (object));
+
+  table = GTK_TABLE (object);
+
+  children = table->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      child->widget->parent = NULL;
+      gtk_object_unref (GTK_OBJECT (child->widget));
+      gtk_widget_destroy (child->widget);
+      g_free (child);
+    }
+
+  g_list_free (table->children);
+  g_free (table->rows);
+  g_free (table->cols);
+
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+gtk_table_map (GtkWidget *widget)
+{
+  GtkTable *table;
+  GtkTableChild *child;
+  GList *children;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_TABLE (widget));
+
+  table = GTK_TABLE (widget);
+  GTK_WIDGET_SET_FLAGS (table, GTK_MAPPED);
+
+  children = table->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (child->widget) &&
+          !GTK_WIDGET_MAPPED (child->widget))
+        gtk_widget_map (child->widget);
+    }
+}
+
+static void
+gtk_table_unmap (GtkWidget *widget)
+{
+  GtkTable *table;
+  GtkTableChild *child;
+  GList *children;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_TABLE (widget));
+
+  table = GTK_TABLE (widget);
+  GTK_WIDGET_UNSET_FLAGS (table, GTK_MAPPED);
+
+  children = table->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (child->widget) &&
+          GTK_WIDGET_MAPPED (child->widget))
+        gtk_widget_unmap (child->widget);
+    }
+}
+
+static void
+gtk_table_draw (GtkWidget    *widget,
+               GdkRectangle *area)
+{
+  GtkTable *table;
+  GtkTableChild *child;
+  GList *children;
+  GdkRectangle child_area;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_TABLE (widget));
+
+  if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget))
+    {
+      table = GTK_TABLE (widget);
+
+      children = table->children;
+      while (children)
+       {
+         child = children->data;
+         children = children->next;
+
+         if (gtk_widget_intersect (child->widget, area, &child_area))
+           gtk_widget_draw (child->widget, &child_area);
+       }
+    }
+}
+
+static gint
+gtk_table_expose (GtkWidget      *widget,
+                 GdkEventExpose *event)
+{
+  GtkTable *table;
+  GtkTableChild *child;
+  GList *children;
+  GdkEventExpose child_event;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_TABLE (widget), FALSE);
+
+  if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget))
+    {
+      table = GTK_TABLE (widget);
+
+      child_event = *event;
+
+      children = table->children;
+      while (children)
+       {
+         child = children->data;
+         children = children->next;
+
+         if (GTK_WIDGET_NO_WINDOW (child->widget) &&
+             gtk_widget_intersect (child->widget, &event->area, &child_event.area))
+           gtk_widget_event (child->widget, (GdkEvent*) &child_event);
+       }
+    }
+
+  return FALSE;
+}
+
+static void
+gtk_table_size_request (GtkWidget      *widget,
+                       GtkRequisition *requisition)
+{
+  GtkTable *table;
+  gint row, col;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_TABLE (widget));
+  g_return_if_fail (requisition != NULL);
+
+  table = GTK_TABLE (widget);
+
+  requisition->width = 0;
+  requisition->height = 0;
+
+  gtk_table_size_request_init (table);
+  gtk_table_size_request_pass1 (table);
+  gtk_table_size_request_pass2 (table);
+  gtk_table_size_request_pass3 (table);
+  gtk_table_size_request_pass2 (table);
+
+  for (col = 0; col < table->ncols; col++)
+    requisition->width += table->cols[col].requisition;
+  for (col = 0; col < table->ncols - 1; col++)
+    requisition->width += table->cols[col].spacing;
+
+  for (row = 0; row < table->nrows; row++)
+    requisition->height += table->rows[row].requisition;
+  for (row = 0; row < table->nrows - 1; row++)
+    requisition->height += table->rows[row].spacing;
+
+  requisition->width += GTK_CONTAINER (table)->border_width * 2;
+  requisition->height += GTK_CONTAINER (table)->border_width * 2;
+}
+
+static void
+gtk_table_size_allocate (GtkWidget     *widget,
+                        GtkAllocation *allocation)
+{
+  GtkTable *table;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_TABLE (widget));
+  g_return_if_fail (allocation != NULL);
+
+  widget->allocation = *allocation;
+  table = GTK_TABLE (widget);
+
+  gtk_table_size_allocate_init (table);
+  gtk_table_size_allocate_pass1 (table);
+  gtk_table_size_allocate_pass2 (table);
+}
+
+static void
+gtk_table_add (GtkContainer *container,
+              GtkWidget    *widget)
+{
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_TABLE (container));
+  g_return_if_fail (widget != NULL);
+
+  gtk_table_attach_defaults (GTK_TABLE (container), widget, 0, 1, 0, 1);
+}
+
+static void
+gtk_table_remove (GtkContainer *container,
+                 GtkWidget    *widget)
+{
+  GtkTable *table;
+  GtkTableChild *child;
+  GList *children;
+
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_TABLE (container));
+  g_return_if_fail (widget != NULL);
+
+  table = GTK_TABLE (container);
+  children = table->children;
+
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (child->widget == widget)
+        {
+         gtk_widget_unparent (widget);
+
+          table->children = g_list_remove (table->children, child);
+          g_free (child);
+
+          if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
+            gtk_widget_queue_resize (GTK_WIDGET (container));
+          break;
+        }
+    }
+}
+
+static void
+gtk_table_foreach (GtkContainer *container,
+                  GtkCallback     callback,
+                  gpointer        callback_data)
+{
+  GtkTable *table;
+  GtkTableChild *child;
+  GList *children;
+
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_TABLE (container));
+  g_return_if_fail (callback != NULL);
+
+  table = GTK_TABLE (container);
+  children = table->children;
+
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      (* callback) (child->widget, callback_data);
+    }
+}
+
+static void
+gtk_table_size_request_init (GtkTable *table)
+{
+  GtkTableChild *child;
+  GList *children;
+  gint row, col;
+
+  for (row = 0; row < table->nrows; row++)
+    table->rows[row].requisition = 0;
+  for (col = 0; col < table->ncols; col++)
+    table->cols[col].requisition = 0;
+
+  children = table->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (child->widget))
+       gtk_widget_size_request (child->widget, &child->widget->requisition);
+    }
+}
+
+static void
+gtk_table_size_request_pass1 (GtkTable *table)
+{
+  GtkTableChild *child;
+  GList *children;
+  gint width;
+  gint height;
+
+  children = table->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (child->widget))
+        {
+          /* Child spans a single column.
+           */
+          if (child->left_attach == (child->right_attach - 1))
+            {
+              width = child->widget->requisition.width + child->xpadding * 2;
+              table->cols[child->left_attach].requisition = MAX (table->cols[child->left_attach].requisition, width);
+            }
+
+          /* Child spans a single row.
+           */
+          if (child->top_attach == (child->bottom_attach - 1))
+            {
+              height = child->widget->requisition.height + child->ypadding * 2;
+              table->rows[child->top_attach].requisition = MAX (table->rows[child->top_attach].requisition, height);
+            }
+        }
+    }
+}
+
+static void
+gtk_table_size_request_pass2 (GtkTable *table)
+{
+  gint max_width;
+  gint max_height;
+  gint row, col;
+
+  if (table->homogeneous)
+    {
+      max_width = 0;
+      max_height = 0;
+
+      for (col = 0; col < table->ncols; col++)
+        max_width = MAX (max_width, table->cols[col].requisition);
+      for (row = 0; row < table->nrows; row++)
+        max_height = MAX (max_height, table->rows[row].requisition);
+
+      for (col = 0; col < table->ncols; col++)
+        table->cols[col].requisition = max_width;
+      for (row = 0; row < table->nrows; row++)
+        table->rows[row].requisition = max_height;
+    }
+}
+
+static void
+gtk_table_size_request_pass3 (GtkTable *table)
+{
+  GtkTableChild *child;
+  GList *children;
+  gint width, height;
+  gint row, col;
+  gint extra;
+
+  children = table->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (child->widget))
+        {
+          /* Child spans multiple columns.
+           */
+          if (child->left_attach != (child->right_attach - 1))
+            {
+              /* Check and see if there is already enough space
+               *  for the child.
+               */
+              width = 0;
+              for (col = child->left_attach; col < child->right_attach; col++)
+                {
+                  width += table->cols[col].requisition;
+                  if ((col + 1) < child->right_attach)
+                    width += table->cols[col].spacing;
+                }
+
+              /* If we need to request more space for this child to fill
+               *  its requisition, then divide up the needed space evenly
+               *  amongst the columns it spans.
+               */
+              if (width < child->widget->requisition.width)
+                {
+                  width = child->widget->requisition.width - width;
+                  extra = width / (child->right_attach - child->left_attach);
+
+                  for (col = child->left_attach; col < child->right_attach; col++)
+                    {
+                      if ((col + 1) < child->right_attach)
+                        table->cols[col].requisition += extra;
+                      else
+                        table->cols[col].requisition += width;
+                      width -= extra;
+                    }
+                }
+            }
+
+          /* Child spans multiple rows.
+           */
+          if (child->top_attach != (child->bottom_attach - 1))
+            {
+              /* Check and see if there is already enough space
+               *  for the child.
+               */
+              height = 0;
+              for (row = child->top_attach; row < child->bottom_attach; row++)
+                {
+                  height += table->rows[row].requisition;
+                  if ((row + 1) < child->bottom_attach)
+                    height += table->rows[row].spacing;
+                }
+
+              /* If we need to request more space for this child to fill
+               *  its requisition, then divide up the needed space evenly
+               *  amongst the columns it spans.
+               */
+              if (height < child->widget->requisition.height)
+                {
+                  height = child->widget->requisition.height - height;
+                  extra = height / (child->bottom_attach - child->top_attach);
+
+                  for (row = child->top_attach; row < child->bottom_attach; row++)
+                    {
+                      if ((row + 1) < child->bottom_attach)
+                        table->rows[row].requisition += extra;
+                      else
+                        table->rows[row].requisition += height;
+                      height -= extra;
+                    }
+                }
+            }
+        }
+    }
+}
+
+static void
+gtk_table_size_allocate_init (GtkTable *table)
+{
+  GtkTableChild *child;
+  GList *children;
+  gint row, col;
+  gint has_expand;
+  gint has_shrink;
+
+  /* Initialize the rows and cols.
+   *  By default, rows and cols do not expand and do shrink.
+   *  Those values are modified by the children that occupy
+   *  the rows and cols.
+   */
+  for (col = 0; col < table->ncols; col++)
+    {
+      table->cols[col].allocation = table->cols[col].requisition;
+      table->cols[col].need_expand = FALSE;
+      table->cols[col].need_shrink = TRUE;
+      table->cols[col].expand = FALSE;
+      table->cols[col].shrink = TRUE;
+    }
+  for (row = 0; row < table->nrows; row++)
+    {
+      table->rows[row].allocation = table->rows[row].requisition;
+      table->rows[row].need_expand = FALSE;
+      table->rows[row].need_shrink = TRUE;
+      table->rows[row].expand = FALSE;
+      table->rows[row].shrink = TRUE;
+    }
+
+  /* Loop over all the children and adjust the row and col values
+   *  based on whether the children want to be allowed to expand
+   *  or shrink. This loop handles children that occupy a single
+   *  row or column.
+   */
+  children = table->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (child->widget))
+        {
+          if (child->left_attach == (child->right_attach - 1))
+            {
+              if (child->xexpand)
+                table->cols[child->left_attach].expand = TRUE;
+
+              if (!child->xshrink)
+                table->cols[child->left_attach].shrink = FALSE;
+            }
+
+          if (child->top_attach == (child->bottom_attach - 1))
+            {
+              if (child->yexpand)
+                table->rows[child->top_attach].expand = TRUE;
+
+              if (!child->yshrink)
+                table->rows[child->top_attach].shrink = FALSE;
+            }
+        }
+    }
+
+  /* Loop over all the children again and this time handle children
+   *  which span multiple rows or columns.
+   */
+  children = table->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (child->widget))
+        {
+          if (child->left_attach != (child->right_attach - 1))
+            {
+              if (child->xexpand)
+                {
+                  has_expand = FALSE;
+                  for (col = child->left_attach; col < child->right_attach; col++)
+                    if (table->cols[col].expand)
+                      {
+                        has_expand = TRUE;
+                        break;
+                      }
+
+                  if (!has_expand)
+                    for (col = child->left_attach; col < child->right_attach; col++)
+                      table->cols[col].need_expand = TRUE;
+                }
+
+              if (!child->xshrink)
+                {
+                  has_shrink = TRUE;
+                  for (col = child->left_attach; col < child->right_attach; col++)
+                    if (!table->cols[col].shrink)
+                      {
+                        has_shrink = FALSE;
+                        break;
+                      }
+
+                  if (has_shrink)
+                    for (col = child->left_attach; col < child->right_attach; col++)
+                      table->cols[col].need_shrink = FALSE;
+                }
+            }
+
+          if (child->top_attach != (child->bottom_attach - 1))
+            {
+              if (child->yexpand)
+                {
+                  has_expand = FALSE;
+                  for (row = child->top_attach; row < child->bottom_attach; row++)
+                    if (table->rows[row].expand)
+                      {
+                        has_expand = TRUE;
+                        break;
+                      }
+
+                  if (!has_expand)
+                    for (row = child->top_attach; row < child->bottom_attach; row++)
+                      table->rows[row].need_expand = TRUE;
+                }
+
+              if (!child->yshrink)
+                {
+                  has_shrink = TRUE;
+                  for (row = child->top_attach; row < child->bottom_attach; row++)
+                    if (!table->rows[row].shrink)
+                      {
+                        has_shrink = FALSE;
+                        break;
+                      }
+
+                  if (has_shrink)
+                    for (row = child->top_attach; row < child->bottom_attach; row++)
+                      table->rows[row].need_shrink = FALSE;
+                }
+            }
+        }
+    }
+
+  /* Loop over the columns and set the expand and shrink values
+   *  if the column can be expanded or shrunk.
+   */
+  for (col = 0; col < table->ncols; col++)
+    {
+      if (table->cols[col].need_expand)
+        table->cols[col].expand = TRUE;
+      if (!table->cols[col].need_shrink)
+        table->cols[col].shrink = FALSE;
+    }
+
+  /* Loop over the rows and set the expand and shrink values
+   *  if the row can be expanded or shrunk.
+   */
+  for (row = 0; row < table->nrows; row++)
+    {
+      if (table->rows[row].need_expand)
+        table->rows[row].expand = TRUE;
+      if (!table->rows[row].need_shrink)
+        table->rows[row].shrink = FALSE;
+    }
+}
+
+static void
+gtk_table_size_allocate_pass1 (GtkTable *table)
+{
+  gint real_width;
+  gint real_height;
+  gint width, height;
+  gint row, col;
+  gint nexpand;
+  gint nshrink;
+  gint extra;
+
+  /* If we were allocated more space than we requested
+   *  then we have to expand any expandable rows and columns
+   *  to fill in the extra space.
+   */
+
+  real_width = GTK_WIDGET (table)->allocation.width - GTK_CONTAINER (table)->border_width * 2;
+  real_height = GTK_WIDGET (table)->allocation.height - GTK_CONTAINER (table)->border_width * 2;
+
+  if (table->homogeneous)
+    {
+      nexpand = 0;
+      for (col = 0; col < table->ncols; col++)
+        if (table->cols[col].expand)
+          {
+            nexpand += 1;
+            break;
+          }
+
+      if (nexpand > 0)
+        {
+          width = real_width;
+
+          for (col = 0; col < table->ncols - 1; col++)
+            width -= table->cols[col].spacing;
+
+          extra = width / table->ncols;
+
+          for (col = 0; col < table->ncols; col++)
+            {
+              if ((col + 1) == table->ncols)
+                table->cols[col].allocation = width;
+              else
+                table->cols[col].allocation = extra;
+
+              width -= extra;
+            }
+        }
+    }
+  else
+    {
+      width = 0;
+      nexpand = 0;
+      nshrink = 0;
+
+      for (col = 0; col < table->ncols; col++)
+        {
+          width += table->cols[col].requisition;
+          if (table->cols[col].expand)
+            nexpand += 1;
+          if (table->cols[col].shrink)
+            nshrink += 1;
+        }
+      for (col = 0; col < table->ncols - 1; col++)
+        width += table->cols[col].spacing;
+
+      /* Check to see if we were allocated more width than we requested.
+       */
+      if ((width < real_width) && (nexpand >= 1))
+        {
+          width = real_width - width;
+          extra = width / nexpand;
+
+          for (col = 0; col < table->ncols; col++)
+            if (table->cols[col].expand)
+              {
+                if (nexpand == 1)
+                  table->cols[col].allocation += width;
+                else
+                  table->cols[col].allocation += extra;
+
+                width -= extra;
+                nexpand -= 1;
+              }
+        }
+
+      /* Check to see if we were allocated less width than we requested.
+       */
+      if ((width > real_width) && (nshrink >= 1))
+        {
+          width = width - real_width;
+          extra = width / nshrink;
+
+          for (col = 0; col < table->ncols; col++)
+            if (table->cols[col].shrink)
+              {
+                if (nshrink == 1)
+                  table->cols[col].allocation -= width;
+                else
+                  table->cols[col].allocation -= extra;
+
+                width -= extra;
+                nshrink -= 1;
+              }
+        }
+    }
+
+  if (table->homogeneous)
+    {
+      nexpand = 0;
+      for (row = 0; row < table->nrows; row++)
+        if (table->rows[row].expand)
+          {
+            nexpand += 1;
+            break;
+          }
+
+      if (nexpand > 0)
+        {
+          height = real_height;
+
+          for (row = 0; row < table->nrows - 1; row++)
+            height -= table->rows[row].spacing;
+
+          extra = height / table->nrows;
+
+          for (row = 0; row < table->nrows; row++)
+            {
+              if ((row + 1) == table->nrows)
+                table->rows[row].allocation = height;
+              else
+                table->rows[row].allocation = extra;
+
+              height -= extra;
+            }
+        }
+    }
+  else
+    {
+      height = 0;
+      nexpand = 0;
+      nshrink = 0;
+
+      for (row = 0; row < table->nrows; row++)
+        {
+          height += table->rows[row].requisition;
+          if (table->rows[row].expand)
+            nexpand += 1;
+          if (table->rows[row].shrink)
+            nshrink += 1;
+        }
+      for (row = 0; row < table->nrows - 1; row++)
+        height += table->rows[row].spacing;
+
+      /* Check to see if we were allocated more height than we requested.
+       */
+      if ((height < real_height) && (nexpand >= 1))
+        {
+          height = real_height - height;
+          extra = height / nexpand;
+
+          for (row = 0; row < table->nrows; row++)
+            if (table->rows[row].expand)
+              {
+                if (nexpand == 1)
+                  table->rows[row].allocation += height;
+                else
+                  table->rows[row].allocation += extra;
+
+                height -= extra;
+                nexpand -= 1;
+              }
+        }
+
+      /* Check to see if we were allocated less height than we requested.
+       */
+      if ((height > real_height) && (nshrink >= 1))
+        {
+          height = height - real_height;
+          extra = height / nshrink;
+
+          for (row = 0; row < table->nrows; row++)
+            if (table->rows[row].shrink)
+              {
+                if (nshrink == 1)
+                  table->rows[row].allocation -= height;
+                else
+                  table->rows[row].allocation -= extra;
+
+                height -= extra;
+                nshrink -= 1;
+              }
+        }
+    }
+}
+
+static void
+gtk_table_size_allocate_pass2 (GtkTable *table)
+{
+  GtkTableChild *child;
+  GList *children;
+  gint max_width;
+  gint max_height;
+  gint x, y;
+  gint row, col;
+  GtkAllocation allocation;
+
+  children = table->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (child->widget))
+        {
+          x = GTK_WIDGET (table)->allocation.x + GTK_CONTAINER (table)->border_width;
+          y = GTK_WIDGET (table)->allocation.y + GTK_CONTAINER (table)->border_width;
+          max_width = 0;
+          max_height = 0;
+
+          for (col = 0; col < child->left_attach; col++)
+            {
+              x += table->cols[col].allocation;
+              x += table->cols[col].spacing;
+            }
+
+          for (col = child->left_attach; col < child->right_attach; col++)
+            {
+              max_width += table->cols[col].allocation;
+              if ((col + 1) < child->right_attach)
+                max_width += table->cols[col].spacing;
+            }
+
+          for (row = 0; row < child->top_attach; row++)
+            {
+              y += table->rows[row].allocation;
+              y += table->rows[row].spacing;
+            }
+
+          for (row = child->top_attach; row < child->bottom_attach; row++)
+            {
+              max_height += table->rows[row].allocation;
+              if ((row + 1) < child->bottom_attach)
+                max_height += table->rows[row].spacing;
+            }
+
+          if (child->xfill)
+            {
+              allocation.width = max_width - child->xpadding * 2;
+              allocation.x = x + (max_width - allocation.width) / 2;
+            }
+          else
+            {
+              allocation.width = child->widget->requisition.width;
+              allocation.x = x + (max_width - allocation.width) / 2;
+            }
+
+          if (child->yfill)
+            {
+              allocation.height = max_height - child->ypadding * 2;
+              allocation.y = y + (max_height - allocation.height) / 2;
+            }
+          else
+            {
+              allocation.height = child->widget->requisition.height;
+              allocation.y = y + (max_height - allocation.height) / 2;
+            }
+
+         gtk_widget_size_allocate (child->widget, &allocation);
+        }
+    }
+}
diff --git a/gtk/gtktable.h b/gtk/gtktable.h
new file mode 100644 (file)
index 0000000..f144e78
--- /dev/null
@@ -0,0 +1,126 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_TABLE_H__
+#define __GTK_TABLE_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkcontainer.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_TABLE(obj)          GTK_CHECK_CAST (obj, gtk_table_get_type (), GtkTable)
+#define GTK_TABLE_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_table_get_type (), GtkTableClass)
+#define GTK_IS_TABLE(obj)       GTK_CHECK_TYPE (obj, gtk_table_get_type ())
+
+
+typedef struct _GtkTable        GtkTable;
+typedef struct _GtkTableClass   GtkTableClass;
+typedef struct _GtkTableChild   GtkTableChild;
+typedef struct _GtkTableRowCol  GtkTableRowCol;
+
+struct _GtkTable
+{
+  GtkContainer container;
+
+  GList *children;
+  GtkTableRowCol *rows;
+  GtkTableRowCol *cols;
+  guint16 nrows;
+  guint16 ncols;
+
+  guint homogeneous : 1;
+};
+
+struct _GtkTableClass
+{
+  GtkContainerClass parent_class;
+};
+
+struct _GtkTableChild
+{
+  GtkWidget *widget;
+  guint16 left_attach;
+  guint16 right_attach;
+  guint16 top_attach;
+  guint16 bottom_attach;
+  guint16 xpadding;
+  guint16 ypadding;
+  guint xexpand : 1;
+  guint yexpand : 1;
+  guint xshrink : 1;
+  guint yshrink : 1;
+  guint xfill : 1;
+  guint yfill : 1;
+};
+
+struct _GtkTableRowCol
+{
+  guint16 requisition;
+  guint16 allocation;
+  guint16 spacing;
+  guint need_expand : 1;
+  guint need_shrink : 1;
+  guint expand : 1;
+  guint shrink : 1;
+};
+
+
+guint      gtk_table_get_type         (void);
+GtkWidget* gtk_table_new              (gint           rows,
+                                      gint           columns,
+                                      gint           homogeneous);
+
+void       gtk_table_attach           (GtkTable      *table,
+                                      GtkWidget     *child,
+                                      gint           left_attach,
+                                      gint           right_attach,
+                                      gint           top_attach,
+                                      gint           bottom_attach,
+                                      gint           xoptions,
+                                      gint           yoptions,
+                                      gint           xpadding,
+                                      gint           ypadding);
+void       gtk_table_attach_defaults  (GtkTable      *table,
+                                      GtkWidget     *widget,
+                                      gint           left_attach,
+                                      gint           right_attach,
+                                      gint           top_attach,
+                                      gint           bottom_attach);
+void       gtk_table_set_row_spacing  (GtkTable      *table,
+                                      gint           row,
+                                      gint           spacing);
+void       gtk_table_set_col_spacing  (GtkTable      *table,
+                                      gint           column,
+                                      gint           spacing);
+void       gtk_table_set_row_spacings (GtkTable      *table,
+                                      gint           spacing);
+void       gtk_table_set_col_spacings (GtkTable      *table,
+                                      gint           spacing);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_TABLE_H__ */
diff --git a/gtk/gtktext.c b/gtk/gtktext.c
new file mode 100644 (file)
index 0000000..ae3dd4b
--- /dev/null
@@ -0,0 +1,3522 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <ctype.h>
+#include <string.h>
+#include "gdk/gdkkeysyms.h"
+#include "gtkmain.h"
+#include "gtksignal.h"
+#include "gtktext.h"
+#include "line-wrap.xbm"
+#include "line-arrow.xbm"
+
+
+#define INITIAL_BUFFER_SIZE      1024
+#define INITIAL_LINE_CACHE_SIZE  256
+#define MIN_GAP_SIZE             256
+#define LINE_DELIM               '\n'
+#define MIN_TEXT_WIDTH_LINES     20
+#define MIN_TEXT_HEIGHT_LINES    10
+#define TEXT_BORDER_ROOM         3
+#define LINE_WRAP_ROOM           8           /* The bitmaps are 6 wide. */
+#define DEFAULT_TAB_STOP_WIDTH   4
+#define SCROLL_PIXELS            5
+#define KEY_SCROLL_PIXELS        10
+
+#define SET_PROPERTY_MARK(m, p, o)  do {                   \
+                                      (m)->property = (p); \
+                                     (m)->offset = (o);   \
+                                   } while (0)
+#define MARK_CURRENT_PROPERTY(mark) ((TextProperty*)(mark)->property->data)
+#define MARK_NEXT_PROPERTY(mark)    ((TextProperty*)(mark)->property->next->data)
+#define MARK_PREV_PROPERTY(mark)    ((TextProperty*)((mark)->property->prev ?     \
+                                                    (mark)->property->prev->data \
+                                                    : NULL))
+#define MARK_PREV_LIST_PTR(mark)    ((mark)->property->prev)
+#define MARK_LIST_PTR(mark)         ((mark)->property)
+#define MARK_NEXT_LIST_PTR(mark)    ((mark)->property->next)
+#define MARK_OFFSET(mark)           ((mark)->offset)
+#define MARK_PROPERTY_LENGTH(mark)  (MARK_CURRENT_PROPERTY(mark)->length)
+#define MARK_CURRENT_FONT(mark)     (((TextProperty*)(mark)->property->data)->font->gdk_font)
+#define MARK_CURRENT_FORE(mark)     (((TextProperty*)(mark)->property->data)->fore_color)
+#define MARK_CURRENT_BACK(mark)     (((TextProperty*)(mark)->property->data)->back_color)
+#define MARK_CURRENT_TEXT_FONT(m)   (((TextProperty*)(m)->property->data)->font)
+#define TEXT_INDEX(t, index)        ((index) < (t)->gap_position ? (t)->text[index] : \
+                                    (t)->text[(index) + (t)->gap_size])
+#define TEXT_LENGTH(t)              ((t)->text_end - (t)->gap_size)
+#define FONT_HEIGHT(f)              ((f)->ascent + (f)->descent)
+#define LINE_HEIGHT(l)              ((l).font_ascent + (l).font_descent)
+#define LINE_CONTAINS(l, i)         ((l).start.index <= (i) && (l).end.index >= (i))
+#define LINE_STARTS_AT(l, i)        ((l).start.index == (i))
+#define LINE_START_PIXEL(l)         ((l).tab_cont.pixel_offset)
+#define LAST_INDEX(t, m)            ((m).index == TEXT_LENGTH(t))
+#define CACHE_DATA(c)               (*(LineParams*)(c)->data)
+
+
+typedef struct _TextFont              TextFont;
+typedef struct _TextProperty          TextProperty;
+typedef struct _TabStopMark           TabStopMark;
+typedef struct _PrevTabCont           PrevTabCont;
+typedef struct _FetchLinesData        FetchLinesData;
+typedef struct _LineParams            LineParams;
+typedef struct _SetVerticalScrollData SetVerticalScrollData;
+
+typedef gint (*LineIteratorFunction) (GtkText* text, LineParams* lp, void* data);
+
+typedef enum
+{
+  FetchLinesPixels,
+  FetchLinesCount
+} FLType;
+
+struct _SetVerticalScrollData {
+  gint pixel_height;
+  gint last_didnt_wrap;
+  gint last_line_start;
+  GtkPropertyMark mark;
+};
+
+struct _TextFont
+{
+  /* The actual font. */
+  GdkFont *gdk_font;
+
+  gint16 char_widths[256];
+};
+
+struct _TextProperty
+{
+  /* Font. */
+  TextFont* font;
+
+  /* Background Color. */
+  GdkColor* back_color;
+
+  /* Foreground Color. */
+  GdkColor* fore_color;
+
+  /* Length of this property. */
+  guint length;
+};
+
+struct _TabStopMark
+{
+  GList* tab_stops; /* Index into list containing the next tab position.  If
+                    * NULL, using default widths. */
+  gint to_next_tab;
+};
+
+struct _PrevTabCont
+{
+  guint pixel_offset;
+  TabStopMark tab_start;
+};
+
+struct _FetchLinesData
+{
+  GList* new_lines;
+  FLType fl_type;
+  gint data;
+  gint data_max;
+};
+
+struct _LineParams
+{
+  guint font_ascent;
+  guint font_descent;
+  guint pixel_width;
+  guint displayable_chars;
+  guint wraps : 1;
+
+  PrevTabCont tab_cont;
+  PrevTabCont tab_cont_next;
+
+  GtkPropertyMark start;
+  GtkPropertyMark end;
+};
+
+
+static void  gtk_text_class_init     (GtkTextClass   *klass);
+static void  gtk_text_init           (GtkText        *text);
+static void  gtk_text_destroy        (GtkObject      *object);
+static void  gtk_text_realize        (GtkWidget      *widget);
+static void  gtk_text_unrealize      (GtkWidget      *widget);
+static void  gtk_text_draw_focus     (GtkWidget      *widget);
+static void  gtk_text_size_request   (GtkWidget      *widget,
+                                     GtkRequisition *requisition);
+static void  gtk_text_size_allocate  (GtkWidget      *widget,
+                                     GtkAllocation  *allocation);
+static void  gtk_text_adjustment     (GtkAdjustment  *adjustment,
+                                     GtkText        *text);
+static void  gtk_text_disconnect     (GtkAdjustment  *adjustment,
+                                     GtkText        *text);
+
+/* Event handlers */
+static void  gtk_text_draw              (GtkWidget         *widget,
+                                        GdkRectangle      *area);
+static gint  gtk_text_expose            (GtkWidget         *widget,
+                                        GdkEventExpose    *event);
+static gint  gtk_text_button_press      (GtkWidget         *widget,
+                                        GdkEventButton    *event);
+static gint  gtk_text_button_release    (GtkWidget         *widget,
+                                        GdkEventButton    *event);
+static gint  gtk_text_motion_notify     (GtkWidget         *widget,
+                                        GdkEventMotion    *event);
+static gint  gtk_text_key_press         (GtkWidget         *widget,
+                                        GdkEventKey       *event);
+static gint  gtk_text_focus_in          (GtkWidget         *widget,
+                                        GdkEventFocus     *event);
+static gint  gtk_text_focus_out         (GtkWidget         *widget,
+                                        GdkEventFocus     *event);
+static gint  gtk_text_selection_clear   (GtkWidget         *widget,
+                                        GdkEventSelection *event);
+static gint  gtk_text_selection_request (GtkWidget         *widget,
+                                        GdkEventSelection *event);
+static gint  gtk_text_selection_notify  (GtkWidget         *widget,
+                                        GdkEventSelection *event);
+
+static void move_gap_to_point (GtkText* text);
+static void make_forward_space (GtkText* text, guint len);
+static void insert_text_property (GtkText* text, GdkFont* font,
+                                 GdkColor *fore, GdkColor* back, guint len);
+static void delete_text_property (GtkText* text, guint len);
+static void init_properties (GtkText *text);
+static guint pixel_height_of (GtkText* text, GList* cache_line);
+
+/* Property Movement and Size Computations */
+static void advance_mark (GtkPropertyMark* mark);
+static void decrement_mark (GtkPropertyMark* mark);
+static void advance_mark_n (GtkPropertyMark* mark, gint n);
+static void decrement_mark_n (GtkPropertyMark* mark, gint n);
+static void move_mark_n (GtkPropertyMark* mark, gint n);
+static GtkPropertyMark find_mark (GtkText* text, guint mark_position);
+static GtkPropertyMark find_mark_near (GtkText* text, guint mark_position, const GtkPropertyMark* near);
+static void find_line_containing_point (GtkText* text, guint point);
+static TextProperty* new_text_property (GdkFont* font, GdkColor* fore, GdkColor* back, guint length);
+
+/* Display */
+static gint total_line_height (GtkText* text,
+                              GList* line,
+                              gint line_count);
+static LineParams find_line_params (GtkText* text,
+                                   const GtkPropertyMark *mark,
+                                   const PrevTabCont *tab_cont,
+                                   PrevTabCont *next_cont);
+static void recompute_geometry (GtkText* text);
+static void insert_char_line_expose (GtkText* text, gchar key, guint old_pixels);
+static void delete_char_line_expose (GtkText* text, gchar key, guint old_pixels);
+static void clear_area (GtkText *text, GdkRectangle *area);
+static void draw_line (GtkText* text,
+                      gint pixel_height,
+                      LineParams* lp);
+static void draw_line_wrap (GtkText* text,
+                           guint height);
+static void draw_cursor (GtkText* text, gint absolute);
+static void undraw_cursor (GtkText* text, gint absolute);
+static gint drawn_cursor_min (GtkText* text);
+static gint drawn_cursor_max (GtkText* text);
+static void expose_text (GtkText* text, GdkRectangle *area, gboolean cursor);
+
+/* Search and Placement. */
+static void find_cursor (GtkText* text);
+static void find_cursor_at_line (GtkText* text,
+                                const LineParams* start_line,
+                                gint pixel_height);
+static void mouse_click_1 (GtkText* text, GdkEventButton *event);
+
+/* Scrolling. */
+static void adjust_adj  (GtkText* text, GtkAdjustment* adj);
+static void scroll_up   (GtkText* text, gint diff);
+static void scroll_down (GtkText* text, gint diff);
+static void scroll_int  (GtkText* text, gint diff);
+
+/* Cache Management. */
+static GList* remove_cache_line (GtkText* text, GList* list);
+
+/* Key Motion. */
+static void move_cursor_buffer_ver (GtkText *text, int dir);
+static void move_cursor_page_ver (GtkText *text, int dir);
+static void move_cursor_ver (GtkText *text, int count);
+static void move_cursor_hor (GtkText *text, int count);
+
+/*#define DEBUG_GTK_TEXT*/
+
+#if defined(DEBUG_GTK_TEXT) && defined(__GNUC__)
+/* Debugging utilities. */
+static void gtk_text_assert_mark (GtkText         *text,
+                                 GtkPropertyMark *mark,
+                                 GtkPropertyMark *before,
+                                 GtkPropertyMark *after,
+                                 const gchar     *msg,
+                                 const gchar     *where,
+                                 gint             line);
+
+static void gtk_text_assert (GtkText         *text,
+                            const gchar     *msg,
+                            gint             line);
+static void gtk_text_show_cache_line (GtkText *text, GList *cache,
+                                     const char* what, const char* func, gint line);
+static void gtk_text_show_cache (GtkText *text, const char* func, gint line);
+static void gtk_text_show_adj (GtkText *text,
+                              GtkAdjustment *adj,
+                              const char* what,
+                              const char* func,
+                              gint line);
+static void gtk_text_show_props (GtkText* test,
+                                const char* func,
+                                int line);
+
+#define TDEBUG(args) g_print args
+#define TEXT_ASSERT(text) gtk_text_assert (text,__PRETTY_FUNCTION__,__LINE__)
+#define TEXT_ASSERT_MARK(text,mark,msg) gtk_text_assert_mark (text,mark, \
+                                          __PRETTY_FUNCTION__,msg,__LINE__)
+#define TEXT_SHOW(text) gtk_text_show_cache (text, __PRETTY_FUNCTION__,__LINE__)
+#define TEXT_SHOW_LINE(text,line,msg) gtk_text_show_cache_line (text,line,msg,\
+                                          __PRETTY_FUNCTION__,__LINE__)
+#define TEXT_SHOW_ADJ(text,adj,msg) gtk_text_show_adj (text,adj,msg, \
+                                         __PRETTY_FUNCTION__,__LINE__)
+#else
+#define TDEBUG(args)
+#define TEXT_ASSERT(text)
+#define TEXT_ASSERT_MARK(text,mark,msg)
+#define TEXT_SHOW(text)
+#define TEXT_SHOW_LINE(text,line,msg)
+#define TEXT_SHOW_ADJ(text,adj,msg)
+#endif
+
+/* Memory Management. */
+static GMemChunk  *params_mem_chunk    = NULL;
+static GMemChunk  *text_property_chunk = NULL;
+
+static GtkWidgetClass *parent_class = NULL;
+
+
+/**********************************************************************/
+/*                             Widget Crap                           */
+/**********************************************************************/
+
+guint
+gtk_text_get_type ()
+{
+  static guint text_type = 0;
+
+  if (!text_type)
+    {
+      GtkTypeInfo text_info =
+      {
+       "GtkText",
+       sizeof (GtkText),
+       sizeof (GtkTextClass),
+       (GtkClassInitFunc) gtk_text_class_init,
+       (GtkObjectInitFunc) gtk_text_init,
+       (GtkArgFunc) NULL,
+      };
+
+      text_type = gtk_type_unique (gtk_widget_get_type (), &text_info);
+    }
+
+  return text_type;
+}
+
+static void
+gtk_text_class_init (GtkTextClass *class)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+
+  object_class = (GtkObjectClass*) class;
+  widget_class = (GtkWidgetClass*) class;
+
+  parent_class = gtk_type_class (gtk_widget_get_type ());
+
+  object_class->destroy = gtk_text_destroy;
+
+  widget_class->realize = gtk_text_realize;
+  widget_class->unrealize = gtk_text_unrealize;
+  widget_class->draw_focus = gtk_text_draw_focus;
+  widget_class->size_request = gtk_text_size_request;
+  widget_class->size_allocate = gtk_text_size_allocate;
+  widget_class->draw = gtk_text_draw;
+  widget_class->expose_event = gtk_text_expose;
+  widget_class->button_press_event = gtk_text_button_press;
+  widget_class->button_release_event = gtk_text_button_release;
+  widget_class->motion_notify_event = gtk_text_motion_notify;
+  widget_class->key_press_event = gtk_text_key_press;
+  widget_class->focus_in_event = gtk_text_focus_in;
+  widget_class->focus_out_event = gtk_text_focus_out;
+  widget_class->selection_clear_event = gtk_text_selection_clear;
+  widget_class->selection_request_event = gtk_text_selection_request;
+  widget_class->selection_notify_event = gtk_text_selection_notify;
+}
+
+static void
+gtk_text_init (GtkText *text)
+{
+  GTK_WIDGET_SET_FLAGS (text, GTK_CAN_FOCUS);
+
+  text->text = g_new (guchar, INITIAL_BUFFER_SIZE);
+  text->text_len = INITIAL_BUFFER_SIZE;
+
+  if (!params_mem_chunk)
+    params_mem_chunk = g_mem_chunk_new ("LineParams",
+                                       sizeof (LineParams),
+                                       256 * sizeof (LineParams),
+                                       G_ALLOC_AND_FREE);
+
+  text->default_tab_width = 4;
+  text->tab_stops = NULL;
+
+  text->tab_stops = g_list_prepend (text->tab_stops, (void*)8);
+  text->tab_stops = g_list_prepend (text->tab_stops, (void*)8);
+
+  text->line_wrap = TRUE;
+  text->is_editable = TRUE;
+}
+
+GtkWidget*
+gtk_text_new (GtkAdjustment *hadj,
+             GtkAdjustment *vadj)
+{
+  GtkText *text;
+
+  text = gtk_type_new (gtk_text_get_type ());
+
+  gtk_text_set_adjustments (text, hadj, vadj);
+
+  return GTK_WIDGET (text);
+}
+
+void
+gtk_text_set_editable (GtkText *text,
+                      gint     editable)
+{
+  g_return_if_fail (text != NULL);
+  g_return_if_fail (GTK_IS_TEXT (text));
+
+  text->is_editable = (editable != FALSE);
+  text->is_editable = FALSE; /* UNTIL JOSH FIXES IT */
+}
+
+void
+gtk_text_set_adjustments (GtkText       *text,
+                         GtkAdjustment *hadj,
+                         GtkAdjustment *vadj)
+{
+  g_return_if_fail (text != NULL);
+  g_return_if_fail (GTK_IS_TEXT (text));
+
+  if (text->hadj && (text->hadj != hadj))
+    {
+      gtk_signal_disconnect_by_data (GTK_OBJECT (text->hadj), text);
+      gtk_object_unref (GTK_OBJECT (text->hadj));
+    }
+
+  if (text->vadj && (text->vadj != vadj))
+    {
+      gtk_signal_disconnect_by_data (GTK_OBJECT (text->vadj), text);
+      gtk_object_unref (GTK_OBJECT (text->vadj));
+    }
+
+  if (!hadj)
+    hadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
+
+  if (!vadj)
+    vadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
+
+  if (text->hadj != hadj)
+    {
+      text->hadj = hadj;
+      gtk_object_ref (GTK_OBJECT (text->hadj));
+
+      gtk_signal_connect (GTK_OBJECT (text->hadj), "changed",
+                         (GtkSignalFunc) gtk_text_adjustment,
+                         text);
+      gtk_signal_connect (GTK_OBJECT (text->hadj), "value_changed",
+                         (GtkSignalFunc) gtk_text_adjustment,
+                         text);
+      gtk_signal_connect (GTK_OBJECT (text->hadj), "disconnect",
+                         (GtkSignalFunc) gtk_text_disconnect,
+                         text);
+    }
+
+  if (text->vadj != vadj)
+    {
+      text->vadj = vadj;
+      gtk_object_ref (GTK_OBJECT (text->vadj));
+
+      gtk_signal_connect (GTK_OBJECT (text->vadj), "changed",
+                         (GtkSignalFunc) gtk_text_adjustment,
+                         text);
+      gtk_signal_connect (GTK_OBJECT (text->vadj), "value_changed",
+                         (GtkSignalFunc) gtk_text_adjustment,
+                         text);
+      gtk_signal_connect (GTK_OBJECT (text->vadj), "disconnect",
+                         (GtkSignalFunc) gtk_text_disconnect,
+                         text);
+    }
+}
+
+void
+gtk_text_set_point (GtkText *text,
+                   guint    index)
+{
+  g_return_if_fail (text != NULL);
+  g_return_if_fail (GTK_IS_TEXT (text));
+  g_return_if_fail (index >= 0 && index <= TEXT_LENGTH (text))
+
+  text->point = find_mark (text, index);
+}
+
+guint
+gtk_text_get_point (GtkText *text)
+{
+  g_return_val_if_fail (text != NULL, 0);
+  g_return_val_if_fail (GTK_IS_TEXT (text), 0);
+
+  return text->point.index;
+}
+
+guint
+gtk_text_get_length (GtkText *text)
+{
+  g_return_val_if_fail (text != NULL, 0);
+  g_return_val_if_fail (GTK_IS_TEXT (text), 0);
+
+  return TEXT_LENGTH (text);
+}
+
+void
+gtk_text_freeze (GtkText *text)
+{
+  g_return_if_fail (text != NULL);
+  g_return_if_fail (GTK_IS_TEXT (text));
+
+  text->freeze = TRUE;
+}
+
+void
+gtk_text_thaw (GtkText *text)
+{
+  g_return_if_fail (text != NULL);
+  g_return_if_fail (GTK_IS_TEXT (text));
+
+  text->freeze = FALSE;
+
+  if (GTK_WIDGET_DRAWABLE (text))
+    {
+      recompute_geometry (text);
+      gtk_widget_queue_draw (GTK_WIDGET (text));
+    }
+}
+
+void
+gtk_text_insert (GtkText    *text,
+                GdkFont    *font,
+                GdkColor   *fore,
+                GdkColor   *back,
+                const char *chars,
+                gint        length)
+{
+  g_return_if_fail (text != NULL);
+  g_return_if_fail (GTK_IS_TEXT (text));
+
+  g_assert (GTK_WIDGET_REALIZED (text));
+
+  /* back may be NULL, fore may not. */
+  if (fore == NULL)
+    fore = &text->widget.style->fg[GTK_STATE_NORMAL];
+
+  /* This must be because we need to have the style set up. */
+  g_assert (GTK_WIDGET_REALIZED(text));
+
+  if (length < 0)
+    length = strlen (chars);
+
+  if (length == 0)
+    return;
+
+  move_gap_to_point (text);
+
+  if (font == NULL)
+    font = GTK_WIDGET (text)->style->font;
+
+  make_forward_space (text, length);
+
+  memcpy (text->text + text->gap_position, chars, length);
+
+  insert_text_property (text, font, fore, back, length);
+
+  text->gap_size -= length;
+  text->gap_position += length;
+
+  advance_mark_n (&text->point, length);
+}
+
+gint
+gtk_text_backward_delete (GtkText *text,
+                         guint    nchars)
+{
+  g_return_val_if_fail (text != NULL, 0);
+  g_return_val_if_fail (GTK_IS_TEXT (text), 0);
+
+  if (nchars > text->point.index || nchars <= 0)
+    return FALSE;
+
+  gtk_text_set_point (text, text->point.index - nchars);
+
+  return gtk_text_foreward_delete (text, nchars);
+}
+
+gint
+gtk_text_foreward_delete (GtkText *text,
+                         guint    nchars)
+{
+  g_return_val_if_fail (text != NULL, 0);
+  g_return_val_if_fail (GTK_IS_TEXT (text), 0);
+
+  if (text->point.index + nchars > TEXT_LENGTH (text) || nchars <= 0)
+    return FALSE;
+
+  move_gap_to_point (text);
+
+  text->gap_size += nchars;
+
+  delete_text_property (text, nchars);
+
+  return TRUE;
+}
+
+static void
+gtk_text_destroy (GtkObject *object)
+{
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_TEXT (object));
+
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+gtk_text_realize (GtkWidget *widget)
+{
+  GtkText *text;
+  GdkWindowAttr attributes;
+  gint attributes_mask;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_TEXT (widget));
+
+  text = (GtkText*) widget;
+  GTK_WIDGET_SET_FLAGS (text, GTK_REALIZED);
+
+  attributes.window_type = GDK_WINDOW_CHILD;
+  attributes.x = widget->allocation.x;
+  attributes.y = widget->allocation.y;
+  attributes.width = widget->allocation.width;
+  attributes.height = widget->allocation.height;
+  attributes.wclass = GDK_INPUT_OUTPUT;
+  attributes.visual = gtk_widget_get_visual (widget);
+  attributes.colormap = gtk_widget_get_colormap (widget);
+  attributes.event_mask = gtk_widget_get_events (widget);
+  attributes.event_mask |= (GDK_EXPOSURE_MASK |
+                           GDK_BUTTON_PRESS_MASK |
+                           GDK_BUTTON_RELEASE_MASK |
+                           GDK_BUTTON_MOTION_MASK |
+                           GDK_ENTER_NOTIFY_MASK |
+                           GDK_LEAVE_NOTIFY_MASK |
+                           GDK_KEY_PRESS_MASK);
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+
+  widget->window = gdk_window_new (widget->parent->window, &attributes, attributes_mask);
+  gdk_window_set_user_data (widget->window, text);
+
+  attributes.x = (widget->style->klass->xthickness + TEXT_BORDER_ROOM);
+  attributes.y = (widget->style->klass->ythickness + TEXT_BORDER_ROOM);
+  attributes.width = widget->allocation.width - attributes.x * 2;
+  attributes.height = widget->allocation.height - attributes.y * 2;
+
+  text->text_area = gdk_window_new (widget->window, &attributes, attributes_mask);
+  gdk_window_set_user_data (text->text_area, text);
+
+  widget->style = gtk_style_attach (widget->style, widget->window);
+
+  /* Can't call gtk_style_set_background here because its handled specially */
+  if (!text->widget.style->bg_pixmap[GTK_STATE_NORMAL])
+    gdk_window_set_background (text->widget.window, &text->widget.style->bg[GTK_STATE_NORMAL]);
+
+  if (!text->widget.style->bg_pixmap[GTK_STATE_NORMAL])
+    gdk_window_set_background (text->text_area, &text->widget.style->bg[GTK_STATE_NORMAL]);
+
+  text->line_wrap_bitmap = gdk_bitmap_create_from_data (text->text_area,
+                                                       (gchar*) line_wrap_bits,
+                                                       line_wrap_width,
+                                                       line_wrap_height);
+
+  text->line_arrow_bitmap = gdk_bitmap_create_from_data (text->text_area,
+                                                        (gchar*) line_arrow_bits,
+                                                        line_arrow_width,
+                                                        line_arrow_height);
+
+  text->gc = gdk_gc_new (text->text_area);
+  gdk_gc_set_exposures (text->gc, TRUE);
+  gdk_gc_set_foreground (text->gc, &widget->style->fg[GTK_STATE_NORMAL]);
+
+  init_properties (text);
+
+  gdk_window_show (text->text_area);
+}
+
+static void
+gtk_text_unrealize (GtkWidget *widget)
+{
+  GtkText *text;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_TEXT (widget));
+
+  text = GTK_TEXT (widget);
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED | GTK_MAPPED);
+
+  gtk_style_detach (widget->style);
+  gdk_window_destroy (widget->window);
+  gdk_window_destroy (text->text_area);
+  gdk_gc_destroy (text->gc);
+
+  widget->window = NULL;
+  text->text_area = NULL;
+  text->gc = NULL;
+}
+
+static void
+clear_focus_area (GtkText *text, gint area_x, gint area_y, gint area_width, gint area_height)
+{
+  gint ythick = TEXT_BORDER_ROOM + text->widget.style->klass->ythickness;
+  gint xthick = TEXT_BORDER_ROOM + text->widget.style->klass->xthickness;
+
+  gint width, height;
+  gint xorig, yorig;
+  gint x, y;
+
+  gdk_window_get_size (text->widget.style->bg_pixmap[GTK_STATE_NORMAL], &width, &height);
+
+  yorig = - text->first_onscreen_ver_pixel + ythick;
+  xorig = - text->first_onscreen_hor_pixel + xthick;
+
+  while (yorig > 0)
+    yorig -= height;
+
+  while (xorig > 0)
+    xorig -= width;
+
+  for (y = area_y; y < area_y + area_height; )
+    {
+      gint yoff = (y - yorig) % height;
+      gint yw = MIN(height - yoff, (area_y + area_height) - y);
+
+      for (x = area_x; x < area_x + area_width; )
+       {
+         gint xoff = (x - xorig) % width;
+         gint xw = MIN(width - xoff, (area_x + area_width) - x);
+
+         gdk_draw_pixmap (text->widget.window,
+                          text->gc,
+                          text->widget.style->bg_pixmap[GTK_STATE_NORMAL],
+                          xoff,
+                          yoff,
+                          x,
+                          y,
+                          xw,
+                          yw);
+
+         x += width - xoff;
+       }
+      y += height - yoff;
+    }
+}
+
+static void
+gtk_text_draw_focus (GtkWidget *widget)
+{
+  GtkText *text;
+  gint width, height;
+  gint x, y;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_TEXT (widget));
+
+  text = GTK_TEXT (widget);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      TDEBUG (("in gtk_text_draw_focus\n"));
+
+      x = 0;
+      y = 0;
+      width = widget->allocation.width;
+      height = widget->allocation.height;
+
+      if (widget->style->bg_pixmap[GTK_STATE_NORMAL])
+       {
+         gint ythick = TEXT_BORDER_ROOM + widget->style->klass->ythickness;
+         gint xthick = TEXT_BORDER_ROOM + widget->style->klass->xthickness;
+
+         /* top rect */
+         clear_focus_area (text, 0, 0, width, ythick);
+         /* right rect */
+         clear_focus_area (text, 0, ythick, xthick, height - 2 * ythick);
+         /* left rect */
+         clear_focus_area (text, width - xthick, ythick, xthick, height - 2 * ythick);
+         /* bottom rect */
+         clear_focus_area (text, 0, height - ythick, width, ythick);
+       }
+
+      if (GTK_WIDGET_HAS_FOCUS (widget))
+       {
+         x += 1;
+         y += 1;
+         width -=  2;
+         height -= 2;
+
+         gdk_draw_rectangle (widget->window,
+                             widget->style->fg_gc[GTK_STATE_NORMAL],
+                             FALSE, 0, 0,
+                             widget->allocation.width - 1,
+                             widget->allocation.height - 1);
+       }
+      else
+       {
+         gdk_draw_rectangle (widget->window,
+                             widget->style->white_gc, FALSE,
+                             x + 2,
+                             y + 2,
+                             width - 1 - 2,
+                             height - 1 - 2);
+       }
+
+      gtk_draw_shadow (widget->style, widget->window,
+                      GTK_STATE_NORMAL, GTK_SHADOW_IN,
+                      x, y, width, height);
+    }
+  else
+    {
+      TDEBUG (("in gtk_text_draw_focus (undrawable !!!)\n"));
+    }
+}
+
+static void
+gtk_text_size_request (GtkWidget      *widget,
+                      GtkRequisition *requisition)
+{
+  gint xthickness;
+  gint ythickness;
+  gint char_height;
+  gint char_width;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_TEXT (widget));
+  g_return_if_fail (requisition != NULL);
+
+  xthickness = widget->style->klass->xthickness + TEXT_BORDER_ROOM;
+  ythickness = widget->style->klass->ythickness + TEXT_BORDER_ROOM;
+
+  char_height = MIN_TEXT_HEIGHT_LINES * (widget->style->font->ascent +
+                                        widget->style->font->descent);
+
+  char_width = MIN_TEXT_WIDTH_LINES * (gdk_text_width (widget->style->font,
+                                                      "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
+                                                      26)
+                                      / 26);
+
+  requisition->width  = char_width  + xthickness * 2;
+  requisition->height = char_height + ythickness * 2;
+}
+
+static void
+gtk_text_size_allocate (GtkWidget     *widget,
+                       GtkAllocation *allocation)
+{
+  GtkText *text;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_TEXT (widget));
+  g_return_if_fail (allocation != NULL);
+
+  text = GTK_TEXT (widget);
+
+  widget->allocation = *allocation;
+  if (GTK_WIDGET_REALIZED (widget))
+    {
+      gdk_window_move_resize (widget->window,
+                             allocation->x, allocation->y,
+                             allocation->width, allocation->height);
+
+      gdk_window_move_resize (text->text_area,
+                             widget->style->klass->xthickness + TEXT_BORDER_ROOM,
+                             widget->style->klass->ythickness + TEXT_BORDER_ROOM,
+                             widget->allocation.width - (widget->style->klass->xthickness +
+                                                         TEXT_BORDER_ROOM) * 2,
+                             widget->allocation.height - (widget->style->klass->ythickness +
+                                                          TEXT_BORDER_ROOM) * 2);
+
+      recompute_geometry (text);
+    }
+}
+
+static void
+gtk_text_draw (GtkWidget    *widget,
+              GdkRectangle *area)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_TEXT (widget));
+  g_return_if_fail (area != NULL);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      expose_text (GTK_TEXT (widget), area, TRUE);
+      gtk_widget_draw_focus (widget);
+    }
+}
+
+static gint
+gtk_text_expose (GtkWidget      *widget,
+                GdkEventExpose *event)
+{
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_TEXT (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (event->window == GTK_TEXT (widget)->text_area)
+    {
+      TDEBUG (("in gtk_text_expose (expose)\n"));
+      expose_text (GTK_TEXT (widget), &event->area, TRUE);
+    }
+  else if (event->count == 0)
+    {
+      TDEBUG (("in gtk_text_expose (focus)\n"));
+      gtk_widget_draw_focus (widget);
+    }
+
+  return FALSE;
+}
+
+static gint
+gtk_text_button_press (GtkWidget      *widget,
+                      GdkEventButton *event)
+{
+  GtkText *text;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_TEXT (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  text = GTK_TEXT(widget);
+  if (!GTK_WIDGET_HAS_FOCUS (widget))
+    gtk_widget_grab_focus (widget);
+
+  if (event->type == GDK_BUTTON_PRESS && event->button != 2)
+    gtk_grab_add (widget);
+
+  if (event->button == 1)
+    {
+      switch (event->type)
+       {
+       case GDK_BUTTON_PRESS:
+         undraw_cursor (GTK_TEXT (widget), FALSE);
+         mouse_click_1 (GTK_TEXT (widget), event);
+         draw_cursor (GTK_TEXT (widget), FALSE);
+         /* start selection */
+         break;
+
+       case GDK_2BUTTON_PRESS:
+         /* select word */
+         break;
+
+       case GDK_3BUTTON_PRESS:
+         /* select line */
+         break;
+
+       default:
+         break;
+       }
+    }
+  else if (event->type == GDK_BUTTON_PRESS)
+    {
+      if (event->button == 2)
+       {
+         /* insert selection. */
+       }
+      else
+       {
+         /* start selection */
+       }
+    }
+
+  return FALSE;
+}
+
+static gint
+gtk_text_button_release (GtkWidget      *widget,
+                        GdkEventButton *event)
+{
+  GtkText *text;
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_TEXT (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (event->button != 2)
+    {
+      gtk_grab_remove (widget);
+
+      text = GTK_TEXT (widget);
+
+      /* stop selecting. */
+    }
+
+  return FALSE;
+}
+
+static gint
+gtk_text_motion_notify (GtkWidget      *widget,
+                        GdkEventMotion *event)
+{
+  GtkText *text;
+  gint x;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_TEXT (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  text = GTK_TEXT (widget);
+
+  x = event->x;
+  if (event->is_hint || (text->text_area != event->window))
+    gdk_window_get_pointer (text->text_area, &x, NULL, NULL);
+
+  /* update selection */
+
+  return FALSE;
+}
+
+static void
+gtk_text_insert_1_at_point (GtkText* text, char key)
+{
+  gtk_text_insert (text,
+                  MARK_CURRENT_FONT (&text->point),
+                  MARK_CURRENT_FORE (&text->point),
+                  MARK_CURRENT_BACK (&text->point),
+                  &key, 1);
+}
+
+static gint
+gtk_text_key_press (GtkWidget   *widget,
+                   GdkEventKey *event)
+{
+  GtkText *text;
+  gchar key;
+  gint return_val;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_TEXT (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  return_val = FALSE;
+
+  text = GTK_TEXT (widget);
+
+  if (!return_val)
+    {
+      key = event->keyval;
+      return_val = TRUE;
+
+      if (text->is_editable == FALSE)
+       {
+         switch (event->keyval)
+           {
+           case GDK_Home:      scroll_int (text, -text->vadj->value); break;
+           case GDK_End:       scroll_int (text, +text->vadj->upper); break;
+           case GDK_Page_Up:   scroll_int (text, -text->vadj->page_increment); break;
+           case GDK_Page_Down: scroll_int (text, +text->vadj->page_increment); break;
+           case GDK_Up:        scroll_int (text, -KEY_SCROLL_PIXELS); break;
+           case GDK_Down:      scroll_int (text, +KEY_SCROLL_PIXELS); break;
+           default: break;
+           }
+       }
+      else
+       {
+         text->point = find_mark (text, text->cursor_mark.index);
+
+         switch (event->keyval)
+           {
+           case GDK_Home:      move_cursor_buffer_ver (text, -1); break;
+           case GDK_End:       move_cursor_buffer_ver (text, +1); break;
+           case GDK_Page_Up:   move_cursor_page_ver (text, -1); break;
+           case GDK_Page_Down: move_cursor_page_ver (text, +1); break;
+           case GDK_Up:        move_cursor_ver (text, -1); break;
+           case GDK_Down:      move_cursor_ver (text, +1); break;
+           case GDK_Left:      move_cursor_hor (text, -1); break;
+           case GDK_Right:     move_cursor_hor (text, +1); break;
+
+           case GDK_BackSpace:
+             if (!text->has_cursor || text->cursor_mark.index == 0)
+               break;
+
+             gtk_text_backward_delete (text, 1);
+             break;
+           case GDK_Delete:
+             if (!text->has_cursor || LAST_INDEX (text, text->cursor_mark))
+               break;
+
+             gtk_text_foreward_delete (text, 1);
+             break;
+           case GDK_Tab:
+             if (!text->has_cursor)
+               break;
+
+             gtk_text_insert_1_at_point (text, '\t');
+             break;
+           case GDK_Return:
+             if (!text->has_cursor)
+               break;
+
+             gtk_text_insert_1_at_point (text, '\n');
+             break;
+           default:
+             if (!text->has_cursor)
+               break;
+
+             if ((event->keyval >= 0x20) && (event->keyval <= 0x7e))
+               {
+                 return_val = TRUE;
+
+                 if (event->state & GDK_CONTROL_MASK)
+                   {
+                     if ((key >= 'A') && (key <= 'Z'))
+                       key -= 'A' - 'a';
+
+                     if ((key >= 'a') && (key <= 'z') && text->control_keys[(int) (key - 'a')])
+                       (* text->control_keys[(int) (key - 'a')]) (text);
+                   }
+                 else if (event->state & GDK_MOD1_MASK)
+                   {
+                     g_message ("alt key");
+
+                     if ((key >= 'A') && (key <= 'Z'))
+                       key -= 'A' - 'a';
+
+                     if ((key >= 'a') && (key <= 'z') && text->alt_keys[(int) (key - 'a')])
+                       (* text->alt_keys[(int) (key - 'a')]) (text);
+                   }
+                 else
+                   {
+                     gtk_text_insert_1_at_point (text, key);
+                   }
+               }
+             else
+               {
+                 return_val = FALSE;
+               }
+             break;
+           }
+       }
+    }
+
+  return return_val;
+}
+
+static gint
+gtk_text_focus_in (GtkWidget     *widget,
+                  GdkEventFocus *event)
+{
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_TEXT (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  TDEBUG (("in gtk_text_focus_in\n"));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
+  gtk_widget_draw_focus (widget);
+
+  draw_cursor (GTK_TEXT(widget), TRUE);
+
+  return FALSE;
+}
+
+static gint
+gtk_text_focus_out (GtkWidget     *widget,
+                   GdkEventFocus *event)
+{
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_TEXT (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  TDEBUG (("in gtk_text_focus_out\n"));
+
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
+  gtk_widget_draw_focus (widget);
+
+  undraw_cursor (GTK_TEXT(widget), TRUE);
+
+  return FALSE;
+}
+
+static void
+gtk_text_adjustment (GtkAdjustment *adjustment,
+                    GtkText       *text)
+{
+  g_return_if_fail (adjustment != NULL);
+  g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
+  g_return_if_fail (text != NULL);
+  g_return_if_fail (GTK_IS_TEXT (text));
+
+  if (adjustment == text->hadj)
+    {
+      g_warning ("horizontal scrolling not implemented");
+    }
+  else
+    {
+      gint diff = ((gint)adjustment->value) - text->last_ver_value;
+
+      if (diff != 0)
+       {
+         undraw_cursor (text, FALSE);
+
+         if (diff > 0)
+           scroll_down (text, diff);
+         else /* if (diff < 0) */
+           scroll_up (text, diff);
+
+         draw_cursor (text, FALSE);
+
+         text->last_ver_value = adjustment->value;
+       }
+    }
+}
+
+static void
+gtk_text_disconnect (GtkAdjustment *adjustment,
+                    GtkText       *text)
+{
+  g_return_if_fail (adjustment != NULL);
+  g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
+  g_return_if_fail (text != NULL);
+  g_return_if_fail (GTK_IS_TEXT (text));
+
+  if (adjustment == text->hadj)
+    text->hadj = NULL;
+  if (adjustment == text->vadj)
+    text->vadj = NULL;
+}
+
+
+static GtkPropertyMark
+find_this_line_start_mark (GtkText* text, guint point_position, const GtkPropertyMark* near)
+{
+  GtkPropertyMark mark;
+
+  mark = find_mark_near (text, point_position, near);
+
+  while (mark.index > 0 &&
+        TEXT_INDEX (text, mark.index - 1) != LINE_DELIM)
+    decrement_mark (&mark);
+
+  return mark;
+}
+
+static void
+init_tab_cont (GtkText* text, PrevTabCont* tab_cont)
+{
+  tab_cont->pixel_offset          = 0;
+  tab_cont->tab_start.tab_stops   = text->tab_stops;
+  tab_cont->tab_start.to_next_tab = (gulong) text->tab_stops->data;
+
+  if (!tab_cont->tab_start.to_next_tab)
+    tab_cont->tab_start.to_next_tab = text->default_tab_width;
+}
+
+static void
+line_params_iterate (GtkText* text,
+                    const GtkPropertyMark* mark0,
+                    const PrevTabCont* tab_mark0,
+                    gint8 alloc,
+                    void* data,
+                    LineIteratorFunction iter)
+  /* mark0 MUST be a real line start.  if ALLOC, allocate line params
+   * from a mem chunk.  DATA is passed to ITER_CALL, which is called
+   * for each line following MARK, iteration continues unless ITER_CALL
+   * returns TRUE. */
+{
+  GtkPropertyMark mark = *mark0;
+  PrevTabCont  tab_conts[2];
+  LineParams   *lp, lpbuf;
+  gint         tab_cont_index = 0;
+
+  if (tab_mark0)
+    tab_conts[0] = *tab_mark0;
+  else
+    init_tab_cont (text, tab_conts);
+
+  for (;;)
+    {
+      if (alloc)
+       lp = g_chunk_new (LineParams, params_mem_chunk);
+      else
+       lp = &lpbuf;
+
+      *lp = find_line_params (text, &mark, tab_conts + tab_cont_index,
+                             tab_conts + (tab_cont_index + 1) % 2);
+
+      if ((*iter) (text, lp, data))
+       return;
+
+      if (LAST_INDEX (text, lp->end))
+       break;
+
+      mark = lp->end;
+      advance_mark (&mark);
+      tab_cont_index = (tab_cont_index + 1) % 2;
+    }
+}
+
+static gint
+fetch_lines_iterator (GtkText* text, LineParams* lp, void* data)
+{
+  FetchLinesData *fldata = (FetchLinesData*) data;
+
+  fldata->new_lines = g_list_prepend (fldata->new_lines, lp);
+
+  switch (fldata->fl_type)
+    {
+    case FetchLinesCount:
+      if (!text->line_wrap || !lp->wraps)
+       fldata->data += 1;
+
+      if (fldata->data >= fldata->data_max)
+       return TRUE;
+
+      break;
+    case FetchLinesPixels:
+
+      fldata->data += LINE_HEIGHT(*lp);
+
+      if (fldata->data >= fldata->data_max)
+       return TRUE;
+
+      break;
+    }
+
+  return FALSE;
+}
+
+static GList*
+fetch_lines (GtkText* text,
+            const GtkPropertyMark* mark0,
+            const PrevTabCont* tab_cont0,
+            FLType fl_type,
+            gint data)
+{
+  FetchLinesData fl_data;
+
+  fl_data.new_lines = NULL;
+  fl_data.data      = 0;
+  fl_data.data_max  = data;
+  fl_data.fl_type   = fl_type;
+
+  line_params_iterate (text, mark0, tab_cont0, TRUE, &fl_data, fetch_lines_iterator);
+
+  return g_list_reverse (fl_data.new_lines);
+}
+
+static void
+fetch_lines_backward (GtkText* text)
+{
+  GList* new_lines = NULL, *new_line_start;
+
+  GtkPropertyMark mark = find_this_line_start_mark (text,
+                                                CACHE_DATA(text->line_start_cache).start.index - 1,
+                                                &CACHE_DATA(text->line_start_cache).start);
+
+  new_line_start = new_lines = fetch_lines (text, &mark, NULL, FetchLinesCount, 1);
+
+  while (new_line_start->next)
+    new_line_start = new_line_start->next;
+
+  new_line_start->next = text->line_start_cache;
+  text->line_start_cache->prev = new_line_start;
+}
+
+static void
+fetch_lines_forward (GtkText* text, gint line_count)
+{
+  GtkPropertyMark mark;
+  GList* line = text->line_start_cache;
+
+  while(line->next)
+    line = line->next;
+
+  mark = CACHE_DATA(line).end;
+
+  if (LAST_INDEX (text, mark))
+    return;
+
+  advance_mark(&mark);
+
+  line->next = fetch_lines (text, &mark, &CACHE_DATA(line).tab_cont_next, FetchLinesCount, line_count);
+
+  if (line->next)
+    line->next->prev = line;
+}
+
+static gint
+total_line_height (GtkText* text, GList* line, gint line_count)
+{
+  gint height = 0;
+
+  for (; line && line_count > 0; line = line->next)
+    {
+      height += LINE_HEIGHT(CACHE_DATA(line));
+
+      if (!text->line_wrap || !CACHE_DATA(line).wraps)
+       line_count -= 1;
+
+      if (!line->next)
+       fetch_lines_forward (text, line_count);
+    }
+
+  return height;
+}
+
+static void
+swap_lines (GtkText* text, GList* old, GList* new, gint old_line_count)
+{
+  if (old == text->line_start_cache)
+    {
+      GList* last;
+
+      for (; old_line_count > 0; old_line_count -= 1)
+       {
+         while (text->line_start_cache &&
+                text->line_wrap &&
+                CACHE_DATA(text->line_start_cache).wraps)
+           remove_cache_line(text, text->line_start_cache);
+
+         remove_cache_line(text, text->line_start_cache);
+       }
+
+      last = g_list_last (new);
+
+      last->next = text->line_start_cache;
+
+      if (text->line_start_cache)
+       text->line_start_cache->prev = last;
+
+      text->line_start_cache = new;
+    }
+  else
+    {
+      GList *last;
+
+      g_assert (old->prev);
+
+      last = old->prev;
+
+      for (; old_line_count > 0; old_line_count -= 1)
+       {
+         while (old && text->line_wrap && CACHE_DATA(old).wraps)
+           old = remove_cache_line (text, old);
+
+         old = remove_cache_line (text, old);
+       }
+
+      last->next = new;
+      new->prev = last;
+
+      last = g_list_last (new);
+
+      last->next = old;
+
+      if (old)
+       old->prev = last;
+    }
+}
+
+static void
+correct_cache_delete (GtkText* text, gint lines)
+{
+  GList* cache = text->current_line;
+  gint i;
+
+  for (i = 0; cache && i < lines; i += 1, cache = cache->next)
+    /* nothing */;
+
+  for (; cache; cache = cache->next)
+    {
+      GtkPropertyMark *start = &CACHE_DATA(cache).start;
+      GtkPropertyMark *end = &CACHE_DATA(cache).end;
+
+      start->index -= 1;
+      end->index -= 1;
+
+      if (start->property == text->point.property)
+       start->offset = start->index - (text->point.index - text->point.offset);
+
+      if (end->property == text->point.property)
+       end->offset = end->index - (text->point.index - text->point.offset);
+
+      /*TEXT_ASSERT_MARK(text, start, "start");*/
+      /*TEXT_ASSERT_MARK(text, end, "end");*/
+    }
+}
+
+static void
+delete_char_line_expose (GtkText* text, gchar key, guint old_pixels)
+{
+  gint pixel_height;
+  guint new_pixels = 0;
+  gint old_line_count = 1 + (key == LINE_DELIM);
+  GdkRectangle rect;
+  GList* new_line = NULL;
+  gint width, height;
+
+  text->cursor_virtual_x = 0;
+
+  undraw_cursor (text, FALSE);
+
+  correct_cache_delete (text, old_line_count);
+
+  pixel_height = pixel_height_of(text, text->current_line) -
+                 LINE_HEIGHT(CACHE_DATA(text->current_line));
+
+  if (CACHE_DATA(text->current_line).start.index == text->point.index)
+    CACHE_DATA(text->current_line).start = text->point;
+
+  new_line = fetch_lines (text,
+                         &CACHE_DATA(text->current_line).start,
+                         &CACHE_DATA(text->current_line).tab_cont,
+                         FetchLinesCount,
+                         1);
+
+  swap_lines (text, text->current_line, new_line, old_line_count);
+
+  text->current_line = new_line;
+
+  new_pixels = total_line_height (text, new_line, 1);
+
+  gdk_window_get_size (text->text_area, &width, &height);
+
+  if (old_pixels != new_pixels)
+    {
+      gdk_draw_pixmap (text->text_area,
+                      text->gc,
+                      text->text_area,
+                      0,
+                      pixel_height + old_pixels,
+                      0,
+                      pixel_height + new_pixels,
+                      width,
+                      height);
+
+      text->vadj->upper += new_pixels;
+      text->vadj->upper -= old_pixels;
+      adjust_adj (text, text->vadj);
+    }
+
+  rect.x = 0;
+  rect.y = pixel_height;
+  rect.width = width;
+  rect.height = new_pixels;
+
+  expose_text (text, &rect, FALSE);
+  gtk_text_draw_focus ( (GtkWidget *) text);
+
+  text->cursor_mark = text->point;
+
+  find_cursor (text);
+
+  draw_cursor (text, FALSE);
+
+  TEXT_ASSERT (text);
+  TEXT_SHOW(text);
+}
+
+static void
+correct_cache_insert (GtkText* text)
+{
+  GList* cache = text->current_line;
+
+  for (; cache; cache = cache->next)
+    {
+      GtkPropertyMark *start = &CACHE_DATA(cache).start;
+      GtkPropertyMark *end = &CACHE_DATA(cache).end;
+
+      if (start->index >= text->point.index)
+       {
+         if (start->property == text->point.property)
+           move_mark_n(start, 1);
+         else
+           start->index += 1;
+       }
+
+      if (end->index >= text->point.index)
+       {
+         if (end->property == text->point.property)
+           move_mark_n(end, 1);
+         else
+           end->index += 1;
+       }
+
+      /*TEXT_ASSERT_MARK(text, start, "start");*/
+      /*TEXT_ASSERT_MARK(text, end, "end");*/
+    }
+}
+
+
+static void
+insert_char_line_expose (GtkText* text, gchar key, guint old_pixels)
+{
+  gint pixel_height;
+  guint new_pixels = 0;
+  guint new_line_count = 1 + (key == LINE_DELIM);
+  GdkRectangle rect;
+  GList* new_line = NULL;
+  gint width, height;
+
+  text->cursor_virtual_x = 0;
+
+  undraw_cursor (text, FALSE);
+
+  correct_cache_insert (text);
+
+  TEXT_SHOW_ADJ (text, text->vadj, "vadj");
+
+  pixel_height = pixel_height_of(text, text->current_line) -
+                 LINE_HEIGHT(CACHE_DATA(text->current_line));
+
+  new_line = fetch_lines (text,
+                         &CACHE_DATA(text->current_line).start,
+                         &CACHE_DATA(text->current_line).tab_cont,
+                         FetchLinesCount,
+                         new_line_count);
+
+  swap_lines (text, text->current_line, new_line, 1);
+
+  text->current_line = new_line;
+
+  new_pixels = total_line_height (text, new_line, new_line_count);
+
+  gdk_window_get_size (text->text_area, &width, &height);
+
+  if (old_pixels != new_pixels)
+    {
+      gdk_draw_pixmap (text->text_area,
+                      text->gc,
+                      text->text_area,
+                      0,
+                      pixel_height + old_pixels,
+                      0,
+                      pixel_height + new_pixels,
+                      width,
+                      height + (old_pixels - new_pixels) - pixel_height);
+
+      text->vadj->upper += new_pixels;
+      text->vadj->upper -= old_pixels;
+      adjust_adj (text, text->vadj);
+    }
+
+  rect.x = 0;
+  rect.y = pixel_height;
+  rect.width = width;
+  rect.height = new_pixels;
+
+  expose_text (text, &rect, FALSE);
+  gtk_text_draw_focus ( (GtkWidget *) text);
+
+  text->cursor_mark = text->point;
+
+  find_cursor (text);
+
+  draw_cursor (text, FALSE);
+
+  TEXT_SHOW_ADJ (text, text->vadj, "vadj");
+  TEXT_ASSERT (text);
+  TEXT_SHOW(text);
+}
+
+static guint
+font_hash (gpointer font)
+{
+  return gdk_font_id ((GdkFont*) font);
+}
+
+static TextFont*
+get_text_font (GdkFont* gfont)
+{
+  static GHashTable *font_cache_table = NULL;
+  TextFont* tf;
+  gpointer lu;
+  gint i;
+
+  if (!font_cache_table)
+    font_cache_table = g_hash_table_new (font_hash, (GCompareFunc) gdk_font_equal);
+
+  lu = g_hash_table_lookup (font_cache_table, gfont);
+
+  if (lu)
+    return (TextFont*)lu;
+
+  tf = g_new (TextFont, 1);
+
+  tf->gdk_font = gfont;
+
+  for(i = 0; i < 256; i += 1)
+    tf->char_widths[i] = gdk_char_width (gfont, (char)i);
+
+  g_hash_table_insert (font_cache_table, gfont, tf);
+
+  return tf;
+}
+
+static gint
+text_properties_equal (TextProperty* prop, GdkFont* font, GdkColor *fore, GdkColor *back)
+{
+  return prop->font == get_text_font(font) &&
+         (fore == prop->fore_color || gdk_color_equal(prop->fore_color, fore)) &&
+         (back == prop->back_color || (back && prop->back_color && gdk_color_equal(prop->back_color, back)));
+}
+
+static TextProperty*
+new_text_property (GdkFont* font, GdkColor* fore, GdkColor* back, guint length)
+{
+  TextProperty *prop;
+
+  if (text_property_chunk == NULL)
+    {
+      text_property_chunk = g_mem_chunk_new ("text property mem chunk",
+                                            sizeof(TextProperty),
+                                            1024*sizeof(TextProperty),
+                                            G_ALLOC_ONLY);
+    }
+
+  prop = g_chunk_new(TextProperty, text_property_chunk);
+
+  prop->font = get_text_font (font);
+  prop->fore_color = fore;
+  prop->back_color = back;
+  prop->length = length;
+
+  return prop;
+}
+
+/* Flop the memory between the point and the gap around like a
+ * dead fish. */
+static void
+move_gap_to_point (GtkText* text)
+{
+  if (text->gap_position < text->point.index)
+    {
+      gint diff = text->point.index - text->gap_position;
+
+      memmove (text->text + text->gap_position,
+              text->text + text->gap_position + text->gap_size,
+              diff);
+
+      text->gap_position = text->point.index;
+    }
+  else if (text->gap_position > text->point.index)
+    {
+      gint diff = text->gap_position - text->point.index;
+
+      memmove (text->text + text->point.index + text->gap_size,
+              text->text + text->point.index,
+              diff);
+
+      text->gap_position = text->point.index;
+    }
+}
+
+/* Increase the gap size. */
+static void
+make_forward_space (GtkText* text, guint len)
+{
+  if (text->gap_size < len)
+    {
+      guint sum = MAX(2*len, MIN_GAP_SIZE) + text->text_end;
+
+      if (sum >= text->text_len)
+       {
+         guint i = 1;
+
+         while (i <= sum) i <<= 1;
+
+         text->text = (guchar*)g_realloc(text->text, i);
+       }
+
+      memmove (text->text + text->gap_position + text->gap_size + 2*len,
+              text->text + text->gap_position + text->gap_size,
+              text->text_end - (text->gap_position + text->gap_size));
+
+      text->text_end += len*2;
+      text->gap_size += len*2;
+    }
+}
+
+/* Inserts into the text property list a list element that guarantees
+ * that for len characters following the point, text has the correct
+ * property.  does not move point.  adjusts text_properties_point and
+ * text_properties_point_offset relative to the current value of
+ * point. */
+static void
+insert_text_property (GtkText* text, GdkFont* font,
+                     GdkColor *fore, GdkColor* back, guint len)
+{
+  GtkPropertyMark *mark = &text->point;
+  TextProperty* forward_prop = MARK_CURRENT_PROPERTY(mark);
+  TextProperty* backward_prop = MARK_PREV_PROPERTY(mark);
+
+  if (MARK_OFFSET(mark) == 0)
+    {
+      /* Point is on the boundary of two properties.
+       * If it is the same as either, grow, else insert
+       * a new one. */
+
+      if (text_properties_equal(forward_prop, font, fore, back))
+       {
+         /* Grow the property in front of us. */
+
+         MARK_PROPERTY_LENGTH(mark) += len;
+       }
+      else if (backward_prop &&
+              text_properties_equal(backward_prop, font, fore, back))
+       {
+         /* Grow property behind us, point property and offset
+          * change. */
+
+         SET_PROPERTY_MARK (&text->point,
+                            MARK_PREV_LIST_PTR (mark),
+                            backward_prop->length);
+
+         backward_prop->length += len;
+       }
+      else
+       {
+         /* Splice a new property into the list. */
+
+         GList* new_prop = g_list_alloc();
+
+         new_prop->next = MARK_LIST_PTR(mark);
+         new_prop->prev = MARK_PREV_LIST_PTR(mark);
+         new_prop->next->prev = new_prop;
+
+         if (new_prop->prev)
+           new_prop->prev->next = new_prop;
+
+         new_prop->data = new_text_property (font, fore, back, len);
+
+         SET_PROPERTY_MARK (mark, new_prop, 0);
+       }
+    }
+  else
+    {
+      /* In the middle of forward_prop, if properties are equal,
+       * just add to its length, else split it into two and splice
+       * in a new one. */
+      if (text_properties_equal (forward_prop, font, fore, back))
+       {
+         forward_prop->length += len;
+       }
+      else
+       {
+         GList* new_prop = g_list_alloc();
+         GList* new_prop_forward = g_list_alloc();
+         gint old_length = forward_prop->length;
+         GList* next = MARK_NEXT_LIST_PTR(mark);
+
+         /* Set the new lengths according to where they are split.  Construct
+          * two new properties. */
+         forward_prop->length = MARK_OFFSET(mark);
+
+         new_prop_forward->data = new_text_property(forward_prop->font->gdk_font,
+                                                    fore,
+                                                    back,
+                                                    old_length - forward_prop->length);
+
+         new_prop->data = new_text_property(font, fore, back, len);
+
+         /* Now splice things in. */
+         MARK_NEXT_LIST_PTR(mark) = new_prop;
+         new_prop->prev = MARK_LIST_PTR(mark);
+
+         new_prop->next = new_prop_forward;
+         new_prop_forward->prev = new_prop;
+
+         new_prop_forward->next = next;
+
+         if (next)
+           next->prev = new_prop_forward;
+
+         SET_PROPERTY_MARK (mark, new_prop, 0);
+       }
+    }
+
+  while (text->text_properties_end->next)
+    text->text_properties_end = text->text_properties_end->next;
+
+  while (text->text_properties->prev)
+    text->text_properties = text->text_properties->prev;
+}
+
+static void
+delete_text_property (GtkText* text, guint nchars)
+{
+  /* Delete nchars forward from point. */
+  TextProperty *prop;
+  GList        *tmp;
+  gint          is_first;
+
+  for(; nchars; nchars -= 1)
+    {
+      prop = MARK_CURRENT_PROPERTY(&text->point);
+
+      prop->length -= 1;
+
+      if (prop->length == 0)
+       {
+         tmp = MARK_LIST_PTR (&text->point);
+
+         is_first = tmp == text->text_properties;
+
+         MARK_LIST_PTR (&text->point) = g_list_remove_link (tmp, tmp);
+         text->point.offset = 0;
+
+         g_mem_chunk_free (text_property_chunk, prop);
+
+         prop = MARK_CURRENT_PROPERTY (&text->point);
+
+         if (is_first)
+           text->text_properties = MARK_LIST_PTR (&text->point);
+
+         g_assert (prop->length != 0);
+       }
+      else if (prop->length == text->point.offset)
+       {
+         MARK_LIST_PTR (&text->point) = MARK_NEXT_LIST_PTR (&text->point);
+         text->point.offset = 0;
+       }
+    }
+}
+
+static void
+init_properties (GtkText *text)
+{
+  if (!text->text_properties)
+    {
+      text->text_properties = g_list_alloc();
+      text->text_properties->next = NULL;
+      text->text_properties->prev = NULL;
+      text->text_properties->data = new_text_property (text->widget.style->font,
+                                                      &text->widget.style->fg[GTK_STATE_NORMAL],
+                                                      &text->widget.style->bg[GTK_STATE_NORMAL],
+                                                      1);
+      text->text_properties_end = text->text_properties;
+
+      SET_PROPERTY_MARK (&text->point, text->text_properties, 0);
+
+      text->point.index = 0;
+    }
+}
+
+
+/**********************************************************************/
+/*                        Property Movement                          */
+/**********************************************************************/
+
+static void
+move_mark_n (GtkPropertyMark* mark, gint n)
+{
+  if (n > 0)
+    advance_mark_n(mark, n);
+  else if (n < 0)
+    decrement_mark_n(mark, -n);
+}
+
+static void
+advance_mark_n (GtkPropertyMark* mark, gint n)
+{
+  gint i;
+
+  g_assert (n > 0);
+
+  for (i = 0; i < n; i += 1)
+    advance_mark (mark);
+}
+
+static void
+advance_mark (GtkPropertyMark* mark)
+{
+  TextProperty* prop = MARK_CURRENT_PROPERTY (mark);
+
+  mark->index += 1;
+
+  if (prop->length > mark->offset + 1)
+    mark->offset += 1;
+  else
+    {
+      mark->property = MARK_NEXT_LIST_PTR (mark);
+      mark->offset   = 0;
+    }
+}
+
+static void
+decrement_mark (GtkPropertyMark* mark)
+{
+  mark->index -= 1;
+
+  if (mark->offset > 0)
+    mark->offset -= 1;
+  else
+    {
+      mark->property = MARK_PREV_LIST_PTR (mark);
+      mark->offset   = MARK_CURRENT_PROPERTY (mark)->length - 1;
+    }
+}
+
+static void
+decrement_mark_n (GtkPropertyMark* mark, gint n)
+{
+  gint i;
+
+  g_assert (n > 0);
+
+  for (i = 0; i < n; i += 1)
+    decrement_mark (mark);
+}
+
+static GtkPropertyMark
+find_mark (GtkText* text, guint mark_position)
+{
+  return find_mark_near (text, mark_position, &text->point);
+}
+
+/* This can be optimized in two ways.
+ * First, advances can be made in units of the current TextProperty
+ * length, when possible.  This will reduce computation and function
+ * call overhead.
+ *
+ * You can also start from the end, what a drag.
+ */
+static GtkPropertyMark
+find_mark_near (GtkText* text, guint mark_position, const GtkPropertyMark* near)
+{
+  gint diffa;
+  gint diffb;
+
+  GtkPropertyMark mark;
+
+  if (!near)
+    diffa = mark_position + 1;
+  else
+    diffa = mark_position - near->index;
+
+  diffb = mark_position;
+
+  if (diffa < 0)
+    diffa = -diffa;
+
+  if (diffa <= diffb)
+    {
+      mark = *near;
+    }
+  else
+    {
+      mark.index = 0;
+      mark.property = text->text_properties;
+      mark.offset = 0;
+    }
+
+  if (mark.index > mark_position)
+    {
+      while (mark.index > mark_position)
+       decrement_mark (&mark);
+    }
+  else
+    {
+      while (mark_position > mark.index)
+       advance_mark (&mark);
+    }
+
+  return mark;
+}
+
+static void
+find_line_containing_point (GtkText* text, guint point)
+{
+  GList* cache;
+  gint height;
+
+  text->current_line = NULL;
+
+  if (!text->line_start_cache->next)
+    {
+      /* @@@ Its visible, right? */
+      text->current_line = text->line_start_cache;
+      return;
+    }
+
+  while ( ( (text->first_cut_pixels != 0) &&
+           (CACHE_DATA(text->line_start_cache->next).start.index > point) ) ||
+         ( (text->first_cut_pixels == 0) &&
+           (CACHE_DATA(text->line_start_cache).start.index > point) ) )
+    {
+      scroll_int (text, - SCROLL_PIXELS);
+      g_assert (text->line_start_cache->next);
+    }
+
+  TEXT_SHOW (text);
+  gdk_window_get_size (text->text_area, NULL, &height);
+
+  for (cache = text->line_start_cache; cache; cache = cache->next)
+    {
+      guint lph;
+
+      if (CACHE_DATA(cache).end.index >= point ||
+         LAST_INDEX(text, CACHE_DATA(cache).end))
+       {
+         text->current_line = cache; /* LOOK HERE, this proc has an
+                                      * important side effect. */
+         return;
+       }
+
+      TEXT_SHOW_LINE (text, cache, "cache");
+
+      lph = pixel_height_of (text, cache->next);
+
+      while (lph > height || lph == 0)
+       {
+         TEXT_SHOW_LINE (text, cache, "cache");
+         TEXT_SHOW_LINE (text, cache->next, "cache->next");
+         scroll_int (text, LINE_HEIGHT(CACHE_DATA(cache->next)));
+         lph = pixel_height_of (text, cache->next);
+       }
+    }
+
+  g_assert (FALSE); /* Must set text->current_line here */
+}
+
+static guint
+pixel_height_of (GtkText* text, GList* cache_line)
+{
+  gint pixels = - text->first_cut_pixels;
+  GList *cache = text->line_start_cache;
+
+  while (TRUE) {
+    pixels += LINE_HEIGHT (CACHE_DATA(cache));
+
+    if (cache->data == cache_line->data)
+      break;
+
+    cache = cache->next;
+  }
+
+  return pixels;
+}
+
+/**********************************************************************/
+/*                     Search and Placement                          */
+/**********************************************************************/
+
+static gint
+find_char_width (GtkText* text, const GtkPropertyMark *mark, const TabStopMark *tab_mark)
+{
+  gchar ch = TEXT_INDEX (text, mark->index);
+  gint16* char_widths = MARK_CURRENT_TEXT_FONT (mark)->char_widths;
+
+  if (ch == '\t')
+    {
+      return tab_mark->to_next_tab * char_widths[' '];
+    }
+  else
+    {
+      return char_widths[ch & 0xff];
+    }
+}
+
+static void
+advance_tab_mark (GtkText* text, TabStopMark* tab_mark, gchar ch)
+{
+  if (tab_mark->to_next_tab == 1 || ch == '\t')
+    {
+      if (tab_mark->tab_stops->next)
+       {
+         tab_mark->tab_stops = tab_mark->tab_stops->next;
+         tab_mark->to_next_tab = (gulong) tab_mark->tab_stops->data;
+       }
+      else
+       {
+         tab_mark->to_next_tab = text->default_tab_width;
+       }
+    }
+  else
+    {
+      tab_mark->to_next_tab -= 1;
+    }
+}
+
+static void
+advance_tab_mark_n (GtkText* text, TabStopMark* tab_mark, gint n)
+  /* No tabs! */
+{
+  while (n--)
+    advance_tab_mark (text, tab_mark, 0);
+}
+
+static void
+find_cursor_at_line (GtkText* text, const LineParams* start_line, gint pixel_height)
+{
+  gchar ch;
+
+  GtkPropertyMark mark        = start_line->start;
+  TabStopMark  tab_mark    = start_line->tab_cont.tab_start;
+  gint         pixel_width = LINE_START_PIXEL (*start_line);
+
+  while (mark.index < text->cursor_mark.index)
+    {
+      pixel_width += find_char_width (text, &mark, &tab_mark);
+
+      advance_tab_mark (text, &tab_mark, TEXT_INDEX(text, mark.index));
+      advance_mark (&mark);
+    }
+
+  text->cursor_pos_x       = pixel_width;
+  text->cursor_pos_y       = pixel_height;
+  text->cursor_char_offset = start_line->font_descent;
+  text->cursor_mark        = mark;
+
+  ch = TEXT_INDEX (text, mark.index);
+
+  if (!isspace(ch))
+    text->cursor_char = ch;
+  else
+    text->cursor_char = 0;
+}
+
+static void
+find_cursor (GtkText* text)
+{
+  if (!text->has_cursor)
+    return;
+
+  find_line_containing_point (text, text->cursor_mark.index);
+
+  g_assert (text->cursor_mark.index >= text->first_line_start_index);
+
+  if (text->current_line)
+    find_cursor_at_line (text,
+                        &CACHE_DATA(text->current_line),
+                        pixel_height_of(text, text->current_line));
+}
+
+static void
+mouse_click_1_at_line (GtkText *text, const LineParams* lp,
+                      guint line_pixel_height,
+                      gint button_x)
+{
+  GtkPropertyMark mark     = lp->start;
+  TabStopMark  tab_mark = lp->tab_cont.tab_start;
+
+  guint char_width = find_char_width(text, &mark, &tab_mark);
+  guint pixel_width = LINE_START_PIXEL (*lp) + (char_width+1)/2;
+
+  text->cursor_pos_y = line_pixel_height;
+
+  for (;;)
+    {
+      gchar ch = TEXT_INDEX (text, mark.index);
+
+      if (button_x < pixel_width || mark.index == lp->end.index)
+       {
+         text->cursor_pos_x       = pixel_width - (char_width+1)/2;
+         text->cursor_mark        = mark;
+         text->cursor_char_offset = lp->font_descent;
+
+         if (!isspace(ch))
+           text->cursor_char = ch;
+         else
+           text->cursor_char = 0;
+
+         break;
+       }
+
+      advance_tab_mark (text, &tab_mark, ch);
+      advance_mark (&mark);
+
+      pixel_width += char_width/2;
+
+      char_width = find_char_width (text, &mark, &tab_mark);
+
+      pixel_width += (char_width+1)/2;
+    }
+}
+
+static void
+mouse_click_1 (GtkText* text, GdkEventButton *event)
+{
+  if (text->is_editable)
+    {
+      gint pixel_height;
+      GList* cache = text->line_start_cache;
+
+      g_assert (cache);
+
+      pixel_height = - text->first_cut_pixels;
+
+      text->has_cursor = 1;
+
+      for (; cache; cache = cache->next)
+       {
+         pixel_height += LINE_HEIGHT(CACHE_DATA(cache));
+
+         if (event->y < pixel_height || !cache->next)
+           {
+             mouse_click_1_at_line (text, &CACHE_DATA(cache), pixel_height, event->x);
+
+             find_cursor (text);
+
+             return;
+           }
+       }
+    }
+}
+
+/**********************************************************************/
+/*                         Cache Manager                             */
+/**********************************************************************/
+
+static void
+free_cache (GtkText* text)
+{
+  GList* cache = text->line_start_cache;
+
+  for (; cache; cache = cache->next)
+    g_mem_chunk_free (params_mem_chunk, cache->data);
+
+  g_list_free (text->line_start_cache);
+
+  text->line_start_cache = NULL;
+}
+
+static GList*
+remove_cache_line (GtkText* text, GList* member)
+{
+  if (member == text->line_start_cache)
+    {
+      if (text->line_start_cache)
+       text->line_start_cache = text->line_start_cache->next;
+      return text->line_start_cache;
+    }
+  else
+    {
+      GList *list = member->prev;
+
+      list->next = list->next->next;
+      if (list->next)
+       list->next->prev = list;
+
+      member->next = NULL;
+      g_mem_chunk_free (params_mem_chunk, member->data);
+      g_list_free (member);
+
+      return list->next;
+    }
+}
+
+/**********************************************************************/
+/*                          Key Motion                               */
+/**********************************************************************/
+
+static void
+move_cursor_buffer_ver (GtkText *text, int dir)
+{
+  if (dir > 0)
+    scroll_int (text, text->vadj->upper);
+  else
+    scroll_int (text, - text->vadj->value);
+}
+
+static void
+move_cursor_page_ver (GtkText *text, int dir)
+{
+  scroll_int (text, dir * text->vadj->page_increment);
+}
+
+static void
+move_cursor_ver (GtkText *text, int count)
+{
+  gint i;
+  GtkPropertyMark mark;
+  gint offset;
+
+  if (!text->has_cursor)
+    {
+      scroll_int (text, count * KEY_SCROLL_PIXELS);
+      return;
+    }
+
+  mark = find_this_line_start_mark (text, text->cursor_mark.index, &text->cursor_mark);
+  offset = text->cursor_mark.index - mark.index;
+
+  if (offset > text->cursor_virtual_x)
+    text->cursor_virtual_x = offset;
+
+  if (count < 0)
+    {
+      if (mark.index == 0)
+       return;
+
+      decrement_mark (&mark);
+      mark = find_this_line_start_mark (text, mark.index, &mark);
+    }
+  else
+    {
+      mark = text->cursor_mark;
+
+      while (!LAST_INDEX(text, mark) && TEXT_INDEX(text, mark.index) != LINE_DELIM)
+       advance_mark (&mark);
+
+      if (LAST_INDEX(text, mark))
+         return;
+
+      advance_mark (&mark);
+    }
+
+  for (i=0; i < text->cursor_virtual_x; i += 1, advance_mark(&mark))
+    if (LAST_INDEX(text, mark) || TEXT_INDEX(text, mark.index) == LINE_DELIM)
+      break;
+
+  undraw_cursor (text, FALSE);
+
+  text->cursor_mark = mark;
+
+  find_cursor (text);
+
+  draw_cursor (text, FALSE);
+}
+
+static void
+move_cursor_hor (GtkText *text, int count)
+{
+  /* count should be +-1. */
+  if (!text->has_cursor)
+    return;
+
+  if ( (count > 0 && text->cursor_mark.index + count > TEXT_LENGTH(text)) ||
+       (count < 0 && text->cursor_mark.index < (- count)) ||
+       (count == 0) )
+    return;
+
+  text->cursor_virtual_x = 0;
+
+  undraw_cursor (text, FALSE);
+
+  move_mark_n (&text->cursor_mark, count);
+
+  find_cursor (text);
+
+  draw_cursor (text, FALSE);
+}
+
+/**********************************************************************/
+/*                           Scrolling                               */
+/**********************************************************************/
+
+static void
+adjust_adj (GtkText* text, GtkAdjustment* adj)
+{
+  gint height;
+
+  gdk_window_get_size (text->text_area, NULL, &height);
+
+  adj->step_increment = MIN (adj->upper, (float) SCROLL_PIXELS);
+  adj->page_increment = MIN (adj->upper, height - (float) KEY_SCROLL_PIXELS);
+  adj->page_size      = MIN (adj->upper, height);
+  adj->value          = MIN (adj->value, adj->upper - adj->page_size);
+  adj->value          = MAX (adj->value, 0.0);
+
+  gtk_signal_emit_by_name (GTK_OBJECT (adj), "changed");
+}
+
+static gint
+set_vertical_scroll_iterator (GtkText* text, LineParams* lp, void* data)
+{
+  gint *pixel_count = (gint*) data;
+
+  if (text->first_line_start_index == lp->start.index)
+    text->vadj->value = (float) *pixel_count;
+
+  *pixel_count += LINE_HEIGHT (*lp);
+
+  return FALSE;
+}
+
+static gint
+set_vertical_scroll_find_iterator (GtkText* text, LineParams* lp, void* data)
+{
+  SetVerticalScrollData *svdata = (SetVerticalScrollData *) data;
+  gint return_val;
+
+  if (svdata->last_didnt_wrap)
+    svdata->last_line_start = lp->start.index;
+
+  if (svdata->pixel_height <= (gint) text->vadj->value &&
+      svdata->pixel_height + LINE_HEIGHT(*lp) > (gint) text->vadj->value)
+    {
+      svdata->mark = lp->start;
+
+      text->first_cut_pixels = (gint)text->vadj->value - svdata->pixel_height;
+      text->first_onscreen_ver_pixel = svdata->pixel_height;
+      text->first_line_start_index = svdata->last_line_start;
+
+      return_val = TRUE;
+    }
+  else
+    {
+      svdata->pixel_height += LINE_HEIGHT (*lp);
+
+      return_val = FALSE;
+    }
+
+  if (!lp->wraps)
+    svdata->last_didnt_wrap = TRUE;
+  else
+    svdata->last_didnt_wrap = FALSE;
+
+  return return_val;
+}
+
+static GtkPropertyMark
+set_vertical_scroll (GtkText* text)
+{
+  GtkPropertyMark mark = find_mark (text, 0);
+  SetVerticalScrollData data;
+  gint height;
+  gint pixel_count = 0;
+  gint orig_value;
+
+  line_params_iterate (text, &mark, NULL, FALSE, &pixel_count, set_vertical_scroll_iterator);
+
+  text->vadj->upper = (float) pixel_count;
+  orig_value = (gint) text->vadj->value;
+
+  gdk_window_get_size (text->text_area, NULL, &height);
+
+  text->vadj->step_increment = MIN (text->vadj->upper, (float) SCROLL_PIXELS);
+  text->vadj->page_increment = MIN (text->vadj->upper, height - (float) KEY_SCROLL_PIXELS);
+  text->vadj->page_size      = MIN (text->vadj->upper, height);
+  text->vadj->value          = MIN (text->vadj->value, text->vadj->upper - text->vadj->page_size);
+  text->vadj->value          = MAX (text->vadj->value, 0.0);
+
+  text->last_ver_value = (gint)text->vadj->value;
+  text->first_cut_pixels = 0;
+
+  gtk_signal_emit_by_name (GTK_OBJECT (text->vadj), "changed");
+
+  if (text->vadj->value != orig_value)
+    {
+      /* We got clipped, and don't really know which line to put first. */
+      data.pixel_height = 0;
+      data.last_didnt_wrap = TRUE;
+
+      line_params_iterate (text, &mark, NULL,
+                          FALSE, &data,
+                          set_vertical_scroll_find_iterator);
+
+      return data.mark;
+    }
+  else
+    {
+      return find_mark (text, text->first_line_start_index);
+    }
+}
+
+static void
+scroll_int (GtkText* text, gint diff)
+{
+  gfloat upper;
+
+  text->vadj->value += diff;
+
+  upper = text->vadj->upper - text->vadj->page_size;
+  text->vadj->value = MIN (text->vadj->value, upper);
+  text->vadj->value = MAX (text->vadj->value, 0.0);
+
+  gtk_signal_emit_by_name (GTK_OBJECT (text->vadj), "value_changed");
+}
+
+static gint last_visible_line_height (GtkText* text)
+{
+  GList *cache = text->line_start_cache;
+  gint height;
+
+  gdk_window_get_size (text->text_area, NULL, &height);
+
+  for (; cache->next; cache = cache->next)
+    if (pixel_height_of(text, cache->next) > height)
+      break;
+
+  if (cache)
+    return pixel_height_of(text, cache) - 1;
+  else
+    return 0;
+}
+
+static gint first_visible_line_height (GtkText* text)
+{
+  if (text->first_cut_pixels)
+    return pixel_height_of(text, text->line_start_cache) + 1;
+  else
+    return 1;
+}
+
+static void
+scroll_down (GtkText* text, gint diff0)
+{
+  GdkRectangle rect;
+  gint real_diff = 0;
+  gint width, height;
+
+  text->first_onscreen_ver_pixel += diff0;
+
+  while (diff0-- > 0)
+    {
+      g_assert (text->line_start_cache &&
+               text->line_start_cache->next);
+
+      if (text->first_cut_pixels < LINE_HEIGHT(CACHE_DATA(text->line_start_cache)) - 1)
+       {
+         text->first_cut_pixels += 1;
+       }
+      else
+       {
+         text->first_cut_pixels = 0;
+
+         text->line_start_cache = text->line_start_cache->next;
+
+         text->first_line_start_index =
+           CACHE_DATA(text->line_start_cache).start.index;
+
+         if (!text->line_start_cache->next)
+           fetch_lines_forward (text, 1);
+       }
+
+      real_diff += 1;
+    }
+
+  gdk_window_get_size (text->text_area, &width, &height);
+  if (height > real_diff)
+    gdk_draw_pixmap (text->text_area,
+                    text->gc,
+                    text->text_area,
+                    0,
+                    real_diff,
+                    0,
+                    0,
+                    width,
+                    height - real_diff);
+
+  rect.x      = 0;
+  rect.y      = MAX (0, height - real_diff);
+  rect.width  = width;
+  rect.height = MIN (height, real_diff);
+
+  expose_text (text, &rect, FALSE);
+  gtk_text_draw_focus ( (GtkWidget *) text);
+
+  if (text->current_line)
+    {
+      gint cursor_min;
+
+      text->cursor_pos_y -= real_diff;
+      cursor_min = drawn_cursor_min(text);
+
+      if (cursor_min < 0)
+       {
+         GdkEventButton button;
+
+         button.x = text->cursor_pos_x;
+         button.y = first_visible_line_height (text);
+
+         mouse_click_1 (text, &button);
+       }
+    }
+}
+
+static void
+scroll_up (GtkText* text, gint diff0)
+{
+  gint real_diff = 0;
+  GdkRectangle rect;
+  gint width, height;
+
+  text->first_onscreen_ver_pixel += diff0;
+
+  while (diff0++ < 0)
+    {
+      g_assert (text->line_start_cache);
+
+      if (text->first_cut_pixels > 0)
+       {
+         text->first_cut_pixels -= 1;
+       }
+      else
+       {
+         if (!text->line_start_cache->prev)
+           fetch_lines_backward (text);
+
+         text->line_start_cache = text->line_start_cache->prev;
+
+         text->first_line_start_index =
+           CACHE_DATA(text->line_start_cache).start.index;
+
+         text->first_cut_pixels = LINE_HEIGHT(CACHE_DATA(text->line_start_cache)) - 1;
+       }
+
+      real_diff += 1;
+    }
+
+  gdk_window_get_size (text->text_area, &width, &height);
+  if (height > real_diff)
+    gdk_draw_pixmap (text->text_area,
+                    text->gc,
+                    text->text_area,
+                    0,
+                    0,
+                    0,
+                    real_diff,
+                    width,
+                    height - real_diff);
+
+  rect.x      = 0;
+  rect.y      = 0;
+  rect.width  = width;
+  rect.height = MIN (height, real_diff);
+
+  expose_text (text, &rect, FALSE);
+  gtk_text_draw_focus ( (GtkWidget *) text);
+
+  if (text->current_line)
+    {
+      gint cursor_max;
+      gint height;
+
+      text->cursor_pos_y += real_diff;
+      cursor_max = drawn_cursor_max(text);
+      gdk_window_get_size (text->text_area, NULL, &height);
+
+      if (cursor_max >= height)
+       {
+         GdkEventButton button;
+
+         button.x = text->cursor_pos_x;
+         button.y = last_visible_line_height(text);
+
+         mouse_click_1 (text, &button);
+       }
+    }
+}
+
+/**********************************************************************/
+/*                           Display Code                            */
+/**********************************************************************/
+
+/* Assumes mark starts a line.  Calculates the height, width, and
+ * displayable character count of a single DISPLAYABLE line.  That
+ * means that in line-wrap mode, this does may not compute the
+ * properties of an entire line. */
+static LineParams
+find_line_params (GtkText* text,
+                 const GtkPropertyMark* mark,
+                 const PrevTabCont *tab_cont,
+                 PrevTabCont *next_cont)
+{
+  LineParams lp;
+  TabStopMark tab_mark = tab_cont->tab_start;
+  guint max_display_pixels;
+  gchar ch;
+  gint ch_width;
+  GdkFont *font;
+
+  gdk_window_get_size (text->text_area, (gint*) &max_display_pixels, NULL);
+  max_display_pixels -= LINE_WRAP_ROOM;
+
+  lp.wraps             = 0;
+  lp.tab_cont          = *tab_cont;
+  lp.start             = *mark;
+  lp.end               = *mark;
+  lp.pixel_width       = tab_cont->pixel_offset;
+  lp.displayable_chars = 0;
+  lp.font_ascent       = 0;
+  lp.font_descent      = 0;
+
+  init_tab_cont (text, next_cont);
+
+  while (!LAST_INDEX(text, lp.end))
+    {
+      g_assert (lp.end.property);
+
+      ch   = TEXT_INDEX (text, lp.end.index);
+      font = MARK_CURRENT_FONT (&lp.end);
+
+      if (ch == LINE_DELIM)
+       {
+         /* Newline doesn't count in computation of line height, even
+          * if its in a bigger font than the rest of the line.  Unless,
+          * of course, there are no other characters. */
+
+         if (!lp.font_ascent && !lp.font_descent)
+           {
+             lp.font_ascent = font->ascent;
+             lp.font_descent = font->descent;
+           }
+
+         lp.tab_cont_next = *next_cont;
+
+         return lp;
+       }
+
+      ch_width = find_char_width (text, &lp.end, &tab_mark);
+
+      if (ch_width + lp.pixel_width > max_display_pixels)
+       {
+         lp.wraps = 1;
+
+         if (text->line_wrap)
+           {
+             next_cont->tab_start    = tab_mark;
+             next_cont->pixel_offset = 0;
+
+             if (ch == '\t')
+               {
+                 /* Here's the tough case, a tab is wrapping. */
+                 gint pixels_avail = max_display_pixels - lp.pixel_width;
+                 gint space_width  = MARK_CURRENT_TEXT_FONT(&lp.end)->char_widths[' '];
+                 gint spaces_avail = pixels_avail / space_width;
+
+                 if (spaces_avail == 0)
+                   {
+                     decrement_mark (&lp.end);
+                   }
+                 else
+                   {
+                     advance_tab_mark (text, &next_cont->tab_start, '\t');
+                     next_cont->pixel_offset = space_width * (tab_mark.to_next_tab -
+                                                              spaces_avail);
+                     lp.displayable_chars += 1;
+                   }
+               }
+             else
+               {
+                 /* Don't include this character, it will wrap. */
+                 decrement_mark (&lp.end);
+               }
+
+             lp.tab_cont_next = *next_cont;
+
+             return lp;
+           }
+       }
+      else
+       {
+         lp.displayable_chars += 1;
+       }
+
+      lp.font_ascent = MAX (font->ascent, lp.font_ascent);
+      lp.font_descent = MAX (font->descent, lp.font_descent);
+      lp.pixel_width  += ch_width;
+
+      advance_mark(&lp.end);
+      advance_tab_mark (text, &tab_mark, ch);
+    }
+
+  if (LAST_INDEX(text, lp.start))
+    {
+      /* Special case, empty last line. */
+      font = MARK_CURRENT_FONT (&lp.end);
+
+      lp.font_ascent = font->ascent;
+      lp.font_descent = font->descent;
+    }
+
+  lp.tab_cont_next = *next_cont;
+
+  return lp;
+}
+
+static void
+expand_scratch_buffer (GtkText* text, guint len)
+{
+  if (len >= text->scratch_buffer_len)
+    {
+      guint i = 1;
+
+      while (i <= len && i < MIN_GAP_SIZE) i <<= 1;
+
+      if (text->scratch_buffer)
+       text->scratch_buffer = g_new (guchar, i);
+      else
+       text->scratch_buffer = g_realloc (text->scratch_buffer, i);
+
+      text->scratch_buffer_len = i;
+    }
+}
+
+static void
+draw_line (GtkText* text,
+          gint pixel_start_height,
+          LineParams* lp)
+{
+  GdkGCValues gc_values;
+  gint i;
+  gint len = 0;
+  guint running_offset = lp->tab_cont.pixel_offset;
+  guchar* buffer;
+
+  GtkPropertyMark mark = lp->start;
+  TabStopMark tab_mark = lp->tab_cont.tab_start;
+  gint pixel_height = pixel_start_height + lp->font_ascent;
+  guint chars = lp->displayable_chars;
+
+  /* First provide a contiguous segment of memory.  This makes reading
+   * the code below *much* easier, and only incurs the cost of copying
+   * when the line being displayed spans the gap. */
+  if (mark.index <= text->gap_position &&
+      mark.index + chars > text->gap_position)
+    {
+      expand_scratch_buffer (text, chars);
+
+      for (i = 0; i < chars; i += 1)
+       text->scratch_buffer[i] = TEXT_INDEX(text, mark.index + i);
+
+      buffer = text->scratch_buffer;
+    }
+  else
+    {
+      if (mark.index >= text->gap_position)
+       buffer = text->text + mark.index + text->gap_size;
+      else
+       buffer = text->text + mark.index;
+    }
+
+  if (running_offset > 0 && MARK_CURRENT_BACK (&mark))
+    {
+      gdk_gc_set_foreground (text->gc, MARK_CURRENT_BACK (&mark));
+
+      gdk_draw_rectangle (text->text_area,
+                         text->gc,
+                         TRUE,
+                         0,
+                         pixel_start_height,
+                         running_offset,
+                         LINE_HEIGHT (*lp));
+    }
+
+  for (; chars > 0; chars -= len, buffer += len, len = 0)
+    {
+      if (buffer[0] != '\t')
+       {
+         guchar* next_tab = memchr (buffer, '\t', chars);
+         gint pixel_width;
+         GdkFont *font;
+
+         len = MIN (MARK_CURRENT_PROPERTY (&mark)->length - mark.offset, chars);
+
+         if (next_tab)
+           len = MIN (len, next_tab - buffer);
+
+         font = MARK_CURRENT_PROPERTY (&mark)->font->gdk_font;
+         if (font->type == GDK_FONT_FONT)
+           {
+             gdk_gc_set_font (text->gc, font);
+             gdk_gc_get_values (text->gc, &gc_values);
+             pixel_width = gdk_text_width (gc_values.font,
+                                           (gchar*) buffer, len);
+           }
+         else
+           pixel_width = gdk_text_width (font, (gchar*) buffer, len);
+
+         if (MARK_CURRENT_BACK (&mark))
+           {
+             gdk_gc_set_foreground (text->gc, MARK_CURRENT_BACK (&mark));
+
+             gdk_draw_rectangle (text->text_area,
+                                 text->gc,
+                                 TRUE,
+                                 running_offset,
+                                 pixel_start_height,
+                                 pixel_width,
+                                 LINE_HEIGHT(*lp));
+           }
+
+         gdk_gc_set_foreground (text->gc, MARK_CURRENT_FORE (&mark));
+
+         gdk_draw_text (text->text_area, MARK_CURRENT_FONT (&mark),
+                        text->gc,
+                        running_offset,
+                        pixel_height,
+                        (gchar*) buffer,
+                        len);
+
+         running_offset += pixel_width;
+
+         advance_tab_mark_n (text, &tab_mark, len);
+       }
+      else
+       {
+         len = 1;
+
+         if (MARK_CURRENT_BACK (&mark))
+           {
+             gint pixels_remaining;
+             gint space_width;
+             gint spaces_avail;
+
+             gdk_window_get_size (text->text_area, &pixels_remaining, NULL);
+             pixels_remaining -= (LINE_WRAP_ROOM + running_offset);
+
+             space_width = MARK_CURRENT_TEXT_FONT(&mark)->char_widths[' '];
+
+             spaces_avail = pixels_remaining / space_width;
+             spaces_avail = MIN (spaces_avail, tab_mark.to_next_tab);
+
+             gdk_gc_set_foreground (text->gc, MARK_CURRENT_BACK (&mark));
+
+             gdk_draw_rectangle (text->text_area,
+                                 text->gc,
+                                 TRUE,
+                                 running_offset,
+                                 pixel_start_height,
+                                 spaces_avail * space_width,
+                                 LINE_HEIGHT (*lp));
+           }
+
+         running_offset += tab_mark.to_next_tab *
+           MARK_CURRENT_TEXT_FONT(&mark)->char_widths[' '];
+
+         advance_tab_mark (text, &tab_mark, '\t');
+       }
+
+      advance_mark_n (&mark, len);
+    }
+}
+
+static void
+draw_line_wrap (GtkText* text, guint height /* baseline height */)
+{
+  gint width;
+  GdkPixmap *bitmap;
+  gint bitmap_width;
+  gint bitmap_height;
+
+  if (text->line_wrap)
+    {
+      bitmap = text->line_wrap_bitmap;
+      bitmap_width = line_wrap_width;
+      bitmap_height = line_wrap_height;
+    }
+  else
+    {
+      bitmap = text->line_arrow_bitmap;
+      bitmap_width = line_arrow_width;
+      bitmap_height = line_arrow_height;
+    }
+
+  gdk_window_get_size (text->text_area, &width, NULL);
+  width -= LINE_WRAP_ROOM;
+
+  gdk_gc_set_stipple (text->gc,
+                     bitmap);
+
+  gdk_gc_set_fill (text->gc, GDK_STIPPLED);
+
+  gdk_gc_set_foreground (text->gc, &text->widget.style->fg[GTK_STATE_NORMAL]);
+
+  gdk_gc_set_ts_origin (text->gc,
+                       width + 1,
+                       height - bitmap_height - 1);
+
+  gdk_draw_rectangle (text->text_area,
+                     text->gc,
+                     TRUE,
+                     width + 1,
+                     height - bitmap_height - 1 /* one pixel above the baseline. */,
+                     bitmap_width,
+                     bitmap_height);
+
+  gdk_gc_set_ts_origin (text->gc, 0, 0);
+
+  gdk_gc_set_fill (text->gc, GDK_SOLID);
+}
+
+static void
+undraw_cursor (GtkText* text, gint absolute)
+{
+  TDEBUG (("in undraw_cursor\n"));
+
+  if (absolute)
+    text->cursor_drawn_level = 0;
+
+  if (text->has_cursor && (text->cursor_drawn_level ++ == 0))
+    {
+      GdkFont* font;
+
+      g_assert(text->cursor_mark.property);
+
+      font = MARK_CURRENT_FONT(&text->cursor_mark);
+
+      if (text->widget.style->bg_pixmap[GTK_STATE_NORMAL])
+       {
+         GdkRectangle rect;
+
+         rect.x = text->cursor_pos_x;
+         rect.y = text->cursor_pos_y - text->cursor_char_offset - font->ascent;
+         rect.width = 1;
+         rect.height = font->ascent + 1; /* @@@ I add one here because draw_line is inclusive, right? */
+
+         clear_area (text, &rect);
+       }
+      else
+       {
+         if (MARK_CURRENT_BACK (&text->cursor_mark))
+           gdk_gc_set_foreground (text->gc, MARK_CURRENT_BACK (&text->cursor_mark));
+         else
+           gdk_gc_set_foreground (text->gc, &text->widget.style->bg[GTK_STATE_NORMAL]);
+
+         gdk_draw_line (text->text_area, text->gc, text->cursor_pos_x,
+                        text->cursor_pos_y - text->cursor_char_offset, text->cursor_pos_x,
+                        text->cursor_pos_y - text->cursor_char_offset - font->ascent);
+       }
+
+      if (text->cursor_char)
+       {
+         if (font->type == GDK_FONT_FONT)
+           gdk_gc_set_font (text->gc, font);
+
+         gdk_gc_set_foreground (text->gc, MARK_CURRENT_FORE (&text->cursor_mark));
+
+         gdk_draw_text (text->text_area, font,
+                        text->gc,
+                        text->cursor_pos_x,
+                        text->cursor_pos_y - text->cursor_char_offset,
+                        &text->cursor_char,
+                        1);
+       }
+    }
+}
+
+static gint
+drawn_cursor_min (GtkText* text)
+{
+  if (text->has_cursor)
+    {
+      GdkFont* font;
+
+      g_assert(text->cursor_mark.property);
+
+      font = MARK_CURRENT_FONT(&text->cursor_mark);
+
+      return text->cursor_pos_y - text->cursor_char_offset - font->ascent;
+    }
+  else
+    return 0;
+}
+
+static gint
+drawn_cursor_max (GtkText* text)
+{
+  if (text->has_cursor)
+    {
+      GdkFont* font;
+
+      g_assert(text->cursor_mark.property);
+
+      font = MARK_CURRENT_FONT(&text->cursor_mark);
+
+      return text->cursor_pos_y - text->cursor_char_offset;
+    }
+  else
+    return 0;
+}
+
+static void
+draw_cursor (GtkText* text, gint absolute)
+{
+  TDEBUG (("in draw_cursor\n"));
+
+  if (absolute)
+    text->cursor_drawn_level = 1;
+
+  if (text->has_cursor && (--text->cursor_drawn_level == 0))
+    {
+      GdkFont* font;
+
+      g_assert (text->cursor_mark.property);
+
+      font = MARK_CURRENT_FONT (&text->cursor_mark);
+
+      gdk_gc_set_foreground (text->gc, &text->widget.style->fg[GTK_STATE_NORMAL]);
+
+      gdk_draw_line (text->text_area, text->gc, text->cursor_pos_x,
+                    text->cursor_pos_y - text->cursor_char_offset,
+                    text->cursor_pos_x,
+                    text->cursor_pos_y - text->cursor_char_offset - font->ascent);
+    }
+}
+
+static void
+clear_area (GtkText *text, GdkRectangle *area)
+{
+  if (text->widget.style->bg_pixmap[GTK_STATE_NORMAL])
+    {
+      gint width, height;
+      gint x = area->x, y = area->y;
+      gint xorig, yorig;
+
+      gdk_window_get_size (text->widget.style->bg_pixmap[GTK_STATE_NORMAL], &width, &height);
+
+      yorig = - text->first_onscreen_ver_pixel;
+      xorig = - text->first_onscreen_hor_pixel;
+
+      for (y = area->y; y < area->y + area->height; )
+       {
+         gint yoff = (y - yorig) % height;
+         gint yw = MIN(height - yoff, (area->y + area->height) - y);
+
+         for (x = area->x; x < area->x + area->width; )
+           {
+             gint xoff = (x - xorig) % width;
+             gint xw = MIN(width - xoff, (area->x + area->width) - x);
+
+             gdk_draw_pixmap (text->text_area,
+                              text->gc,
+                              text->widget.style->bg_pixmap[GTK_STATE_NORMAL],
+                              xoff,
+                              yoff,
+                              x,
+                              y,
+                              xw,
+                              yw);
+
+             x += width - xoff;
+           }
+         y += height - yoff;
+       }
+    }
+  else
+    gdk_window_clear_area (text->text_area, area->x, area->y, area->width, area->height);
+}
+
+static void
+expose_text (GtkText* text, GdkRectangle *area, gboolean cursor)
+{
+  GList *cache = text->line_start_cache;
+  gint pixels = - text->first_cut_pixels;
+  gint min_y = area->y;
+  gint max_y = area->y + area->height;
+  gint height;
+
+  gdk_window_get_size (text->text_area, NULL, &height);
+  max_y = MIN (max_y, height);
+
+  TDEBUG (("in expose x=%d y=%d w=%d h=%d\n", area->x, area->y, area->width, area->height));
+
+  clear_area (text, area);
+
+  for (; pixels < height; cache = cache->next)
+    {
+      if (pixels < max_y && (pixels + LINE_HEIGHT(CACHE_DATA(cache))) >= min_y)
+       {
+         draw_line (text, pixels, &CACHE_DATA(cache));
+
+         if (CACHE_DATA(cache).wraps)
+           draw_line_wrap (text, pixels + CACHE_DATA(cache).font_ascent);
+       }
+
+      if (cursor && text->has_cursor && GTK_WIDGET_HAS_FOCUS (&text->widget))
+       {
+         if (CACHE_DATA(cache).start.index <= text->cursor_mark.index &&
+             CACHE_DATA(cache).end.index >= text->cursor_mark.index)
+           draw_cursor (text, TRUE);
+       }
+
+      pixels += LINE_HEIGHT(CACHE_DATA(cache));
+
+      if (!cache->next)
+       {
+         fetch_lines_forward (text, 1);
+
+         if (!cache->next)
+           break;
+       }
+    }
+}
+
+static void
+recompute_geometry (GtkText* text)
+{
+  GtkPropertyMark start_mark;
+  gint height;
+  gint width;
+
+  free_cache (text);
+
+  start_mark = set_vertical_scroll (text);
+
+  gdk_window_get_size (text->text_area, &width, &height);
+
+  text->line_start_cache = fetch_lines (text,
+                                       &start_mark,
+                                       NULL,
+                                       FetchLinesPixels,
+                                       height + text->first_cut_pixels);
+
+  find_cursor (text);
+}
+
+/**********************************************************************/
+/*                            Selection                               */
+/**********************************************************************/
+
+static gint
+gtk_text_selection_clear (GtkWidget         *widget,
+                         GdkEventSelection *event)
+{
+#if 0
+  GtkEntry *entry;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_ENTRY (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  entry = GTK_ENTRY (widget);
+
+  if (entry->have_selection)
+    {
+      entry->have_selection = FALSE;
+      gtk_entry_queue_draw (entry);
+    }
+#endif
+  return FALSE;
+}
+
+static gint
+gtk_text_selection_request (GtkWidget         *widget,
+                           GdkEventSelection *event)
+{
+#if 0
+
+  GtkEntry *entry;
+  gint selection_start_pos;
+  gint selection_end_pos;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_ENTRY (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  entry = GTK_ENTRY (widget);
+  if (entry->selection_start_pos != entry->selection_end_pos)
+    {
+      selection_start_pos = MIN (entry->selection_start_pos, entry->selection_end_pos);
+      selection_end_pos = MAX (entry->selection_start_pos, entry->selection_end_pos);
+
+      gdk_selection_set (event->requestor, event->selection,
+                        event->property, event->time,
+                        (guchar*) &entry->text[selection_start_pos],
+                        selection_end_pos - selection_start_pos);
+    }
+#endif
+  return FALSE;
+}
+
+static gint
+gtk_text_selection_notify (GtkWidget         *widget,
+                          GdkEventSelection *event)
+{
+#if 0
+  GtkEntry *entry;
+  gchar *data;
+  gint tmp_pos;
+  gint reselect;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_ENTRY (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  entry = GTK_ENTRY (widget);
+
+  gdk_selection_get (widget->window, (guchar**) &data);
+
+  reselect = FALSE;
+  if (entry->selection_start_pos != entry->selection_end_pos)
+    {
+      reselect = TRUE;
+      gtk_delete_selection (entry);
+    }
+
+  tmp_pos = entry->current_pos;
+  gtk_entry_insert_text (entry, data, strlen (data), &tmp_pos);
+
+  if (reselect)
+    {
+      reselect = entry->have_selection;
+      gtk_select_region (entry, entry->current_pos, tmp_pos);
+      entry->have_selection = reselect;
+    }
+
+  entry->current_pos = tmp_pos;
+
+  gtk_entry_queue_draw (entry);
+#endif
+  return FALSE;
+}
+
+/**********************************************************************/
+/*                              Debug                                 */
+/**********************************************************************/
+
+#ifdef DEBUG_GTK_TEXT
+static void
+gtk_text_show_cache_line (GtkText *text, GList *cache,
+                         const char* what, const char* func, gint line)
+{
+  LineParams *lp = &CACHE_DATA(cache);
+  gint i;
+
+  g_print ("%s:%d: cache line %s s=%d,e=%d,lh=%d (",
+          func,
+          line,
+          what,
+          lp->start.index,
+          lp->end.index,
+          LINE_HEIGHT(*lp));
+
+  for (i = lp->start.index; i < (lp->end.index + lp->wraps); i += 1)
+    g_print ("%c", TEXT_INDEX (text, i));
+
+  g_print (")\n");
+}
+
+static void
+gtk_text_show_cache (GtkText *text, const char* func, gint line)
+{
+  GList *l = text->line_start_cache;
+
+  g_print ("*** line cache ***\n");
+  for (; l; l = l->next)
+    gtk_text_show_cache_line (text, l, "all", func, line);
+}
+
+static void
+gtk_text_assert_mark (GtkText         *text,
+                     GtkPropertyMark *mark,
+                     GtkPropertyMark *before,
+                     GtkPropertyMark *after,
+                     const gchar     *msg,
+                     const gchar     *where,
+                     gint             line)
+{
+  GtkPropertyMark correct_mark = find_mark (text, mark->index);
+
+  if (mark->offset != correct_mark.offset ||
+      mark->property != correct_mark.property)
+    g_warning ("incorrect %s text property marker in %s:%d, index %d -- bad!", where, msg, line, mark->index);
+}
+
+static void
+gtk_text_assert (GtkText         *text,
+                const gchar     *msg,
+                gint             line)
+{
+  GList* cache = text->line_start_cache;
+  GtkPropertyMark* before_mark = NULL;
+  GtkPropertyMark* after_mark = NULL;
+
+  gtk_text_show_props (text, msg, line);
+
+  for (; cache->prev; cache = cache->prev)
+    /* nothing */;
+
+  g_print ("*** line markers ***\n");
+
+  for (; cache; cache = cache->next)
+    {
+      after_mark = &CACHE_DATA(cache).end;
+      gtk_text_assert_mark (text, &CACHE_DATA(cache).start, before_mark, after_mark, msg, "start", line);
+      before_mark = &CACHE_DATA(cache).start;
+
+      if (cache->next)
+       after_mark = &CACHE_DATA(cache->next).start;
+      else
+       after_mark = NULL;
+
+      gtk_text_assert_mark (text, &CACHE_DATA(cache).end, before_mark, after_mark, msg, "end", line);
+      before_mark = &CACHE_DATA(cache).end;
+    }
+}
+
+static void
+gtk_text_show_adj (GtkText *text,
+                  GtkAdjustment *adj,
+                  const char* what,
+                  const char* func,
+                  gint line)
+{
+  g_print ("*** adjustment ***\n");
+
+  g_print ("%s:%d: %s adjustment l=%.1f u=%.1f v=%.1f si=%.1f pi=%.1f ps=%.1f\n",
+          func,
+          line,
+          what,
+          adj->lower,
+          adj->upper,
+          adj->value,
+          adj->step_increment,
+          adj->page_increment,
+          adj->page_size);
+}
+
+static void
+gtk_text_show_props (GtkText *text,
+                    const char* msg,
+                    int line)
+{
+  GList* props = text->text_properties;
+  int proplen = 0;
+
+  g_print ("%s:%d: ", msg, line);
+
+  for (; props; props = props->next)
+    {
+      TextProperty *p = (TextProperty*)props->data;
+
+      proplen += p->length;
+
+      g_print ("[%d,%p,%p,%p,%p] ", p->length, p, p->font, p->fore_color, p->back_color);
+    }
+
+  g_print ("\n");
+
+  if (proplen - 1 != TEXT_LENGTH(text))
+    g_warning ("incorrect property list length in %s:%d -- bad!", msg, line);
+}
+#endif
diff --git a/gtk/gtktext.h b/gtk/gtktext.h
new file mode 100644 (file)
index 0000000..012d679
--- /dev/null
@@ -0,0 +1,204 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_TEXT_H__
+#define __GTK_TEXT_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkadjustment.h>
+#include <gtk/gtkwidget.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_TEXT(obj)          GTK_CHECK_CAST (obj, gtk_text_get_type (), GtkText)
+#define GTK_TEXT_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_text_get_type (), GtkTextClass)
+#define GTK_IS_TEXT(obj)       GTK_CHECK_TYPE (obj, gtk_text_get_type ())
+
+
+typedef struct _GtkPropertyMark   GtkPropertyMark;
+typedef struct _GtkText           GtkText;
+typedef struct _GtkTextClass      GtkTextClass;
+
+typedef void  (*GtkTextFunction) (GtkText *text);
+
+struct _GtkPropertyMark
+{
+  /* Position in list. */
+  GList* property;
+
+  /* Offset into that property. */
+  guint offset;
+
+  /* Current index. */
+  guint index;
+};
+
+struct _GtkText
+{
+  GtkWidget widget;
+
+  GdkWindow *text_area;
+
+  GtkAdjustment *hadj;
+  GtkAdjustment *vadj;
+
+  GdkGC *gc;
+
+  GdkPixmap* line_wrap_bitmap;
+  GdkPixmap* line_arrow_bitmap;
+
+                     /* GAPPED TEXT SEGMENT */
+
+  /* The text, a single segment of text a'la emacs, with a gap
+   * where insertion occurs. */
+  guchar* text;
+  /* The allocated length of the text segment. */
+  guint text_len;
+  /* The gap position, index into address where a char
+   * should be inserted. */
+  guint gap_position;
+  /* The gap size, s.t. *(text + gap_position + gap_size) is
+   * the first valid character following the gap. */
+  guint gap_size;
+  /* The last character position, index into address where a
+   * character should be appeneded.  Thus, text_end - gap_size
+   * is the length of the actual data. */
+  guint text_end;
+                       /* LINE START CACHE */
+
+  /* A cache of line-start information.  Data is a LineParam*. */
+  GList *line_start_cache;
+  /* Index to the start of the first visible line. */
+  guint first_line_start_index;
+  /* The number of pixels cut off of the top line. */
+  guint first_cut_pixels;
+  /* First visible horizontal pixel. */
+  guint first_onscreen_hor_pixel;
+  /* First visible vertical pixel. */
+  guint first_onscreen_ver_pixel;
+
+                            /* FLAGS */
+
+  /* True iff the cursor has been placed yet. */
+  guint has_cursor : 1;
+  /* True iff this buffer is editable. (Allowing a cursor to be placed). */
+  guint is_editable : 1;
+  /* True iff this buffer is wrapping lines, otherwise it is using a
+   * horizontal scrollbar. */
+  guint line_wrap : 1;
+  /* Frozen, don't do updates. @@@ fixme */
+  guint freeze : 1;
+  /* Whether a selection. */
+  guint has_selection : 1;
+  /* Whether the selection is in the clipboard. */
+  guint own_selection : 1;
+  /* Whether it has been realized yet. */
+
+                       /* TEXT PROPERTIES */
+
+  /* A doubly-linked-list containing TextProperty objects. */
+  GList *text_properties;
+  /* The end of this list. */
+  GList *text_properties_end;
+  /* The first node before or on the point along with its offset to
+   * the point and the buffer's current point.  This is the only
+   * PropertyMark whose index is guaranteed to remain correct
+   * following a buffer insertion or deletion. */
+  GtkPropertyMark point;
+
+                         /* SCRATCH AREA */
+
+  guchar* scratch_buffer;
+  guint   scratch_buffer_len;
+
+                          /* SCROLLING */
+
+  gint last_ver_value;
+
+                            /* CURSOR */
+
+  gint            cursor_pos_x;       /* Position of cursor. */
+  gint            cursor_pos_y;       /* Baseline of line cursor is drawn on. */
+  GtkPropertyMark cursor_mark;        /* Where it is in the buffer. */
+  gchar           cursor_char;        /* Character to redraw. */
+  gchar           cursor_char_offset; /* Distance from baseline of the font. */
+  gint            cursor_virtual_x;   /* Where it would be if it could be. */
+  gint            cursor_drawn_level; /* How many people have undrawn. */
+
+                         /* Current Line */
+
+  GList *current_line;
+
+                          /* Tab Stops */
+
+  GList *tab_stops;
+  gint default_tab_width;
+
+                         /* Key bindings */
+
+  GtkTextFunction control_keys[26];
+  GtkTextFunction alt_keys[26];
+
+                     /* Selection nonsense. */
+
+  guint selection_start;
+  guint selection_stop;
+};
+
+struct _GtkTextClass
+{
+  GtkWidgetClass parent_class;
+};
+
+
+guint      gtk_text_get_type        (void);
+GtkWidget* gtk_text_new             (GtkAdjustment *hadj,
+                                    GtkAdjustment *vadj);
+void       gtk_text_set_editable    (GtkText       *text,
+                                    gint           editable);
+void       gtk_text_set_adjustments (GtkText       *text,
+                                    GtkAdjustment *hadj,
+                                    GtkAdjustment *vadj);
+void       gtk_text_set_point       (GtkText       *text,
+                                    guint          index);
+guint      gtk_text_get_point       (GtkText       *text);
+guint      gtk_text_get_length      (GtkText       *text);
+void       gtk_text_freeze          (GtkText       *text);
+void       gtk_text_thaw            (GtkText       *text);
+void       gtk_text_insert          (GtkText       *text,
+                                    GdkFont       *font,
+                                    GdkColor      *fore,
+                                    GdkColor      *back,
+                                    const char    *chars,
+                                    gint           length);
+gint       gtk_text_backward_delete (GtkText       *text,
+                                    guint          nchars);
+gint       gtk_text_foreward_delete (GtkText       *text,
+                                    guint          nchars);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_TEXT_H__ */
diff --git a/gtk/gtktogglebutton.c b/gtk/gtktogglebutton.c
new file mode 100644 (file)
index 0000000..eabcb1b
--- /dev/null
@@ -0,0 +1,372 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtklabel.h"
+#include "gtkmain.h"
+#include "gtksignal.h"
+#include "gtktogglebutton.h"
+
+
+#define DEFAULT_LEFT_POS  4
+#define DEFAULT_TOP_POS   4
+#define DEFAULT_SPACING   7
+
+enum {
+  TOGGLED,
+  LAST_SIGNAL
+};
+
+
+static void gtk_toggle_button_class_init (GtkToggleButtonClass *klass);
+static void gtk_toggle_button_init       (GtkToggleButton      *toggle_button);
+static void gtk_toggle_button_draw_focus (GtkWidget            *widget);
+static void gtk_toggle_button_pressed    (GtkButton            *button);
+static void gtk_toggle_button_released   (GtkButton            *button);
+static void gtk_toggle_button_clicked    (GtkButton            *button);
+static void gtk_toggle_button_enter      (GtkButton            *button);
+static void gtk_toggle_button_leave      (GtkButton            *button);
+
+
+static gint toggle_button_signals[LAST_SIGNAL] = { 0 };
+
+
+guint
+gtk_toggle_button_get_type ()
+{
+  static guint toggle_button_type = 0;
+
+  if (!toggle_button_type)
+    {
+      GtkTypeInfo toggle_button_info =
+      {
+       "GtkToggleButton",
+       sizeof (GtkToggleButton),
+       sizeof (GtkToggleButtonClass),
+       (GtkClassInitFunc) gtk_toggle_button_class_init,
+       (GtkObjectInitFunc) gtk_toggle_button_init,
+       (GtkArgFunc) NULL,
+      };
+
+      toggle_button_type = gtk_type_unique (gtk_button_get_type (), &toggle_button_info);
+    }
+
+  return toggle_button_type;
+}
+
+static void
+gtk_toggle_button_class_init (GtkToggleButtonClass *class)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+  GtkContainerClass *container_class;
+  GtkButtonClass *button_class;
+
+  object_class = (GtkObjectClass*) class;
+  widget_class = (GtkWidgetClass*) class;
+  container_class = (GtkContainerClass*) class;
+  button_class = (GtkButtonClass*) class;
+
+  toggle_button_signals[TOGGLED] =
+    gtk_signal_new ("toggled",
+                    GTK_RUN_FIRST,
+                    object_class->type,
+                    GTK_SIGNAL_OFFSET (GtkToggleButtonClass, toggled),
+                    gtk_signal_default_marshaller,
+                   GTK_TYPE_NONE, 0);
+
+  gtk_object_class_add_signals (object_class, toggle_button_signals, LAST_SIGNAL);
+
+  widget_class->draw_focus = gtk_toggle_button_draw_focus;
+  widget_class->draw_default = NULL;
+
+  button_class->pressed = gtk_toggle_button_pressed;
+  button_class->released = gtk_toggle_button_released;
+  button_class->clicked = gtk_toggle_button_clicked;
+  button_class->enter = gtk_toggle_button_enter;
+  button_class->leave = gtk_toggle_button_leave;
+
+  class->toggled = NULL;
+}
+
+static void
+gtk_toggle_button_init (GtkToggleButton *toggle_button)
+{
+  toggle_button->active = FALSE;
+  toggle_button->draw_indicator = FALSE;
+}
+
+
+GtkWidget*
+gtk_toggle_button_new ()
+{
+  return GTK_WIDGET (gtk_type_new (gtk_toggle_button_get_type ()));
+}
+
+GtkWidget*
+gtk_toggle_button_new_with_label (const gchar *label)
+{
+  GtkWidget *toggle_button;
+  GtkWidget *label_widget;
+
+  toggle_button = gtk_toggle_button_new ();
+  label_widget = gtk_label_new (label);
+  gtk_misc_set_alignment (GTK_MISC (label_widget), 0.5, 0.5);
+
+  gtk_container_add (GTK_CONTAINER (toggle_button), label_widget);
+  gtk_widget_show (label_widget);
+
+  return toggle_button;
+}
+
+void
+gtk_toggle_button_set_mode (GtkToggleButton *toggle_button,
+                           gint             draw_indicator)
+{
+  g_return_if_fail (toggle_button != NULL);
+  g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button));
+
+  draw_indicator = draw_indicator ? TRUE : FALSE;
+
+  if (toggle_button->draw_indicator != draw_indicator)
+    {
+      toggle_button->draw_indicator = draw_indicator;
+
+      if (GTK_WIDGET_VISIBLE (toggle_button))
+       gtk_widget_queue_resize (GTK_WIDGET (toggle_button));
+    }
+}
+
+void
+gtk_toggle_button_set_state (GtkToggleButton *toggle_button,
+                            gint             state)
+{
+  g_return_if_fail (toggle_button != NULL);
+  g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button));
+
+  if (toggle_button->active != state)
+    gtk_button_clicked (GTK_BUTTON (toggle_button));
+}
+
+void
+gtk_toggle_button_toggled (GtkToggleButton *toggle_button)
+{
+  gtk_signal_emit (GTK_OBJECT (toggle_button), toggle_button_signals[TOGGLED]);
+}
+
+
+static void
+gtk_toggle_button_draw_focus (GtkWidget *widget)
+{
+  GtkButton *button;
+  GtkToggleButton *toggle_button;
+  GtkShadowType shadow_type;
+  gint width, height;
+  gint x, y;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_TOGGLE_BUTTON (widget));
+
+  if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget))
+    {
+      button = GTK_BUTTON (widget);
+      toggle_button = GTK_TOGGLE_BUTTON (widget);
+
+      x = 0;
+      y = 0;
+      width = widget->allocation.width;
+      height = widget->allocation.height;
+
+      if (GTK_WIDGET_CAN_DEFAULT (widget))
+        {
+          x += widget->style->klass->xthickness;
+          y += widget->style->klass->ythickness;
+          width -= 2 * x + DEFAULT_SPACING;
+          height -= 2 * y + DEFAULT_SPACING;
+          x += DEFAULT_LEFT_POS;
+          y += DEFAULT_TOP_POS;
+        }
+
+      if (GTK_WIDGET_HAS_FOCUS (widget))
+       {
+         x += 1;
+         y += 1;
+         width -= 2;
+         height -= 2;
+       }
+      else
+       {
+         if (GTK_WIDGET_STATE (widget) == GTK_STATE_ACTIVE)
+           gdk_draw_rectangle (widget->window,
+                               widget->style->bg_gc[GTK_WIDGET_STATE (widget)], FALSE,
+                               x + 1, y + 1, width - 4, height - 4);
+         else
+           gdk_draw_rectangle (widget->window,
+                               widget->style->bg_gc[GTK_WIDGET_STATE (widget)], FALSE,
+                               x + 2, y + 2, width - 5, height - 5);
+       }
+
+      if (GTK_WIDGET_STATE (widget) == GTK_STATE_ACTIVE)
+       shadow_type = GTK_SHADOW_IN;
+      else if ((GTK_WIDGET_STATE (widget) == GTK_STATE_PRELIGHT) && toggle_button->active)
+       shadow_type = GTK_SHADOW_IN;
+      else
+       shadow_type = GTK_SHADOW_OUT;
+
+      gtk_draw_shadow (widget->style, widget->window,
+                      GTK_WIDGET_STATE (widget), shadow_type,
+                      x, y, width, height);
+
+      if (GTK_WIDGET_HAS_FOCUS (widget))
+       {
+         x -= 1;
+         y -= 1;
+         width += 2;
+         height += 2;
+
+         gdk_draw_rectangle (widget->window,
+                             widget->style->black_gc, FALSE,
+                             x, y, width - 1, height - 1);
+       }
+    }
+}
+
+static void
+gtk_toggle_button_pressed (GtkButton *button)
+{
+  GtkToggleButton *toggle_button;
+  GtkStateType new_state;
+
+  g_return_if_fail (button != NULL);
+  g_return_if_fail (GTK_IS_TOGGLE_BUTTON (button));
+
+  toggle_button = GTK_TOGGLE_BUTTON (button);
+
+  button->button_down = TRUE;
+
+  if (toggle_button->active)
+    new_state = (button->in_button ? GTK_STATE_NORMAL : GTK_STATE_ACTIVE);
+  else
+    new_state = (button->in_button ? GTK_STATE_ACTIVE : GTK_STATE_NORMAL);
+
+  if (GTK_WIDGET_STATE (button) != new_state)
+    {
+      gtk_widget_set_state (GTK_WIDGET (button), new_state);
+      gtk_widget_queue_draw (GTK_WIDGET (button));
+    }
+}
+
+static void
+gtk_toggle_button_released (GtkButton *button)
+{
+  GtkToggleButton *toggle_button;
+  GtkStateType new_state;
+
+  g_return_if_fail (button != NULL);
+  g_return_if_fail (GTK_IS_TOGGLE_BUTTON (button));
+
+  if (button->button_down)
+    {
+      toggle_button = GTK_TOGGLE_BUTTON (button);
+
+      button->button_down = FALSE;
+
+      if (button->in_button)
+       {
+         gtk_button_clicked (button);
+       }
+      else
+       {
+         if (toggle_button->active)
+           new_state = (button->in_button ? GTK_STATE_PRELIGHT : GTK_STATE_ACTIVE);
+         else
+           new_state = (button->in_button ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL);
+
+         if (GTK_WIDGET_STATE (button) != new_state)
+           {
+             gtk_widget_set_state (GTK_WIDGET (button), new_state);
+             gtk_widget_queue_draw (GTK_WIDGET (button));
+           }
+       }
+    }
+}
+
+static void
+gtk_toggle_button_clicked (GtkButton *button)
+{
+  GtkToggleButton *toggle_button;
+  GtkStateType new_state;
+
+  g_return_if_fail (button != NULL);
+  g_return_if_fail (GTK_IS_TOGGLE_BUTTON (button));
+
+  toggle_button = GTK_TOGGLE_BUTTON (button);
+  toggle_button->active = !toggle_button->active;
+
+  gtk_toggle_button_toggled (toggle_button);
+
+  if (toggle_button->active)
+    new_state = (button->in_button ? GTK_STATE_PRELIGHT : GTK_STATE_ACTIVE);
+  else
+    new_state = (button->in_button ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL);
+
+  if (GTK_WIDGET_STATE (button) != new_state)
+    gtk_widget_set_state (GTK_WIDGET (button), new_state);
+  gtk_widget_queue_draw (GTK_WIDGET (button));
+}
+
+static void
+gtk_toggle_button_enter (GtkButton *button)
+{
+  GtkToggleButton *toggle_button;
+  GtkStateType new_state;
+
+  g_return_if_fail (button != NULL);
+  g_return_if_fail (GTK_IS_TOGGLE_BUTTON (button));
+
+  toggle_button = GTK_TOGGLE_BUTTON (button);
+
+  if (toggle_button->active)
+    new_state = (button->button_down ? GTK_STATE_NORMAL : GTK_STATE_PRELIGHT);
+  else
+    new_state = (button->button_down ? GTK_STATE_ACTIVE : GTK_STATE_PRELIGHT);
+
+  if (GTK_WIDGET_STATE (button) != new_state)
+    {
+      gtk_widget_set_state (GTK_WIDGET (button), new_state);
+      gtk_widget_queue_draw (GTK_WIDGET (button));
+    }
+}
+
+static void
+gtk_toggle_button_leave (GtkButton *button)
+{
+  GtkToggleButton *toggle_button;
+  GtkStateType new_state;
+
+  g_return_if_fail (button != NULL);
+  g_return_if_fail (GTK_IS_TOGGLE_BUTTON (button));
+
+  toggle_button = GTK_TOGGLE_BUTTON (button);
+
+  new_state = (toggle_button->active ? GTK_STATE_ACTIVE : GTK_STATE_NORMAL);
+
+  if (GTK_WIDGET_STATE (button) != new_state)
+    {
+      gtk_widget_set_state (GTK_WIDGET (button), new_state);
+      gtk_widget_queue_draw (GTK_WIDGET (button));
+    }
+}
diff --git a/gtk/gtktogglebutton.h b/gtk/gtktogglebutton.h
new file mode 100644 (file)
index 0000000..e48d1cf
--- /dev/null
@@ -0,0 +1,70 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_TOGGLE_BUTTON_H__
+#define __GTK_TOGGLE_BUTTON_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkbutton.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_TOGGLE_BUTTON(obj)          GTK_CHECK_CAST (obj, gtk_toggle_button_get_type (), GtkToggleButton)
+#define GTK_TOGGLE_BUTTON_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_toggle_button_get_type (), GtkToggleButtonClass)
+#define GTK_IS_TOGGLE_BUTTON(obj)       GTK_CHECK_TYPE (obj, gtk_toggle_button_get_type ())
+
+
+typedef struct _GtkToggleButton       GtkToggleButton;
+typedef struct _GtkToggleButtonClass  GtkToggleButtonClass;
+
+struct _GtkToggleButton
+{
+  GtkButton button;
+
+  guint active : 1;
+  guint draw_indicator : 1;
+};
+
+struct _GtkToggleButtonClass
+{
+  GtkButtonClass parent_class;
+
+  void (* toggled) (GtkToggleButton *toggle_button);
+};
+
+
+guint      gtk_toggle_button_get_type       (void);
+GtkWidget* gtk_toggle_button_new            (void);
+GtkWidget* gtk_toggle_button_new_with_label (const gchar     *label);
+void       gtk_toggle_button_set_mode       (GtkToggleButton *toggle_button,
+                                            gint             draw_indicator);
+void       gtk_toggle_button_set_state      (GtkToggleButton *toggle_button,
+                                            gint             state);
+void       gtk_toggle_button_toggled        (GtkToggleButton *toggle_button);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_TOGGLE_BUTTON_H__ */
diff --git a/gtk/gtktooltips.c b/gtk/gtktooltips.c
new file mode 100644 (file)
index 0000000..953d425
--- /dev/null
@@ -0,0 +1,632 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdlib.h>
+#include <string.h>
+
+#include "gtkmain.h"
+#include "gtkwidget.h"
+#include "gtkwindow.h"
+#include "gtksignal.h"
+#include "gtkstyle.h"
+#include "gtktooltips.h"
+
+
+#define DEFAULT_DELAY 500           /* Default delay in ms */
+
+
+static gint gtk_tooltips_event_handler     (GtkWidget   *widget,
+                                            GdkEvent    *event);
+static void gtk_tooltips_widget_unmap      (GtkWidget   *widget,
+                                            gpointer     data);
+static void gtk_tooltips_widget_remove     (GtkWidget   *widget,
+                                            gpointer     data);
+static void gtk_tooltips_set_active_widget (GtkTooltips *tooltips,
+                                            GtkWidget   *widget);
+static gint gtk_tooltips_widget_visible    (GtkWidget   *widget);
+static gint gtk_tooltips_timeout           (gpointer     data);
+static void gtk_tooltips_draw_tips         (GtkTooltips *tooltips);
+
+
+GtkTooltips *
+gtk_tooltips_new ()
+{
+  GtkTooltips *tooltips;
+
+  tooltips = g_new0 (GtkTooltips, 1);
+
+  if (tooltips != NULL)
+    {
+      tooltips->ref_count = 0;
+      tooltips->pending_destroy = 0;
+
+      tooltips->enabled = TRUE;
+      tooltips->numwidgets = 0;
+      tooltips->delay = DEFAULT_DELAY;
+      tooltips->widget_list = NULL;
+      tooltips->gc = NULL;
+      tooltips->foreground = NULL;
+      tooltips->background = NULL;
+      tooltips->tip_window = NULL;
+    }
+
+  return tooltips;
+}
+
+GtkTooltips*
+gtk_tooltips_ref (GtkTooltips *tooltips)
+{
+  g_return_val_if_fail (tooltips != NULL, NULL);
+  tooltips->ref_count += 1;
+  return tooltips;
+}
+
+void
+gtk_tooltips_unref (GtkTooltips *tooltips)
+{
+  g_return_if_fail (tooltips != NULL);
+  tooltips->ref_count -= 1;
+  if (tooltips->ref_count == 0 && tooltips->pending_destroy)
+    gtk_tooltips_destroy (tooltips);
+}
+
+void
+gtk_tooltips_free_string (gpointer data, gpointer user_data)
+{
+  if (data)
+    g_free (data);
+}
+
+static void
+gtk_tooltips_destroy_data (GtkTooltips     *tooltips,
+                          GtkTooltipsData *tooltipsdata)
+{
+  g_free (tooltipsdata->tips_text);
+  g_list_foreach (tooltipsdata->row, gtk_tooltips_free_string, 0);
+  if (tooltipsdata->row)
+    g_list_free (tooltipsdata->row);
+  gtk_signal_disconnect_by_data (GTK_OBJECT (tooltipsdata->widget),
+                                (gpointer) tooltips);
+  gtk_widget_set_events(tooltipsdata->widget,tooltipsdata->old_event_mask);
+  g_free (tooltipsdata);
+}
+
+void
+gtk_tooltips_destroy (GtkTooltips *tooltips)
+{
+  GList *current;
+  GtkTooltipsData *tooltipsdata;
+
+  g_return_if_fail (tooltips != NULL);
+
+  if (tooltips->ref_count > 0)
+    {
+      tooltips->pending_destroy = 1;
+      return;
+    }
+
+  if (tooltips->timer_active == TRUE)
+    {
+      tooltips->timer_active = FALSE;
+      gtk_timeout_remove (tooltips->timer_tag);
+    }
+
+  if (tooltips->widget_list != NULL)
+    {
+      current = g_list_first (tooltips->widget_list);
+      while (current != NULL)
+       {
+         tooltipsdata = (GtkTooltipsData*) current->data;
+         gtk_tooltips_destroy_data (tooltips, tooltipsdata);
+         current = current->next;
+       }
+      g_list_free (tooltips->widget_list);
+    }
+
+  if (tooltips->tip_window != NULL)
+    gtk_widget_destroy (tooltips->tip_window);
+
+  if (tooltips->gc != NULL)
+    gdk_gc_destroy (tooltips->gc);
+
+  g_free (tooltips);
+}
+
+static void
+gtk_tooltips_layout_text (GtkTooltips *tooltips, GtkTooltipsData *data)
+{
+  GtkStyle *style = gtk_widget_get_default_style ();
+  gchar *row_end, *text, *row_text, *break_pos;
+  gint i, row_width, window_width = 0;
+  size_t len;
+
+  g_list_foreach (data->row, gtk_tooltips_free_string, 0);
+  if (data->row)
+    g_list_free (data->row);
+  data->row = 0;
+  data->font = style->font;
+  data->width = 0;
+
+  text = data->tips_text;
+  if (!text)
+    return;
+
+  while (*text)
+    {
+      row_end = strchr (text, '\n');
+      if (!row_end)
+       row_end = strchr (text, '\0');
+
+      len = row_end - text + 1;
+      row_text = g_new(gchar, len);
+      memcpy (row_text, text, len - 1);
+      row_text[len - 1] = '\0';
+
+      /* now either adjust the window's width or shorten the row until
+        it fits in the window */
+
+      while (1)
+       {
+         row_width = gdk_string_width (data->font, row_text);
+         if (!window_width)
+           {
+             /* make an initial guess at window's width: */
+
+             if (row_width > gdk_screen_width () / 4)
+               window_width = gdk_screen_width () / 4;
+             else
+               window_width = row_width;
+           }
+         if (row_width <= window_width)
+           break;
+
+         if (strchr (row_text, ' '))
+           {
+             /* the row is currently too wide, but we have blanks in
+                the row so we can break it into smaller pieces */
+
+             gint avg_width = row_width / strlen (row_text);
+
+             i = window_width;
+             if (avg_width)
+               i /= avg_width;
+             if ((size_t) i >= len)
+               i = len - 1;
+
+             break_pos = strchr (row_text + i, ' ');
+             if (!break_pos)
+               {
+                 break_pos = row_text + i;
+                 while (*--break_pos != ' ');
+               }
+             *break_pos = '\0';
+           }
+         else
+           {
+             /* we can't break this row into any smaller pieces, so
+                we have no choice but to widen the window: */
+
+             window_width = row_width;
+             break;
+           }
+       }
+      if (row_width > data->width)
+       data->width = row_width;
+      data->row = g_list_append (data->row, row_text);
+      text += strlen (row_text);
+      if (!*text)
+       break;
+
+      if (text[0] == '\n' && text[1])
+       /* end of paragraph and there is more text to come */
+       data->row = g_list_append (data->row, 0);
+      ++text;  /* skip blank or newline */
+    }
+  data->width += 8;    /* leave some border */
+}
+
+void
+gtk_tooltips_enable (GtkTooltips *tooltips)
+{
+  g_return_if_fail (tooltips != NULL);
+
+  tooltips->enabled = TRUE;
+}
+
+void
+gtk_tooltips_disable (GtkTooltips *tooltips)
+{
+  g_return_if_fail (tooltips != NULL);
+
+  tooltips->enabled = FALSE;
+
+  if (tooltips->timer_active == TRUE)
+    {
+      gtk_timeout_remove (tooltips->timer_tag);
+      tooltips->timer_active = FALSE;
+    }
+
+  if (tooltips->active_widget != NULL)
+    {
+      if (tooltips->tip_window != NULL)
+       gtk_widget_hide (tooltips->tip_window);
+      tooltips->active_widget = NULL;
+    }
+}
+
+void
+gtk_tooltips_set_delay (GtkTooltips *tooltips,
+                        gint         delay)
+{
+  g_return_if_fail (tooltips != NULL);
+
+  tooltips->delay = delay;
+}
+
+void
+gtk_tooltips_set_tips (GtkTooltips *tooltips,
+                      GtkWidget   *widget,
+                      const gchar *tips_text)
+{
+  GtkTooltipsData *tooltipsdata;
+
+  g_return_if_fail (tooltips != NULL);
+  g_return_if_fail (widget != NULL);
+
+  if (gtk_object_get_data (GTK_OBJECT (widget), "_GtkTooltips") != NULL)
+    gtk_tooltips_widget_remove (widget, NULL);
+
+  if (gtk_object_get_data (GTK_OBJECT (widget), "_GtkTooltips") != NULL)
+    gtk_tooltips_widget_remove (widget, NULL);
+  
+  tooltipsdata = g_new(GtkTooltipsData, 1);
+
+  if (tooltipsdata != NULL)
+    {
+      memset (tooltipsdata, 0, sizeof (*tooltipsdata));
+      tooltipsdata->widget = widget;
+
+      tooltipsdata->tips_text = g_strdup (tips_text);
+      if (!tooltipsdata->tips_text)
+        {
+          g_free (tooltipsdata);
+          return;
+       }
+
+      gtk_tooltips_layout_text (tooltips, tooltipsdata);
+      tooltips->widget_list = g_list_append (tooltips->widget_list,
+                                             tooltipsdata);
+      tooltips->numwidgets++;
+      tooltipsdata->old_event_mask = gtk_widget_get_events (widget);
+
+      gtk_signal_connect_after(GTK_OBJECT (widget), "event",
+                               (GtkSignalFunc) gtk_tooltips_event_handler,
+                              (gpointer) tooltips);
+
+      gtk_object_set_data (GTK_OBJECT (widget), "_GtkTooltips",
+                           (gpointer) tooltips);
+
+      gtk_signal_connect (GTK_OBJECT (widget), "destroy",
+                          (GtkSignalFunc) gtk_tooltips_widget_remove,
+                          (gpointer) tooltips);
+
+      gtk_signal_connect (GTK_OBJECT (widget), "unmap",
+                          (GtkSignalFunc) gtk_tooltips_widget_unmap,
+                          (gpointer) tooltips);
+
+      gtk_signal_connect (GTK_OBJECT (widget), "unrealize",
+                          (GtkSignalFunc) gtk_tooltips_widget_unmap,
+                          (gpointer) tooltips);
+    }
+}
+
+void
+gtk_tooltips_set_colors (GtkTooltips *tooltips,
+                        GdkColor    *background,
+                        GdkColor    *foreground)
+{
+  g_return_if_fail (tooltips != NULL);
+
+  if (background != NULL)
+    tooltips->foreground = foreground;
+  if (foreground != NULL)
+    tooltips->background = background;
+}
+
+static void
+gtk_tooltips_draw_tips (GtkTooltips * tooltips)
+{
+  GtkWidget *widget;
+  GtkStyle *style = gtk_widget_get_default_style ();
+  gint gap, x, y, w, h, scr_w, scr_h, baseline_skip;
+  GtkTooltipsData *data;
+  GList *el;
+
+  if (tooltips->tip_window == NULL)
+    {
+      tooltips->tip_window = gtk_window_new (GTK_WINDOW_POPUP);
+      gtk_window_set_policy (GTK_WINDOW (tooltips->tip_window), FALSE, FALSE, TRUE);
+    }
+  else
+    gtk_widget_hide (tooltips->tip_window);
+
+  widget = tooltips->active_widget->widget;
+
+  scr_w = gdk_screen_width ();
+  scr_h = gdk_screen_height ();
+
+  data = tooltips->active_widget;
+  if (data->font != style->font)
+    gtk_tooltips_layout_text (tooltips, data);
+
+  gap = (style->font->ascent + style->font->descent) / 4;
+  if (gap < 2)
+    gap = 2;
+  baseline_skip = style->font->ascent + style->font->descent + gap;
+  w = data->width;
+  h = 8 - gap;
+  for (el = data->row; el; el = el->next)
+    if (el->data)
+      h += baseline_skip;
+    else
+      h += baseline_skip / 2;
+  if (h < 8)
+    h = 8;
+
+  gdk_window_get_pointer (NULL, &x, NULL, NULL);
+  gdk_window_get_origin (widget->window, NULL, &y);
+
+  x -= ((w >> 1) + 4);
+
+  if ((x + w) > scr_w)
+    x -= (x + w) - scr_w;
+  else if (x < 0)
+    x = 0;
+
+  if ((y + h + widget->allocation.height + 4) > scr_h)
+    y = y - h - 4;
+  else
+    y = y + widget->allocation.height + 4;
+
+  gtk_widget_set_usize (tooltips->tip_window, w + 1, h + 1);
+  gtk_widget_popup (tooltips->tip_window, x, y);
+
+  if (tooltips->gc == NULL)
+    tooltips->gc = gdk_gc_new (tooltips->tip_window->window);
+
+  if (tooltips->background != NULL)
+    {
+      gdk_gc_set_foreground (tooltips->gc, tooltips->background);
+      gdk_gc_set_background (tooltips->gc, tooltips->foreground);
+    }
+  else
+    {
+      gdk_gc_set_foreground (tooltips->gc, &style->bg[GTK_STATE_NORMAL]);
+      gdk_gc_set_background (tooltips->gc, &style->fg[GTK_STATE_NORMAL]);
+    }
+
+  gdk_gc_set_font (tooltips->gc, style->font);
+  gdk_draw_rectangle (tooltips->tip_window->window, tooltips->gc, TRUE, 0, 0, w, h);
+
+  if (tooltips->foreground != NULL)
+    {
+      gdk_gc_set_foreground (tooltips->gc, tooltips->foreground);
+      gdk_gc_set_background (tooltips->gc, tooltips->background);
+    }
+  else
+    {
+      gdk_gc_set_foreground (tooltips->gc, &style->fg[GTK_STATE_NORMAL]);
+      gdk_gc_set_background (tooltips->gc, &style->bg[GTK_STATE_NORMAL]);
+    }
+
+  gdk_draw_rectangle (tooltips->tip_window->window, tooltips->gc, FALSE, 0, 0, w, h);
+  y = style->font->ascent + 4;
+
+  for (el = data->row; el; el = el->next)
+    {
+      if (el->data)
+       {
+         gdk_draw_string (tooltips->tip_window->window, style->font,
+                         tooltips->gc, 4, y, el->data);
+         y += baseline_skip;
+       }
+      else
+       y += baseline_skip / 2;
+    }
+}
+
+static gint
+gtk_tooltips_timeout (gpointer data)
+{
+  GtkTooltips *tooltips = (GtkTooltips *) data;
+
+  if (tooltips->active_widget != NULL &&
+      GTK_WIDGET_DRAWABLE (tooltips->active_widget->widget))
+    gtk_tooltips_draw_tips (tooltips);
+
+  return FALSE;
+}
+
+static gint
+gtk_tooltips_widget_visible (GtkWidget *widget)
+{
+  GtkWidget *current;
+
+  current = widget;
+
+  while (current != NULL)
+    {
+      if (!GTK_WIDGET_MAPPED (current) || !GTK_WIDGET_REALIZED (current))
+       return FALSE;
+      current = current->parent;
+    }
+
+  return TRUE;
+}
+
+static void
+gtk_tooltips_set_active_widget (GtkTooltips *tooltips,
+                                GtkWidget   *widget)
+{
+  GtkTooltipsData *tooltipsdata;
+  GList *current;
+
+  current = g_list_first (tooltips->widget_list);
+  tooltips->active_widget = NULL;
+
+  while (current != NULL)
+    {
+      tooltipsdata = (GtkTooltipsData*) current->data;
+
+      if (widget == tooltipsdata->widget &&
+          gtk_tooltips_widget_visible (tooltipsdata->widget) == TRUE)
+       {
+         tooltips->active_widget = tooltipsdata;
+         return;
+       }
+
+      current = current->next;
+    }
+}
+
+static gint
+gtk_tooltips_event_handler (GtkWidget *widget,
+                            GdkEvent  *event)
+{
+  GtkTooltips *tooltips;
+  GtkTooltipsData *old_widget;
+  gint returnval = FALSE;
+
+  tooltips = (GtkTooltips*) gtk_object_get_data (GTK_OBJECT (widget),"_GtkTooltips");
+
+  if (tooltips->enabled == FALSE)
+    return returnval;
+
+  if ((event->type == GDK_LEAVE_NOTIFY || event->type == GDK_ENTER_NOTIFY) &&
+      event->crossing.detail == GDK_NOTIFY_INFERIOR)
+    return returnval;
+
+  if (event->type == GDK_LEAVE_NOTIFY)
+    {
+      if (tooltips->timer_active == TRUE)
+       {
+         gtk_timeout_remove (tooltips->timer_tag);
+         tooltips->timer_active = FALSE;
+       }
+      if (tooltips->tip_window != NULL)
+       gtk_widget_hide (tooltips->tip_window);
+      tooltips->active_widget = NULL;
+    }
+  else if (event->type == GDK_MOTION_NOTIFY || event->type == GDK_ENTER_NOTIFY)
+    {
+      old_widget = tooltips->active_widget;
+#if 0
+      if (widget->window != event->crossing.window)
+        tooltips->active_widget = NULL;
+      else
+#endif
+        gtk_tooltips_set_active_widget (tooltips, widget);
+
+      if (old_widget != tooltips->active_widget)
+       {
+         if (tooltips->timer_active == TRUE)
+           {
+             gtk_timeout_remove (tooltips->timer_tag);
+             tooltips->timer_active = FALSE;
+           }
+         if (tooltips->active_widget != NULL)
+           {
+             if (tooltips->tip_window != NULL)
+               gtk_widget_hide (tooltips->tip_window);
+
+             tooltips->timer_tag = gtk_timeout_add (tooltips->delay,
+                gtk_tooltips_timeout, (gpointer) tooltips);
+
+             tooltips->timer_active = TRUE;
+           }
+       }
+      else if (tooltips->active_widget == NULL)
+       {
+         if (tooltips->tip_window != NULL)
+           gtk_widget_hide (tooltips->tip_window);
+       }
+    }
+  else
+    {
+      if (tooltips->tip_window != NULL)
+       gtk_widget_hide (tooltips->tip_window);
+    }
+
+  return returnval;
+}
+
+static void
+gtk_tooltips_widget_unmap (GtkWidget *widget,
+                          gpointer   data)
+{
+  GtkTooltips *tooltips;
+
+  tooltips = (GtkTooltips*) gtk_object_get_data (GTK_OBJECT (widget), "_GtkTooltips");
+
+  if (tooltips->active_widget &&
+      (tooltips->active_widget->widget == widget))
+    {
+      if (tooltips->tip_window != NULL)
+       gtk_widget_hide (tooltips->tip_window);
+      tooltips->active_widget = NULL;
+    }
+}
+
+static void
+gtk_tooltips_widget_remove (GtkWidget *widget,
+                           gpointer   data)
+{
+  GtkTooltips *tooltips;
+  GtkTooltipsData *tooltipsdata;
+  GList *list;
+
+  tooltips = (GtkTooltips*) gtk_object_get_data (GTK_OBJECT (widget), "_GtkTooltips");
+
+  gtk_tooltips_widget_unmap (widget, data);
+
+  list = g_list_first (tooltips->widget_list);
+  while (list)
+    {
+      tooltipsdata = (GtkTooltipsData*) list->data;
+
+      if (tooltipsdata->widget == widget)
+        break;
+
+      list = list->next;
+    }
+
+  if (list)
+    {
+      tooltipsdata = (GtkTooltipsData*) list->data;
+
+      g_free (tooltipsdata->tips_text);
+      g_list_foreach (tooltipsdata->row, gtk_tooltips_free_string, 0);
+      g_list_free (tooltipsdata->row);
+      gtk_signal_disconnect_by_data (GTK_OBJECT (tooltipsdata->widget), (gpointer) tooltips);
+      gtk_widget_set_events (tooltipsdata->widget,tooltipsdata->old_event_mask);
+      g_free (tooltipsdata);
+
+      tooltips->widget_list = g_list_remove (tooltips->widget_list, tooltipsdata);
+    }
+
+  gtk_object_set_data (GTK_OBJECT (widget), "_GtkTooltips", NULL);
+}
diff --git a/gtk/gtktooltips.h b/gtk/gtktooltips.h
new file mode 100644 (file)
index 0000000..e3ac596
--- /dev/null
@@ -0,0 +1,88 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_TOOLTIPS_H__
+#define __GTK_TOOLTIPS_H__
+
+#include <gdk/gdk.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+typedef struct
+{
+  GtkWidget *widget;
+  gchar *tips_text;
+  GdkFont *font;
+  gint width;
+  GList *row;
+  gint old_event_mask;
+} GtkTooltipsData;
+
+typedef struct
+{
+  GtkWidget *tip_window;
+  GtkTooltipsData *active_widget;
+  GList *widget_list;
+
+  GdkGC *gc;
+  GdkColor *foreground;
+  GdkColor *background;
+
+  gint numwidgets;
+  gint enabled;
+  gint inside;
+  gint delay;
+  gint timer_tag;
+  gint timer_active;
+
+  gint ref_count;
+  gint pending_destroy;
+} GtkTooltips;
+
+
+GtkTooltips* gtk_tooltips_new        (void);
+
+void         gtk_tooltips_destroy    (GtkTooltips *tooltips);
+GtkTooltips* gtk_tooltips_ref        (GtkTooltips *tooltips);
+void         gtk_tooltips_unref      (GtkTooltips *tooltips);
+
+void         gtk_tooltips_enable     (GtkTooltips *tooltips);
+
+void         gtk_tooltips_disable    (GtkTooltips *tooltips);
+
+void         gtk_tooltips_set_delay  (GtkTooltips *tooltips,
+                                      gint         delay);
+
+void         gtk_tooltips_set_tips   (GtkTooltips *tooltips,
+                                      GtkWidget   *widget,
+                                      const gchar *tips_text);
+
+void         gtk_tooltips_set_colors (GtkTooltips *tooltips,
+                                      GdkColor    *background,
+                                      GdkColor    *foreground);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_TOOLTIPS_H__ */
diff --git a/gtk/gtktree.c b/gtk/gtktree.c
new file mode 100644 (file)
index 0000000..f3981ea
--- /dev/null
@@ -0,0 +1,81 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtktree.h"
+
+
+static void gtk_tree_class_init (GtkTreeClass *klass);
+static void gtk_tree_init       (GtkTree      *tree);
+
+
+guint
+gtk_tree_get_type ()
+{
+  static guint tree_type = 0;
+
+  if (!tree_type)
+    {
+      GtkTypeInfo tree_info =
+      {
+       "GtkTree",
+       sizeof (GtkTree),
+       sizeof (GtkTreeClass),
+       (GtkClassInitFunc) gtk_tree_class_init,
+       (GtkObjectInitFunc) gtk_tree_init,
+       (GtkArgFunc) NULL,
+      };
+
+      tree_type = gtk_type_unique (gtk_container_get_type (), &tree_info);
+    }
+
+  return tree_type;
+}
+
+static void
+gtk_tree_class_init (GtkTreeClass *class)
+{
+}
+
+static void
+gtk_tree_init (GtkTree *tree)
+{
+}
+
+GtkWidget*
+gtk_tree_new ()
+{
+  return GTK_WIDGET (gtk_type_new (gtk_tree_get_type ()));
+}
+
+void
+gtk_tree_append (GtkTree   *tree,
+                GtkWidget *child)
+{
+}
+
+void
+gtk_tree_prepend (GtkTree   *tree,
+                 GtkWidget *child)
+{
+}
+
+void
+gtk_tree_insert (GtkTree   *tree,
+                GtkWidget *child,
+                gint       position)
+{
+}
diff --git a/gtk/gtktree.h b/gtk/gtktree.h
new file mode 100644 (file)
index 0000000..1486a82
--- /dev/null
@@ -0,0 +1,68 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_TREE_H__
+#define __GTK_TREE_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkcontainer.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_TREE(obj)          GTK_CHECK_CAST (obj, gtk_tree_get_type (), GtkTree)
+#define GTK_TREE_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_tree_get_type (), GtkTreeClass)
+#define GTK_IS_TREE(obj)       GTK_CHECK_TYPE (obj, gtk_tree_get_type ())
+
+
+typedef struct _GtkTree       GtkTree;
+typedef struct _GtkTreeClass  GtkTreeClass;
+
+struct _GtkTree
+{
+  GtkContainer container;
+
+  GList *children;
+};
+
+struct _GtkTreeClass
+{
+  GtkContainerClass parent_class;
+};
+
+
+guint      gtk_tree_get_type   (void);
+GtkWidget* gtk_tree_new        (void);
+void       gtk_tree_append     (GtkTree   *tree,
+                               GtkWidget *child);
+void       gtk_tree_prepend    (GtkTree   *tree,
+                               GtkWidget *child);
+void       gtk_tree_insert     (GtkTree   *tree,
+                               GtkWidget *child,
+                               gint       position);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_TREE_H__ */
diff --git a/gtk/gtktreeitem.c b/gtk/gtktreeitem.c
new file mode 100644 (file)
index 0000000..8f0d9f0
--- /dev/null
@@ -0,0 +1,108 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtklabel.h"
+#include "gtktreeitem.h"
+
+
+static void gtk_tree_item_class_init (GtkTreeItemClass *klass);
+static void gtk_tree_item_init       (GtkTreeItem      *tree_item);
+
+
+guint
+gtk_tree_item_get_type ()
+{
+  static guint tree_item_type = 0;
+
+  if (!tree_item_type)
+    {
+      GtkTypeInfo tree_item_info =
+      {
+       "GtkTreeItem",
+       sizeof (GtkTreeItem),
+       sizeof (GtkTreeItemClass),
+       (GtkClassInitFunc) gtk_tree_item_class_init,
+       (GtkObjectInitFunc) gtk_tree_item_init,
+       (GtkArgFunc) NULL,
+      };
+
+      tree_item_type = gtk_type_unique (gtk_item_get_type (), &tree_item_info);
+    }
+
+  return tree_item_type;
+}
+
+static void
+gtk_tree_item_class_init (GtkTreeItemClass *class)
+{
+}
+
+static void
+gtk_tree_item_init (GtkTreeItem *tree_item)
+{
+}
+
+
+GtkWidget*
+gtk_tree_item_new ()
+{
+  return GTK_WIDGET (gtk_type_new (gtk_tree_item_get_type ()));
+}
+
+GtkWidget*
+gtk_tree_item_new_with_label (gchar *label)
+{
+  GtkWidget *tree_item;
+  GtkWidget *label_widget;
+
+  tree_item = gtk_tree_item_new ();
+  label_widget = gtk_label_new (label);
+  gtk_misc_set_alignment (GTK_MISC (label_widget), 0.0, 0.5);
+
+  gtk_container_add (GTK_CONTAINER (tree_item), label_widget);
+  gtk_widget_show (label_widget);
+
+  return tree_item;
+}
+
+void
+gtk_tree_item_set_subtree (GtkTreeItem *tree_item,
+                          GtkWidget   *subtree)
+{
+  g_return_if_fail (tree_item != NULL);
+  g_return_if_fail (GTK_IS_TREE_ITEM (tree_item));
+}
+
+void
+gtk_tree_item_select (GtkTreeItem *tree_item)
+{
+}
+
+void
+gtk_tree_item_deselect (GtkTreeItem *tree_item)
+{
+}
+
+void
+gtk_tree_item_expand (GtkTreeItem *tree_item)
+{
+}
+
+void
+gtk_tree_item_collapse (GtkTreeItem *tree_item)
+{
+}
diff --git a/gtk/gtktreeitem.h b/gtk/gtktreeitem.h
new file mode 100644 (file)
index 0000000..921f681
--- /dev/null
@@ -0,0 +1,72 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_TREE_ITEM_H__
+#define __GTK_TREE_ITEM_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkitem.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_TREE_ITEM(obj)          GTK_CHECK_CAST (obj, gtk_tree_item_get_type (), GtkTreeItem)
+#define GTK_TREE_ITEM_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_tree_item_get_type (), GtkTreeItemClass)
+#define GTK_IS_TREE_ITEM(obj)       GTK_CHECK_TYPE (obj, gtk_tree_item_get_type ())
+
+
+typedef struct _GtkTreeItem       GtkTreeItem;
+typedef struct _GtkTreeItemClass  GtkTreeItemClass;
+
+struct _GtkTreeItem
+{
+  GtkItem item;
+
+  GtkWidget *child;
+  GtkWidget *subtree;
+};
+
+struct _GtkTreeItemClass
+{
+  GtkItemClass parent_class;
+
+  void (* expand)   (GtkTreeItem *tree_item);
+  void (* collapse) (GtkTreeItem *tree_item);
+};
+
+
+guint      gtk_tree_item_get_type       (void);
+GtkWidget* gtk_tree_item_new            (void);
+GtkWidget* gtk_tree_item_new_with_label (gchar       *label);
+void       gtk_tree_item_set_subtree    (GtkTreeItem *tree_item,
+                                        GtkWidget   *subtree);
+void       gtk_tree_item_select         (GtkTreeItem *tree_item);
+void       gtk_tree_item_deselect       (GtkTreeItem *tree_item);
+void       gtk_tree_item_expand         (GtkTreeItem *tree_item);
+void       gtk_tree_item_collapse       (GtkTreeItem *tree_item);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_TREE_ITEM_H__ */
diff --git a/gtk/gtktypebuiltins.c b/gtk/gtktypebuiltins.c
new file mode 100644 (file)
index 0000000..e435731
--- /dev/null
@@ -0,0 +1,53 @@
+/* generated by gentypeinfo from "gtk.defs" */
+
+  { "GtkWindowType", GTK_TYPE_ENUM },
+  { "GtkStateType", GTK_TYPE_ENUM },
+  { "GtkDirectionType", GTK_TYPE_ENUM },
+  { "GtkShadowType", GTK_TYPE_ENUM },
+  { "GtkArrowType", GTK_TYPE_ENUM },
+  { "GtkPackType", GTK_TYPE_ENUM },
+  { "GtkPolicyType", GTK_TYPE_ENUM },
+  { "GtkUpdateType", GTK_TYPE_ENUM },
+  { "GtkAttachOptions", GTK_TYPE_FLAGS },
+  { "GtkSignalRunType", GTK_TYPE_FLAGS },
+  { "GtkWindowPosition", GTK_TYPE_ENUM },
+  { "GtkSubmenuDirection", GTK_TYPE_ENUM },
+  { "GtkSubmenuPlacement", GTK_TYPE_ENUM },
+  { "GtkMenuFactoryType", GTK_TYPE_ENUM },
+  { "GtkMetricType", GTK_TYPE_ENUM },
+  { "GtkScrollType", GTK_TYPE_ENUM },
+  { "GtkTroughType", GTK_TYPE_ENUM },
+  { "GtkPositionType", GTK_TYPE_ENUM },
+  { "GtkPreviewType", GTK_TYPE_ENUM },
+  { "GtkWidgetFlags", GTK_TYPE_FLAGS },
+  { "GdkWindowType", GTK_TYPE_ENUM },
+  { "GdkWindowClass", GTK_TYPE_ENUM },
+  { "GdkImageType", GTK_TYPE_ENUM },
+  { "GdkVisualType", GTK_TYPE_ENUM },
+  { "GdkWindowAttributesType", GTK_TYPE_FLAGS },
+  { "GdkWindowHints", GTK_TYPE_FLAGS },
+  { "GdkFunction", GTK_TYPE_ENUM },
+  { "GdkFill", GTK_TYPE_ENUM },
+  { "GdkLineStyle", GTK_TYPE_ENUM },
+  { "GdkCapStyle", GTK_TYPE_ENUM },
+  { "GdkJoinStyle", GTK_TYPE_ENUM },
+  { "GdkCursorType", GTK_TYPE_ENUM },
+  { "GdkEventType", GTK_TYPE_ENUM },
+  { "GdkEventMask", GTK_TYPE_FLAGS },
+  { "GdkNotifyType", GTK_TYPE_ENUM },
+  { "GdkModifierType", GTK_TYPE_FLAGS },
+  { "GdkSubwindowMode", GTK_TYPE_ENUM },
+  { "GdkInputCondition", GTK_TYPE_FLAGS },
+  { "GdkStatus", GTK_TYPE_ENUM },
+  { "GdkByteOrder", GTK_TYPE_ENUM },
+  { "GdkGCValuesMask", GTK_TYPE_FLAGS },
+  { "GdkSelection", GTK_TYPE_ENUM },
+  { "GdkPropertyState", GTK_TYPE_ENUM },
+  { "GdkPropMode", GTK_TYPE_ENUM },
+  { "GtkAcceleratorTable", GTK_TYPE_BOXED },
+  { "GtkStyle", GTK_TYPE_BOXED },
+  { "GdkColormap", GTK_TYPE_BOXED },
+  { "GdkVisual", GTK_TYPE_BOXED },
+  { "GdkFont", GTK_TYPE_BOXED },
+  { "GdkWindow", GTK_TYPE_BOXED },
+  { "GdkEvent", GTK_TYPE_BOXED },
diff --git a/gtk/gtktypebuiltins.h b/gtk/gtktypebuiltins.h
new file mode 100644 (file)
index 0000000..ba9131f
--- /dev/null
@@ -0,0 +1,54 @@
+/* generated by gentypeinfo from "gtk.defs" */
+
+#define GTK_TYPE_WINDOW_TYPE (gtk_type_builtins[0])
+#define GTK_TYPE_STATE_TYPE (gtk_type_builtins[1])
+#define GTK_TYPE_DIRECTION_TYPE (gtk_type_builtins[2])
+#define GTK_TYPE_SHADOW_TYPE (gtk_type_builtins[3])
+#define GTK_TYPE_ARROW_TYPE (gtk_type_builtins[4])
+#define GTK_TYPE_PACK_TYPE (gtk_type_builtins[5])
+#define GTK_TYPE_POLICY_TYPE (gtk_type_builtins[6])
+#define GTK_TYPE_UPDATE_TYPE (gtk_type_builtins[7])
+#define GTK_TYPE_ATTACH_OPTIONS (gtk_type_builtins[8])
+#define GTK_TYPE_SIGNAL_RUN_TYPE (gtk_type_builtins[9])
+#define GTK_TYPE_WINDOW_POSITION (gtk_type_builtins[10])
+#define GTK_TYPE_SUBMENU_DIRECTION (gtk_type_builtins[11])
+#define GTK_TYPE_SUBMENU_PLACEMENT (gtk_type_builtins[12])
+#define GTK_TYPE_MENU_FACTORY_TYPE (gtk_type_builtins[13])
+#define GTK_TYPE_METRIC_TYPE (gtk_type_builtins[14])
+#define GTK_TYPE_SCROLL_TYPE (gtk_type_builtins[15])
+#define GTK_TYPE_TROUGH_TYPE (gtk_type_builtins[16])
+#define GTK_TYPE_POSITION_TYPE (gtk_type_builtins[17])
+#define GTK_TYPE_PREVIEW_TYPE (gtk_type_builtins[18])
+#define GTK_TYPE_WIDGET_FLAGS (gtk_type_builtins[19])
+#define GTK_TYPE_GDK_WINDOW_TYPE (gtk_type_builtins[20])
+#define GTK_TYPE_GDK_WINDOW_CLASS (gtk_type_builtins[21])
+#define GTK_TYPE_GDK_IMAGE_TYPE (gtk_type_builtins[22])
+#define GTK_TYPE_GDK_VISUAL_TYPE (gtk_type_builtins[23])
+#define GTK_TYPE_GDK_WINDOW_ATTRIBUTES_TYPE (gtk_type_builtins[24])
+#define GTK_TYPE_GDK_WINDOW_HINTS (gtk_type_builtins[25])
+#define GTK_TYPE_GDK_FUNCTION (gtk_type_builtins[26])
+#define GTK_TYPE_GDK_FILL (gtk_type_builtins[27])
+#define GTK_TYPE_GDK_LINE_STYLE (gtk_type_builtins[28])
+#define GTK_TYPE_GDK_CAP_STYLE (gtk_type_builtins[29])
+#define GTK_TYPE_GDK_JOIN_STYLE (gtk_type_builtins[30])
+#define GTK_TYPE_GDK_CURSOR_TYPE (gtk_type_builtins[31])
+#define GTK_TYPE_GDK_EVENT_TYPE (gtk_type_builtins[32])
+#define GTK_TYPE_GDK_EVENT_MASK (gtk_type_builtins[33])
+#define GTK_TYPE_GDK_NOTIFY_TYPE (gtk_type_builtins[34])
+#define GTK_TYPE_GDK_MODIFIER_TYPE (gtk_type_builtins[35])
+#define GTK_TYPE_GDK_SUBWINDOW_MODE (gtk_type_builtins[36])
+#define GTK_TYPE_GDK_INPUT_CONDITION (gtk_type_builtins[37])
+#define GTK_TYPE_GDK_STATUS (gtk_type_builtins[38])
+#define GTK_TYPE_GDK_BYTE_ORDER (gtk_type_builtins[39])
+#define GTK_TYPE_GDK_GCVALUES_MASK (gtk_type_builtins[40])
+#define GTK_TYPE_GDK_SELECTION (gtk_type_builtins[41])
+#define GTK_TYPE_GDK_PROPERTY_STATE (gtk_type_builtins[42])
+#define GTK_TYPE_GDK_PROP_MODE (gtk_type_builtins[43])
+#define GTK_TYPE_ACCELERATOR_TABLE (gtk_type_builtins[44])
+#define GTK_TYPE_STYLE (gtk_type_builtins[45])
+#define GTK_TYPE_GDK_COLORMAP (gtk_type_builtins[46])
+#define GTK_TYPE_GDK_VISUAL (gtk_type_builtins[47])
+#define GTK_TYPE_GDK_FONT (gtk_type_builtins[48])
+#define GTK_TYPE_GDK_WINDOW (gtk_type_builtins[49])
+#define GTK_TYPE_GDK_EVENT (gtk_type_builtins[50])
+#define GTK_TYPE_NUM_BUILTINS 51
diff --git a/gtk/gtktypeutils.c b/gtk/gtktypeutils.c
new file mode 100644 (file)
index 0000000..46e035f
--- /dev/null
@@ -0,0 +1,459 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <string.h>
+#include "gtkobject.h"
+#include "gtktypeutils.h"
+
+
+typedef struct _GtkTypeNode GtkTypeNode;
+
+struct _GtkTypeNode
+{
+  GtkType type;
+  gint init_class;
+  gpointer klass;
+  GtkTypeInfo type_info;
+  GtkTypeNode *parent;
+  GList *children;
+};
+
+
+static void  gtk_type_insert       (guint        parent_type,
+                                   GtkType      type,
+                                   GtkTypeInfo *type_info);
+static void  gtk_type_class_init   (GtkTypeNode *node);
+static void  gtk_type_object_init  (GtkTypeNode *node,
+                                   gpointer     object);
+static guint gtk_type_hash         (GtkType     *key);
+static gint  gtk_type_compare      (GtkType     *a,
+                                   GtkType     *b);
+static guint gtk_type_name_hash    (const char  *key);
+static gint  gtk_type_name_compare (const char  *a,
+                                   const char  *b);
+static void  gtk_type_init_builtin_types ();
+
+
+static int initialize = TRUE;
+static GHashTable *type_hash_table = NULL;
+static GHashTable *name_hash_table = NULL;
+
+
+void
+gtk_type_init ()
+{
+  if (initialize)
+    {
+      g_assert (sizeof (GtkType) >= 4);
+
+      initialize = FALSE;
+      type_hash_table = g_hash_table_new ((GHashFunc) gtk_type_hash,
+                                         (GCompareFunc) gtk_type_compare);
+      name_hash_table = g_hash_table_new ((GHashFunc) gtk_type_name_hash,
+                                         (GCompareFunc) gtk_type_name_compare);
+      gtk_type_init_builtin_types ();
+    }
+}
+
+GtkType
+gtk_type_unique (GtkType      parent_type,
+                GtkTypeInfo *type_info)
+{
+  static guint next_seqno = 0;
+  GtkType new_type;
+
+  g_return_val_if_fail (type_info != NULL, 0);
+
+  if (initialize)
+    gtk_type_init ();
+
+  next_seqno++;
+  if (parent_type == GTK_TYPE_INVALID)
+    new_type = next_seqno;
+  else
+    new_type = GTK_TYPE_MAKE (GTK_FUNDAMENTAL_TYPE (parent_type), next_seqno);
+  gtk_type_insert (parent_type, new_type, type_info);
+
+  return new_type;
+}
+
+gchar*
+gtk_type_name (GtkType type)
+{
+  GtkTypeNode *node;
+
+  if (initialize)
+    gtk_type_init ();
+
+  node = g_hash_table_lookup (type_hash_table, &type);
+
+  if (node)
+    return node->type_info.type_name;
+
+  return NULL;
+}
+
+GtkType
+gtk_type_from_name (const gchar *name)
+{
+  GtkTypeNode *node;
+
+  if (initialize)
+    gtk_type_init ();
+
+  node = g_hash_table_lookup (name_hash_table, (gpointer) name);
+
+  if (node)
+    return node->type;
+
+  return 0;
+}
+
+GtkType
+gtk_type_parent (GtkType type)
+{
+  GtkTypeNode *node;
+
+  if (initialize)
+    gtk_type_init ();
+
+  node = g_hash_table_lookup (type_hash_table, &type);
+
+  if (node && node->parent)
+    return node->parent->type;
+
+  return 0;
+}
+
+gpointer
+gtk_type_class (GtkType type)
+{
+  GtkTypeNode *node;
+
+  if (initialize)
+    gtk_type_init ();
+
+  node = g_hash_table_lookup (type_hash_table, &type);
+  g_return_val_if_fail (node != NULL, NULL);
+
+  if (node->init_class)
+    gtk_type_class_init (node);
+
+  return node->klass;
+}
+
+gpointer
+gtk_type_new (GtkType type)
+{
+  GtkTypeNode *node;
+  gpointer object;
+
+  if (initialize)
+    gtk_type_init ();
+
+  node = g_hash_table_lookup (type_hash_table, &type);
+  g_return_val_if_fail (node != NULL, NULL);
+
+  object = g_new0 (guchar, node->type_info.object_size);
+  ((GtkObject*) object)->klass = gtk_type_class (type);
+  gtk_type_object_init (node, object);
+
+  return object;
+}
+
+void
+gtk_type_describe_heritage (GtkType type)
+{
+  GtkTypeNode *node;
+  gint first;
+
+  if (initialize)
+    gtk_type_init ();
+
+  node = g_hash_table_lookup (type_hash_table, &type);
+  first = TRUE;
+
+  while (node)
+    {
+      if (first)
+       {
+         first = FALSE;
+         g_print ("is a ");
+       }
+
+      if (node->type_info.type_name)
+       g_print ("%s\n", node->type_info.type_name);
+      else
+       g_print ("<unnamed type>\n");
+
+      node = node->parent;
+    }
+}
+
+void
+gtk_type_describe_tree (GtkType type,
+                       gint  show_size)
+{
+  static gint indent = 0;
+  GtkTypeNode *node;
+  GtkTypeNode *child;
+  GList *children;
+  gint old_indent;
+  gint i;
+
+  if (initialize)
+    gtk_type_init ();
+
+  node = g_hash_table_lookup (type_hash_table, &type);
+
+  for (i = 0; i < indent; i++)
+    g_print (" ");
+
+  if (node->type_info.type_name)
+    g_print ("%s", node->type_info.type_name);
+  else
+    g_print ("<unnamed type>");
+
+  if (show_size)
+    g_print (" ( %d bytes )\n", node->type_info.object_size);
+  else
+    g_print ("\n");
+
+  old_indent = indent;
+  indent += 4;
+
+  children = node->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      gtk_type_describe_tree (child->type, show_size);
+    }
+
+  indent = old_indent;
+}
+
+gint
+gtk_type_is_a (GtkType type,
+              GtkType is_a_type)
+{
+  GtkTypeNode *node;
+
+  if (initialize)
+    gtk_type_init ();
+
+  node = g_hash_table_lookup (type_hash_table, &type);
+
+  while (node)
+    {
+      if (node->type == is_a_type)
+       return TRUE;
+      node = node->parent;
+    }
+
+  return FALSE;
+}
+
+void
+gtk_type_set_arg (GtkObject *object,
+                 GtkType      type,
+                 GtkArg    *arg)
+{
+  GtkTypeNode *node;
+
+  if (initialize)
+    gtk_type_init ();
+
+  node = g_hash_table_lookup (type_hash_table, &type);
+
+  if (node->type_info.arg_func)
+    (* node->type_info.arg_func) (object, arg);
+}
+
+static void
+gtk_type_insert (GtkType        parent_type,
+                GtkType        type,
+                GtkTypeInfo   *type_info)
+{
+  GtkTypeNode *node;
+  GtkTypeNode *parent;
+
+  parent = g_hash_table_lookup (type_hash_table, &parent_type);
+
+  node = g_new (GtkTypeNode, 1);
+  node->type = type;
+  node->init_class = TRUE;
+  node->klass = NULL;
+  node->type_info = *type_info;
+  node->parent = parent;
+  node->children = NULL;
+
+  if (node->parent)
+    node->parent->children = g_list_append (node->parent->children, node);
+
+  g_hash_table_insert (type_hash_table, &node->type, node);
+  g_hash_table_insert (name_hash_table, node->type_info.type_name, node);
+}
+
+static void
+gtk_type_class_init (GtkTypeNode *node)
+{
+  GtkObjectClass *object_class;
+
+  if (node->init_class)
+    {
+      node->init_class = FALSE;
+      node->klass = g_new0 (guchar, node->type_info.class_size);
+
+      if (node->parent)
+       {
+         if (node->parent->init_class)
+           gtk_type_class_init (node->parent);
+
+         memcpy (node->klass, node->parent->klass, node->parent->type_info.class_size);
+       }
+
+      object_class = node->klass;
+      object_class->type = node->type;
+
+      if (node->type_info.class_init_func)
+       (* node->type_info.class_init_func) (node->klass);
+    }
+}
+
+static void
+gtk_type_object_init (GtkTypeNode *node,
+                     gpointer     object)
+{
+  if (node->parent)
+    gtk_type_object_init (node->parent, object);
+
+  if (node->type_info.object_init_func)
+    (* node->type_info.object_init_func) (object);
+}
+
+static guint
+gtk_type_hash (GtkType *key)
+{
+  return GTK_TYPE_SEQNO (*key);
+}
+
+static gint
+gtk_type_compare (GtkType *a,
+                 GtkType *b)
+{
+  g_return_val_if_fail(a != NULL && b != NULL, 0);
+  return (*a == *b);
+}
+
+static guint
+gtk_type_name_hash (const char *key)
+{
+  guint result;
+
+  result = 0;
+  while (*key)
+    result += (result << 3) + *key++;
+
+  return result;
+}
+
+static gint
+gtk_type_name_compare (const char *a,
+                      const char *b)
+{
+  return (strcmp (a, b) == 0);
+}
+
+static GtkType
+gtk_type_register_builtin (char   *name,
+                          GtkType parent)
+{
+  GtkTypeInfo info;
+
+  info.type_name = name;
+  info.object_size = info.class_size = 0;
+  info.class_init_func = NULL;
+  info.object_init_func = NULL;
+  info.arg_func = NULL;
+
+  return gtk_type_unique (parent, &info);
+}
+
+extern void gtk_object_init_type ();
+
+GtkType gtk_type_builtins[GTK_TYPE_NUM_BUILTINS];
+
+static void
+gtk_type_init_builtin_types ()
+{
+  /* GTK_TYPE_INVALID has typeid 0.  The first type id returned by
+     gtk_type_unique is 1, which is GTK_TYPE_NONE.  And so on. */
+
+  static struct {
+    GtkType enum_id;
+    gchar *name;
+  } fundamental_info[] = {
+    { GTK_TYPE_NONE, "void" },
+    { GTK_TYPE_CHAR, "char" },
+    { GTK_TYPE_BOOL, "bool" },
+    { GTK_TYPE_INT, "int" },
+    { GTK_TYPE_UINT, "uint" },
+    { GTK_TYPE_LONG, "long" },
+    { GTK_TYPE_ULONG, "ulong" },
+    { GTK_TYPE_FLOAT, "float" },
+    { GTK_TYPE_STRING, "string" },
+    { GTK_TYPE_ENUM, "enum" },
+    { GTK_TYPE_FLAGS, "flags" },
+    { GTK_TYPE_BOXED, "boxed" },
+    { GTK_TYPE_FOREIGN, "foreign" },
+    { GTK_TYPE_CALLBACK, "callback" },
+    { GTK_TYPE_ARGS, "args" },
+
+    { GTK_TYPE_POINTER, "pointer" },
+    { GTK_TYPE_SIGNAL, "signal" },
+    { GTK_TYPE_C_CALLBACK, "c_callback" }
+  };
+
+  static struct {
+    char *name;
+    GtkType parent;
+  } builtin_info[] = {
+#include "gtktypebuiltins.c"
+    { NULL }
+  };
+
+  int i;
+
+  for (i = 0; i < sizeof (fundamental_info)/sizeof(fundamental_info[0]); i++)
+    {
+      GtkType id;
+      id = gtk_type_register_builtin (fundamental_info[i].name,
+                                     GTK_TYPE_INVALID);
+      g_assert (id == fundamental_info[i].enum_id);
+    }
+
+  gtk_object_init_type ();
+
+  for (i = 0; builtin_info[i].name; i++)
+    {
+      gtk_type_builtins[i] =
+       gtk_type_register_builtin (builtin_info[i].name,
+                                  builtin_info[i].parent);
+    }
+}
diff --git a/gtk/gtktypeutils.h b/gtk/gtktypeutils.h
new file mode 100644 (file)
index 0000000..911885b
--- /dev/null
@@ -0,0 +1,196 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_TYPE_UTILS_H__
+#define __GTK_TYPE_UTILS_H__
+
+
+#include <gdk/gdk.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* Fundamental Types */
+
+typedef enum
+{
+  GTK_TYPE_INVALID,
+  GTK_TYPE_NONE,
+  GTK_TYPE_CHAR,
+  GTK_TYPE_BOOL,
+  GTK_TYPE_INT,
+  GTK_TYPE_UINT,
+  GTK_TYPE_LONG,
+  GTK_TYPE_ULONG,
+  GTK_TYPE_FLOAT,
+  GTK_TYPE_STRING,
+  GTK_TYPE_ENUM,
+  GTK_TYPE_FLAGS,
+  GTK_TYPE_BOXED,
+  GTK_TYPE_FOREIGN,
+  GTK_TYPE_CALLBACK,
+  GTK_TYPE_ARGS,
+
+  GTK_TYPE_POINTER,
+
+  /* it'd be great if the next two could be removed eventually */
+  GTK_TYPE_SIGNAL,
+  GTK_TYPE_C_CALLBACK,
+
+  GTK_TYPE_OBJECT
+
+} GtkFundamentalType;
+
+typedef guint GtkType;
+
+/* Builtin Types */
+
+extern GtkType gtk_type_builtins[];
+#include <gtk/gtktypebuiltins.h>
+
+/* General Types */
+
+#define GTK_TYPE_MAKE(ft, seqno) (((seqno)<<8)|ft)
+#define GTK_FUNDAMENTAL_TYPE(t)  ((GtkFundamentalType)((t)&0xFF))
+#define GTK_TYPE_SEQNO(t)        ((t)>0xFF? (t)>>8:(t))
+
+typedef struct _GtkArg         GtkArg;
+typedef struct _GtkObject      GtkObject;   /* forward declaration of object type */
+typedef struct _GtkTypeInfo    GtkTypeInfo;
+
+typedef void (*GtkClassInitFunc)  (gpointer klass);
+typedef void (*GtkObjectInitFunc) (gpointer object);
+typedef void (*GtkArgFunc) (GtkObject *object, GtkArg *arg);
+typedef gint (*GtkFunction) (gpointer data);
+typedef void (*GtkRemoveFunction) (gpointer data);
+typedef void (*GtkCallbackMarshal) (GtkObject *object,
+                                   gpointer data,
+                                   int n_args,
+                                   GtkArg *args);
+typedef void (*GtkDestroyNotify) (gpointer data);
+
+struct _GtkArg
+{
+  GtkType type;
+  char *name;
+
+  union {
+    gchar char_data;
+    gint int_data;
+    guint uint_data;
+    gint bool_data;
+    glong long_data;
+    gulong ulong_data;
+    gfloat float_data;
+    gchar *string_data;
+    gpointer pointer_data;
+    GtkObject *object_data;
+    struct {
+      GtkCallbackMarshal marshal;
+      gpointer data;
+      GtkDestroyNotify notify;
+    } callback_data;
+    struct {
+      gpointer data;
+      GtkDestroyNotify notify;
+    } foreign_data;
+    struct {
+      gint n_args;
+      GtkArg *args;
+    } args_data;
+    struct {
+      GtkFunction f;
+      gpointer d;
+    } signal_data;
+    struct {
+      GtkFunction func;
+      gpointer func_data;
+    } c_callback_data;
+  } d;
+};
+
+#define GTK_VALUE_CHAR(a)       ((a).d.char_data)
+#define GTK_VALUE_BOOL(a)       ((a).d.bool_data)
+#define GTK_VALUE_INT(a)        ((a).d.int_data)
+#define GTK_VALUE_UINT(a)       ((a).d.uint_data)
+#define GTK_VALUE_LONG(a)       ((a).d.long_data)
+#define GTK_VALUE_ULONG(a)      ((a).d.ulong_data)
+#define GTK_VALUE_FLOAT(a)      ((a).d.float_data)
+#define GTK_VALUE_STRING(a)     ((a).d.string_data)
+#define GTK_VALUE_ENUM(a)       ((a).d.int_data)
+#define GTK_VALUE_FLAGS(a)      ((a).d.int_data)
+#define GTK_VALUE_BOXED(a)      ((a).d.pointer_data)
+#define GTK_VALUE_FOREIGN(a)    ((a).d.foreign_data)
+#define GTK_VALUE_CALLBACK(a)   ((a).d.callback_data)
+#define GTK_VALUE_ARGS(a)       ((a).d.args_data)
+#define GTK_VALUE_OBJECT(a)     ((a).d.object_data)
+#define GTK_VALUE_POINTER(a)    ((a).d.pointer_data)
+#define GTK_VALUE_SIGNAL(a)     ((a).d.signal_data)
+#define GTK_VALUE_C_CALLBACK(a) ((a).d.c_callback_data)
+
+#define GTK_RETLOC_CHAR(a)      ((gchar*)(a).d.pointer_data)
+#define GTK_RETLOC_BOOL(a)      ((gint*)(a).d.pointer_data)
+#define GTK_RETLOC_INT(a)       ((gint*)(a).d.pointer_data)
+#define GTK_RETLOC_UINT(a)      ((guint*)(a).d.pointer_data)
+#define GTK_RETLOC_LONG(a)      ((glong*)(a).d.pointer_data)
+#define GTK_RETLOC_ULONG(a)     ((gulong*)(a).d.pointer_data)
+#define GTK_RETLOC_FLOAT(a)     ((gfloat*)(a).d.pointer_data)
+#define GTK_RETLOC_STRING(a)    ((gchar**)(a).d.pointer_data)
+#define GTK_RETLOC_ENUM(a)      ((gint*)(a).d.pointer_data)
+#define GTK_RETLOC_FLAGS(a)     ((gint*)(a).d.pointer_data)
+#define GTK_RETLOC_BOXED(a)     ((gpointer*)(a).d.pointer_data)
+#define GTK_RETLOC_OBJECT(a)    ((GtkObject**)(a).d.pointer_data)
+#define GTK_RETLOC_POINTER(a)   ((gpointer*)(a).d.pointer_data)
+
+struct _GtkTypeInfo
+{
+  gchar *type_name;
+  guint object_size;
+  guint class_size;
+  GtkClassInitFunc class_init_func;
+  GtkObjectInitFunc object_init_func;
+  GtkArgFunc arg_func;
+};
+
+
+void     gtk_type_init              (void);
+GtkType  gtk_type_unique            (guint        parent_type,
+                                    GtkTypeInfo *type_info);
+gchar*   gtk_type_name              (guint        type);
+GtkType  gtk_type_from_name         (const gchar *name);
+GtkType  gtk_type_parent            (GtkType      type);
+gpointer gtk_type_class             (GtkType      type);
+gpointer gtk_type_new               (GtkType      type);
+void     gtk_type_describe_heritage (GtkType      type);
+void     gtk_type_describe_tree     (GtkType      type,
+                                    gint         show_size);
+gint     gtk_type_is_a              (GtkType      type,
+                                    GtkType      is_a_type);
+void     gtk_type_set_arg           (GtkObject   *object,
+                                    GtkType      type,
+                                    GtkArg      *arg);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_TYPE_UTILS_H__ */
diff --git a/gtk/gtkvbbox.c b/gtk/gtkvbbox.c
new file mode 100644 (file)
index 0000000..4fc867f
--- /dev/null
@@ -0,0 +1,272 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkvbbox.h"
+
+
+static void gtk_vbutton_box_class_init    (GtkVButtonBoxClass   *klass);
+static void gtk_vbutton_box_init          (GtkVButtonBox        *box);
+static void gtk_vbutton_box_size_request  (GtkWidget      *widget,
+                                          GtkRequisition *requisition);
+static void gtk_vbutton_box_size_allocate (GtkWidget      *widget,
+                                          GtkAllocation  *allocation);
+
+static gint default_spacing = 10;
+static gint default_layout_style = GTK_BUTTONBOX_EDGE;
+
+guint
+gtk_vbutton_box_get_type ()
+{
+  static guint vbutton_box_type = 0;
+
+  if (!vbutton_box_type)
+    {
+      GtkTypeInfo vbutton_box_info =
+      {
+       "GtkVButtonBox",
+       sizeof (GtkVButtonBox),
+       sizeof (GtkVButtonBoxClass),
+       (GtkClassInitFunc) gtk_vbutton_box_class_init,
+       (GtkObjectInitFunc) gtk_vbutton_box_init,
+       (GtkArgFunc) NULL,
+      };
+
+      vbutton_box_type = gtk_type_unique (gtk_button_box_get_type (), &vbutton_box_info);
+    }
+
+  return vbutton_box_type;
+}
+
+static void
+gtk_vbutton_box_class_init (GtkVButtonBoxClass *class)
+{
+  GtkWidgetClass *widget_class;
+
+  widget_class = (GtkWidgetClass*) class;
+
+  widget_class->size_request = gtk_vbutton_box_size_request;
+  widget_class->size_allocate = gtk_vbutton_box_size_allocate;
+}
+
+static void
+gtk_vbutton_box_init (GtkVButtonBox *vbutton_box)
+{
+  /* button_box_init has done everything allready */
+}
+
+GtkWidget*
+gtk_vbutton_box_new ()
+{
+  GtkVButtonBox *vbutton_box;
+
+  vbutton_box = gtk_type_new (gtk_vbutton_box_get_type ());
+  return GTK_WIDGET (vbutton_box);
+}
+
+
+
+/* set default value for spacing */
+
+void gtk_vbutton_box_set_spacing_default (gint spacing)
+{
+  default_spacing = spacing;
+}
+
+
+/* set default value for layout style */
+
+void gtk_vbutton_box_set_layout_default (gint layout)
+{
+  default_layout_style = layout;
+}
+
+/* get default value for spacing */
+
+gint gtk_vbutton_box_get_spacing_default (void)
+{
+  return default_spacing;
+}
+
+
+
+/* get default value for layout style */
+
+gint gtk_vbutton_box_get_layout_default (void)
+{
+  return default_layout_style;
+}
+
+
+
+  
+static void
+gtk_vbutton_box_size_request (GtkWidget      *widget,
+                             GtkRequisition *requisition)
+{
+  GtkBox *box;
+  GtkButtonBox *bbox;
+  gint nvis_children;
+  gint child_width;
+  gint child_height;
+  gint spacing;
+  gint layout;
+  
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_VBUTTON_BOX (widget));
+  g_return_if_fail (requisition != NULL);
+
+  box = GTK_BOX (widget);
+  bbox = GTK_BUTTON_BOX (widget);
+
+  spacing = bbox->spacing != GTK_BUTTONBOX_DEFAULT
+         ? bbox->spacing : default_spacing;
+  layout = bbox->layout_style != GTK_BUTTONBOX_DEFAULT
+         ? bbox->layout_style : default_layout_style;
+  
+  gtk_button_box_child_requisition (widget,
+                                   &nvis_children,
+                                   &child_width,
+                                   &child_height);
+
+  if (nvis_children == 0)
+    {
+      requisition->width = 0; 
+      requisition->height = 0;
+    }
+  else
+    {
+      switch (layout)
+      {
+      case GTK_BUTTONBOX_SPREAD:
+        requisition->height =
+               nvis_children*child_height + ((nvis_children+1)*spacing);
+       break;
+      case GTK_BUTTONBOX_EDGE:
+      case GTK_BUTTONBOX_START:
+      case GTK_BUTTONBOX_END:
+        requisition->height =
+               nvis_children*child_height + ((nvis_children-1)*spacing);
+       break;
+      default:
+           g_assert_not_reached();
+           break;
+      }
+         
+      requisition->width = child_width;
+    }
+         
+  requisition->width += GTK_CONTAINER (box)->border_width * 2;
+  requisition->height += GTK_CONTAINER (box)->border_width * 2;
+}
+
+
+
+static void
+gtk_vbutton_box_size_allocate (GtkWidget     *widget,
+                              GtkAllocation *allocation)
+{
+  GtkButtonBox *box;
+  GtkVButtonBox *hbox;
+  GtkBoxChild *child;
+  GList *children;
+  GtkAllocation child_allocation;
+  gint nvis_children;
+  gint child_width;
+  gint child_height;
+  gint x = 0;
+  gint y = 0;
+  gint height;
+  gint childspace;
+  gint childspacing = 0;
+  gint layout;
+  gint spacing;
+  
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_VBUTTON_BOX (widget));
+  g_return_if_fail (allocation != NULL);
+
+  box = GTK_BUTTON_BOX (widget);
+  hbox = GTK_VBUTTON_BOX (widget);
+  spacing = box->spacing != GTK_BUTTONBOX_DEFAULT
+         ? box->spacing : default_spacing;
+  layout = box->layout_style != GTK_BUTTONBOX_DEFAULT
+         ? box->layout_style : default_layout_style;
+  gtk_button_box_child_requisition (widget,
+                                   &nvis_children,
+                                   &child_width,
+                                   &child_height);
+  widget->allocation = *allocation;
+  height = allocation->height - GTK_CONTAINER (box)->border_width*2;
+  switch (layout)
+  {
+  case GTK_BUTTONBOX_SPREAD:
+    childspacing = (height - (nvis_children*child_height)) / (nvis_children+1);
+    y = allocation->y + GTK_CONTAINER (box)->border_width + childspacing;
+    break;
+  case GTK_BUTTONBOX_EDGE:
+    if (nvis_children >= 2)
+      {
+        childspacing =
+               (height - (nvis_children*child_height)) / (nvis_children-1);
+       y = allocation->y + GTK_CONTAINER (box)->border_width;
+      }
+    else
+      {
+                     /* one or zero children, just center */
+             childspacing = height;
+             y = allocation->y + (allocation->height - child_height) / 2;
+      }
+    break;
+  case GTK_BUTTONBOX_START:
+    childspacing = spacing;
+    y = allocation->y + GTK_CONTAINER (box)->border_width;
+    break;
+  case GTK_BUTTONBOX_END:
+    childspacing = spacing;
+    y = allocation->x + allocation->height - child_height * nvis_children
+           - spacing * (nvis_children-1)
+           - GTK_CONTAINER (box)->border_width;
+    break;
+  default:
+    g_assert_not_reached();
+    break;
+  }
+                 
+  
+  x = allocation->x + (allocation->width - child_width) / 2;
+  childspace = child_height + childspacing;
+
+  children = GTK_BOX (box)->children;
+         
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (child->widget))
+       {
+         child_allocation.width = child_width;
+         child_allocation.height = child_height;
+         child_allocation.x = x;
+         child_allocation.y = y;
+         gtk_widget_size_allocate (child->widget, &child_allocation);
+         y += childspace;
+       }
+    }
+}
+  
+  
diff --git a/gtk/gtkvbbox.h b/gtk/gtkvbbox.h
new file mode 100644 (file)
index 0000000..310553d
--- /dev/null
@@ -0,0 +1,66 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_VBUTTON_BOX_H__
+#define __GTK_VBUTTON_BOX_H__
+
+
+#include "gtkbbox.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_VBUTTON_BOX(obj)          GTK_CHECK_CAST (obj, gtk_vbutton_box_get_type (), GtkVButtonBox)
+#define GTK_VBUTTON_BOX_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_vbutton_box_get_type (), GtkVButtonBoxClass)
+#define GTK_IS_VBUTTON_BOX(obj)       GTK_CHECK_TYPE (obj, gtk_vbutton_box_get_type ())
+
+
+typedef struct _GtkVButtonBox       GtkVButtonBox;
+typedef struct _GtkVButtonBoxClass  GtkVButtonBoxClass;
+
+struct _GtkVButtonBox
+{
+  GtkButtonBox button_box;
+};
+
+struct _GtkVButtonBoxClass
+{
+  GtkButtonBoxClass parent_class;
+};
+
+
+guint      gtk_vbutton_box_get_type (void);
+GtkWidget *gtk_vbutton_box_new      (void);
+
+/* buttons can be added by gtk_container_add() */
+
+gint gtk_vbutton_box_get_spacing_default (void);
+void gtk_vbutton_box_set_spacing_default (gint spacing);
+
+void gtk_vbutton_box_set_spacing_default (gint spacing);
+void gtk_vbutton_box_set_layout_default (gint layout);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_VBUTTON_BOX_H__ */
diff --git a/gtk/gtkvbox.c b/gtk/gtkvbox.c
new file mode 100644 (file)
index 0000000..585e99b
--- /dev/null
@@ -0,0 +1,306 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkvbox.h"
+
+
+static void gtk_vbox_class_init    (GtkVBoxClass   *klass);
+static void gtk_vbox_init          (GtkVBox        *box);
+static void gtk_vbox_size_request  (GtkWidget      *widget,
+                                   GtkRequisition *requisition);
+static void gtk_vbox_size_allocate (GtkWidget      *widget,
+                                   GtkAllocation  *allocation);
+
+
+guint
+gtk_vbox_get_type ()
+{
+  static guint vbox_type = 0;
+
+  if (!vbox_type)
+    {
+      GtkTypeInfo vbox_info =
+      {
+       "GtkVBox",
+       sizeof (GtkVBox),
+       sizeof (GtkVBoxClass),
+       (GtkClassInitFunc) gtk_vbox_class_init,
+       (GtkObjectInitFunc) gtk_vbox_init,
+       (GtkArgFunc) NULL,
+      };
+
+      vbox_type = gtk_type_unique (gtk_box_get_type (), &vbox_info);
+    }
+
+  return vbox_type;
+}
+
+static void
+gtk_vbox_class_init (GtkVBoxClass *class)
+{
+  GtkWidgetClass *widget_class;
+
+  widget_class = (GtkWidgetClass*) class;
+
+  widget_class->size_request = gtk_vbox_size_request;
+  widget_class->size_allocate = gtk_vbox_size_allocate;
+}
+
+static void
+gtk_vbox_init (GtkVBox *vbox)
+{
+}
+
+GtkWidget*
+gtk_vbox_new (gint homogeneous,
+             gint spacing)
+{
+  GtkVBox *vbox;
+
+  vbox = gtk_type_new (gtk_vbox_get_type ());
+
+  GTK_BOX (vbox)->spacing = spacing;
+  GTK_BOX (vbox)->homogeneous = homogeneous ? TRUE : FALSE;
+
+  return GTK_WIDGET (vbox);
+}
+
+
+static void
+gtk_vbox_size_request (GtkWidget      *widget,
+                      GtkRequisition *requisition)
+{
+  GtkBox *box;
+  GtkBoxChild *child;
+  GList *children;
+  gint nvis_children;
+  gint height;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_VBOX (widget));
+  g_return_if_fail (requisition != NULL);
+
+  box = GTK_BOX (widget);
+  requisition->width = 0;
+  requisition->height = 0;
+  nvis_children = 0;
+
+  children = box->children;
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (child->widget))
+       {
+         gtk_widget_size_request (child->widget, &child->widget->requisition);
+
+         if (box->homogeneous)
+           {
+             height = child->widget->requisition.height + child->padding * 2;
+             requisition->height = MAX (requisition->height, height);
+           }
+         else
+           {
+             requisition->height += child->widget->requisition.height + child->padding * 2;
+           }
+
+         requisition->width = MAX (requisition->width, child->widget->requisition.width);
+
+         nvis_children += 1;
+       }
+    }
+
+  if (nvis_children > 0)
+    {
+      if (box->homogeneous)
+       requisition->height *= nvis_children;
+      requisition->height += (nvis_children - 1) * box->spacing;
+    }
+
+  requisition->width += GTK_CONTAINER (box)->border_width * 2;
+  requisition->height += GTK_CONTAINER (box)->border_width * 2;
+}
+
+static void
+gtk_vbox_size_allocate (GtkWidget     *widget,
+                       GtkAllocation *allocation)
+{
+  GtkBox *box;
+  GtkBoxChild *child;
+  GList *children;
+  GtkAllocation child_allocation;
+  gint nvis_children;
+  gint nexpand_children;
+  gint child_height;
+  gint height;
+  gint extra;
+  gint y;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_VBOX (widget));
+  g_return_if_fail (allocation != NULL);
+
+  box = GTK_BOX (widget);
+  widget->allocation = *allocation;
+
+  nvis_children = 0;
+  nexpand_children = 0;
+  children = box->children;
+
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (child->widget))
+       {
+         nvis_children += 1;
+         if (child->expand)
+           nexpand_children += 1;
+       }
+    }
+
+  if (nvis_children > 0)
+    {
+      if (box->homogeneous)
+       {
+         height = (allocation->height -
+                  GTK_CONTAINER (box)->border_width * 2 -
+                  (nvis_children - 1) * box->spacing);
+         extra = height / nvis_children;
+       }
+      else if (nexpand_children > 0)
+       {
+         height = allocation->height - widget->requisition.height;
+         extra = height / nexpand_children;
+       }
+      else
+       {
+         height = 0;
+         extra = 0;
+       }
+
+      y = allocation->y + GTK_CONTAINER (box)->border_width;
+      child_allocation.x = allocation->x + GTK_CONTAINER (box)->border_width;
+      child_allocation.width = allocation->width - GTK_CONTAINER (box)->border_width * 2;
+
+      children = box->children;
+      while (children)
+       {
+         child = children->data;
+         children = children->next;
+
+         if ((child->pack == GTK_PACK_START) && GTK_WIDGET_VISIBLE (child->widget))
+           {
+             if (box->homogeneous)
+               {
+                 if (nvis_children == 1)
+                   child_height = height;
+                 else
+                   child_height = extra;
+
+                 nvis_children -= 1;
+                 height -= extra;
+               }
+             else
+               {
+                 child_height = child->widget->requisition.height + child->padding * 2;
+
+                 if (child->expand)
+                   {
+                     if (nexpand_children == 1)
+                       child_height += height;
+                     else
+                       child_height += extra;
+
+                     nexpand_children -= 1;
+                     height -= extra;
+                   }
+               }
+
+             if (child->fill)
+               {
+                 child_allocation.height = child_height - child->padding * 2;
+                 child_allocation.y = y + child->padding;
+               }
+             else
+               {
+                 child_allocation.height = child->widget->requisition.height;
+                 child_allocation.y = y + (child_height - child_allocation.height) / 2;
+               }
+
+             gtk_widget_size_allocate (child->widget, &child_allocation);
+
+             y += child_height + box->spacing;
+           }
+       }
+
+      y = allocation->y + allocation->height - GTK_CONTAINER (box)->border_width;
+
+      children = box->children;
+      while (children)
+       {
+         child = children->data;
+         children = children->next;
+
+         if ((child->pack == GTK_PACK_END) && GTK_WIDGET_VISIBLE (child->widget))
+           {
+              if (box->homogeneous)
+                {
+                  if (nvis_children == 1)
+                    child_height = height;
+                  else
+                    child_height = extra;
+
+                  nvis_children -= 1;
+                  height -= extra;
+                }
+              else
+                {
+                 child_height = child->widget->requisition.height + child->padding * 2;
+
+                  if (child->expand)
+                    {
+                      if (nexpand_children == 1)
+                        child_height += height;
+                      else
+                        child_height += extra;
+
+                      nexpand_children -= 1;
+                      height -= extra;
+                    }
+                }
+
+              if (child->fill)
+                {
+                  child_allocation.height = child_height - child->padding * 2;
+                  child_allocation.y = y + child->padding - child_height;
+                }
+              else
+                {
+                  child_allocation.height = child->widget->requisition.height;
+                  child_allocation.y = y + (child_height - child_allocation.height) / 2 - child_height;
+                }
+
+              gtk_widget_size_allocate (child->widget, &child_allocation);
+
+              y -= (child_height + box->spacing);
+           }
+       }
+    }
+}
diff --git a/gtk/gtkvbox.h b/gtk/gtkvbox.h
new file mode 100644 (file)
index 0000000..aad32c9
--- /dev/null
@@ -0,0 +1,60 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_VBOX_H__
+#define __GTK_VBOX_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkbox.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_VBOX(obj)          GTK_CHECK_CAST (obj, gtk_vbox_get_type (), GtkVBox)
+#define GTK_VBOX_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_vbox_get_type (), GtkVBoxClass)
+#define GTK_IS_VBOX(obj)       GTK_CHECK_TYPE (obj, gtk_vbox_get_type ())
+
+
+typedef struct _GtkVBox       GtkVBox;
+typedef struct _GtkVBoxClass  GtkVBoxClass;
+
+struct _GtkVBox
+{
+  GtkBox box;
+};
+
+struct _GtkVBoxClass
+{
+  GtkBoxClass parent_class;
+};
+
+
+guint      gtk_vbox_get_type (void);
+GtkWidget* gtk_vbox_new      (gint homogeneous,
+                             gint spacing);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_VBOX_H__ */
diff --git a/gtk/gtkviewport.c b/gtk/gtkviewport.c
new file mode 100644 (file)
index 0000000..dfa00c4
--- /dev/null
@@ -0,0 +1,616 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtksignal.h"
+#include "gtkviewport.h"
+
+
+static void gtk_viewport_class_init               (GtkViewportClass *klass);
+static void gtk_viewport_init                     (GtkViewport      *viewport);
+static void gtk_viewport_map                      (GtkWidget        *widget);
+static void gtk_viewport_unmap                    (GtkWidget        *widget);
+static void gtk_viewport_realize                  (GtkWidget        *widget);
+static void gtk_viewport_unrealize                (GtkWidget        *widget);
+static void gtk_viewport_paint                    (GtkWidget        *widget,
+                                                  GdkRectangle     *area);
+static void gtk_viewport_draw                     (GtkWidget        *widget,
+                                                  GdkRectangle     *area);
+static gint gtk_viewport_expose                   (GtkWidget        *widget,
+                                                  GdkEventExpose   *event);
+static void gtk_viewport_size_request             (GtkWidget        *widget,
+                                                  GtkRequisition   *requisition);
+static void gtk_viewport_size_allocate            (GtkWidget        *widget,
+                                                  GtkAllocation    *allocation);
+static gint gtk_viewport_need_resize              (GtkContainer     *container);
+static void gtk_viewport_adjustment_changed       (GtkAdjustment    *adjustment,
+                                                  gpointer          data);
+static void gtk_viewport_adjustment_value_changed (GtkAdjustment    *adjustment,
+                                                  gpointer          data);
+
+
+guint
+gtk_viewport_get_type ()
+{
+  static guint viewport_type = 0;
+
+  if (!viewport_type)
+    {
+      GtkTypeInfo viewport_info =
+      {
+       "GtkViewport",
+       sizeof (GtkViewport),
+       sizeof (GtkViewportClass),
+       (GtkClassInitFunc) gtk_viewport_class_init,
+       (GtkObjectInitFunc) gtk_viewport_init,
+       (GtkArgFunc) NULL,
+      };
+
+      viewport_type = gtk_type_unique (gtk_bin_get_type (), &viewport_info);
+    }
+
+  return viewport_type;
+}
+
+static void
+gtk_viewport_class_init (GtkViewportClass *class)
+{
+  GtkWidgetClass *widget_class;
+  GtkContainerClass *container_class;
+
+  widget_class = (GtkWidgetClass*) class;
+  container_class = (GtkContainerClass*) class;
+
+  widget_class->map = gtk_viewport_map;
+  widget_class->unmap = gtk_viewport_unmap;
+  widget_class->realize = gtk_viewport_realize;
+  widget_class->unrealize = gtk_viewport_unrealize;
+  widget_class->draw = gtk_viewport_draw;
+  widget_class->expose_event = gtk_viewport_expose;
+  widget_class->size_request = gtk_viewport_size_request;
+  widget_class->size_allocate = gtk_viewport_size_allocate;
+
+  container_class->need_resize = gtk_viewport_need_resize;
+}
+
+static void
+gtk_viewport_init (GtkViewport *viewport)
+{
+  GTK_WIDGET_UNSET_FLAGS (viewport, GTK_NO_WINDOW);
+  GTK_WIDGET_SET_FLAGS (viewport, GTK_BASIC);
+
+  viewport->shadow_type = GTK_SHADOW_IN;
+  viewport->main_window = NULL;
+  viewport->view_window = NULL;
+  viewport->hadjustment = NULL;
+  viewport->vadjustment = NULL;
+}
+
+GtkWidget*
+gtk_viewport_new (GtkAdjustment *hadjustment,
+                 GtkAdjustment *vadjustment)
+{
+  GtkViewport *viewport;
+
+  viewport = gtk_type_new (gtk_viewport_get_type ());
+
+  if (!hadjustment)
+    hadjustment = (GtkAdjustment*) gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+
+  if (!vadjustment)
+    vadjustment = (GtkAdjustment*) gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+
+  gtk_viewport_set_hadjustment (viewport, hadjustment);
+  gtk_viewport_set_vadjustment (viewport, vadjustment);
+
+  return GTK_WIDGET (viewport);
+}
+
+GtkAdjustment*
+gtk_viewport_get_hadjustment (GtkViewport *viewport)
+{
+  g_return_val_if_fail (viewport != NULL, NULL);
+  g_return_val_if_fail (GTK_IS_VIEWPORT (viewport), NULL);
+
+  return viewport->hadjustment;
+}
+
+GtkAdjustment*
+gtk_viewport_get_vadjustment (GtkViewport *viewport)
+{
+  g_return_val_if_fail (viewport != NULL, NULL);
+  g_return_val_if_fail (GTK_IS_VIEWPORT (viewport), NULL);
+
+  return viewport->vadjustment;
+}
+
+void
+gtk_viewport_set_hadjustment (GtkViewport   *viewport,
+                             GtkAdjustment *adjustment)
+{
+  g_return_if_fail (viewport != NULL);
+  g_return_if_fail (GTK_IS_VIEWPORT (viewport));
+  g_return_if_fail (adjustment != NULL);
+
+  if (viewport->hadjustment)
+    {
+      gtk_signal_disconnect_by_data (GTK_OBJECT (viewport->hadjustment), (gpointer) viewport);
+      gtk_object_unref (GTK_OBJECT (viewport->hadjustment));
+    }
+
+  viewport->hadjustment = adjustment;
+  gtk_object_ref (GTK_OBJECT (viewport->hadjustment));
+
+  gtk_signal_connect (GTK_OBJECT (adjustment), "changed",
+                     (GtkSignalFunc) gtk_viewport_adjustment_changed,
+                     (gpointer) viewport);
+  gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
+                     (GtkSignalFunc) gtk_viewport_adjustment_value_changed,
+                     (gpointer) viewport);
+
+  gtk_viewport_adjustment_changed (adjustment, (gpointer) viewport);
+}
+
+void
+gtk_viewport_set_vadjustment (GtkViewport   *viewport,
+                             GtkAdjustment *adjustment)
+{
+  g_return_if_fail (viewport != NULL);
+  g_return_if_fail (GTK_IS_VIEWPORT (viewport));
+  g_return_if_fail (adjustment != NULL);
+
+  if (viewport->vadjustment)
+    {
+      gtk_signal_disconnect_by_data (GTK_OBJECT (viewport->vadjustment), (gpointer) viewport);
+      gtk_object_unref (GTK_OBJECT (viewport->vadjustment));
+    }
+
+  viewport->vadjustment = adjustment;
+  gtk_object_ref (GTK_OBJECT (viewport->vadjustment));
+
+  gtk_signal_connect (GTK_OBJECT (adjustment), "changed",
+                     (GtkSignalFunc) gtk_viewport_adjustment_changed,
+                     (gpointer) viewport);
+  gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
+                     (GtkSignalFunc) gtk_viewport_adjustment_value_changed,
+                     (gpointer) viewport);
+
+  gtk_viewport_adjustment_changed (adjustment, (gpointer) viewport);
+}
+
+void
+gtk_viewport_set_shadow_type (GtkViewport   *viewport,
+                             GtkShadowType  type)
+{
+  g_return_if_fail (viewport != NULL);
+  g_return_if_fail (GTK_IS_VIEWPORT (viewport));
+
+  if ((GtkShadowType) viewport->shadow_type != type)
+    {
+      viewport->shadow_type = type;
+
+      if (GTK_WIDGET_VISIBLE (viewport))
+       {
+         gtk_widget_size_allocate (GTK_WIDGET (viewport), &(GTK_WIDGET (viewport)->allocation));
+         gtk_widget_queue_draw (GTK_WIDGET (viewport));
+       }
+    }
+}
+
+
+static void
+gtk_viewport_map (GtkWidget *widget)
+{
+  GtkViewport *viewport;
+  GtkBin *bin;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_VIEWPORT (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
+  viewport = GTK_VIEWPORT (widget);
+  bin = GTK_BIN (widget);
+
+  gdk_window_show (viewport->main_window);
+
+  if (bin->child &&
+      GTK_WIDGET_VISIBLE (bin->child) &&
+      !GTK_WIDGET_MAPPED (bin->child))
+    gtk_widget_map (bin->child);
+}
+
+static void
+gtk_viewport_unmap (GtkWidget *widget)
+{
+  GtkViewport *viewport;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_VIEWPORT (widget));
+
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
+  viewport = GTK_VIEWPORT (widget);
+  
+  gdk_window_hide (viewport->main_window);
+}
+
+static void
+gtk_viewport_realize (GtkWidget *widget)
+{
+  GtkViewport *viewport;
+  GdkWindowAttr attributes;
+  GtkRequisition *child_requisition;
+  gint attributes_mask;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_VIEWPORT (widget));
+
+  viewport = GTK_VIEWPORT (widget);
+  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+
+  attributes.x = widget->allocation.x + GTK_CONTAINER (widget)->border_width;
+  attributes.y = widget->allocation.y + GTK_CONTAINER (widget)->border_width;
+  attributes.width = widget->allocation.width - GTK_CONTAINER (widget)->border_width * 2;
+  attributes.height = widget->allocation.height - GTK_CONTAINER (widget)->border_width * 2;
+  attributes.window_type = GDK_WINDOW_CHILD;
+  attributes.wclass = GDK_INPUT_OUTPUT;
+  attributes.visual = gtk_widget_get_visual (widget);
+  attributes.colormap = gtk_widget_get_colormap (widget);
+  attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK;
+
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+
+  viewport->main_window = gdk_window_new (widget->parent->window, &attributes, attributes_mask);
+  gdk_window_set_user_data (viewport->main_window, viewport);
+
+  attributes.x += widget->style->klass->xthickness;
+  attributes.y += widget->style->klass->ythickness;
+  attributes.width -= widget->style->klass->xthickness * 2;
+  attributes.height -= widget->style->klass->ythickness * 2;
+
+  viewport->view_window = gdk_window_new (viewport->main_window, &attributes, attributes_mask);
+  gdk_window_set_user_data (viewport->view_window, viewport);
+
+  attributes.x = 0;
+  attributes.y = 0;
+
+  if (GTK_BIN (viewport)->child)
+    {
+      child_requisition = &GTK_WIDGET (GTK_BIN (viewport)->child)->requisition;
+      attributes.width = child_requisition->width;
+      attributes.height = child_requisition->height;
+    }
+
+  widget->window = gdk_window_new (viewport->view_window, &attributes, attributes_mask);
+  gdk_window_set_user_data (widget->window, viewport);
+
+  widget->style = gtk_style_attach (widget->style, viewport->main_window);
+  gtk_style_set_background (widget->style, viewport->main_window, GTK_STATE_NORMAL);
+  gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
+  
+  gdk_window_show (widget->window);
+  gdk_window_show (viewport->view_window);
+}
+
+static void
+gtk_viewport_unrealize (GtkWidget *widget)
+{
+  GtkViewport *viewport;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_VIEWPORT (widget));
+
+  viewport = GTK_VIEWPORT (widget);
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED | GTK_MAPPED);
+
+  gtk_style_detach (widget->style);
+
+  gdk_window_destroy (widget->window);
+  gdk_window_destroy (viewport->view_window);
+  gdk_window_destroy (viewport->main_window);
+
+  widget->window = NULL;
+  viewport->view_window = NULL;
+  viewport->main_window = NULL;
+}
+
+static void
+gtk_viewport_paint (GtkWidget    *widget,
+                   GdkRectangle *area)
+{
+  GtkViewport *viewport;
+  GtkStateType state;
+  gint x, y;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_VIEWPORT (widget));
+  g_return_if_fail (area != NULL);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      viewport = GTK_VIEWPORT (widget);
+
+      state = widget->state;
+      if (!GTK_WIDGET_IS_SENSITIVE (widget))
+        state = GTK_STATE_INSENSITIVE;
+
+      x = GTK_CONTAINER (viewport)->border_width;
+      y = GTK_CONTAINER (viewport)->border_width;
+
+      gtk_draw_shadow (widget->style, viewport->main_window,
+                      GTK_STATE_NORMAL, viewport->shadow_type,
+                      0, 0, -1, -1);
+    }
+}
+
+static void
+gtk_viewport_draw (GtkWidget    *widget,
+                  GdkRectangle *area)
+{
+  GtkViewport *viewport;
+  GtkBin *bin;
+  GdkRectangle tmp_area;
+  GdkRectangle child_area;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_VIEWPORT (widget));
+  g_return_if_fail (area != NULL);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      viewport = GTK_VIEWPORT (widget);
+      bin = GTK_BIN (widget);
+
+      gtk_viewport_paint (widget, area);
+
+      if (bin->child)
+       {
+         tmp_area = *area;
+         tmp_area.x += viewport->hadjustment->value;
+         tmp_area.y += viewport->vadjustment->value;
+
+         if (gtk_widget_intersect (bin->child, &tmp_area, &child_area))
+           gtk_widget_draw (bin->child, &child_area);
+       }
+    }
+}
+
+static gint
+gtk_viewport_expose (GtkWidget      *widget,
+                    GdkEventExpose *event)
+{
+  GtkViewport *viewport;
+  GtkBin *bin;
+  GdkEventExpose child_event;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_VIEWPORT (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      viewport = GTK_VIEWPORT (widget);
+      bin = GTK_BIN (widget);
+
+      if (event->window == viewport->main_window)
+       gtk_viewport_paint (widget, &event->area);
+
+      child_event = *event;
+      if (bin->child &&
+         GTK_WIDGET_NO_WINDOW (bin->child) &&
+         gtk_widget_intersect (bin->child, &event->area, &child_event.area))
+       gtk_widget_event (bin->child, (GdkEvent*) &child_event);
+    }
+
+  return FALSE;
+}
+
+static void
+gtk_viewport_size_request (GtkWidget      *widget,
+                          GtkRequisition *requisition)
+{
+  GtkViewport *viewport;
+  GtkBin *bin;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_VIEWPORT (widget));
+  g_return_if_fail (requisition != NULL);
+
+  viewport = GTK_VIEWPORT (widget);
+  bin = GTK_BIN (widget);
+
+  requisition->width = (GTK_CONTAINER (widget)->border_width +
+                       GTK_WIDGET (widget)->style->klass->xthickness) * 2 + 5;
+
+  requisition->height = (GTK_CONTAINER (widget)->border_width * 2 +
+                        GTK_WIDGET (widget)->style->klass->ythickness) * 2 + 5;
+
+  if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
+    gtk_widget_size_request (bin->child, &bin->child->requisition);
+}
+
+static void
+gtk_viewport_size_allocate (GtkWidget     *widget,
+                           GtkAllocation *allocation)
+{
+  GtkViewport *viewport;
+  GtkBin *bin;
+  GtkAllocation child_allocation;
+  gint hval, vval;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_VIEWPORT (widget));
+  g_return_if_fail (allocation != NULL);
+
+  widget->allocation = *allocation;
+  viewport = GTK_VIEWPORT (widget);
+  bin = GTK_BIN (widget);
+
+  child_allocation.x = GTK_WIDGET (viewport)->style->klass->xthickness;
+  child_allocation.width = allocation->width - child_allocation.x * 2;
+
+  child_allocation.y = GTK_WIDGET (viewport)->style->klass->ythickness;
+  child_allocation.height = allocation->height - child_allocation.y * 2;
+
+  if (GTK_WIDGET_REALIZED (widget))
+    {
+      gdk_window_move_resize (viewport->main_window,
+                             allocation->x + GTK_CONTAINER (viewport)->border_width,
+                             allocation->y + GTK_CONTAINER (viewport)->border_width,
+                             allocation->width - GTK_CONTAINER (viewport)->border_width * 2,
+                             allocation->height - GTK_CONTAINER (viewport)->border_width * 2);
+
+      gdk_window_move_resize (viewport->view_window,
+                             child_allocation.x,
+                             child_allocation.y,
+                             child_allocation.width,
+                             child_allocation.height);
+    }
+
+  viewport->hadjustment->page_size = child_allocation.width;
+  viewport->hadjustment->page_increment = viewport->hadjustment->page_size / 2;
+  viewport->hadjustment->step_increment = 10;
+
+  viewport->vadjustment->page_size = child_allocation.height;
+  viewport->vadjustment->page_increment = viewport->vadjustment->page_size / 2;
+  viewport->vadjustment->step_increment = 10;
+
+  hval = viewport->hadjustment->value;
+  vval = viewport->vadjustment->value;
+
+  if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
+    {
+      viewport->hadjustment->lower = 0;
+      viewport->hadjustment->upper = MAX (bin->child->requisition.width,
+                                         child_allocation.width);
+
+      hval = CLAMP (hval, 0,
+                   viewport->hadjustment->upper -
+                   viewport->hadjustment->page_size);
+
+      viewport->vadjustment->lower = 0;
+      viewport->vadjustment->upper = MAX (bin->child->requisition.height,
+                                         child_allocation.height);
+
+      vval = CLAMP (vval, 0,
+                   viewport->vadjustment->upper -
+                   viewport->vadjustment->page_size);
+    }
+
+  if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
+    {
+      child_allocation.x = 0;
+      child_allocation.y = 0;
+
+      child_allocation.width = viewport->hadjustment->upper;
+      child_allocation.height = viewport->vadjustment->upper;
+
+      if (!GTK_WIDGET_REALIZED (widget))
+        gtk_widget_realize (widget);
+
+      gdk_window_resize (widget->window,
+                        child_allocation.width,
+                        child_allocation.height);
+
+      child_allocation.x = 0;
+      child_allocation.y = 0;
+      gtk_widget_size_allocate (bin->child, &child_allocation);
+    }
+
+  gtk_signal_emit_by_name (GTK_OBJECT (viewport->hadjustment), "changed");
+  gtk_signal_emit_by_name (GTK_OBJECT (viewport->vadjustment), "changed");
+  if (viewport->hadjustment->value != hval)
+    {
+      viewport->hadjustment->value = hval;
+      gtk_signal_emit_by_name (GTK_OBJECT (viewport->hadjustment), "value_changed");
+    }
+  if (viewport->vadjustment->value != vval)
+    {
+      viewport->vadjustment->value = vval;
+      gtk_signal_emit_by_name (GTK_OBJECT (viewport->vadjustment), "value_changed");
+    }
+}
+
+static gint
+gtk_viewport_need_resize (GtkContainer *container)
+{
+  GtkBin *bin;
+
+  g_return_val_if_fail (container != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_VIEWPORT (container), FALSE);
+
+  if (GTK_WIDGET_REALIZED (container))
+    {
+      bin = GTK_BIN (container);
+
+      gtk_widget_size_request (bin->child, &bin->child->requisition);
+
+      gtk_widget_size_allocate (GTK_WIDGET (container),
+                               &(GTK_WIDGET (container)->allocation));
+    }
+
+  return FALSE;
+}
+
+static void
+gtk_viewport_adjustment_changed (GtkAdjustment *adjustment,
+                                gpointer       data)
+{
+  GtkViewport *viewport;
+
+  g_return_if_fail (adjustment != NULL);
+  g_return_if_fail (data != NULL);
+  g_return_if_fail (GTK_IS_VIEWPORT (data));
+
+  viewport = GTK_VIEWPORT (data);
+}
+
+static void
+gtk_viewport_adjustment_value_changed (GtkAdjustment *adjustment,
+                                      gpointer       data)
+{
+  GtkViewport *viewport;
+  GtkBin *bin;
+  GtkAllocation child_allocation;
+  gint width, height;
+
+  g_return_if_fail (adjustment != NULL);
+  g_return_if_fail (data != NULL);
+  g_return_if_fail (GTK_IS_VIEWPORT (data));
+
+  viewport = GTK_VIEWPORT (data);
+  bin = GTK_BIN (data);
+
+  if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
+    {
+      gdk_window_get_size (viewport->view_window, &width, &height);
+
+      child_allocation.x = 0;
+      child_allocation.y = 0;
+
+      if (viewport->hadjustment->lower != (viewport->hadjustment->upper -
+                                          viewport->hadjustment->page_size))
+       child_allocation.x =  viewport->hadjustment->lower - viewport->hadjustment->value;
+
+      if (viewport->vadjustment->lower != (viewport->vadjustment->upper -
+                                          viewport->vadjustment->page_size))
+       child_allocation.y = viewport->vadjustment->lower - viewport->vadjustment->value;
+
+      if (GTK_WIDGET_REALIZED (viewport))
+       gdk_window_move (GTK_WIDGET (viewport)->window,
+                        child_allocation.x,
+                        child_allocation.y);
+    }
+}
diff --git a/gtk/gtkviewport.h b/gtk/gtkviewport.h
new file mode 100644 (file)
index 0000000..9af4e87
--- /dev/null
@@ -0,0 +1,75 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_VIEWPORT_H__
+#define __GTK_VIEWPORT_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkadjustment.h>
+#include <gtk/gtkbin.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_VIEWPORT(obj)          GTK_CHECK_CAST (obj, gtk_viewport_get_type (), GtkViewport)
+#define GTK_VIEWPORT_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_viewport_get_type (), GtkViewportClass)
+#define GTK_IS_VIEWPORT(obj)       GTK_CHECK_TYPE (obj, gtk_viewport_get_type ())
+
+
+typedef struct _GtkViewport       GtkViewport;
+typedef struct _GtkViewportClass  GtkViewportClass;
+
+struct _GtkViewport
+{
+  GtkBin bin;
+
+  gint shadow_type;
+  GdkWindow *main_window;
+  GdkWindow *view_window;
+  GtkAdjustment *hadjustment;
+  GtkAdjustment *vadjustment;
+};
+
+struct _GtkViewportClass
+{
+  GtkBinClass parent_class;
+};
+
+
+guint          gtk_viewport_get_type        (void);
+GtkWidget*     gtk_viewport_new             (GtkAdjustment *hadjustment,
+                                            GtkAdjustment *vadjustment);
+GtkAdjustment* gtk_viewport_get_hadjustment (GtkViewport   *viewport);
+GtkAdjustment* gtk_viewport_get_vadjustment (GtkViewport   *viewport);
+void           gtk_viewport_set_hadjustment (GtkViewport   *viewport,
+                                            GtkAdjustment *adjustment);
+void           gtk_viewport_set_vadjustment (GtkViewport   *viewport,
+                                            GtkAdjustment *adjustment);
+void           gtk_viewport_set_shadow_type (GtkViewport   *viewport,
+                                            GtkShadowType  type);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_VIEWPORT_H__ */
diff --git a/gtk/gtkvpaned.c b/gtk/gtkvpaned.c
new file mode 100644 (file)
index 0000000..2dae032
--- /dev/null
@@ -0,0 +1,356 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkvpaned.h"
+#include "gtkmain.h"
+#include "gtksignal.h"
+
+static void gtk_vpaned_class_init       (GtkVPanedClass *klass);
+static void gtk_vpaned_init             (GtkVPaned      *vpaned);
+static void gtk_vpaned_size_request     (GtkWidget      *widget,
+                                        GtkRequisition *requisition);
+static void gtk_vpaned_size_allocate    (GtkWidget          *widget,
+                                        GtkAllocation      *allocation);
+static void gtk_vpaned_draw             (GtkWidget    *widget,
+                                        GdkRectangle *area);
+static void gtk_vpaned_xor_line         (GtkPaned *paned);
+static gint gtk_vpaned_button_press     (GtkWidget *widget,
+                                        GdkEventButton *event);
+static gint gtk_vpaned_button_release   (GtkWidget *widget,
+                                        GdkEventButton *event);
+static gint gtk_vpaned_motion           (GtkWidget *widget,
+                                        GdkEventMotion *event);
+
+guint
+gtk_vpaned_get_type ()
+{
+  static guint vpaned_type = 0;
+
+  if (!vpaned_type)
+    {
+      GtkTypeInfo vpaned_info =
+      {
+       "GtkVPaned",
+       sizeof (GtkVPaned),
+       sizeof (GtkVPanedClass),
+       (GtkClassInitFunc) gtk_vpaned_class_init,
+       (GtkObjectInitFunc) gtk_vpaned_init,
+       (GtkArgFunc) NULL,
+      };
+
+      vpaned_type = gtk_type_unique (gtk_paned_get_type (), &vpaned_info);
+    }
+
+  return vpaned_type;
+}
+
+static void
+gtk_vpaned_class_init (GtkVPanedClass *class)
+{
+  GtkWidgetClass *widget_class;
+
+  widget_class = (GtkWidgetClass*) class;
+
+  widget_class->size_request = gtk_vpaned_size_request;
+  widget_class->size_allocate = gtk_vpaned_size_allocate;
+  widget_class->draw = gtk_vpaned_draw;
+  widget_class->button_press_event = gtk_vpaned_button_press;
+  widget_class->button_release_event = gtk_vpaned_button_release;
+  widget_class->motion_notify_event = gtk_vpaned_motion;
+}
+
+static void
+gtk_vpaned_init (GtkVPaned *vpaned)
+{
+}
+
+GtkWidget*
+gtk_vpaned_new ()
+{
+  GtkVPaned *vpaned;
+
+  vpaned = gtk_type_new (gtk_vpaned_get_type ());
+
+  return GTK_WIDGET (vpaned);
+}
+
+static void
+gtk_vpaned_size_request (GtkWidget      *widget,
+                        GtkRequisition *requisition)
+{
+  GtkPaned *paned;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_VPANED (widget));
+  g_return_if_fail (requisition != NULL);
+
+  paned = GTK_PANED (widget);
+  requisition->width = 0;
+  requisition->height = 0;
+
+  if (paned->child1 && GTK_WIDGET_VISIBLE (paned->child1))
+    {
+      gtk_widget_size_request (paned->child1, &paned->child1->requisition);
+
+      requisition->height = paned->child1->requisition.height;
+      requisition->width = paned->child1->requisition.width;
+    }
+
+  if (paned->child2 && GTK_WIDGET_VISIBLE (paned->child2))
+    {
+      gtk_widget_size_request (paned->child2, &paned->child2->requisition);
+
+      requisition->width = MAX (requisition->width,
+                               paned->child2->requisition.width);
+      requisition->height += paned->child2->requisition.height;
+    }
+
+  requisition->height += GTK_CONTAINER (paned)->border_width * 2 + paned->gutter_size;
+  requisition->width += GTK_CONTAINER (paned)->border_width * 2;
+}
+
+static void
+gtk_vpaned_size_allocate (GtkWidget     *widget,
+                         GtkAllocation *allocation)
+{
+  GtkPaned *paned;
+  GtkAllocation child1_allocation;
+  GtkAllocation child2_allocation;
+  guint16 border_width;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_VPANED (widget));
+  g_return_if_fail (allocation != NULL);
+
+  widget->allocation = *allocation;
+
+  paned = GTK_PANED (widget);
+  border_width = GTK_CONTAINER (paned)->border_width;
+
+  if (!paned->position_set)
+    {
+      if (paned->child1 && GTK_WIDGET_VISIBLE (paned->child1))
+       paned->child1_size = paned->child1->requisition.height;
+      else
+       paned->child1_size = 0;
+    }
+
+  /* Move the handle first so we don't get extra expose events */
+
+  paned->handle_xpos = allocation->x + allocation->width - border_width - 2 * paned->handle_size;
+  paned->handle_ypos = allocation->y + paned->child1_size + border_width + paned->gutter_size / 2 - paned->handle_size / 2;
+
+  if (GTK_WIDGET_REALIZED (widget))
+    {
+      gdk_window_move (paned->handle, paned->handle_xpos, paned->handle_ypos);
+      gdk_window_raise (paned->handle);
+    }
+
+  if (GTK_WIDGET_MAPPED (widget))
+    {
+      gdk_window_clear_area (widget->window,
+                            paned->groove_rectangle.x,
+                            paned->groove_rectangle.y,
+                            paned->groove_rectangle.width,
+                            paned->groove_rectangle.height);
+    }
+  
+  child1_allocation.width = child2_allocation.width = allocation->width - border_width * 2;
+  child1_allocation.height = paned->child1_size;
+  child1_allocation.x = child2_allocation.x = allocation->x + border_width;
+  child1_allocation.y = allocation->y + border_width;
+  
+  paned->groove_rectangle.y = child1_allocation.y 
+    + child1_allocation.height + paned->gutter_size / 2 - 1;
+  paned->groove_rectangle.x = allocation->x;
+  paned->groove_rectangle.height = 2;
+  paned->groove_rectangle.width = allocation->width;
+  
+  child2_allocation.y = paned->groove_rectangle.y + paned->gutter_size / 2 + 1;
+  child2_allocation.height = allocation->y + allocation->height 
+    - child2_allocation.y - border_width;
+  
+  /* Now allocate the childen, making sure, when resizing not to
+   * overlap the windows */
+  if (GTK_WIDGET_MAPPED(widget) &&
+      paned->child1 && GTK_WIDGET_VISIBLE (paned->child1) &&
+      paned->child1->allocation.height < child1_allocation.height)
+    {
+      if (paned->child2 && GTK_WIDGET_VISIBLE (paned->child2))
+       gtk_widget_size_allocate (paned->child2, &child2_allocation);
+      gtk_widget_size_allocate (paned->child1, &child1_allocation);      
+    }
+  else
+    {
+      if (paned->child1 && GTK_WIDGET_VISIBLE (paned->child1))
+       gtk_widget_size_allocate (paned->child1, &child1_allocation);
+      if (paned->child2 && GTK_WIDGET_VISIBLE (paned->child2))
+       gtk_widget_size_allocate (paned->child2, &child2_allocation);
+    }
+}
+
+static void
+gtk_vpaned_draw (GtkWidget    *widget,
+               GdkRectangle *area)
+{
+  GtkPaned *paned;
+  GdkRectangle child_area;
+  guint16 border_width;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_PANED (widget));
+
+  if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget))
+    {
+      paned = GTK_PANED (widget);
+      border_width = GTK_CONTAINER (paned)->border_width;
+
+      if (paned->child1 &&
+         gtk_widget_intersect (paned->child1, area, &child_area))
+        gtk_widget_draw (paned->child1, &child_area);
+      if (paned->child2 &&
+         gtk_widget_intersect (paned->child2, area, &child_area))
+        gtk_widget_draw (paned->child2, &child_area);
+
+      gdk_draw_line (widget->window,
+                    widget->style->dark_gc[widget->state],
+                    widget->allocation.x,
+                    widget->allocation.y + border_width + paned->child1_size + paned->gutter_size / 2 - 1,
+                    widget->allocation.x + widget->allocation.width - 1,
+                    widget->allocation.y + border_width + paned->child1_size + paned->gutter_size / 2 - 1);
+      gdk_draw_line (widget->window,
+                    widget->style->light_gc[widget->state],
+                    widget->allocation.x,
+                    widget->allocation.y + border_width + paned->child1_size + paned->gutter_size / 2,
+                    widget->allocation.x + widget->allocation.width - 1,
+                    widget->allocation.y + border_width + paned->child1_size + paned->gutter_size / 2);
+    }
+}
+
+static void
+gtk_vpaned_xor_line (GtkPaned *paned)
+{
+  GtkWidget *widget;
+  GdkGCValues values;
+  guint16 ypos;
+
+  widget = GTK_WIDGET(paned);
+
+  if (!paned->xor_gc)
+    {
+      values.foreground = widget->style->white;
+      values.function = GDK_XOR;
+      values.subwindow_mode = GDK_INCLUDE_INFERIORS;
+      paned->xor_gc = gdk_gc_new_with_values (widget->window,
+                                             &values,
+                                             GDK_GC_FOREGROUND |
+                                             GDK_GC_FUNCTION |
+                                             GDK_GC_SUBWINDOW);
+    }
+
+  ypos = widget->allocation.y + paned->child1_size
+    + GTK_CONTAINER (paned)->border_width + paned->gutter_size / 2;
+
+  gdk_draw_line (widget->window, paned->xor_gc,
+                widget->allocation.x,
+                ypos,
+                widget->allocation.x + widget->allocation.width - 1,
+                ypos);
+}
+
+static gint
+gtk_vpaned_button_press (GtkWidget *widget, GdkEventButton *event)
+{
+  GtkPaned *paned;
+
+  g_return_val_if_fail (widget != NULL,FALSE);
+  g_return_val_if_fail (GTK_IS_PANED (widget),FALSE);
+
+  paned = GTK_PANED (widget);
+
+  if (!paned->in_drag &&
+      (event->window == paned->handle) && (event->button == 1))
+    {
+      paned->in_drag = TRUE;
+      /* We need a server grab here, not gtk_grab_add(), since
+       * we don't want to pass events on to the widget's children */
+      gdk_pointer_grab (paned->handle, FALSE,
+                       GDK_POINTER_MOTION_HINT_MASK 
+                       | GDK_BUTTON1_MOTION_MASK 
+                       | GDK_BUTTON_RELEASE_MASK,
+                       NULL, NULL, event->time);
+      paned->child1_size += event->y - paned->handle_size / 2;
+      paned->child1_size = CLAMP (paned->child1_size, 0,
+                                  widget->allocation.height - paned->gutter_size
+                                  - 2 * GTK_CONTAINER (paned)->border_width);
+      gtk_vpaned_xor_line (paned);
+    }
+
+  return TRUE;
+}
+
+static gint
+gtk_vpaned_button_release (GtkWidget *widget, GdkEventButton *event)
+{
+  GtkPaned *paned;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_PANED (widget), FALSE);
+
+  paned = GTK_PANED (widget);
+
+  if (paned->in_drag && (event->button == 1))
+    {
+      gtk_vpaned_xor_line (paned);
+      paned->in_drag = FALSE;
+      paned->position_set = TRUE;
+      gdk_pointer_ungrab (event->time);
+      gtk_widget_queue_resize (GTK_WIDGET (paned));
+    }
+
+  return TRUE;
+}
+
+static gint
+gtk_vpaned_motion (GtkWidget *widget, GdkEventMotion *event)
+{
+  GtkPaned *paned;
+  gint y;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_PANED (widget), FALSE);
+
+  if (event->is_hint || event->window != widget->window)
+      gtk_widget_get_pointer(widget, NULL, &y);
+  else
+      y = event->y;
+
+  paned = GTK_PANED (widget);
+
+  if (paned->in_drag)
+    {
+      gtk_vpaned_xor_line (paned);
+      paned->child1_size = y - GTK_CONTAINER (paned)->border_width -
+       paned->gutter_size/2;
+      paned->child1_size = CLAMP (paned->child1_size, 0,
+                                  widget->allocation.height - paned->gutter_size
+                                  - 2 * GTK_CONTAINER (paned)->border_width);
+      gtk_vpaned_xor_line (paned);
+    }
+
+  return TRUE;
+}
diff --git a/gtk/gtkvpaned.h b/gtk/gtkvpaned.h
new file mode 100644 (file)
index 0000000..9e66c12
--- /dev/null
@@ -0,0 +1,59 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_VPANED_H__
+#define __GTK_VPANED_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkpaned.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_VPANED(obj)          GTK_CHECK_CAST (obj, gtk_vpaned_get_type (), GtkVPaned)
+#define GTK_VPANED_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_vpaned_get_type (), GtkVPanedClass)
+#define GTK_IS_VPANED(obj)       GTK_CHECK_TYPE (obj, gtk_vpaned_get_type ())
+
+
+typedef struct _GtkVPaned       GtkVPaned;
+typedef struct _GtkVPanedClass  GtkVPanedClass;
+
+struct _GtkVPaned
+{
+  GtkPaned paned;
+};
+
+struct _GtkVPanedClass
+{
+  GtkPanedClass parent_class;
+};
+
+
+guint      gtk_vpaned_get_type (void);
+GtkWidget* gtk_vpaned_new      ();
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_VPANED_H__ */
diff --git a/gtk/gtkvruler.c b/gtk/gtkvruler.c
new file mode 100644 (file)
index 0000000..43fe16b
--- /dev/null
@@ -0,0 +1,282 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+#include "gtkvruler.h"
+
+
+#define RULER_WIDTH           14
+#define MINIMUM_INCR          5
+#define MAXIMUM_SUBDIVIDE     5
+#define MAXIMUM_SCALES        10
+
+#define ROUND(x) ((int) ((x) + 0.5))
+
+
+static void gtk_vruler_class_init    (GtkVRulerClass *klass);
+static void gtk_vruler_init          (GtkVRuler      *vruler);
+static gint gtk_vruler_motion_notify (GtkWidget      *widget,
+                                     GdkEventMotion *event);
+static void gtk_vruler_draw_ticks    (GtkRuler       *ruler);
+static void gtk_vruler_draw_pos      (GtkRuler       *ruler);
+
+
+guint
+gtk_vruler_get_type ()
+{
+  static guint vruler_type = 0;
+
+  if (!vruler_type)
+    {
+      GtkTypeInfo vruler_info =
+      {
+       "GtkVRuler",
+       sizeof (GtkVRuler),
+       sizeof (GtkVRulerClass),
+       (GtkClassInitFunc) gtk_vruler_class_init,
+       (GtkObjectInitFunc) gtk_vruler_init,
+       (GtkArgFunc) NULL,
+      };
+
+      vruler_type = gtk_type_unique (gtk_ruler_get_type (), &vruler_info);
+    }
+
+  return vruler_type;
+}
+
+static void
+gtk_vruler_class_init (GtkVRulerClass *klass)
+{
+  GtkWidgetClass *widget_class;
+  GtkRulerClass *ruler_class;
+
+  widget_class = (GtkWidgetClass*) klass;
+  ruler_class = (GtkRulerClass*) klass;
+
+  widget_class->motion_notify_event = gtk_vruler_motion_notify;
+
+  ruler_class->draw_ticks = gtk_vruler_draw_ticks;
+  ruler_class->draw_pos = gtk_vruler_draw_pos;
+}
+
+static void
+gtk_vruler_init (GtkVRuler *vruler)
+{
+  GtkWidget *widget;
+
+  widget = GTK_WIDGET (vruler);
+  widget->requisition.width = widget->style->klass->xthickness * 2 + RULER_WIDTH;
+  widget->requisition.height = widget->style->klass->ythickness * 2 + 1;
+}
+
+GtkWidget*
+gtk_vruler_new ()
+{
+  return GTK_WIDGET (gtk_type_new (gtk_vruler_get_type ()));
+}
+
+
+static gint
+gtk_vruler_motion_notify (GtkWidget      *widget,
+                         GdkEventMotion *event)
+{
+  GtkRuler *ruler;
+  gint y;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_VRULER (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  ruler = GTK_RULER (widget);
+
+  if (event->is_hint)
+    gdk_window_get_pointer (widget->window, NULL, &y, NULL);
+  else
+    y = event->y;
+
+  ruler->position = ruler->lower + ((ruler->upper - ruler->lower) * y) / widget->allocation.height;
+
+  /*  Make sure the ruler has been allocated already  */
+  if (ruler->backing_store != NULL)
+    gtk_ruler_draw_pos (ruler);
+
+  return FALSE;
+}
+
+static void
+gtk_vruler_draw_ticks (GtkRuler *ruler)
+{
+  GtkWidget *widget;
+  GdkGC *gc;
+  gint i, j;
+  gint width, height;
+  gint xthickness;
+  gint ythickness;
+  gint length;
+  gfloat subd_incr;
+  gfloat step_incr;
+  gfloat increment;
+  gfloat start, end, cur;
+  gchar unit_str[12];
+  gchar digit_str[2] = { '\0', '\0' };
+  gint text_height;
+  gint digit_height;
+  gint pos;
+  gint scale;
+
+  g_return_if_fail (ruler != NULL);
+  g_return_if_fail (GTK_IS_VRULER (ruler));
+
+  if (GTK_WIDGET_DRAWABLE (ruler))
+    {
+      widget = GTK_WIDGET (ruler);
+
+      gc = widget->style->fg_gc[GTK_STATE_NORMAL];
+      xthickness = widget->style->klass->xthickness;
+      ythickness = widget->style->klass->ythickness;
+      digit_height = widget->style->font->ascent;
+
+      width = widget->allocation.height;
+      height = widget->allocation.width - ythickness * 2;
+      gdk_draw_line (ruler->backing_store, gc,
+                    height + xthickness,
+                    ythickness,
+                    height + xthickness,
+                    widget->allocation.height - ythickness);
+
+      if ((ruler->upper - ruler->lower) == 0)
+       return;
+
+      increment = (gfloat) width * ruler->metric->pixels_per_unit / (ruler->upper - ruler->lower);
+
+      /*  determine the scale
+       *   use the maximum extents of the ruler to determine the largest possible
+       *   number to be displayed.  calculate the height in pixels of this displayed
+       *   text as for the vertical ruler case.  use this height to find a scale
+       *   which leaves sufficient room for drawing the ruler.
+       */
+      scale = ceil (ruler->max_size / ruler->metric->pixels_per_unit);
+      sprintf (unit_str, "%d", scale);
+      text_height = strlen (unit_str) * digit_height + 1;
+
+      for (scale = 0; scale < MAXIMUM_SCALES; scale++)
+       if (ruler->metric->ruler_scale[scale] * increment > 2 * text_height)
+         break;
+
+      if (scale == MAXIMUM_SCALES)
+       scale = MAXIMUM_SCALES - 1;
+
+      for (i = 0; i < MAXIMUM_SUBDIVIDE; i++)
+       {
+         subd_incr = (gfloat) ruler->metric->ruler_scale[scale] / (gfloat) ruler->metric->subdivide[i];
+         step_incr = subd_incr * increment;
+         if (step_incr <= MINIMUM_INCR)
+           break;
+
+         start = floor ((ruler->lower / ruler->metric->pixels_per_unit) / subd_incr) * subd_incr;
+         end = ceil ((ruler->upper / ruler->metric->pixels_per_unit) / subd_incr) * subd_incr;
+
+         length = height / (i + 1) - 1;
+
+         cur = start;
+         while (cur <= end)
+           {
+             pos = ROUND ((cur - (ruler->lower / ruler->metric->pixels_per_unit)) * increment);
+
+             gdk_draw_line (ruler->backing_store, gc,
+                            height + xthickness - length,
+                            pos,
+                            height + xthickness,
+                            pos);
+
+             if (i == 0)
+               {
+                 sprintf (unit_str, "%d", (int) cur);
+                 for (j = 0; j < (int) strlen (unit_str); j++)
+                   {
+                     digit_str[0] = unit_str[j];
+                     gdk_draw_string (ruler->backing_store, widget->style->font, gc,
+                                      xthickness + 1,
+                                      pos + digit_height * (j + 1) + 1,
+                                      digit_str);
+                   }
+               }
+
+             cur += subd_incr;
+           }
+       }
+    }
+}
+
+static void
+gtk_vruler_draw_pos (GtkRuler *ruler)
+{
+  GtkWidget *widget;
+  GdkGC *gc;
+  int i;
+  gint x, y;
+  gint width, height;
+  gint bs_width, bs_height;
+  gint xthickness;
+  gint ythickness;
+  gfloat increment;
+
+  g_return_if_fail (ruler != NULL);
+  g_return_if_fail (GTK_IS_VRULER (ruler));
+
+  if (GTK_WIDGET_DRAWABLE (ruler))
+    {
+      widget = GTK_WIDGET (ruler);
+
+      gc = widget->style->fg_gc[GTK_STATE_NORMAL];
+      xthickness = widget->style->klass->xthickness;
+      ythickness = widget->style->klass->ythickness;
+      width = widget->allocation.width - xthickness * 2;
+      height = widget->allocation.height;
+
+      bs_height = width / 2;
+      bs_height |= 1;  /* make sure it's odd */
+      bs_width = bs_height / 2 + 1;
+
+      if ((bs_width > 0) && (bs_height > 0))
+       {
+         /*  If a backing store exists, restore the ruler  */
+         if (ruler->backing_store && ruler->non_gr_exp_gc)
+           gdk_draw_pixmap (ruler->widget.window,
+                            ruler->non_gr_exp_gc,
+                            ruler->backing_store,
+                            ruler->xsrc, ruler->ysrc,
+                            ruler->xsrc, ruler->ysrc,
+                            bs_width, bs_height);
+
+         increment = (gfloat) height / (ruler->upper - ruler->lower);
+
+         x = (width + bs_width) / 2 + xthickness;
+         y = ROUND ((ruler->position - ruler->lower) * increment) + (ythickness - bs_height) / 2 - 1;
+
+         for (i = 0; i < bs_width; i++)
+           gdk_draw_line (widget->window, gc,
+                          x + i, y + i,
+                          x + i, y + bs_height - 1 - i);
+
+         ruler->xsrc = x;
+         ruler->ysrc = y;
+       }
+    }
+}
diff --git a/gtk/gtkvruler.h b/gtk/gtkvruler.h
new file mode 100644 (file)
index 0000000..22bef71
--- /dev/null
@@ -0,0 +1,59 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_VRULER_H__
+#define __GTK_VRULER_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkruler.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_VRULER(obj)          GTK_CHECK_CAST (obj, gtk_vruler_get_type (), GtkVRuler)
+#define GTK_VRULER_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_vruler_get_type (), GtkVRulerClass)
+#define GTK_IS_VRULER(obj)       GTK_CHECK_TYPE (obj, gtk_vruler_get_type ())
+
+
+typedef struct _GtkVRuler       GtkVRuler;
+typedef struct _GtkVRulerClass  GtkVRulerClass;
+
+struct _GtkVRuler
+{
+  GtkRuler ruler;
+};
+
+struct _GtkVRulerClass
+{
+  GtkRulerClass parent_class;
+};
+
+
+guint      gtk_vruler_get_type (void);
+GtkWidget* gtk_vruler_new      (void);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_VRULER_H__ */
diff --git a/gtk/gtkvscale.c b/gtk/gtkvscale.c
new file mode 100644 (file)
index 0000000..9c2e305
--- /dev/null
@@ -0,0 +1,441 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdio.h>
+#include "gtkvscale.h"
+#include "gtksignal.h"
+#include "gdk/gdkkeysyms.h"
+
+
+#define SCALE_CLASS(w)  GTK_SCALE_CLASS (GTK_OBJECT (w)->klass)
+#define RANGE_CLASS(w)  GTK_RANGE_CLASS (GTK_OBJECT (w)->klass)
+
+
+static void gtk_vscale_class_init    (GtkVScaleClass *klass);
+static void gtk_vscale_init          (GtkVScale      *vscale);
+static void gtk_vscale_realize       (GtkWidget      *widget);
+static void gtk_vscale_size_request  (GtkWidget      *widget,
+                                     GtkRequisition *requisition);
+static void gtk_vscale_size_allocate (GtkWidget      *widget,
+                                     GtkAllocation  *allocation);
+static void gtk_vscale_pos_trough    (GtkVScale      *vscale,
+                                     gint           *x,
+                                     gint           *y,
+                                     gint           *w,
+                                     gint           *h);
+static void gtk_vscale_draw_slider   (GtkRange       *range);
+static void gtk_vscale_draw_value    (GtkScale       *scale);
+static gint gtk_vscale_trough_keys   (GtkRange *range,
+                                     GdkEventKey *key,
+                                     GtkScrollType *scroll,
+                                     GtkTroughType *pos);
+
+
+guint
+gtk_vscale_get_type ()
+{
+  static guint vscale_type = 0;
+
+  if (!vscale_type)
+    {
+      GtkTypeInfo vscale_info =
+      {
+       "GtkVScale",
+       sizeof (GtkVScale),
+       sizeof (GtkVScaleClass),
+       (GtkClassInitFunc) gtk_vscale_class_init,
+       (GtkObjectInitFunc) gtk_vscale_init,
+       (GtkArgFunc) NULL,
+      };
+
+      vscale_type = gtk_type_unique (gtk_scale_get_type (), &vscale_info);
+    }
+
+  return vscale_type;
+}
+
+static void
+gtk_vscale_class_init (GtkVScaleClass *class)
+{
+  GtkWidgetClass *widget_class;
+  GtkRangeClass *range_class;
+  GtkScaleClass *scale_class;
+
+  widget_class = (GtkWidgetClass*) class;
+  range_class = (GtkRangeClass*) class;
+  scale_class = (GtkScaleClass*) class;
+
+  widget_class->realize = gtk_vscale_realize;
+  widget_class->size_request = gtk_vscale_size_request;
+  widget_class->size_allocate = gtk_vscale_size_allocate;
+
+  range_class->slider_update = gtk_range_default_vslider_update;
+  range_class->trough_click = gtk_range_default_vtrough_click;
+  range_class->motion = gtk_range_default_vmotion;
+  range_class->draw_slider = gtk_vscale_draw_slider;
+  range_class->trough_keys = gtk_vscale_trough_keys;
+
+  scale_class->draw_value = gtk_vscale_draw_value;
+}
+
+static void
+gtk_vscale_init (GtkVScale *vscale)
+{
+}
+
+GtkWidget*
+gtk_vscale_new (GtkAdjustment *adjustment)
+{
+  GtkVScale *vscale;
+
+  vscale = gtk_type_new (gtk_vscale_get_type ());
+
+  if (!adjustment)
+    adjustment = (GtkAdjustment*) gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+
+  gtk_range_set_adjustment (GTK_RANGE (vscale), adjustment);
+
+  return GTK_WIDGET (vscale);
+}
+
+
+static void
+gtk_vscale_realize (GtkWidget *widget)
+{
+  GtkRange *range;
+  GdkWindowAttr attributes;
+  gint attributes_mask;
+  gint x, y, w, h;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_VSCALE (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+  range = GTK_RANGE (widget);
+
+  attributes.x = widget->allocation.x;
+  attributes.y = widget->allocation.y;
+  attributes.width = widget->allocation.width;
+  attributes.height = widget->allocation.height;
+  attributes.wclass = GDK_INPUT_OUTPUT;
+  attributes.window_type = GDK_WINDOW_CHILD;
+  attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK;
+  attributes.visual = gtk_widget_get_visual (widget);
+  attributes.colormap = gtk_widget_get_colormap (widget);
+
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+  widget->window = gdk_window_new (widget->parent->window, &attributes, attributes_mask);
+
+  gtk_vscale_pos_trough (GTK_VSCALE (widget), &x, &y, &w, &h);
+  attributes.x = x;
+  attributes.y = y;
+  attributes.width = w;
+  attributes.height = h;
+  attributes.event_mask |= (GDK_BUTTON_PRESS_MASK |
+                           GDK_BUTTON_RELEASE_MASK |
+                           GDK_ENTER_NOTIFY_MASK |
+                           GDK_LEAVE_NOTIFY_MASK);
+
+  range->trough = gdk_window_new (widget->window, &attributes, attributes_mask);
+
+  attributes.width = RANGE_CLASS (range)->slider_width;
+  attributes.height = SCALE_CLASS (range)->slider_length;
+  attributes.event_mask |= (GDK_BUTTON_MOTION_MASK |
+                           GDK_POINTER_MOTION_HINT_MASK);
+
+  range->slider = gdk_window_new (range->trough, &attributes, attributes_mask);
+
+  widget->style = gtk_style_attach (widget->style, widget->window);
+
+  gdk_window_set_user_data (widget->window, widget);
+  gdk_window_set_user_data (range->trough, widget);
+  gdk_window_set_user_data (range->slider, widget);
+
+  gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
+  gtk_style_set_background (widget->style, range->trough, GTK_STATE_ACTIVE);
+  gtk_style_set_background (widget->style, range->slider, GTK_STATE_NORMAL);
+
+  gtk_range_slider_update (GTK_RANGE (widget));
+
+  gdk_window_show (range->slider);
+  gdk_window_show (range->trough);
+}
+
+static void
+gtk_vscale_size_request (GtkWidget      *widget,
+                        GtkRequisition *requisition)
+{
+  GtkScale *scale;
+  gint value_width;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_VSCALE (widget));
+  g_return_if_fail (requisition != NULL);
+
+  scale = GTK_SCALE (widget);
+
+  requisition->width = (RANGE_CLASS (scale)->slider_width +
+                       widget->style->klass->ythickness * 2);
+  requisition->height = (SCALE_CLASS (scale)->slider_length +
+                        widget->style->klass->xthickness) * 2;
+
+  if (scale->draw_value)
+    {
+      value_width = gtk_scale_value_width (scale);
+
+      if ((scale->value_pos == GTK_POS_LEFT) ||
+         (scale->value_pos == GTK_POS_RIGHT))
+       {
+         requisition->width += value_width + SCALE_CLASS (scale)->value_spacing;
+         if (requisition->height < (widget->style->font->ascent + widget->style->font->descent))
+           requisition->height = widget->style->font->ascent + widget->style->font->descent;
+       }
+      else if ((scale->value_pos == GTK_POS_TOP) ||
+              (scale->value_pos == GTK_POS_BOTTOM))
+       {
+         if (requisition->width < value_width)
+           requisition->width = value_width;
+         requisition->height += widget->style->font->ascent + widget->style->font->descent;
+       }
+    }
+}
+
+static void
+gtk_vscale_size_allocate (GtkWidget     *widget,
+                         GtkAllocation *allocation)
+{
+  GtkRange *range;
+  GtkScale *scale;
+  gint width, height;
+  gint x, y;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_VSCALE (widget));
+  g_return_if_fail (allocation != NULL);
+
+  widget->allocation = *allocation;
+  if (GTK_WIDGET_REALIZED (widget))
+    {
+      range = GTK_RANGE (widget);
+      scale = GTK_SCALE (widget);
+
+      gdk_window_move_resize (widget->window,
+                             allocation->x, allocation->y,
+                             allocation->width, allocation->height);
+
+      gtk_vscale_pos_trough (GTK_VSCALE (widget), &x, &y, &width, &height);
+
+      gdk_window_move_resize (range->trough, x, y, width, height);
+      gtk_range_slider_update (GTK_RANGE (widget));
+    }
+}
+
+static void
+gtk_vscale_pos_trough (GtkVScale *vscale,
+                      gint      *x,
+                      gint      *y,
+                      gint      *w,
+                      gint      *h)
+{
+  GtkWidget *widget;
+  GtkScale *scale;
+
+  g_return_if_fail (vscale != NULL);
+  g_return_if_fail (GTK_IS_VSCALE (vscale));
+  g_return_if_fail ((x != NULL) && (y != NULL) && (w != NULL) && (h != NULL));
+
+  widget = GTK_WIDGET (vscale);
+  scale = GTK_SCALE (vscale);
+
+  *w = (RANGE_CLASS (scale)->slider_width +
+       widget->style->klass->xthickness * 2);
+  *h = widget->allocation.height;
+
+  if (scale->draw_value)
+    {
+      *x = 0;
+      *y = 0;
+
+      switch (scale->value_pos)
+       {
+       case GTK_POS_LEFT:
+         *x = (gtk_scale_value_width (scale) +
+               (widget->allocation.width - widget->requisition.width) / 2);
+         break;
+       case GTK_POS_RIGHT:
+         *x = (widget->allocation.width - widget->requisition.width) / 2;
+         break;
+       case GTK_POS_TOP:
+         *x = (widget->allocation.width - *w) / 2;
+         *y = widget->style->font->ascent + widget->style->font->descent;
+         *h -= *y;
+         break;
+       case GTK_POS_BOTTOM:
+         *x = (widget->allocation.width - *w) / 2;
+         *h -= widget->style->font->ascent + widget->style->font->descent;
+         break;
+       }
+    }
+  else
+    {
+      *x = (widget->allocation.width - *w) / 2;
+      *y = 0;
+    }
+  *y += 1;
+  *h -= 2;
+}
+
+static void
+gtk_vscale_draw_slider (GtkRange *range)
+{
+  GtkStateType state_type;
+  gint width, height;
+
+  g_return_if_fail (range != NULL);
+  g_return_if_fail (GTK_IS_VSCALE (range));
+
+  if (range->slider)
+    {
+      if ((range->in_child == RANGE_CLASS (range)->slider) ||
+          (range->click_child == RANGE_CLASS (range)->slider))
+        state_type = GTK_STATE_PRELIGHT;
+      else
+        state_type = GTK_STATE_NORMAL;
+
+      gtk_style_set_background (GTK_WIDGET (range)->style, range->slider, state_type);
+      gdk_window_clear (range->slider);
+
+      gdk_window_get_size (range->slider, &width, &height);
+      gtk_draw_hline (GTK_WIDGET (range)->style, range->slider,
+                     state_type, 1, width - 2, height / 2);
+
+      gtk_draw_shadow (GTK_WIDGET (range)->style, range->slider,
+                       state_type, GTK_SHADOW_OUT,
+                       0, 0, -1, -1);
+    }
+}
+
+static void
+gtk_vscale_draw_value (GtkScale *scale)
+{
+  GtkStateType state_type;
+  gchar buffer[16];
+  gint text_width;
+  gint width, height;
+  gint x, y;
+
+  g_return_if_fail (scale != NULL);
+  g_return_if_fail (GTK_IS_VSCALE (scale));
+
+  if (scale->draw_value)
+    {
+      gdk_window_get_size (GTK_WIDGET (scale)->window, &width, &height);
+      gdk_window_clear_area (GTK_WIDGET (scale)->window, 1, 1, width - 3, height - 3);
+
+      sprintf (buffer, "%0.*f", GTK_RANGE (scale)->digits, GTK_RANGE (scale)->adjustment->value);
+      text_width = gdk_string_measure (GTK_WIDGET (scale)->style->font, buffer);
+
+      switch (scale->value_pos)
+       {
+       case GTK_POS_LEFT:
+         gdk_window_get_position (GTK_RANGE (scale)->trough, &x, NULL);
+         gdk_window_get_position (GTK_RANGE (scale)->slider, NULL, &y);
+         gdk_window_get_size (GTK_RANGE (scale)->trough, &width, NULL);
+         gdk_window_get_size (GTK_RANGE (scale)->slider, NULL, &height);
+
+         x -= SCALE_CLASS (scale)->value_spacing + text_width;
+         y += ((height -
+                (GTK_WIDGET (scale)->style->font->ascent +
+                 GTK_WIDGET (scale)->style->font->descent)) / 2 +
+               GTK_WIDGET (scale)->style->font->ascent);
+         break;
+       case GTK_POS_RIGHT:
+         gdk_window_get_position (GTK_RANGE (scale)->trough, &x, NULL);
+         gdk_window_get_position (GTK_RANGE (scale)->slider, NULL, &y);
+         gdk_window_get_size (GTK_RANGE (scale)->trough, &width, NULL);
+         gdk_window_get_size (GTK_RANGE (scale)->slider, NULL, &height);
+
+         x += width + SCALE_CLASS (scale)->value_spacing;
+         y += ((height -
+                (GTK_WIDGET (scale)->style->font->ascent +
+                 GTK_WIDGET (scale)->style->font->descent)) / 2 +
+               GTK_WIDGET (scale)->style->font->ascent);
+         break;
+       case GTK_POS_TOP:
+         gdk_window_get_position (GTK_RANGE (scale)->trough, &x, &y);
+         gdk_window_get_size (GTK_RANGE (scale)->slider, &width, NULL);
+         gdk_window_get_size (GTK_RANGE (scale)->trough, NULL, &height);
+
+         x += (width - text_width) / 2;
+         y -= GTK_WIDGET (scale)->style->font->descent;
+         break;
+       case GTK_POS_BOTTOM:
+         gdk_window_get_position (GTK_RANGE (scale)->trough, &x, &y);
+         gdk_window_get_size (GTK_RANGE (scale)->slider, &width, NULL);
+         gdk_window_get_size (GTK_RANGE (scale)->trough, NULL, &height);
+
+         x += (width - text_width) / 2;
+         y += height + GTK_WIDGET (scale)->style->font->ascent;
+         break;
+       }
+
+      state_type = GTK_STATE_NORMAL;
+      if (!GTK_WIDGET_IS_SENSITIVE (scale))
+       state_type = GTK_STATE_INSENSITIVE;
+
+      gtk_draw_string (GTK_WIDGET (scale)->style,
+                      GTK_WIDGET (scale)->window,
+                      state_type, x, y, buffer);
+    }
+}
+
+static gint
+gtk_vscale_trough_keys(GtkRange *range,
+                      GdkEventKey *key,
+                      GtkScrollType *scroll,
+                      GtkTroughType *pos)
+{
+  gint return_val = FALSE;
+  switch (key->keyval)
+    {
+    case GDK_Up:
+      return_val = TRUE;
+      *scroll = GTK_SCROLL_STEP_BACKWARD;
+      break;
+    case GDK_Down:
+      return_val = TRUE;
+      *scroll = GTK_SCROLL_STEP_FORWARD;
+      break;
+    case GDK_Page_Up:
+      return_val = TRUE;
+      *scroll = GTK_SCROLL_PAGE_BACKWARD;
+      break;
+    case GDK_Page_Down:
+      return_val = TRUE;
+      *scroll = GTK_SCROLL_PAGE_FORWARD;
+      break;
+    case GDK_Home:
+      return_val = TRUE;
+      *pos = GTK_TROUGH_START;
+      break;
+    case GDK_End:
+      return_val = TRUE;
+      *pos = GTK_TROUGH_END;
+      break;
+    }
+  return return_val;
+}
diff --git a/gtk/gtkvscale.h b/gtk/gtkvscale.h
new file mode 100644 (file)
index 0000000..75862d3
--- /dev/null
@@ -0,0 +1,59 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_VSCALE_H__
+#define __GTK_VSCALE_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkscale.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_VSCALE(obj)          GTK_CHECK_CAST (obj, gtk_vscale_get_type (), GtkVScale)
+#define GTK_VSCALE_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_vscale_get_type (), GtkVScaleClass)
+#define GTK_IS_VSCALE(obj)       GTK_CHECK_TYPE (obj, gtk_vscale_get_type ())
+
+
+typedef struct _GtkVScale       GtkVScale;
+typedef struct _GtkVScaleClass  GtkVScaleClass;
+
+struct _GtkVScale
+{
+  GtkScale scale;
+};
+
+struct _GtkVScaleClass
+{
+  GtkScaleClass parent_class;
+};
+
+
+guint      gtk_vscale_get_type (void);
+GtkWidget* gtk_vscale_new      (GtkAdjustment *adjustment);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_VSCALE_H__ */
diff --git a/gtk/gtkvscrollbar.c b/gtk/gtkvscrollbar.c
new file mode 100644 (file)
index 0000000..87421c7
--- /dev/null
@@ -0,0 +1,387 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkvscrollbar.h"
+#include "gtksignal.h"
+#include "gdk/gdkkeysyms.h"
+
+
+#define EPSILON 0.01
+
+#define RANGE_CLASS(w)  GTK_RANGE_CLASS (GTK_OBJECT (w)->klass)
+
+
+static void gtk_vscrollbar_class_init       (GtkVScrollbarClass *klass);
+static void gtk_vscrollbar_init             (GtkVScrollbar      *vscrollbar);
+static void gtk_vscrollbar_realize          (GtkWidget          *widget);
+static void gtk_vscrollbar_size_allocate    (GtkWidget          *widget,
+                                            GtkAllocation      *allocation);
+static void gtk_vscrollbar_draw_step_forw   (GtkRange           *range);
+static void gtk_vscrollbar_draw_step_back   (GtkRange           *range);
+static void gtk_vscrollbar_slider_update    (GtkRange           *range);
+static void gtk_vscrollbar_calc_slider_size (GtkVScrollbar      *vscrollbar);
+static gint gtk_vscrollbar_trough_keys      (GtkRange *range,
+                                            GdkEventKey *key,
+                                            GtkScrollType *scroll,
+                                            GtkTroughType *pos);
+
+guint
+gtk_vscrollbar_get_type ()
+{
+  static guint vscrollbar_type = 0;
+
+  if (!vscrollbar_type)
+    {
+      GtkTypeInfo vscrollbar_info =
+      {
+       "GtkVScrollbar",
+       sizeof (GtkVScrollbar),
+       sizeof (GtkVScrollbarClass),
+       (GtkClassInitFunc) gtk_vscrollbar_class_init,
+       (GtkObjectInitFunc) gtk_vscrollbar_init,
+       (GtkArgFunc) NULL,
+      };
+
+      vscrollbar_type = gtk_type_unique (gtk_scrollbar_get_type (), &vscrollbar_info);
+    }
+
+  return vscrollbar_type;
+}
+
+static void
+gtk_vscrollbar_class_init (GtkVScrollbarClass *klass)
+{
+  GtkWidgetClass *widget_class;
+  GtkRangeClass *range_class;
+
+  widget_class = (GtkWidgetClass*) klass;
+  range_class = (GtkRangeClass*) klass;
+
+  widget_class->realize = gtk_vscrollbar_realize;
+  widget_class->size_allocate = gtk_vscrollbar_size_allocate;
+
+  range_class->draw_step_forw = gtk_vscrollbar_draw_step_forw;
+  range_class->draw_step_back = gtk_vscrollbar_draw_step_back;
+  range_class->slider_update = gtk_vscrollbar_slider_update;
+  range_class->trough_click = gtk_range_default_vtrough_click;
+  range_class->trough_keys = gtk_vscrollbar_trough_keys;
+  range_class->motion = gtk_range_default_vmotion;
+}
+
+static void
+gtk_vscrollbar_init (GtkVScrollbar *vscrollbar)
+{
+  GtkWidget *widget;
+  GtkRequisition *requisition;
+
+  widget = GTK_WIDGET (vscrollbar);
+  requisition = &widget->requisition;
+
+  requisition->width = (RANGE_CLASS (widget)->slider_width +
+                       widget->style->klass->xthickness * 2);
+  requisition->height = (RANGE_CLASS (widget)->min_slider_size +
+                        RANGE_CLASS (widget)->stepper_size +
+                        RANGE_CLASS (widget)->stepper_slider_spacing +
+                        widget->style->klass->ythickness) * 2;
+}
+
+GtkWidget*
+gtk_vscrollbar_new (GtkAdjustment *adjustment)
+{
+  GtkVScrollbar *vscrollbar;
+
+  vscrollbar = gtk_type_new (gtk_vscrollbar_get_type ());
+
+  if (!adjustment)
+    adjustment = (GtkAdjustment*) gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+
+  gtk_range_set_adjustment (GTK_RANGE (vscrollbar), adjustment);
+
+  return GTK_WIDGET (vscrollbar);
+}
+
+
+static void
+gtk_vscrollbar_realize (GtkWidget *widget)
+{
+  GtkRange *range;
+  GdkWindowAttr attributes;
+  gint attributes_mask;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_VSCROLLBAR (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+  range = GTK_RANGE (widget);
+
+  attributes.x = widget->allocation.x + (widget->allocation.width - widget->requisition.width) / 2;
+  attributes.y = widget->allocation.y;
+  attributes.width = widget->requisition.width;
+  attributes.height = widget->allocation.height;
+  attributes.wclass = GDK_INPUT_OUTPUT;
+  attributes.window_type = GDK_WINDOW_CHILD;
+  attributes.visual = gtk_widget_get_visual (widget);
+  attributes.colormap = gtk_widget_get_colormap (widget);
+  attributes.event_mask = gtk_widget_get_events (widget);
+  attributes.event_mask |= (GDK_EXPOSURE_MASK |
+                           GDK_BUTTON_PRESS_MASK |
+                           GDK_BUTTON_RELEASE_MASK |
+                           GDK_ENTER_NOTIFY_MASK |
+                           GDK_LEAVE_NOTIFY_MASK);
+
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+  widget->window = gdk_window_new (widget->parent->window, &attributes, attributes_mask);
+  range->trough = widget->window;
+
+  attributes.x = widget->style->klass->xthickness;
+  attributes.y = widget->style->klass->ythickness;
+  attributes.width = RANGE_CLASS (widget)->stepper_size;
+  attributes.height = RANGE_CLASS (widget)->stepper_size;
+
+  range->step_back = gdk_window_new (range->trough, &attributes, attributes_mask);
+
+  attributes.y = (widget->allocation.height -
+                 widget->style->klass->ythickness -
+                 RANGE_CLASS (widget)->stepper_size);
+
+  range->step_forw = gdk_window_new (range->trough, &attributes, attributes_mask);
+
+  attributes.x = widget->style->klass->ythickness;
+  attributes.y = 0;
+  attributes.width = RANGE_CLASS (widget)->slider_width;
+  attributes.height = RANGE_CLASS (widget)->min_slider_size;
+  attributes.event_mask |= (GDK_BUTTON_MOTION_MASK |
+                           GDK_POINTER_MOTION_HINT_MASK);
+
+  range->slider = gdk_window_new (range->trough, &attributes, attributes_mask);
+
+  gtk_vscrollbar_calc_slider_size (GTK_VSCROLLBAR (widget));
+  gtk_range_slider_update (GTK_RANGE (widget));
+
+  widget->style = gtk_style_attach (widget->style, widget->window);
+
+  gdk_window_set_user_data (range->trough, widget);
+  gdk_window_set_user_data (range->slider, widget);
+  gdk_window_set_user_data (range->step_forw, widget);
+  gdk_window_set_user_data (range->step_back, widget);
+
+  gtk_style_set_background (widget->style, range->trough, GTK_STATE_ACTIVE);
+  gtk_style_set_background (widget->style, range->slider, GTK_STATE_NORMAL);
+  gtk_style_set_background (widget->style, range->step_forw, GTK_STATE_ACTIVE);
+  gtk_style_set_background (widget->style, range->step_back, GTK_STATE_ACTIVE);
+
+  gdk_window_show (range->slider);
+  gdk_window_show (range->step_forw);
+  gdk_window_show (range->step_back);
+}
+
+static void
+gtk_vscrollbar_size_allocate (GtkWidget     *widget,
+                             GtkAllocation *allocation)
+{
+  GtkRange *range;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_VSCROLLBAR (widget));
+  g_return_if_fail (allocation != NULL);
+
+  widget->allocation = *allocation;
+  if (GTK_WIDGET_REALIZED (widget))
+    {
+      range = GTK_RANGE (widget);
+
+      gdk_window_move_resize (range->trough,
+                             allocation->x + (allocation->width - widget->requisition.width) / 2,
+                             allocation->y,
+                             widget->requisition.width, allocation->height);
+      gdk_window_move_resize (range->step_back,
+                             widget->style->klass->xthickness,
+                             widget->style->klass->ythickness,
+                             widget->requisition.width - widget->style->klass->xthickness * 2,
+                             RANGE_CLASS (widget)->stepper_size);
+      gdk_window_move_resize (range->step_forw,
+                             widget->style->klass->xthickness,
+                             allocation->height - widget->style->klass->ythickness -
+                             RANGE_CLASS (widget)->stepper_size,
+                             widget->requisition.width - widget->style->klass->xthickness * 2,
+                             RANGE_CLASS (widget)->stepper_size);
+      gdk_window_resize (range->slider,
+                        widget->requisition.width - widget->style->klass->xthickness * 2,
+                        RANGE_CLASS (range)->min_slider_size);
+
+      gtk_range_slider_update (GTK_RANGE (widget));
+    }
+}
+
+static void
+gtk_vscrollbar_draw_step_forw (GtkRange *range)
+{
+  GtkStateType state_type;
+  GtkShadowType shadow_type;
+
+  g_return_if_fail (range != NULL);
+  g_return_if_fail (GTK_IS_VSCROLLBAR (range));
+
+  if (GTK_WIDGET_DRAWABLE (range))
+    {
+      if (range->in_child == RANGE_CLASS (range)->step_forw)
+       {
+         if (range->click_child == RANGE_CLASS (range)->step_forw)
+           state_type = GTK_STATE_ACTIVE;
+         else
+           state_type = GTK_STATE_PRELIGHT;
+       }
+      else
+       state_type = GTK_STATE_NORMAL;
+
+      if (range->click_child == RANGE_CLASS (range)->step_forw)
+       shadow_type = GTK_SHADOW_IN;
+      else
+       shadow_type = GTK_SHADOW_OUT;
+
+      gtk_draw_arrow (GTK_WIDGET (range)->style, range->step_forw,
+                     state_type, shadow_type, GTK_ARROW_DOWN,
+                     TRUE, 0, 0, -1, -1);
+    }
+}
+
+static void
+gtk_vscrollbar_draw_step_back (GtkRange *range)
+{
+  GtkStateType state_type;
+  GtkShadowType shadow_type;
+
+  g_return_if_fail (range != NULL);
+  g_return_if_fail (GTK_IS_VSCROLLBAR (range));
+
+  if (GTK_WIDGET_DRAWABLE (range))
+    {
+      if (range->in_child == RANGE_CLASS (range)->step_back)
+       {
+         if (range->click_child == RANGE_CLASS (range)->step_back)
+           state_type = GTK_STATE_ACTIVE;
+         else
+           state_type = GTK_STATE_PRELIGHT;
+       }
+      else
+       state_type = GTK_STATE_NORMAL;
+
+      if (range->click_child == RANGE_CLASS (range)->step_back)
+       shadow_type = GTK_SHADOW_IN;
+      else
+       shadow_type = GTK_SHADOW_OUT;
+
+      gtk_draw_arrow (GTK_WIDGET (range)->style, range->step_back,
+                     state_type, shadow_type, GTK_ARROW_UP,
+                     TRUE, 0, 0, -1, -1);
+    }
+}
+
+static void
+gtk_vscrollbar_slider_update (GtkRange *range)
+{
+  g_return_if_fail (range != NULL);
+  g_return_if_fail (GTK_IS_VSCROLLBAR (range));
+
+  gtk_vscrollbar_calc_slider_size (GTK_VSCROLLBAR (range));
+  gtk_range_default_vslider_update (range);
+}
+
+static void
+gtk_vscrollbar_calc_slider_size (GtkVScrollbar *vscrollbar)
+{
+  GtkRange *range;
+  gint step_back_y;
+  gint step_back_height;
+  gint step_forw_y;
+  gint slider_width;
+  gint slider_height;
+  gint top, bottom;
+  gint height;
+
+  g_return_if_fail (vscrollbar != NULL);
+  g_return_if_fail (GTK_IS_VSCROLLBAR (vscrollbar));
+
+  if (GTK_WIDGET_REALIZED (vscrollbar))
+    {
+      range = GTK_RANGE (vscrollbar);
+
+      gdk_window_get_size (range->step_back, NULL, &step_back_height);
+      gdk_window_get_position (range->step_back, NULL, &step_back_y);
+      gdk_window_get_position (range->step_forw, NULL, &step_forw_y);
+
+      top = (step_back_y +
+             step_back_height +
+            RANGE_CLASS (vscrollbar)->stepper_slider_spacing);
+      bottom = step_forw_y - RANGE_CLASS (vscrollbar)->stepper_slider_spacing;
+      height = bottom - top;
+
+      if ((range->adjustment->page_size > 0) &&
+         (range->adjustment->lower != range->adjustment->upper))
+       {
+         if (range->adjustment->page_size >
+             (range->adjustment->upper - range->adjustment->lower))
+           range->adjustment->page_size = range->adjustment->upper - range->adjustment->lower;
+
+         height = (height * range->adjustment->page_size /
+                  (range->adjustment->upper - range->adjustment->lower));
+
+         if (height < RANGE_CLASS (vscrollbar)->min_slider_size)
+           height = RANGE_CLASS (vscrollbar)->min_slider_size;
+       }
+
+      gdk_window_get_size (range->slider, &slider_width, &slider_height);
+
+      if (slider_height != height)
+       gdk_window_resize (range->slider, slider_width, height);
+    }
+}
+
+static gint
+gtk_vscrollbar_trough_keys(GtkRange *range,
+                          GdkEventKey *key,
+                          GtkScrollType *scroll,
+                          GtkTroughType *pos)
+{
+  gint return_val = FALSE;
+  switch (key->keyval)
+    {
+    case GDK_Up:
+      return_val = TRUE;
+      *scroll = GTK_SCROLL_STEP_BACKWARD;
+      break;
+    case GDK_Down:
+      return_val = TRUE;
+      *scroll = GTK_SCROLL_STEP_FORWARD;
+      break;
+    case GDK_Page_Up:
+      return_val = TRUE;
+      if (key->state & GDK_CONTROL_MASK)
+       *pos = GTK_TROUGH_START;
+      else
+       *scroll = GTK_SCROLL_PAGE_BACKWARD;
+      break;
+    case GDK_Page_Down:
+      return_val = TRUE;
+      if (key->state & GDK_CONTROL_MASK)
+       *pos = GTK_TROUGH_END;
+      else
+       *scroll = GTK_SCROLL_PAGE_FORWARD;
+      break;
+    }
+  return return_val;
+}
diff --git a/gtk/gtkvscrollbar.h b/gtk/gtkvscrollbar.h
new file mode 100644 (file)
index 0000000..3160fc0
--- /dev/null
@@ -0,0 +1,59 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_VSCROLLBAR_H__
+#define __GTK_VSCROLLBAR_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkscrollbar.h>
+
+
+#define GTK_VSCROLLBAR(obj)          GTK_CHECK_CAST (obj, gtk_vscrollbar_get_type (), GtkVScrollbar)
+#define GTK_VSCROLLBAR_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_vscrollbar_get_type (), GtkVScrollbarClass)
+#define GTK_IS_VSCROLLBAR(obj)       GTK_CHECK_TYPE (obj, gtk_vscrollbar_get_type ())
+
+
+typedef struct _GtkVScrollbar       GtkVScrollbar;
+typedef struct _GtkVScrollbarClass  GtkVScrollbarClass;
+
+struct _GtkVScrollbar
+{
+  GtkScrollbar scrollbar;
+};
+
+struct _GtkVScrollbarClass
+{
+  GtkScrollbarClass parent_class;
+};
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+guint      gtk_vscrollbar_get_type (void);
+GtkWidget* gtk_vscrollbar_new      (GtkAdjustment *adjustment);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_VSCROLLBAR_H__ */
diff --git a/gtk/gtkvseparator.c b/gtk/gtkvseparator.c
new file mode 100644 (file)
index 0000000..fbbba19
--- /dev/null
@@ -0,0 +1,90 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "gtkvseparator.h"
+
+
+static void gtk_vseparator_class_init (GtkVSeparatorClass *klass);
+static void gtk_vseparator_init       (GtkVSeparator      *vseparator);
+static gint gtk_vseparator_expose     (GtkWidget          *widget,
+                                      GdkEventExpose     *event);
+
+
+guint
+gtk_vseparator_get_type ()
+{
+  static guint vseparator_type = 0;
+
+  if (!vseparator_type)
+    {
+      GtkTypeInfo vseparator_info =
+      {
+       "GtkVSeparator",
+       sizeof (GtkVSeparator),
+       sizeof (GtkVSeparatorClass),
+       (GtkClassInitFunc) gtk_vseparator_class_init,
+       (GtkObjectInitFunc) gtk_vseparator_init,
+       (GtkArgFunc) NULL,
+      };
+
+      vseparator_type = gtk_type_unique (gtk_separator_get_type (), &vseparator_info);
+    }
+
+  return vseparator_type;
+}
+
+static void
+gtk_vseparator_class_init (GtkVSeparatorClass *klass)
+{
+  GtkWidgetClass *widget_class;
+
+  widget_class = (GtkWidgetClass*) klass;
+
+  widget_class->expose_event = gtk_vseparator_expose;
+}
+
+static void
+gtk_vseparator_init (GtkVSeparator *vseparator)
+{
+  GTK_WIDGET (vseparator)->requisition.width = GTK_WIDGET (vseparator)->style->klass->xthickness;
+  GTK_WIDGET (vseparator)->requisition.height = 1;
+}
+
+GtkWidget*
+gtk_vseparator_new ()
+{
+  return GTK_WIDGET (gtk_type_new (gtk_vseparator_get_type ()));
+}
+
+
+static gint
+gtk_vseparator_expose (GtkWidget      *widget,
+                      GdkEventExpose *event)
+{
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_VSEPARATOR (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    gtk_draw_vline (widget->style, widget->window, GTK_STATE_NORMAL,
+                   widget->allocation.y,
+                   widget->allocation.y + widget->allocation.height,
+                   widget->allocation.x + (widget->allocation.width -
+                                           widget->style->klass->xthickness) / 2);
+
+  return FALSE;
+}
diff --git a/gtk/gtkvseparator.h b/gtk/gtkvseparator.h
new file mode 100644 (file)
index 0000000..74d07dd
--- /dev/null
@@ -0,0 +1,59 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_VSEPARATOR_H__
+#define __GTK_VSEPARATOR_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkseparator.h>
+
+
+#define GTK_VSEPARATOR(obj)          GTK_CHECK_CAST (obj, gtk_vseparator_get_type (), GtkVSeparator)
+#define GTK_VSEPARATOR_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_vseparator_get_type (), GtkVSeparatorClass)
+#define GTK_IS_VSEPARATOR(obj)       GTK_CHECK_TYPE (obj, gtk_vseparator_get_type ())
+
+
+typedef struct _GtkVSeparator       GtkVSeparator;
+typedef struct _GtkVSeparatorClass  GtkVSeparatorClass;
+
+struct _GtkVSeparator
+{
+  GtkSeparator separator;
+};
+
+struct _GtkVSeparatorClass
+{
+  GtkSeparatorClass parent_class;
+};
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+guint      gtk_vseparator_get_type (void);
+GtkWidget* gtk_vseparator_new      (void);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_SEPARATOR_H__ */
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
new file mode 100644 (file)
index 0000000..26e0c9b
--- /dev/null
@@ -0,0 +1,3390 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdarg.h>
+#include <string.h>
+#include "gtkcontainer.h"
+#include "gtkmain.h"
+#include "gtkrc.h"
+#include "gtkselection.h"
+#include "gtksignal.h"
+#include "gtkwidget.h"
+#include "gtkwindow.h"
+#include "gdk/gdk.h"
+#include "gdk/gdkx.h"
+
+
+#define WIDGET_CLASS(w)  GTK_WIDGET_CLASS (GTK_OBJECT (w)->klass)
+
+
+enum {
+  SHOW,
+  HIDE,
+  MAP,
+  UNMAP,
+  REALIZE,
+  UNREALIZE,
+  DRAW,
+  DRAW_FOCUS,
+  DRAW_DEFAULT,
+  SIZE_REQUEST,
+  SIZE_ALLOCATE,
+  STATE_CHANGED,
+  INSTALL_ACCELERATOR,
+  REMOVE_ACCELERATOR,
+  EVENT,
+  BUTTON_PRESS_EVENT,
+  BUTTON_RELEASE_EVENT,
+  MOTION_NOTIFY_EVENT,
+  DELETE_EVENT,
+  DESTROY_EVENT,
+  EXPOSE_EVENT,
+  KEY_PRESS_EVENT,
+  KEY_RELEASE_EVENT,
+  ENTER_NOTIFY_EVENT,
+  LEAVE_NOTIFY_EVENT,
+  CONFIGURE_EVENT,
+  FOCUS_IN_EVENT,
+  FOCUS_OUT_EVENT,
+  MAP_EVENT,
+  UNMAP_EVENT,
+  PROPERTY_NOTIFY_EVENT,
+  SELECTION_CLEAR_EVENT,
+  SELECTION_REQUEST_EVENT,
+  SELECTION_NOTIFY_EVENT,
+  SELECTION_RECEIVED,
+  PROXIMITY_IN_EVENT,
+  PROXIMITY_OUT_EVENT,
+  DRAG_BEGIN_EVENT,
+  DRAG_REQUEST_EVENT,
+  DROP_ENTER_EVENT,
+  DROP_LEAVE_EVENT,
+  DROP_DATA_AVAILABLE_EVENT,
+  OTHER_EVENT,
+  LAST_SIGNAL
+};
+
+
+typedef void (*GtkWidgetSignal1) (GtkObject *object,
+                                 gpointer   arg1,
+                                 gpointer   data);
+typedef gint (*GtkWidgetSignal2) (GtkObject *object,
+                                 gpointer   arg1,
+                                 gchar      arg2,
+                                 gchar      arg3,
+                                 gpointer   data);
+typedef void (*GtkWidgetSignal3) (GtkObject *object,
+                                 gpointer   arg1,
+                                 gpointer   data);
+typedef gint (*GtkWidgetSignal4) (GtkObject *object,
+                                 gpointer   arg1,
+                                 gpointer   data);
+
+
+static void gtk_widget_marshal_signal_1 (GtkObject      *object,
+                                        GtkSignalFunc   func,
+                                        gpointer        func_data,
+                                        GtkArg         *args);
+static void gtk_widget_marshal_signal_2 (GtkObject      *object,
+                                        GtkSignalFunc   func,
+                                        gpointer        func_data,
+                                        GtkArg         *args);
+static void gtk_widget_marshal_signal_3 (GtkObject      *object,
+                                        GtkSignalFunc   func,
+                                        gpointer        func_data,
+                                        GtkArg         *args);
+static void gtk_widget_marshal_signal_4 (GtkObject      *object,
+                                        GtkSignalFunc   func,
+                                        gpointer        func_data,
+                                        GtkArg         *args);
+
+static void gtk_widget_class_init                (GtkWidgetClass    *klass);
+static void gtk_widget_init                      (GtkWidget         *widget);
+static void gtk_widget_arg                       (GtkWidget         *widget,
+                                                 GtkArg            *arg);
+static void gtk_real_widget_destroy              (GtkObject         *object);
+static void gtk_real_widget_show                 (GtkWidget         *widget);
+static void gtk_real_widget_hide                 (GtkWidget         *widget);
+static void gtk_real_widget_map                  (GtkWidget         *widget);
+static void gtk_real_widget_unmap                (GtkWidget         *widget);
+static void gtk_real_widget_realize              (GtkWidget         *widget);
+static void gtk_real_widget_unrealize            (GtkWidget         *widget);
+static void gtk_real_widget_draw                 (GtkWidget         *widget,
+                                                 GdkRectangle      *area);
+static gint gtk_real_widget_queue_draw           (GtkWidget         *widget);
+static gint gtk_real_widget_queue_resize         (GtkWidget         *widget);
+static void gtk_real_widget_size_allocate        (GtkWidget         *widget,
+                                                 GtkAllocation     *allocation);
+
+static GdkColormap* gtk_widget_peek_colormap (void);
+static GdkVisual*   gtk_widget_peek_visual   (void);
+static GtkStyle*    gtk_widget_peek_style    (void);
+
+static void gtk_widget_set_parent_sensitive  (GtkWidget *widget,
+                                             gpointer   client_data);
+static void gtk_widget_propagate_restore     (GtkWidget *widget,
+                                             gpointer   client_data);
+static void gtk_widget_propagate_state       (GtkWidget *widget,
+                                             gpointer   client_data);
+static void gtk_widget_draw_children_recurse (GtkWidget *widget,
+                                             gpointer   client_data);
+static void gtk_widget_set_style_internal    (GtkWidget *widget,
+                                             GtkStyle  *style);
+static void gtk_widget_set_style_recurse     (GtkWidget *widget,
+                                             gpointer   client_data);
+
+extern GtkArg* gtk_object_collect_args (gint    *nargs,
+                                       va_list  args1,
+                                       va_list  args2);
+
+static GtkWidgetAuxInfo* gtk_widget_aux_info_new     (void);
+static void              gtk_widget_aux_info_destroy (GtkWidgetAuxInfo *aux_info);
+
+static GtkObjectClass *parent_class = NULL;
+static gint widget_signals[LAST_SIGNAL] = { 0 };
+
+static GMemChunk *aux_info_mem_chunk = NULL;
+
+static GdkColormap *default_colormap = NULL;
+static GdkVisual *default_visual = NULL;
+static GtkStyle *default_style = NULL;
+
+static GSList *colormap_stack = NULL;
+static GSList *visual_stack = NULL;
+static GSList *style_stack = NULL;
+
+static const char *aux_info_key = "aux_info";
+static const char *colormap_key = "colormap";
+static const char *visual_key = "visual";
+static const char *event_key = "event_mask";
+static const char *resize_widgets_key = "resize_widgets";
+static const char *extension_event_key = "extension_event_mode";
+static const char *redraw_handler_key = "redraw_handler_tag";
+static const char *resize_handler_key = "resize_handler_tag";
+static const char *shape_info_key = "shape_info";
+
+
+
+/*****************************************
+ * gtk_widget_get_type:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+guint
+gtk_widget_get_type ()
+{
+  static guint widget_type = 0;
+
+  if (!widget_type)
+    {
+      GtkTypeInfo widget_info =
+      {
+       "GtkWidget",
+       sizeof (GtkWidget),
+       sizeof (GtkWidgetClass),
+       (GtkClassInitFunc) gtk_widget_class_init,
+       (GtkObjectInitFunc) gtk_widget_init,
+       (GtkArgFunc) gtk_widget_arg,
+      };
+
+      widget_type = gtk_type_unique (gtk_object_get_type (), &widget_info);
+    }
+
+  return widget_type;
+}
+
+/*****************************************
+ * gtk_widget_class_init:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static void
+gtk_widget_class_init (GtkWidgetClass *klass)
+{
+  GtkObjectClass *object_class;
+
+  object_class = (GtkObjectClass*) klass;
+
+  parent_class = gtk_type_class (gtk_object_get_type ());
+
+  gtk_object_add_arg_type ("GtkWidget::x", GTK_TYPE_INT);
+  gtk_object_add_arg_type ("GtkWidget::y", GTK_TYPE_INT);
+  gtk_object_add_arg_type ("GtkWidget::width", GTK_TYPE_INT);
+  gtk_object_add_arg_type ("GtkWidget::height", GTK_TYPE_INT);
+  gtk_object_add_arg_type ("GtkWidget::visible", GTK_TYPE_BOOL);
+  gtk_object_add_arg_type ("GtkWidget::sensitive", GTK_TYPE_BOOL);
+  gtk_object_add_arg_type ("GtkWidget::events", GTK_TYPE_GDK_EVENT_MASK);
+  gtk_object_add_arg_type ("GtkWidget::extension_events", GTK_TYPE_GDK_EVENT_MASK);
+  gtk_object_add_arg_type ("GtkWidget::name", GTK_TYPE_STRING);
+  gtk_object_add_arg_type ("GtkWidget::style", GTK_TYPE_STYLE);
+  gtk_object_add_arg_type ("GtkWidget::parent", GTK_TYPE_CONTAINER);
+
+  widget_signals[SHOW] =
+    gtk_signal_new ("show",
+                   GTK_RUN_FIRST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, show),
+                   gtk_signal_default_marshaller,
+                   GTK_TYPE_NONE, 0);
+  widget_signals[HIDE] =
+    gtk_signal_new ("hide",
+                   GTK_RUN_FIRST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, hide),
+                   gtk_signal_default_marshaller,
+                   GTK_TYPE_NONE, 0);
+  widget_signals[MAP] =
+    gtk_signal_new ("map",
+                   GTK_RUN_FIRST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, map),
+                   gtk_signal_default_marshaller,
+                   GTK_TYPE_NONE, 0);
+  widget_signals[UNMAP] =
+    gtk_signal_new ("unmap",
+                   GTK_RUN_FIRST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, unmap),
+                   gtk_signal_default_marshaller,
+                   GTK_TYPE_NONE, 0);
+  widget_signals[REALIZE] =
+    gtk_signal_new ("realize",
+                   GTK_RUN_FIRST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, realize),
+                   gtk_signal_default_marshaller,
+                   GTK_TYPE_NONE, 0);
+  widget_signals[UNREALIZE] =
+    gtk_signal_new ("unrealize",
+                   GTK_RUN_FIRST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, unrealize),
+                   gtk_signal_default_marshaller,
+                   GTK_TYPE_NONE, 0);
+  widget_signals[DRAW] =
+    gtk_signal_new ("draw",
+                   GTK_RUN_FIRST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, draw),
+                   gtk_widget_marshal_signal_1,
+                   GTK_TYPE_NONE, 1,
+                   GTK_TYPE_POINTER);
+  widget_signals[DRAW_FOCUS] =
+    gtk_signal_new ("draw_focus",
+                   GTK_RUN_FIRST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, draw_focus),
+                   gtk_signal_default_marshaller,
+                   GTK_TYPE_NONE, 0);
+  widget_signals[DRAW_DEFAULT] =
+    gtk_signal_new ("draw_default",
+                   GTK_RUN_FIRST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, draw_default),
+                   gtk_signal_default_marshaller,
+                   GTK_TYPE_NONE, 0);
+  widget_signals[SIZE_REQUEST] =
+    gtk_signal_new ("size_request",
+                   GTK_RUN_FIRST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, size_request),
+                   gtk_widget_marshal_signal_1,
+                   GTK_TYPE_NONE, 1,
+                   GTK_TYPE_POINTER);
+  widget_signals[SIZE_ALLOCATE] =
+    gtk_signal_new ("size_allocate",
+                   GTK_RUN_FIRST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, size_allocate),
+                   gtk_widget_marshal_signal_1,
+                   GTK_TYPE_NONE, 1,
+                   GTK_TYPE_POINTER);
+  widget_signals[STATE_CHANGED] =
+    gtk_signal_new ("state_changed",
+                   GTK_RUN_FIRST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, state_changed),
+                   gtk_signal_default_marshaller,
+                   GTK_TYPE_NONE, 0);
+  widget_signals[INSTALL_ACCELERATOR] =
+    gtk_signal_new ("install_accelerator",
+                   GTK_RUN_FIRST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, install_accelerator),
+                   gtk_widget_marshal_signal_2,
+                   GTK_TYPE_BOOL, 3,
+                   GTK_TYPE_STRING,
+                   GTK_TYPE_CHAR,
+                   GTK_TYPE_INT);
+  widget_signals[REMOVE_ACCELERATOR] =
+    gtk_signal_new ("remove_accelerator",
+                   GTK_RUN_FIRST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, remove_accelerator),
+                   gtk_widget_marshal_signal_3,
+                   GTK_TYPE_NONE, 1,
+                   GTK_TYPE_STRING);
+  widget_signals[EVENT] =
+    gtk_signal_new ("event",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, event),
+                   gtk_widget_marshal_signal_4,
+                   GTK_TYPE_BOOL, 1,
+                   GTK_TYPE_GDK_EVENT);
+  widget_signals[BUTTON_PRESS_EVENT] =
+    gtk_signal_new ("button_press_event",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, button_press_event),
+                   gtk_widget_marshal_signal_4,
+                   GTK_TYPE_BOOL, 1,
+                   GTK_TYPE_GDK_EVENT);
+  widget_signals[BUTTON_RELEASE_EVENT] =
+    gtk_signal_new ("button_release_event",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, button_release_event),
+                   gtk_widget_marshal_signal_4,
+                   GTK_TYPE_BOOL, 1,
+                   GTK_TYPE_GDK_EVENT);
+  widget_signals[MOTION_NOTIFY_EVENT] =
+    gtk_signal_new ("motion_notify_event",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, motion_notify_event),
+                   gtk_widget_marshal_signal_4,
+                   GTK_TYPE_BOOL, 1,
+                   GTK_TYPE_GDK_EVENT);
+  widget_signals[DELETE_EVENT] =
+    gtk_signal_new ("delete_event",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, delete_event),
+                   gtk_widget_marshal_signal_4,
+                   GTK_TYPE_BOOL, 1,
+                   GTK_TYPE_GDK_EVENT);
+  widget_signals[DESTROY_EVENT] =
+    gtk_signal_new ("destroy_event",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, destroy_event),
+                   gtk_widget_marshal_signal_4,
+                   GTK_TYPE_BOOL, 1,
+                   GTK_TYPE_GDK_EVENT);
+  widget_signals[EXPOSE_EVENT] =
+    gtk_signal_new ("expose_event",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, expose_event),
+                   gtk_widget_marshal_signal_4,
+                   GTK_TYPE_BOOL, 1,
+                   GTK_TYPE_GDK_EVENT);
+  widget_signals[KEY_PRESS_EVENT] =
+    gtk_signal_new ("key_press_event",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, key_press_event),
+                   gtk_widget_marshal_signal_4,
+                   GTK_TYPE_BOOL, 1,
+                   GTK_TYPE_GDK_EVENT);
+  widget_signals[KEY_RELEASE_EVENT] =
+    gtk_signal_new ("key_release_event",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, key_release_event),
+                   gtk_widget_marshal_signal_4,
+                   GTK_TYPE_BOOL, 1,
+                   GTK_TYPE_GDK_EVENT);
+  widget_signals[ENTER_NOTIFY_EVENT] =
+    gtk_signal_new ("enter_notify_event",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, enter_notify_event),
+                   gtk_widget_marshal_signal_4,
+                   GTK_TYPE_BOOL, 1,
+                   GTK_TYPE_GDK_EVENT);
+  widget_signals[LEAVE_NOTIFY_EVENT] =
+    gtk_signal_new ("leave_notify_event",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, leave_notify_event),
+                   gtk_widget_marshal_signal_4,
+                   GTK_TYPE_BOOL, 1,
+                   GTK_TYPE_GDK_EVENT);
+  widget_signals[CONFIGURE_EVENT] =
+    gtk_signal_new ("configure_event",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, configure_event),
+                   gtk_widget_marshal_signal_4,
+                   GTK_TYPE_BOOL, 1,
+                   GTK_TYPE_GDK_EVENT);
+  widget_signals[FOCUS_IN_EVENT] =
+    gtk_signal_new ("focus_in_event",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, focus_in_event),
+                   gtk_widget_marshal_signal_4,
+                   GTK_TYPE_BOOL, 1,
+                   GTK_TYPE_GDK_EVENT);
+  widget_signals[FOCUS_OUT_EVENT] =
+    gtk_signal_new ("focus_out_event",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, focus_out_event),
+                   gtk_widget_marshal_signal_4,
+                   GTK_TYPE_BOOL, 1,
+                   GTK_TYPE_GDK_EVENT);
+  widget_signals[MAP_EVENT] =
+    gtk_signal_new ("map_event",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, map_event),
+                   gtk_widget_marshal_signal_4,
+                   GTK_TYPE_BOOL, 1,
+                   GTK_TYPE_GDK_EVENT);
+  widget_signals[UNMAP_EVENT] =
+    gtk_signal_new ("unmap_event",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, unmap_event),
+                   gtk_widget_marshal_signal_4,
+                   GTK_TYPE_BOOL, 1,
+                   GTK_TYPE_GDK_EVENT);
+  widget_signals[PROPERTY_NOTIFY_EVENT] =
+    gtk_signal_new ("property_notify_event",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, property_notify_event),
+                   gtk_widget_marshal_signal_4,
+                   GTK_TYPE_BOOL, 1,
+                   GTK_TYPE_GDK_EVENT);
+  widget_signals[SELECTION_CLEAR_EVENT] =
+    gtk_signal_new ("selection_clear_event",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, selection_clear_event),
+                   gtk_widget_marshal_signal_4,
+                   GTK_TYPE_BOOL, 1,
+                   GTK_TYPE_GDK_EVENT);
+  widget_signals[SELECTION_REQUEST_EVENT] =
+    gtk_signal_new ("selection_request_event",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, selection_request_event),
+                   gtk_widget_marshal_signal_4,
+                   GTK_TYPE_BOOL, 1,
+                   GTK_TYPE_GDK_EVENT);
+  widget_signals[SELECTION_NOTIFY_EVENT] =
+    gtk_signal_new ("selection_notify_event",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, selection_notify_event),
+                   gtk_widget_marshal_signal_4,
+                   GTK_TYPE_BOOL, 1,
+                   GTK_TYPE_GDK_EVENT);
+  widget_signals[SELECTION_RECEIVED] =
+    gtk_signal_new ("selection_received",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, selection_received),
+                   gtk_widget_marshal_signal_1,
+                   GTK_TYPE_BOOL, 1,
+                   GTK_TYPE_GDK_EVENT);
+  widget_signals[PROXIMITY_IN_EVENT] =
+    gtk_signal_new ("proximity_in_event",
+                   GTK_RUN_FIRST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, proximity_in_event),
+                   gtk_widget_marshal_signal_4,
+                   GTK_TYPE_BOOL, 1,
+                   GTK_TYPE_GDK_EVENT);
+  widget_signals[PROXIMITY_OUT_EVENT] =
+    gtk_signal_new ("proximity_out_event",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, proximity_out_event),
+                   gtk_widget_marshal_signal_4,
+                   GTK_TYPE_BOOL, 1,
+                   GTK_TYPE_GDK_EVENT);
+  widget_signals[DRAG_BEGIN_EVENT] =
+    gtk_signal_new ("drag_begin_event",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_begin_event),
+                   gtk_widget_marshal_signal_4,
+                   GTK_TYPE_BOOL, 1,
+                   GTK_TYPE_GDK_EVENT);
+  widget_signals[DRAG_REQUEST_EVENT] =
+    gtk_signal_new ("drag_request_event",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, drag_request_event),
+                   gtk_widget_marshal_signal_4,
+                   GTK_TYPE_BOOL, 1,
+                   GTK_TYPE_GDK_EVENT);
+  widget_signals[DROP_ENTER_EVENT] =
+    gtk_signal_new ("drop_enter_event",
+                   GTK_RUN_FIRST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, drop_enter_event),
+                   gtk_widget_marshal_signal_4,
+                   GTK_TYPE_BOOL, 1,
+                   GTK_TYPE_GDK_EVENT);
+  widget_signals[DROP_LEAVE_EVENT] =
+    gtk_signal_new ("drop_leave_event",
+                   GTK_RUN_FIRST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, drop_leave_event),
+                   gtk_widget_marshal_signal_4,
+                   GTK_TYPE_BOOL, 1,
+                   GTK_TYPE_GDK_EVENT);
+  widget_signals[DROP_DATA_AVAILABLE_EVENT] =
+    gtk_signal_new ("drop_data_available_event",
+                   GTK_RUN_FIRST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass,
+                                      drop_data_available_event),
+                   gtk_widget_marshal_signal_4,
+                   GTK_TYPE_BOOL, 1,
+                   GTK_TYPE_GDK_EVENT);
+  widget_signals[OTHER_EVENT] =
+    gtk_signal_new ("other_event",
+                   GTK_RUN_LAST,
+                   object_class->type,
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, other_event),
+                   gtk_widget_marshal_signal_4,
+                   GTK_TYPE_BOOL, 1,
+                   GTK_TYPE_GDK_EVENT);
+
+  gtk_object_class_add_signals (object_class, widget_signals, LAST_SIGNAL);
+
+  object_class->destroy = gtk_real_widget_destroy;
+
+  klass->activate_signal = 0;
+  klass->show = gtk_real_widget_show;
+  klass->hide = gtk_real_widget_hide;
+  klass->map = gtk_real_widget_map;
+  klass->unmap = gtk_real_widget_unmap;
+  klass->realize = gtk_real_widget_realize;
+  klass->unrealize = gtk_real_widget_unrealize;
+  klass->draw = gtk_real_widget_draw;
+  klass->draw_focus = NULL;
+  klass->size_request = NULL;
+  klass->size_allocate = gtk_real_widget_size_allocate;
+  klass->state_changed = NULL;
+  klass->install_accelerator = NULL;
+  klass->remove_accelerator = NULL;
+  klass->event = NULL;
+  klass->button_press_event = NULL;
+  klass->button_release_event = NULL;
+  klass->motion_notify_event = NULL;
+  klass->delete_event = NULL;
+  klass->destroy_event = NULL;
+  klass->expose_event = NULL;
+  klass->key_press_event = NULL;
+  klass->key_release_event = NULL;
+  klass->enter_notify_event = NULL;
+  klass->leave_notify_event = NULL;
+  klass->configure_event = NULL;
+  klass->focus_in_event = NULL;
+  klass->focus_out_event = NULL;
+  klass->map_event = NULL;
+  klass->unmap_event = NULL;
+  klass->property_notify_event = gtk_selection_property_notify;
+  klass->selection_clear_event = gtk_selection_clear;
+  klass->selection_request_event = gtk_selection_request;
+  klass->selection_notify_event = gtk_selection_notify;
+  klass->selection_received = NULL;
+  klass->proximity_in_event = NULL;
+  klass->proximity_out_event = NULL;
+  klass->drag_begin_event = NULL;
+  klass->drag_request_event = NULL;
+  klass->drop_enter_event = NULL;
+  klass->drop_leave_event = NULL;
+  klass->drop_data_available_event = NULL;
+  klass->other_event = NULL;
+}
+
+/*****************************************
+ * gtk_widget_arg:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static void
+gtk_widget_arg (GtkWidget *widget,
+               GtkArg    *arg)
+{
+  if (strcmp (arg->name, "x") == 0)
+    {
+      gtk_widget_set_uposition (widget, GTK_VALUE_INT(*arg), -2);
+    }
+  else if (strcmp (arg->name, "y") == 0)
+    {
+      gtk_widget_set_uposition (widget, -2, GTK_VALUE_INT(*arg));
+    }
+  else if (strcmp (arg->name, "width") == 0)
+    {
+      gtk_widget_set_usize (widget, GTK_VALUE_INT(*arg), -1);
+    }
+  else if (strcmp (arg->name, "height") == 0)
+    {
+      gtk_widget_set_usize (widget, -1, GTK_VALUE_INT(*arg));
+    }
+  else if (strcmp (arg->name, "visible") == 0)
+    {
+      if (GTK_VALUE_BOOL(*arg))
+       gtk_widget_show (widget);
+      else
+       gtk_widget_hide (widget);
+    }
+  else if (strcmp (arg->name, "sensitive") == 0)
+    {
+      gtk_widget_set_sensitive (widget, GTK_VALUE_BOOL(*arg));
+    }
+  else if (strcmp (arg->name, "events") == 0)
+    {
+      gtk_widget_set_events (widget, GTK_VALUE_FLAGS(*arg));
+    }
+  else if (strcmp (arg->name, "extension_events") == 0)
+    {
+      gtk_widget_set_extension_events (widget, GTK_VALUE_FLAGS(*arg));
+    }
+  else if (strcmp (arg->name, "name") == 0)
+    {
+      gtk_widget_set_name (widget, GTK_VALUE_STRING(*arg));
+    }
+  else if (strcmp (arg->name, "style") == 0)
+    {
+      gtk_widget_set_style (widget, (GtkStyle*)GTK_VALUE_BOXED(*arg));
+    }
+  else if (strcmp (arg->name, "parent") == 0)
+    {
+      gtk_container_add (GTK_CONTAINER (GTK_VALUE_OBJECT(*arg)), widget);
+    }
+}
+
+/*****************************************
+ * gtk_widget_init:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static void
+gtk_widget_init (GtkWidget *widget)
+{
+  GdkColormap *colormap;
+  GdkVisual *visual;
+
+  GTK_OBJECT_FLAGS (widget) = GTK_SENSITIVE | GTK_PARENT_SENSITIVE;
+  widget->state = GTK_STATE_NORMAL;
+  widget->saved_state = GTK_STATE_NORMAL;
+  widget->name = NULL;
+  widget->requisition.width = 0;
+  widget->requisition.height = 0;
+  widget->allocation.x = -1;
+  widget->allocation.y = -1;
+  widget->allocation.width = 1;
+  widget->allocation.height = 1;
+  widget->window = NULL;
+  widget->parent = NULL;
+
+  widget->style = gtk_widget_peek_style ();
+  gtk_style_ref (widget->style);
+
+  colormap = gtk_widget_peek_colormap ();
+  visual = gtk_widget_peek_visual ();
+
+  if (colormap != gtk_widget_get_default_colormap ())
+    gtk_object_set_data (GTK_OBJECT (widget), colormap_key, colormap);
+
+  if (visual != gtk_widget_get_default_visual ())
+    gtk_object_set_data (GTK_OBJECT (widget), visual_key, visual);
+}
+
+/*****************************************
+ * gtk_widget_new:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+GtkWidget*
+gtk_widget_new (guint type,
+               ...)
+{
+  GtkObject *obj;
+  GtkArg *args;
+  gint nargs;
+  va_list args1;
+  va_list args2;
+
+  g_return_val_if_fail (gtk_type_is_a (type, gtk_widget_get_type ()), NULL);
+
+  obj = gtk_type_new (type);
+
+  va_start (args1, type);
+  va_start (args2, type);
+
+  args = gtk_object_collect_args (&nargs, args1, args2);
+  gtk_object_setv (obj, nargs, args);
+  g_free (args);
+
+  va_end (args1);
+  va_end (args2);
+
+  return GTK_WIDGET (obj);
+}
+
+/*****************************************
+ * gtk_widget_newv:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+GtkWidget*
+gtk_widget_newv (guint   type,
+                gint    nargs,
+                GtkArg *args)
+{
+  g_return_val_if_fail (gtk_type_is_a (type, gtk_widget_get_type ()), NULL);
+
+  return GTK_WIDGET (gtk_object_newv (type, nargs, args));
+}
+
+/*****************************************
+ * gtk_widget_set:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_set (GtkWidget *widget,
+               ...)
+{
+  GtkArg *args;
+  gint nargs;
+  va_list args1;
+  va_list args2;
+
+  g_return_if_fail (widget != NULL);
+
+  va_start (args1, widget);
+  va_start (args2, widget);
+
+  args = gtk_object_collect_args (&nargs, args1, args2);
+  gtk_object_setv (GTK_OBJECT (widget), nargs, args);
+  g_free (args);
+
+  va_end (args1);
+  va_end (args2);
+}
+
+/*****************************************
+ * gtk_widget_setv:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_setv (GtkWidget *widget,
+                gint       nargs,
+                GtkArg    *args)
+{
+  gtk_object_setv (GTK_OBJECT (widget), nargs, args);
+}
+
+/*****************************************
+ * gtk_widget_destroy:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_destroy (GtkWidget *widget)
+{
+  GSList *resize_widgets;
+  GSList *tmp_list;
+  gint tag;
+  
+  g_return_if_fail (widget != NULL);
+
+  if (GTK_WIDGET_REDRAW_PENDING (widget))
+    {
+      GTK_WIDGET_UNSET_FLAGS (widget, GTK_REDRAW_PENDING);
+      gtk_object_unref (GTK_OBJECT (widget));
+      tag = (gint) gtk_object_get_data (GTK_OBJECT (widget), redraw_handler_key);
+      gtk_idle_remove (tag);
+      gtk_object_set_data (GTK_OBJECT (widget), redraw_handler_key, (gpointer) 0);
+    }
+  
+  if (GTK_WIDGET_ANCHORED (widget) &&
+      GTK_WIDGET_RESIZE_PENDING (widget))
+    {
+      GTK_WIDGET_UNSET_FLAGS (widget, GTK_RESIZE_PENDING);
+      gtk_object_unref (GTK_OBJECT (widget));
+      tag = (gint) gtk_object_get_data (GTK_OBJECT (widget), resize_handler_key);
+      gtk_idle_remove (tag);
+      gtk_object_set_data (GTK_OBJECT (widget), resize_handler_key, (gpointer) 0);
+
+      resize_widgets = gtk_object_get_data (GTK_OBJECT (widget), resize_widgets_key);
+
+      tmp_list = resize_widgets;
+      while (tmp_list)
+        {
+          GtkWidget *child;
+          
+          child = tmp_list->data;
+          tmp_list = tmp_list->next;
+          
+          /* referencing needed? */
+          GTK_WIDGET_UNSET_FLAGS (child, GTK_RESIZE_NEEDED);
+          gtk_object_unref (GTK_OBJECT (child));
+        }
+      
+      if (resize_widgets)
+        {
+          gtk_object_set_data (GTK_OBJECT (widget), resize_widgets_key, NULL);
+          g_slist_free (resize_widgets);
+        }
+    }
+  
+  if (GTK_WIDGET_RESIZE_NEEDED (widget))
+    {
+      GtkWidget *toplevel;
+
+      toplevel = gtk_widget_get_toplevel (widget);
+      resize_widgets = gtk_object_get_data (GTK_OBJECT (toplevel), resize_widgets_key);
+
+      if (resize_widgets)
+        {
+          resize_widgets = g_slist_remove (resize_widgets, widget);
+          GTK_WIDGET_UNSET_FLAGS (widget, GTK_RESIZE_NEEDED);
+          gtk_object_unref (GTK_OBJECT (widget));
+
+          gtk_object_set_data (GTK_OBJECT (toplevel), resize_widgets_key, resize_widgets);
+        }
+    }
+
+
+  if (widget->parent)
+    {
+      if (!GTK_OBJECT_BEING_DESTROYED (widget->parent))
+       gtk_container_remove (GTK_CONTAINER (widget->parent), widget);
+      else
+       gtk_object_unref (GTK_OBJECT (widget));
+    }
+  gtk_object_destroy (GTK_OBJECT (widget));
+}
+
+/*****************************************
+ * gtk_widget_unparent: do any cleanup necessary necessary before
+ *                      setting parent = NULL. In particular, remove
+ *                      the focus properly.
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_unparent (GtkWidget *widget)
+{
+  GtkWidget *toplevel;
+  GtkWidget *child;
+
+  g_return_if_fail (widget != NULL);
+
+  toplevel = gtk_widget_get_toplevel (widget);
+  if (GTK_IS_WINDOW (toplevel))
+    {
+      child = GTK_WINDOW (toplevel)->focus_widget;
+
+      while (child && child != widget)
+       child = child->parent;
+
+      if (child == widget)
+       gtk_window_set_focus (GTK_WINDOW (toplevel), NULL);
+    }
+
+  if (widget->window &&
+      GTK_WIDGET_NO_WINDOW (widget) &&
+      GTK_WIDGET_DRAWABLE (widget))
+    gdk_window_clear_area (widget->window,
+                          widget->allocation.x,
+                          widget->allocation.y,
+                          widget->allocation.width,
+                          widget->allocation.height);
+
+  widget->parent = NULL;
+
+  gtk_object_unref (GTK_OBJECT (widget));
+}
+
+/*****************************************
+ * gtk_widget_show:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_show (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+
+  if (!GTK_WIDGET_VISIBLE (widget))
+    gtk_signal_emit (GTK_OBJECT (widget), widget_signals[SHOW]);
+}
+
+/*****************************************
+ * gtk_widget_hide:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_hide (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+
+  if (GTK_WIDGET_VISIBLE (widget))
+    gtk_signal_emit (GTK_OBJECT (widget), widget_signals[HIDE]);
+}
+
+/*****************************************
+ * gtk_widget_map:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_map (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+
+  if (!GTK_WIDGET_MAPPED (widget))
+    {
+      if (!GTK_WIDGET_REALIZED (widget))
+       gtk_widget_realize (widget);
+
+      gtk_signal_emit (GTK_OBJECT (widget), widget_signals[MAP]);
+    }
+}
+
+/*****************************************
+ * gtk_widget_unmap:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_unmap (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+
+  if (GTK_WIDGET_MAPPED (widget))
+    gtk_signal_emit (GTK_OBJECT (widget), widget_signals[UNMAP]);
+}
+
+/*****************************************
+ * gtk_widget_realize:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_realize (GtkWidget *widget)
+{
+  GtkStyle *new_style;
+  gint events;
+  GdkExtensionMode mode;
+  GtkWidgetShapeInfo *shape_info;
+
+  g_return_if_fail (widget != NULL);
+
+  if (!GTK_WIDGET_REALIZED (widget))
+    {
+      /*
+      if (GTK_IS_CONTAINER (widget) && !GTK_WIDGET_NO_WINDOW (widget))
+       g_print ("%s\n", gtk_type_name (GTK_WIDGET_TYPE (widget)));
+       */
+
+      if (widget->parent && !GTK_WIDGET_REALIZED (widget->parent))
+       gtk_widget_realize (widget->parent);
+      
+      if (!GTK_WIDGET_USER_STYLE (widget))
+       {
+         new_style = gtk_rc_get_style (widget);
+         if (new_style != widget->style)
+           gtk_widget_set_style_internal (widget, new_style);
+       }
+
+      gtk_signal_emit (GTK_OBJECT (widget), widget_signals[REALIZE]);
+
+      if (GTK_WIDGET_HAS_SHAPE_MASK(widget))
+       {
+         shape_info = gtk_object_get_data (GTK_OBJECT (widget),
+                                           shape_info_key);
+         g_assert (shape_info != 0);
+         gdk_window_shape_combine_mask (widget->window,
+                                        shape_info->shape_mask,
+                                        shape_info->offset_x,
+                                        shape_info->offset_y);
+       }
+
+      if (!GTK_WIDGET_NO_WINDOW (widget))
+       {
+         mode = gtk_widget_get_extension_events (widget);
+         if (mode != GDK_EXTENSION_EVENTS_NONE)
+           {
+             events = gtk_widget_get_events (widget);
+             gdk_input_set_extension_events (widget->window, events, mode);
+           }
+       }
+      
+    }
+}
+
+/*****************************************
+ * gtk_widget_unrealize:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_unrealize (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+
+  if (GTK_WIDGET_REALIZED (widget))
+    gtk_signal_emit (GTK_OBJECT (widget), widget_signals[UNREALIZE]);
+}
+
+/*****************************************
+ * gtk_widget_queue_draw:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_queue_draw (GtkWidget *widget)
+{
+  GtkWidget *parent;
+  gint tag;
+
+  g_return_if_fail (widget != NULL);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      /* We queue the redraw if:
+       *  a) the widget is not already queued for redraw and
+       *  b) non of the widgets ancestors are queued for redraw.
+       */
+      parent = widget;
+      while (parent)
+       {
+         if (GTK_WIDGET_REDRAW_PENDING (parent))
+           return;
+         parent = parent->parent;
+       }
+
+      GTK_WIDGET_SET_FLAGS (widget, GTK_REDRAW_PENDING);
+      gtk_object_ref (GTK_OBJECT (widget));
+      tag = gtk_idle_add ((GtkFunction) gtk_real_widget_queue_draw, widget);
+      gtk_object_set_data (GTK_OBJECT (widget), redraw_handler_key, (gpointer) tag);
+    }
+}
+
+/*****************************************
+ * gtk_widget_queue_resize:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_queue_resize (GtkWidget *widget)
+{
+  GtkWidget *toplevel;
+  GSList *resize_widgets;
+  gint tag;
+
+  g_return_if_fail (widget != NULL);
+
+  toplevel = gtk_widget_get_toplevel (widget);
+  if (GTK_WIDGET_ANCHORED (toplevel))
+    {
+      if (GTK_WIDGET_VISIBLE (toplevel))
+       {
+         if (!GTK_WIDGET_RESIZE_PENDING (toplevel))
+           {
+             GTK_WIDGET_SET_FLAGS (toplevel, GTK_RESIZE_PENDING);
+             gtk_object_ref (GTK_OBJECT (toplevel));
+             tag = gtk_idle_add ((GtkFunction) gtk_real_widget_queue_resize, toplevel);
+             gtk_object_set_data (GTK_OBJECT (toplevel), resize_handler_key, (gpointer) tag);
+           }
+
+         resize_widgets = gtk_object_get_data (GTK_OBJECT (toplevel), resize_widgets_key);
+         if (g_slist_find (resize_widgets, widget) == NULL)
+           {
+             /* referencing needed? */
+             GTK_WIDGET_SET_FLAGS (widget, GTK_RESIZE_NEEDED);
+             gtk_object_ref (GTK_OBJECT (widget));
+             resize_widgets = g_slist_prepend (resize_widgets, widget);
+             
+             gtk_object_set_data (GTK_OBJECT (toplevel), resize_widgets_key, resize_widgets);
+           }
+       }
+      else
+       {
+         gtk_container_need_resize (GTK_CONTAINER (toplevel));
+       }
+    }
+}
+
+/*****************************************
+ * gtk_widget_draw:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_draw (GtkWidget    *widget,
+                GdkRectangle *area)
+{
+  GdkRectangle temp_area;
+
+  g_return_if_fail (widget != NULL);
+
+  if (GTK_WIDGET_DRAWABLE (widget) &&
+      !GTK_WIDGET_REDRAW_PENDING (widget))
+    {
+      if (!area)
+       {
+         if (GTK_WIDGET_NO_WINDOW (widget))
+           {
+             temp_area.x = widget->allocation.x;
+             temp_area.y = widget->allocation.y;
+           }
+         else
+           {
+             temp_area.x = 0;
+             temp_area.y = 0;
+           }
+
+         temp_area.width = widget->allocation.width;
+         temp_area.height = widget->allocation.height;
+         area = &temp_area;
+       }
+
+      gtk_signal_emit (GTK_OBJECT (widget), widget_signals[DRAW], area);
+    }
+}
+
+/*****************************************
+ * gtk_widget_draw_focus:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_draw_focus (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+
+  gtk_signal_emit (GTK_OBJECT (widget), widget_signals[DRAW_FOCUS]);
+}
+
+/*****************************************
+ * gtk_widget_draw_default:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_draw_default (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+
+  gtk_signal_emit (GTK_OBJECT (widget), widget_signals[DRAW_DEFAULT]);
+}
+
+/*****************************************
+ * gtk_widget_draw_children:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_draw_children (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+
+  if (GTK_IS_CONTAINER (widget))
+    gtk_container_foreach (GTK_CONTAINER (widget),
+                          gtk_widget_draw_children_recurse,
+                          NULL);
+}
+
+/*****************************************
+ * gtk_widget_size_request:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_size_request (GtkWidget      *widget,
+                        GtkRequisition *requisition)
+{
+  GtkWidgetAuxInfo *aux_info;
+
+  g_return_if_fail (widget != NULL);
+
+  if (gtk_signal_emit (GTK_OBJECT (widget), widget_signals[SIZE_REQUEST], requisition))
+    {
+      aux_info = gtk_object_get_data (GTK_OBJECT (widget), aux_info_key);
+      if (aux_info)
+       {
+         if (aux_info->width > 0)
+           requisition->width = aux_info->width;
+         if (aux_info->height > 0)
+           requisition->height = aux_info->height;
+       }
+    }
+}
+
+/*****************************************
+ * gtk_widget_size_allocate:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_size_allocate (GtkWidget     *widget,
+                         GtkAllocation *allocation)
+{
+  GtkWidgetAuxInfo *aux_info;
+  GtkAllocation real_allocation;
+
+  g_return_if_fail (widget != NULL);
+
+  real_allocation = *allocation;
+  aux_info = gtk_object_get_data (GTK_OBJECT (widget), aux_info_key);
+
+  if (aux_info)
+    {
+      if (aux_info->x != -1)
+       real_allocation.x = aux_info->x;
+      if (aux_info->y != -1)
+       real_allocation.y = aux_info->y;
+    }
+
+  gtk_signal_emit (GTK_OBJECT (widget), widget_signals[SIZE_ALLOCATE], &real_allocation);
+}
+
+/*****************************************
+ * gtk_widget_install_accelerator:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_install_accelerator (GtkWidget           *widget,
+                               GtkAcceleratorTable *table,
+                               const gchar         *signal_name,
+                               gchar                key,
+                               guint8               modifiers)
+{
+  gint return_val;
+
+  g_return_if_fail (widget != NULL);
+
+  return_val = TRUE;
+  if (gtk_signal_emit (GTK_OBJECT (widget), widget_signals[INSTALL_ACCELERATOR],
+                      signal_name, key, modifiers, &return_val) && return_val)
+    gtk_accelerator_table_install (table, GTK_OBJECT (widget), signal_name, key, modifiers);
+}
+
+/*****************************************
+ * gtk_widget_remove_accelerator:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_remove_accelerator (GtkWidget           *widget,
+                              GtkAcceleratorTable *table,
+                              const gchar         *signal_name)
+{
+  g_return_if_fail (widget != NULL);
+
+  if (gtk_signal_emit (GTK_OBJECT (widget), widget_signals[REMOVE_ACCELERATOR], signal_name))
+    gtk_accelerator_table_remove (table, GTK_OBJECT (widget), signal_name);
+}
+
+/*****************************************
+ * gtk_widget_event:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+gint
+gtk_widget_event (GtkWidget *widget,
+                 GdkEvent  *event)
+{
+  gint return_val;
+  gint signal_num;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+
+  return_val = FALSE;
+  if (gtk_signal_emit (GTK_OBJECT (widget), widget_signals[EVENT], event, &return_val))
+    {
+      if (return_val)
+       return TRUE;
+
+      switch (event->type)
+       {
+       case GDK_NOTHING:
+         signal_num = -1;
+         break;
+       case GDK_BUTTON_PRESS:
+       case GDK_2BUTTON_PRESS:
+       case GDK_3BUTTON_PRESS:
+         signal_num = BUTTON_PRESS_EVENT;
+         break;
+       case GDK_BUTTON_RELEASE:
+         signal_num = BUTTON_RELEASE_EVENT;
+         break;
+       case GDK_MOTION_NOTIFY:
+         signal_num = MOTION_NOTIFY_EVENT;
+         break;
+       case GDK_DELETE:
+         signal_num = DELETE_EVENT;
+         break;
+       case GDK_DESTROY:
+         signal_num = DESTROY_EVENT;
+         break;
+       case GDK_EXPOSE:
+         signal_num = EXPOSE_EVENT;
+         break;
+       case GDK_KEY_PRESS:
+         signal_num = KEY_PRESS_EVENT;
+         break;
+       case GDK_KEY_RELEASE:
+         signal_num = KEY_RELEASE_EVENT;
+         break;
+       case GDK_ENTER_NOTIFY:
+         signal_num = ENTER_NOTIFY_EVENT;
+         break;
+       case GDK_LEAVE_NOTIFY:
+         signal_num = LEAVE_NOTIFY_EVENT;
+         break;
+       case GDK_FOCUS_CHANGE:
+         if (event->focus_change.in)
+           signal_num = FOCUS_IN_EVENT;
+         else
+           signal_num = FOCUS_OUT_EVENT;
+         break;
+       case GDK_CONFIGURE:
+         signal_num = CONFIGURE_EVENT;
+         break;
+       case GDK_MAP:
+         signal_num = MAP_EVENT;
+         break;
+       case GDK_UNMAP:
+         signal_num = UNMAP_EVENT;
+         break;
+       case GDK_PROPERTY_NOTIFY:
+         signal_num = PROPERTY_NOTIFY_EVENT;
+         break;
+       case GDK_SELECTION_CLEAR:
+         signal_num = SELECTION_CLEAR_EVENT;
+         break;
+       case GDK_SELECTION_REQUEST:
+         signal_num = SELECTION_REQUEST_EVENT;
+         break;
+       case GDK_SELECTION_NOTIFY:
+         signal_num = SELECTION_NOTIFY_EVENT;
+         break;
+       case GDK_PROXIMITY_IN:
+         signal_num = PROXIMITY_IN_EVENT;
+         break;
+       case GDK_PROXIMITY_OUT:
+         signal_num = PROXIMITY_OUT_EVENT;
+         break;
+       case GDK_DRAG_BEGIN:
+         signal_num = DRAG_BEGIN_EVENT;
+         break;
+       case GDK_DRAG_REQUEST:
+         signal_num = DRAG_REQUEST_EVENT;
+         break;
+       case GDK_DROP_ENTER:
+         signal_num = DROP_ENTER_EVENT;
+         break;
+       case GDK_DROP_LEAVE:
+         signal_num = DROP_LEAVE_EVENT;
+         break;
+       case GDK_DROP_DATA_AVAIL:
+         signal_num = DROP_DATA_AVAILABLE_EVENT;
+         break;
+       case GDK_OTHER_EVENT:
+         signal_num = OTHER_EVENT;
+         break;
+       default:
+         g_warning ("could not determine signal number for event: %d", event->type);
+         return return_val;
+       }
+
+      if (signal_num != -1)
+       gtk_signal_emit (GTK_OBJECT (widget), widget_signals[signal_num], event, &return_val);
+    }
+
+  return return_val;
+}
+
+/*****************************************
+ * gtk_widget_activate:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_activate (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+
+  if (WIDGET_CLASS (widget)->activate_signal)
+    gtk_signal_emit (GTK_OBJECT (widget), WIDGET_CLASS (widget)->activate_signal);
+}
+
+/*****************************************
+ * gtk_widget_reparent:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_reparent (GtkWidget *widget,
+                    GtkWidget *new_parent)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (new_parent != NULL);
+  g_return_if_fail (GTK_IS_CONTAINER (new_parent));
+
+  if (widget->parent != new_parent)
+    {
+      gtk_container_remove (GTK_CONTAINER (widget->parent), widget);
+      gtk_container_add (GTK_CONTAINER (new_parent), widget);
+
+      if (GTK_WIDGET_REALIZED (widget))
+       {
+         if (GTK_WIDGET_REALIZED (new_parent) && !GTK_WIDGET_NO_WINDOW (widget))
+           {
+             gdk_window_reparent (widget->window, widget->parent->window, 0, 0);
+           }
+         else
+           {
+             GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED | GTK_MAPPED);
+             if (!GTK_WIDGET_NO_WINDOW (widget))
+               gdk_window_destroy (widget->window);
+             widget->window = NULL;
+
+             if (GTK_WIDGET_REALIZED (new_parent))
+               gtk_widget_realize (widget);
+             if (GTK_WIDGET_MAPPED (new_parent))
+               gtk_widget_map (widget);
+           }
+       }
+
+      if (!GTK_WIDGET_REALIZED (widget) && GTK_WIDGET_REALIZED (new_parent))
+       gtk_widget_realize (widget);
+      if (!GTK_WIDGET_MAPPED (widget) && GTK_WIDGET_MAPPED (new_parent))
+       gtk_widget_map (widget);
+
+      gtk_widget_queue_resize (widget);
+    }
+}
+
+/*****************************************
+ * gtk_widget_popup:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_popup (GtkWidget *widget,
+                 gint       x,
+                 gint       y)
+{
+  g_return_if_fail (widget != NULL);
+
+  if (!GTK_WIDGET_VISIBLE (widget))
+    {
+      if (!GTK_WIDGET_REALIZED (widget))
+       gtk_widget_realize (widget);
+      if (!GTK_WIDGET_NO_WINDOW (widget))
+       gdk_window_move (widget->window, x, y);
+      gtk_widget_show (widget);
+    }
+}
+
+/*****************************************
+ * gtk_widget_intersect:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+gint
+gtk_widget_intersect (GtkWidget    *widget,
+                     GdkRectangle *area,
+                     GdkRectangle *intersection)
+{
+  GdkRectangle *dest;
+  GdkRectangle tmp;
+  gint return_val;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (area != NULL, FALSE);
+
+  if (intersection)
+    dest = intersection;
+  else
+    dest = &tmp;
+
+  return_val = gdk_rectangle_intersect ((GdkRectangle*) &widget->allocation, area, dest);
+
+  if (return_val && intersection && !GTK_WIDGET_NO_WINDOW (widget))
+    {
+      intersection->x -= widget->allocation.x;
+      intersection->y -= widget->allocation.y;
+    }
+
+  return return_val;
+}
+
+
+gint
+gtk_widget_basic (GtkWidget *widget)
+{
+  GList *children;
+  GList *tmp_list;
+  gint return_val;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+
+  if (!GTK_WIDGET_BASIC (widget))
+    return FALSE;
+  else if (GTK_IS_CONTAINER (widget))
+    {
+      children = gtk_container_children (GTK_CONTAINER (widget));
+      if (children)
+       {
+         return_val = TRUE;
+         tmp_list = children;
+
+         while (tmp_list)
+           {
+             if (!gtk_widget_basic (GTK_WIDGET (tmp_list->data)))
+               {
+                 return_val = FALSE;
+                 break;
+               }
+
+             tmp_list = tmp_list->next;
+           }
+
+         g_list_free (children);
+         return return_val;
+       }
+    }
+
+  return TRUE;
+}
+
+
+/*****************************************
+ * gtk_widget_grab_focus:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_grab_focus (GtkWidget *widget)
+{
+  GtkWidget *window;
+  GtkWidget *child;
+  gint window_type;
+
+  g_return_if_fail (widget != NULL);
+
+  window_type = gtk_window_get_type ();
+  window = widget->parent;
+  child = widget;
+
+  while (window && !gtk_type_is_a (GTK_WIDGET_TYPE (window), window_type))
+    {
+      GTK_CONTAINER (window)->focus_child = child;
+      child = window;
+      window = window->parent;
+    }
+
+  if (window && gtk_type_is_a (GTK_WIDGET_TYPE (window), window_type))
+    {
+      GTK_CONTAINER (window)->focus_child = child;
+      gtk_window_set_focus (GTK_WINDOW (window), widget);
+    }
+}
+
+/*****************************************
+ * gtk_widget_grab_default:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_grab_default (GtkWidget *widget)
+{
+  GtkWidget *window;
+  gint window_type;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (widget));
+
+  window_type = gtk_window_get_type ();
+  window = widget->parent;
+
+  while (window && !gtk_type_is_a (GTK_WIDGET_TYPE (window), window_type))
+    window = window->parent;
+
+  if (window && gtk_type_is_a (GTK_WIDGET_TYPE (window), window_type))
+    gtk_window_set_default (GTK_WINDOW (window), widget);
+}
+
+/*****************************************
+ * gtk_widget_restore_state:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_restore_state (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+
+  widget->state = widget->saved_state;
+  if (gtk_signal_emit (GTK_OBJECT (widget), widget_signals[STATE_CHANGED]))
+    {
+      if (GTK_IS_CONTAINER (widget))
+       gtk_container_foreach (GTK_CONTAINER (widget),
+                              gtk_widget_propagate_restore,
+                              NULL);
+    }
+}
+
+/*****************************************
+ * gtk_widget_set_name:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_set_name (GtkWidget   *widget,
+                    const gchar *name)
+{
+  GtkStyle *new_style;
+
+  g_return_if_fail (widget != NULL);
+
+  if (widget->name)
+    g_free (widget->name);
+  widget->name = g_strdup (name);
+
+  if (!GTK_WIDGET_USER_STYLE (widget))
+    {
+      new_style = gtk_rc_get_style (widget);
+      gtk_widget_set_style_internal (widget, new_style);
+    }
+}
+
+/*****************************************
+ * gtk_widget_get_name:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+gchar*
+gtk_widget_get_name (GtkWidget *widget)
+{
+  g_return_val_if_fail (widget != NULL, NULL);
+
+  if (widget->name)
+    return widget->name;
+  return gtk_type_name (GTK_WIDGET_TYPE (widget));
+}
+
+/*****************************************
+ * gtk_widget_set_state:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_set_state (GtkWidget    *widget,
+                     GtkStateType  state)
+{
+  g_return_if_fail (widget != NULL);
+
+  if (widget->state != state)
+    {
+      widget->saved_state = widget->state;
+      widget->state = state;
+
+      if (!gtk_signal_emit (GTK_OBJECT (widget), widget_signals[STATE_CHANGED]))
+       return;
+    }
+
+  if (GTK_IS_CONTAINER (widget))
+    gtk_container_foreach (GTK_CONTAINER (widget),
+                          gtk_widget_propagate_state,
+                          (gpointer) &state);
+}
+
+/*****************************************
+ * gtk_widget_set_sensitive:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_set_sensitive (GtkWidget *widget,
+                         gint       sensitive)
+{
+  GtkWidget *window;
+  gint old_val;
+
+  g_return_if_fail (widget != NULL);
+
+  old_val = GTK_WIDGET_IS_SENSITIVE (widget);
+
+  if (sensitive)
+    {
+      GTK_WIDGET_SET_FLAGS (widget, GTK_SENSITIVE);
+    }
+  else
+    {
+      GTK_WIDGET_UNSET_FLAGS (widget, GTK_SENSITIVE);
+
+      if (GTK_WIDGET_HAS_FOCUS (widget))
+       {
+         window = gtk_widget_get_ancestor (widget, gtk_window_get_type ());
+         if (window)
+           gtk_window_set_focus (GTK_WINDOW (window), NULL);
+       }
+    }
+
+  if (GTK_IS_CONTAINER (widget))
+    gtk_container_foreach (GTK_CONTAINER (widget),
+                          gtk_widget_set_parent_sensitive,
+                          &sensitive);
+
+  if (old_val != GTK_WIDGET_IS_SENSITIVE (widget))
+    gtk_widget_queue_draw (widget);
+}
+
+/*****************************************
+ * gtk_widget_set_parent:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_set_parent (GtkWidget *widget,
+                      GtkWidget *parent)
+{
+  GtkStyle *style;
+  gint sensitive;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (parent != NULL);
+
+  gtk_object_ref (GTK_OBJECT (widget));
+
+  widget->parent = parent;
+
+  sensitive = GTK_WIDGET_IS_SENSITIVE (parent);
+  gtk_widget_set_parent_sensitive (widget, &sensitive);
+
+  if ((widget->parent->state != GTK_STATE_NORMAL) &&
+      (widget->parent->state != widget->state))
+    gtk_widget_set_state (widget, widget->parent->state);
+
+  while (parent->parent != NULL)
+    parent = parent->parent;
+
+  if (GTK_WIDGET_ANCHORED (parent))
+    {
+      if (!GTK_WIDGET_USER_STYLE (widget))
+       {
+         style = gtk_rc_get_style (widget);
+         if (style != widget->style)
+           gtk_widget_set_style_internal (widget, style);
+       }
+
+      if (GTK_IS_CONTAINER (widget))
+       gtk_container_foreach (GTK_CONTAINER (widget),
+                              gtk_widget_set_style_recurse,
+                              NULL);
+    }
+}
+
+/*****************************************
+ * gtk_widget_set_style:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_set_style (GtkWidget *widget,
+                     GtkStyle  *style)
+{
+  g_return_if_fail (widget != NULL);
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_USER_STYLE);
+  gtk_widget_set_style_internal (widget, style);
+}
+
+/*****************************************
+ * gtk_widget_set_uposition:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_set_uposition (GtkWidget *widget,
+                         gint       x,
+                         gint       y)
+{
+  GtkWidgetAuxInfo *aux_info;
+
+  g_return_if_fail (widget != NULL);
+
+  aux_info = gtk_object_get_data (GTK_OBJECT (widget), aux_info_key);
+  if (!aux_info)
+    {
+      aux_info = gtk_widget_aux_info_new ();
+      gtk_object_set_data (GTK_OBJECT (widget), aux_info_key, aux_info);
+    }
+
+  if (x > -2)
+    aux_info->x = x;
+  if (y > -2)
+    aux_info->y = y;
+
+  if (GTK_WIDGET_REALIZED (widget) && GTK_IS_WINDOW (widget) &&
+      (aux_info->x != -1) && (aux_info->y != -1))
+    {
+      gdk_window_set_hints (widget->window, aux_info->x, aux_info->y, 0, 0, 0, 0, GDK_HINT_POS);
+      gdk_window_move (widget->window, aux_info->x, aux_info->y);
+    }
+
+  if (GTK_WIDGET_VISIBLE (widget) && widget->parent)
+    gtk_widget_size_allocate (widget, &widget->allocation);
+}
+
+/*****************************************
+ * gtk_widget_set_usize:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_set_usize (GtkWidget *widget,
+                     gint       width,
+                     gint       height)
+{
+  GtkWidgetAuxInfo *aux_info;
+
+  g_return_if_fail (widget != NULL);
+
+  aux_info = gtk_object_get_data (GTK_OBJECT (widget), aux_info_key);
+  if (!aux_info)
+    {
+      aux_info = gtk_widget_aux_info_new ();
+      gtk_object_set_data (GTK_OBJECT (widget), aux_info_key, aux_info);
+    }
+
+  if (width > -1)
+    aux_info->width = width;
+  if (height > -1)
+    aux_info->height = height;
+
+  if (GTK_WIDGET_VISIBLE (widget))
+    gtk_widget_queue_resize (widget);
+}
+
+/*****************************************
+ * gtk_widget_set_events:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_set_events (GtkWidget *widget,
+                      gint       events)
+{
+  gint *eventp;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (!GTK_WIDGET_NO_WINDOW (widget));
+  g_return_if_fail (!GTK_WIDGET_REALIZED (widget));
+
+  eventp = gtk_object_get_data (GTK_OBJECT (widget), event_key);
+
+  if (events)
+    {
+      if (!eventp)
+       eventp = g_new (gint, 1);
+
+      *eventp = events;
+      gtk_object_set_data (GTK_OBJECT (widget), event_key, eventp);
+    }
+  else
+    {
+      if (eventp)
+       g_free (eventp);
+
+      gtk_object_remove_data (GTK_OBJECT (widget), event_key);
+    }
+}
+
+/*****************************************
+ * gtk_widget_set_extension_events:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_set_extension_events (GtkWidget *widget,
+                                GdkExtensionMode mode)
+{
+  GdkExtensionMode *modep;
+
+  g_return_if_fail (widget != NULL);
+
+  modep = gtk_object_get_data (GTK_OBJECT (widget), extension_event_key);
+
+  if (!modep)
+    modep = g_new (GdkExtensionMode, 1);
+
+  *modep = mode;
+  gtk_object_set_data (GTK_OBJECT (widget), extension_event_key, modep);
+}
+
+
+/*****************************************
+ * gtk_widget_get_toplevel:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+GtkWidget*
+gtk_widget_get_toplevel (GtkWidget *widget)
+{
+  g_return_val_if_fail (widget != NULL, NULL);
+
+  while (widget->parent)
+    widget = widget->parent;
+
+  return widget;
+}
+
+/*****************************************
+ * gtk_widget_get_ancestor:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+GtkWidget*
+gtk_widget_get_ancestor (GtkWidget *widget,
+                        gint       type)
+{
+  g_return_val_if_fail (widget != NULL, NULL);
+
+  while (widget && !gtk_type_is_a (GTK_WIDGET_TYPE (widget), type))
+    widget = widget->parent;
+
+  if (!(widget && gtk_type_is_a (GTK_WIDGET_TYPE (widget), type)))
+    return NULL;
+
+  return widget;
+}
+
+/*****************************************
+ * gtk_widget_get_colormap:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+GdkColormap*
+gtk_widget_get_colormap (GtkWidget *widget)
+{
+  GdkColormap *colormap;
+
+  g_return_val_if_fail (widget != NULL, NULL);
+
+  if (!widget->window)
+    {
+      colormap = gtk_object_get_data (GTK_OBJECT (widget), colormap_key);
+      if (colormap)
+       return colormap;
+      return gtk_widget_get_default_colormap ();
+    }
+
+  return gdk_window_get_colormap (widget->window);
+}
+
+/*****************************************
+ * gtk_widget_get_visual:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+GdkVisual*
+gtk_widget_get_visual (GtkWidget *widget)
+{
+  GdkVisual *visual;
+
+  g_return_val_if_fail (widget != NULL, NULL);
+
+  if (!widget->window)
+    {
+      visual = gtk_object_get_data (GTK_OBJECT (widget), visual_key);
+      if (visual)
+       return visual;
+      return gtk_widget_get_default_visual ();
+    }
+
+  return gdk_window_get_visual (widget->window);
+}
+
+/*****************************************
+ * gtk_widget_get_style:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+GtkStyle*
+gtk_widget_get_style (GtkWidget *widget)
+{
+  g_return_val_if_fail (widget != NULL, NULL);
+
+  return widget->style;
+}
+
+/*****************************************
+ * gtk_widget_get_events:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+gint
+gtk_widget_get_events (GtkWidget *widget)
+{
+  gint *events;
+
+  g_return_val_if_fail (widget != NULL, 0);
+
+  events = gtk_object_get_data (GTK_OBJECT (widget), event_key);
+  if (events)
+    return *events;
+
+  return 0;
+}
+
+/*****************************************
+ * gtk_widget_get_extension_events:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+GdkExtensionMode
+gtk_widget_get_extension_events (GtkWidget *widget)
+{
+  GdkExtensionMode *mode;
+
+  g_return_val_if_fail (widget != NULL, 0);
+
+  mode = gtk_object_get_data (GTK_OBJECT (widget), extension_event_key);
+  if (mode)
+    return *mode;
+
+  return 0;
+}
+
+/*****************************************
+ * gtk_widget_get_pointer:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_get_pointer (GtkWidget *widget,
+                       gint      *x,
+                       gint      *y)
+{
+  g_return_if_fail (widget != NULL);
+
+  if (x)
+    *x = -1;
+  if (y)
+    *y = -1;
+
+  if (GTK_WIDGET_REALIZED (widget))
+    {
+      gdk_window_get_pointer (widget->window, x, y, NULL);
+
+      if (GTK_WIDGET_NO_WINDOW (widget))
+       {
+         if (x)
+           *x -= widget->allocation.x;
+         if (y)
+           *y -= widget->allocation.y;
+       }
+    }
+}
+
+/*****************************************
+ * gtk_widget_is_ancestor:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+gint
+gtk_widget_is_ancestor (GtkWidget *widget,
+                       GtkWidget *ancestor)
+{
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (ancestor != NULL, FALSE);
+
+  while (widget)
+    {
+      if (widget->parent == ancestor)
+       return TRUE;
+      widget = widget->parent;
+    }
+
+  return FALSE;
+}
+
+/*****************************************
+ * gtk_widget_is_child:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+gint
+gtk_widget_is_child (GtkWidget *widget,
+                    GtkWidget *child)
+{
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (child != NULL, FALSE);
+
+  return (child->parent == widget);
+}
+
+/*****************************************
+ * gtk_widget_push_colormap:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_push_colormap (GdkColormap *cmap)
+{
+  colormap_stack = g_slist_prepend (colormap_stack, cmap);
+}
+
+/*****************************************
+ * gtk_widget_push_visual:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_push_visual (GdkVisual *visual)
+{
+  visual_stack = g_slist_prepend (visual_stack, visual);
+}
+
+/*****************************************
+ * gtk_widget_push_style:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_push_style (GtkStyle *style)
+{
+  gtk_style_ref (style);
+  style_stack = g_slist_prepend (style_stack, style);
+}
+
+/*****************************************
+ * gtk_widget_pop_colormap:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_pop_colormap ()
+{
+  GSList *tmp;
+
+  if (colormap_stack)
+    {
+      tmp = colormap_stack;
+      colormap_stack = colormap_stack->next;
+      g_slist_free_1 (tmp);
+    }
+}
+
+/*****************************************
+ * gtk_widget_pop_visual:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_pop_visual ()
+{
+  GSList *tmp;
+
+  if (visual_stack)
+    {
+      tmp = visual_stack;
+      visual_stack = visual_stack->next;
+      g_slist_free_1 (tmp);
+    }
+}
+
+/*****************************************
+ * gtk_widget_pop_style:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_pop_style ()
+{
+  GSList *tmp;
+
+  if (style_stack)
+    {
+      tmp = style_stack;
+      style_stack = style_stack->next;
+      gtk_style_unref ((GtkStyle*) tmp->data);
+      g_slist_free_1 (tmp);
+    }
+}
+
+/*****************************************
+ * gtk_widget_set_default_colormap:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_set_default_colormap (GdkColormap *colormap)
+{
+  if (default_colormap && (default_colormap != colormap))
+    gdk_colormap_destroy (default_colormap);
+  default_colormap = colormap;
+}
+
+/*****************************************
+ * gtk_widget_set_default_visual:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_set_default_visual (GdkVisual *visual)
+{
+  default_visual = visual;
+}
+
+/*****************************************
+ * gtk_widget_set_default_style:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+void
+gtk_widget_set_default_style (GtkStyle *style)
+{
+  if (default_style)
+    gtk_style_unref (default_style);
+
+  default_style = style;
+  gtk_style_ref (default_style);
+}
+
+/* Basically, send a message to all toplevel windows telling them
+   that a new _GTK_STYLE_COLORS property is available on the root
+   window */
+void
+gtk_widget_propagate_default_style(void)
+{
+  GdkEventClient sev;
+  int i;
+
+  /* Set the property on the root window */
+  gdk_property_change(GDK_ROOT_PARENT(),
+                     gdk_atom_intern("_GTK_DEFAULT_COLORS", FALSE),
+                     GDK_NONE, sizeof(gushort),
+                     GDK_PROP_MODE_REPLACE,
+                     gtk_widget_get_default_style(),
+                     GTK_STYLE_NUM_STYLECOLORS() * sizeof(GdkColor));
+
+  for(i = 0; i < 5; i++) sev.data.l[i] = 0;
+  sev.data_format = 32;
+  sev.message_type = gdk_atom_intern("_GTK_STYLE_CHANGED", FALSE);
+  gdk_event_send_clientmessage_toall(&sev);
+}
+
+/*****************************************
+ * gtk_widget_get_default_colormap:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+GdkColormap*
+gtk_widget_get_default_colormap ()
+{
+  if (!default_colormap)
+    default_colormap = gdk_colormap_get_system ();
+
+  return default_colormap;
+}
+
+/*****************************************
+ * gtk_widget_get_default_visual:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+GdkVisual*
+gtk_widget_get_default_visual ()
+{
+  if (!default_visual)
+    default_visual = gdk_visual_get_system ();
+
+  return default_visual;
+}
+
+/*****************************************
+ * gtk_widget_get_default_style:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+GtkStyle*
+gtk_widget_get_default_style ()
+{
+  if (!default_style)
+    {
+      default_style = gtk_style_new ();
+      gtk_style_ref (default_style);
+    }
+
+  return default_style;
+}
+
+
+/*****************************************
+ * gtk_widget_marshal_signal_1:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static void
+gtk_widget_marshal_signal_1 (GtkObject      *object,
+                            GtkSignalFunc   func,
+                            gpointer        func_data,
+                            GtkArg         *args)
+{
+  GtkWidgetSignal1 rfunc;
+
+  rfunc = (GtkWidgetSignal1) func;
+
+  (* rfunc) (object, GTK_VALUE_POINTER (args[0]), func_data);
+}
+
+/*****************************************
+ * gtk_widget_marshal_signal_2:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static void
+gtk_widget_marshal_signal_2 (GtkObject      *object,
+                            GtkSignalFunc   func,
+                            gpointer        func_data,
+                            GtkArg         *args)
+{
+  GtkWidgetSignal2 rfunc;
+  gint *return_val;
+
+  rfunc = (GtkWidgetSignal2) func;
+  return_val = GTK_RETLOC_BOOL (args[3]);
+
+  *return_val = (* rfunc) (object, GTK_VALUE_STRING (args[0]),
+                          GTK_VALUE_CHAR (args[1]), GTK_VALUE_INT (args[2]),
+                          func_data);
+}
+
+/*****************************************
+ * gtk_widget_marshal_signal_3:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static void
+gtk_widget_marshal_signal_3 (GtkObject      *object,
+                            GtkSignalFunc   func,
+                            gpointer        func_data,
+                            GtkArg         *args)
+{
+  GtkWidgetSignal3 rfunc;
+
+  rfunc = (GtkWidgetSignal3) func;
+
+  (* rfunc) (object, GTK_VALUE_STRING (args[0]), func_data);
+}
+
+/*****************************************
+ * gtk_widget_marshal_signal_4:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static void
+gtk_widget_marshal_signal_4 (GtkObject      *object,
+                            GtkSignalFunc   func,
+                            gpointer        func_data,
+                            GtkArg         *args)
+{
+  GtkWidgetSignal4 rfunc;
+  gint *return_val;
+
+  rfunc = (GtkWidgetSignal4) func;
+  return_val = GTK_RETLOC_BOOL (args[1]);
+
+  *return_val = (* rfunc) (object, GTK_VALUE_BOXED (args[0]), func_data);
+}
+
+/*****************************************
+ * gtk_real_widget_destroy:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static void
+gtk_real_widget_destroy (GtkObject *object)
+{
+  GtkWidget *widget;
+  GtkWidgetAuxInfo *aux_info;
+  gint *events;
+  GdkExtensionMode *mode;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_WIDGET (object));
+
+  widget = GTK_WIDGET (object);
+
+  if (GTK_WIDGET_REDRAW_PENDING (widget))
+    g_warning ("redraw pending\n");
+  if (GTK_WIDGET_RESIZE_PENDING (widget))
+    g_warning ("resize pending\n");
+  if (GTK_WIDGET_RESIZE_NEEDED (widget))
+    g_warning ("resize needed\n");
+
+  gtk_grab_remove (widget);
+
+  gtk_selection_remove_all (widget);
+
+  if (widget->name)
+    g_free (widget->name);
+
+  aux_info = gtk_object_get_data (GTK_OBJECT (widget), aux_info_key);
+  if (aux_info)
+    {
+      gtk_widget_aux_info_destroy (aux_info);
+      gtk_object_remove_data (GTK_OBJECT (widget), aux_info_key);
+    }
+
+  events = gtk_object_get_data (GTK_OBJECT (object), event_key);
+  if (events)
+    g_free (events);
+
+  mode = gtk_object_get_data (GTK_OBJECT (object), extension_event_key);
+  if (mode)
+    g_free (mode);
+
+  if (GTK_WIDGET_REALIZED (widget))
+    gtk_widget_unrealize (widget);
+  gtk_style_unref (widget->style);
+
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+/*****************************************
+ * gtk_real_widget_show:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static void
+gtk_real_widget_show (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+
+  if (!GTK_WIDGET_VISIBLE (widget))
+    {
+      GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
+
+      if (widget->parent)
+       {
+         gtk_widget_queue_resize (widget);
+
+         if (GTK_WIDGET_MAPPED (widget->parent))
+           gtk_widget_map (widget);
+       }
+    }
+}
+
+/*****************************************
+ * gtk_real_widget_hide:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static void
+gtk_real_widget_hide (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+
+  if (GTK_WIDGET_VISIBLE (widget))
+    {
+      GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
+
+      if (GTK_WIDGET_MAPPED (widget))
+       gtk_widget_unmap (widget);
+
+      if (widget->parent)
+       gtk_widget_queue_resize (widget);
+    }
+}
+
+/*****************************************
+ * gtk_real_widget_map:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static void
+gtk_real_widget_map (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+
+  if (GTK_WIDGET_REALIZED (widget) && !GTK_WIDGET_MAPPED (widget))
+    {
+      GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
+
+      if (!GTK_WIDGET_NO_WINDOW (widget))
+       gdk_window_show (widget->window);
+      else
+       gtk_widget_queue_draw (widget);
+    }
+}
+
+/*****************************************
+ * gtk_real_widget_unmap:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static void
+gtk_real_widget_unmap (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+
+  if (GTK_WIDGET_MAPPED (widget))
+    {
+      GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
+
+      if (GTK_WIDGET_NO_WINDOW (widget))
+       gdk_window_clear_area (widget->window,
+                              widget->allocation.x,
+                              widget->allocation.y,
+                              widget->allocation.width,
+                              widget->allocation.height);
+      else
+       gdk_window_hide (widget->window);
+    }
+}
+
+/*****************************************
+ * gtk_real_widget_realize:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static void
+gtk_real_widget_realize (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+  if(widget->parent)
+    widget->window = widget->parent->window;
+  widget->style = gtk_style_attach (widget->style, widget->window);
+}
+
+/*****************************************
+ * gtk_real_widget_unrealize:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static void
+gtk_real_widget_unrealize (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED | GTK_MAPPED);
+
+  gtk_style_detach (widget->style);
+  if (!GTK_WIDGET_NO_WINDOW (widget))
+    {
+      gdk_window_set_user_data (widget->window, NULL);
+      gdk_window_destroy (widget->window);
+    }
+  widget->window = NULL;
+}
+
+/*****************************************
+ * gtk_real_widget_draw:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static void
+gtk_real_widget_draw (GtkWidget    *widget,
+                     GdkRectangle *area)
+{
+  GdkEventExpose event;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+  g_return_if_fail (area != NULL);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      event.type = GDK_EXPOSE;
+      event.window = widget->window;
+      event.area = *area;
+
+      gtk_widget_event (widget, (GdkEvent*) &event);
+    }
+}
+
+/*****************************************
+ * gtk_real_widget_queue_draw:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static gint
+gtk_real_widget_queue_draw (GtkWidget *widget)
+{
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
+
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_REDRAW_PENDING);
+
+  gtk_object_unref (GTK_OBJECT (widget));
+  if (GTK_OBJECT_NEED_DESTROY (widget) &&
+      (GTK_OBJECT (widget)->ref_count == 0))
+    gtk_widget_destroy (widget);
+  else
+    gtk_widget_draw (widget, NULL);
+
+  return FALSE;
+}
+
+/*****************************************
+ * gtk_real_widget_queue_resize:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static gint
+gtk_real_widget_queue_resize (GtkWidget *widget)
+{
+  GSList *resize_widgets;
+  GSList *tmp_list;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
+
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_RESIZE_PENDING);
+
+  gtk_object_unref (GTK_OBJECT (widget));
+  if (GTK_OBJECT_NEED_DESTROY (widget) &&
+      (GTK_OBJECT (widget)->ref_count == 0))
+    {
+      gtk_widget_destroy (widget);
+    }
+  else
+    {
+      gtk_container_need_resize (GTK_CONTAINER (widget));
+
+      if (!GTK_WIDGET_RESIZE_PENDING (widget))
+       {
+         resize_widgets = gtk_object_get_data (GTK_OBJECT (widget), resize_widgets_key);
+         
+         tmp_list = resize_widgets;
+         while (tmp_list)
+           {
+             GtkWidget *child;
+             
+             child = tmp_list->data;
+             tmp_list = tmp_list->next;
+             
+             /* referencing needed? */
+             GTK_WIDGET_UNSET_FLAGS (child, GTK_RESIZE_NEEDED);
+             gtk_object_unref (GTK_OBJECT (child));
+           }
+         
+         if (resize_widgets)
+           {
+             gtk_object_set_data (GTK_OBJECT (widget), resize_widgets_key, NULL);
+             g_slist_free (resize_widgets);
+           }
+       }
+    }
+
+  return FALSE;
+}
+
+/*****************************************
+ * gtk_real_widget_size_allocate:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static void
+gtk_real_widget_size_allocate (GtkWidget     *widget,
+                              GtkAllocation *allocation)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+
+  if (GTK_WIDGET_NO_WINDOW (widget) &&
+      GTK_WIDGET_MAPPED (widget) &&
+      ((widget->allocation.x != allocation->x) ||
+       (widget->allocation.y != allocation->y) ||
+       (widget->allocation.width != allocation->width) ||
+       (widget->allocation.height != allocation->height)) &&
+      (widget->allocation.width != 0) &&
+      (widget->allocation.height != 0))
+    gdk_window_clear_area (widget->window,
+                          widget->allocation.x,
+                          widget->allocation.y,
+                          widget->allocation.width,
+                          widget->allocation.height);
+
+  widget->allocation = *allocation;
+
+  if (GTK_WIDGET_REALIZED (widget) &&
+      !GTK_WIDGET_NO_WINDOW (widget))
+    gdk_window_move_resize (widget->window,
+                           allocation->x, allocation->y,
+                           allocation->width, allocation->height);
+}
+
+/*****************************************
+ * gtk_widget_peek_colormap:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static GdkColormap*
+gtk_widget_peek_colormap ()
+{
+  if (colormap_stack)
+    return (GdkColormap*) colormap_stack->data;
+  return gtk_widget_get_default_colormap ();
+}
+
+/*****************************************
+ * gtk_widget_peek_visual:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static GdkVisual*
+gtk_widget_peek_visual ()
+{
+  if (visual_stack)
+    return (GdkVisual*) visual_stack->data;
+  return gtk_widget_get_default_visual ();
+}
+
+/*****************************************
+ * gtk_widget_peek_style:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static GtkStyle*
+gtk_widget_peek_style ()
+{
+  if (style_stack)
+    return (GtkStyle*) style_stack->data;
+  return gtk_widget_get_default_style ();
+}
+
+
+/*****************************************
+ * gtk_widget_set_parent_sensitive:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static void
+gtk_widget_set_parent_sensitive (GtkWidget *widget,
+                                gpointer   client_data)
+{
+  GtkWidget *window;
+  gint *sensitive;
+
+  sensitive = client_data;
+  if (*sensitive)
+    {
+      GTK_WIDGET_SET_FLAGS (widget, GTK_PARENT_SENSITIVE);
+
+      if (GTK_IS_CONTAINER (widget) && GTK_WIDGET_SENSITIVE (widget))
+       gtk_container_foreach (GTK_CONTAINER (widget),
+                              gtk_widget_set_parent_sensitive,
+                              client_data);
+    }
+  else
+    {
+      GTK_WIDGET_UNSET_FLAGS (widget, GTK_PARENT_SENSITIVE);
+
+      if (GTK_WIDGET_HAS_FOCUS (widget))
+       {
+         window = gtk_widget_get_ancestor (widget, gtk_window_get_type ());
+         if (window)
+           gtk_window_set_focus (GTK_WINDOW (window), NULL);
+       }
+
+      if (GTK_IS_CONTAINER (widget))
+       gtk_container_foreach (GTK_CONTAINER (widget),
+                              gtk_widget_set_parent_sensitive,
+                              client_data);
+    }
+}
+
+/*****************************************
+ * gtk_widget_propagate_restore:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static void
+gtk_widget_propagate_restore (GtkWidget *widget,
+                             gpointer   client_data)
+{
+  gtk_widget_restore_state (widget);
+}
+
+/*****************************************
+ * gtk_widget_propagate_state:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static void
+gtk_widget_propagate_state (GtkWidget *widget,
+                           gpointer   client_data)
+{
+  GtkStateType *state;
+
+  state = (GtkStateType*) client_data;
+  gtk_widget_set_state (widget, *state);
+}
+
+/*****************************************
+ * gtk_widget_draw_children_recurse:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static void
+gtk_widget_draw_children_recurse (GtkWidget *widget,
+                                 gpointer   client_data)
+{
+  gtk_widget_draw (widget, NULL);
+  gtk_widget_draw_children (widget);
+}
+
+/*****************************************
+ * gtk_widget_set_style_internal:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static void
+gtk_widget_set_style_internal (GtkWidget *widget,
+                              GtkStyle  *style)
+{
+  GtkRequisition old_requisition;
+
+  g_return_if_fail (widget != NULL);
+
+  if (widget->style != style)
+    {
+      if (GTK_WIDGET_REALIZED (widget))
+       gtk_style_detach (widget->style);
+
+      gtk_style_unref (widget->style);
+
+      widget->style = style;
+      gtk_style_ref (widget->style);
+
+      if (GTK_WIDGET_REALIZED (widget))
+       widget->style = gtk_style_attach (widget->style, widget->window);
+
+      if (widget->parent)
+       {
+         old_requisition = widget->requisition;
+         gtk_widget_size_request (widget, &widget->requisition);
+
+         if ((old_requisition.width != widget->requisition.width) ||
+             (old_requisition.height != widget->requisition.height))
+           gtk_widget_queue_resize (widget);
+         else if (GTK_WIDGET_DRAWABLE (widget))
+           gtk_widget_queue_draw (widget);
+       }
+    }
+}
+
+/*****************************************
+ * gtk_widget_set_style_recurse:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static void
+gtk_widget_set_style_recurse (GtkWidget *widget,
+                             gpointer   client_data)
+{
+  GtkStyle *style;
+
+  style = gtk_rc_get_style (widget);
+  if (style != widget->style)
+    gtk_widget_set_style_internal (widget, style);
+
+  if (GTK_IS_CONTAINER (widget))
+    gtk_container_foreach (GTK_CONTAINER (widget),
+                          gtk_widget_set_style_recurse,
+                          NULL);
+}
+
+/*****************************************
+ * gtk_widget_aux_info_new:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static GtkWidgetAuxInfo*
+gtk_widget_aux_info_new ()
+{
+  GtkWidgetAuxInfo *aux_info;
+
+  if (!aux_info_mem_chunk)
+    aux_info_mem_chunk = g_mem_chunk_new ("widget aux info mem chunk",
+                                         sizeof (GtkWidgetAuxInfo),
+                                         1024, G_ALLOC_AND_FREE);
+
+  aux_info = g_chunk_new (GtkWidgetAuxInfo, aux_info_mem_chunk);
+
+  aux_info->x = -1;
+  aux_info->y = -1;
+  aux_info->width = 0;
+  aux_info->height = 0;
+
+  return aux_info;
+}
+
+/*****************************************
+ * gtk_widget_aux_info_destroy:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+
+static void
+gtk_widget_aux_info_destroy (GtkWidgetAuxInfo *aux_info)
+{
+  g_return_if_fail (aux_info != NULL);
+
+  g_mem_chunk_free (aux_info_mem_chunk, aux_info);
+}
+
+/*****************************************
+ * gtk_widget_shape_combine_mask: 
+ *   set a shape for this widgets' gdk window, this allows for
+ *   transparent windows etc., see gdk_window_shape_combine_mask
+ *   for more information
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+void
+gtk_widget_shape_combine_mask (GtkWidget *widget,
+                              GdkBitmap *shape_mask,
+                              gint       offset_x,
+                              gint       offset_y)
+{
+  GtkWidgetShapeInfo* shape_info;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (shape_mask != NULL);
+  /*  set_shape doesn't work on widgets without gdk window */
+  g_return_if_fail (!GTK_WIDGET_NO_WINDOW (widget));
+
+  /*
+   * remember shape mask for later gtk_widget_realize's
+   */
+  shape_info = gtk_object_get_data (GTK_OBJECT (widget), shape_info_key);
+  if (!shape_info)
+    {
+      shape_info = g_new (GtkWidgetShapeInfo, 1);
+      gtk_object_set_data (GTK_OBJECT (widget), shape_info_key, shape_info);
+    }
+  shape_info->shape_mask = shape_mask;
+  shape_info->offset_x = offset_x;
+  shape_info->offset_y = offset_y;
+  GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_SHAPE_MASK);
+
+  /* 
+   * set shape if widget has a gdk window allready.
+   * otherwise the shape is scheduled to be set by gtk_widget_realize.
+   */
+  if (widget->window)
+    gdk_window_shape_combine_mask (widget->window, shape_mask,
+                                  offset_x, offset_y); 
+  
+}
+
+/*****************************************
+ * gtk_widget_dnd_drag_add:
+ *   when you get a DRAG_ENTER event, you can use this           
+ *   to tell Gtk ofother widgets that are to be dragged as well
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+void
+gtk_widget_dnd_drag_add (GtkWidget *widget)
+{
+}
+
+/*****************************************
+ * gtk_widget_dnd_drag_set:
+ *   these two functions enable drag and/or drop on a
+ *   widget and also let Gtk know what data types will be accepted
+ *   use MIME type naming,plus tacking "URL:" on the front for link 
+ *   dragging
+ *             
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+void
+gtk_widget_dnd_drag_set (GtkWidget   *widget,
+                        guint8       drag_enable,
+                        gchar      **type_accept_list,
+                        guint        numtypes)
+{
+  g_return_if_fail(widget != NULL);
+
+  if (!widget->window)
+    gtk_widget_realize (widget);
+
+  g_return_if_fail (widget->window != NULL);
+  gdk_window_dnd_drag_set (widget->window,
+                          drag_enable,
+                          type_accept_list,
+                          numtypes);
+}
+
+/*****************************************
+ * gtk_widget_dnd_drop_set:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+void
+gtk_widget_dnd_drop_set (GtkWidget   *widget,
+                        guint8       drop_enable,
+                        gchar      **type_accept_list,
+                        guint        numtypes,
+                        guint8       is_destructive_operation)
+{
+  g_return_if_fail(widget != NULL);
+
+  if (!widget->window)
+    gtk_widget_realize (widget);
+
+  g_return_if_fail (widget->window != NULL);
+  gdk_window_dnd_drop_set (widget->window,
+                          drop_enable,
+                          type_accept_list,
+                          numtypes,
+                          is_destructive_operation);
+}
+
+/*****************************************
+ * gtk_widget_dnd_data_set:
+ *
+ *   arguments:
+ *
+ *   results:
+ *****************************************/
+void
+gtk_widget_dnd_data_set (GtkWidget   *widget,
+                        GdkEvent    *event,
+                        gpointer     data,
+                        gulong       data_numbytes)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (widget->window != NULL);
+
+  gdk_window_dnd_data_set (widget->window, event, data, data_numbytes);
+}
+
diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h
new file mode 100644 (file)
index 0000000..51ea994
--- /dev/null
@@ -0,0 +1,505 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_WIDGET_H__
+#define __GTK_WIDGET_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkaccelerator.h>
+#include <gtk/gtkobject.h>
+#include <gtk/gtkstyle.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* The flags that are used in the flags member of the GtkObject
+ *  structure.
+ */
+enum
+{
+  GTK_VISIBLE          = 1 << 3,
+  GTK_MAPPED           = 1 << 4,
+  GTK_UNMAPPED         = 1 << 5,
+  GTK_REALIZED         = 1 << 6,
+  GTK_SENSITIVE        = 1 << 7,
+  GTK_PARENT_SENSITIVE = 1 << 8,
+  GTK_NO_WINDOW        = 1 << 9,
+  GTK_HAS_FOCUS        = 1 << 10,
+  GTK_CAN_FOCUS        = 1 << 11,
+  GTK_HAS_DEFAULT      = 1 << 12,
+  GTK_CAN_DEFAULT      = 1 << 13,
+  GTK_PROPAGATE_STATE  = 1 << 14,
+  GTK_ANCHORED         = 1 << 15,
+  GTK_BASIC            = 1 << 16,
+  GTK_USER_STYLE       = 1 << 17,
+  GTK_GRAB_ALL         = 1 << 18,
+  GTK_REDRAW_PENDING   = 1 << 19,
+  GTK_RESIZE_PENDING   = 1 << 20,
+  GTK_RESIZE_NEEDED    = 1 << 21,
+  GTK_HAS_SHAPE_MASK   = 1 << 22
+};
+
+
+/* Macro for casting a pointer to a GtkWidget pointer.
+ */
+#define GTK_WIDGET(obj)                   GTK_CHECK_CAST (obj, gtk_widget_get_type (), GtkWidget)
+
+/* Macro for casting the "class" field of an object to
+ *  a GtkWidgetClass pointer.
+ */
+#define GTK_WIDGET_CLASS(klass)           GTK_CHECK_CLASS_CAST (klass, gtk_widget_get_type (), GtkWidgetClass)
+
+/* Macros for extracting various fields from GtkWidget and
+ *  GtkWidgetClass structures.
+ */
+#define GTK_WIDGET_TYPE(obj)              (GTK_OBJECT_TYPE (obj))
+#define GTK_WIDGET_STATE(obj)             (GTK_WIDGET (obj)->state)
+#define GTK_WIDGET_SAVED_STATE(obj)       (GTK_WIDGET (obj)->saved_state)
+#define GTK_WIDGET_VISIBLE(obj)           (GTK_OBJECT_FLAGS (obj) & GTK_VISIBLE)
+#define GTK_WIDGET_MAPPED(obj)            (GTK_OBJECT_FLAGS (obj) & GTK_MAPPED)
+#define GTK_WIDGET_UNMAPPED(obj)          (GTK_OBJECT_FLAGS (obj) & GTK_UNMAPPED)
+#define GTK_WIDGET_REALIZED(obj)          (GTK_OBJECT_FLAGS (obj) & GTK_REALIZED)
+#define GTK_WIDGET_SENSITIVE(obj)         (GTK_OBJECT_FLAGS (obj) & GTK_SENSITIVE)
+#define GTK_WIDGET_PARENT_SENSITIVE(obj)  (GTK_OBJECT_FLAGS (obj) & GTK_PARENT_SENSITIVE)
+#define GTK_WIDGET_IS_SENSITIVE(obj)      ((GTK_WIDGET_SENSITIVE (obj) && \
+                                            GTK_WIDGET_PARENT_SENSITIVE (obj)) != 0)
+#define GTK_WIDGET_NO_WINDOW(obj)         (GTK_OBJECT_FLAGS (obj) & GTK_NO_WINDOW)
+#define GTK_WIDGET_HAS_FOCUS(obj)         (GTK_OBJECT_FLAGS (obj) & GTK_HAS_FOCUS)
+#define GTK_WIDGET_CAN_FOCUS(obj)         (GTK_OBJECT_FLAGS (obj) & GTK_CAN_FOCUS)
+#define GTK_WIDGET_HAS_DEFAULT(obj)       (GTK_OBJECT_FLAGS (obj) & GTK_HAS_DEFAULT)
+#define GTK_WIDGET_CAN_DEFAULT(obj)       (GTK_OBJECT_FLAGS (obj) & GTK_CAN_DEFAULT)
+#define GTK_WIDGET_PROPAGATE_STATE(obj)   (GTK_OBJECT_FLAGS (obj) & GTK_PROPAGATE_STATE)
+#define GTK_WIDGET_DRAWABLE(obj)          (GTK_WIDGET_VISIBLE (obj) && GTK_WIDGET_MAPPED (obj))
+#define GTK_WIDGET_ANCHORED(obj)          (GTK_OBJECT_FLAGS (obj) & GTK_ANCHORED)
+#define GTK_WIDGET_BASIC(obj)             (GTK_OBJECT_FLAGS (obj) & GTK_BASIC)
+#define GTK_WIDGET_USER_STYLE(obj)        (GTK_OBJECT_FLAGS (obj) & GTK_USER_STYLE)
+#define GTK_WIDGET_GRAB_ALL(obj)          (GTK_OBJECT_FLAGS (obj) & GTK_GRAB_ALL)
+#define GTK_WIDGET_REDRAW_PENDING(obj)    (GTK_OBJECT_FLAGS (obj) & GTK_REDRAW_PENDING)
+#define GTK_WIDGET_RESIZE_PENDING(obj)    (GTK_OBJECT_FLAGS (obj) & GTK_RESIZE_PENDING)
+#define GTK_WIDGET_RESIZE_NEEDED(obj)     (GTK_OBJECT_FLAGS (obj) & GTK_RESIZE_NEEDED)
+#define GTK_WIDGET_HAS_SHAPE_MASK(obj)    (GTK_OBJECT_FLAGS (obj) & GTK_HAS_SHAPE_MASK)
+
+#define GTK_TYPE_WIDGET                   (gtk_widget_get_type ())
+
+/* Macro for testing whether "obj" is of type GtkWidget.
+ */
+#define GTK_IS_WIDGET(obj)                GTK_CHECK_TYPE (obj, GTK_TYPE_WIDGET)
+
+/* Macros for setting and clearing widget flags. Notice
+ *  that these are only wrappers for the macros which
+ *  set and clear the flags in the GtkObject structure.
+ */
+#define GTK_WIDGET_SET_FLAGS(obj,flag)    (GTK_OBJECT_SET_FLAGS (obj, flag))
+#define GTK_WIDGET_UNSET_FLAGS(obj,flag)  (GTK_OBJECT_UNSET_FLAGS (obj, flag))
+
+
+
+typedef struct _GtkRequisition    GtkRequisition;
+typedef struct _GtkAllocation     GtkAllocation;
+typedef struct _GtkSelectionData GtkSelectionData;
+typedef struct _GtkWidget         GtkWidget;
+typedef struct _GtkWidgetClass    GtkWidgetClass;
+typedef struct _GtkWidgetAuxInfo  GtkWidgetAuxInfo;
+typedef struct _GtkWidgetShapeInfo GtkWidgetShapeInfo;
+
+typedef void (*GtkCallback) (GtkWidget *widget,
+                            gpointer   data);
+
+/* A requisition is a desired amount of space which a
+ *  widget may request.
+ */
+struct _GtkRequisition
+{
+  guint16 width;
+  guint16 height;
+};
+
+/* An allocation is a size and position. Where a widget
+ *  can ask for a desired size, it is actually given
+ *  this amount of space at the specified position.
+ */
+struct _GtkAllocation
+{
+  gint16 x;
+  gint16 y;
+  guint16 width;
+  guint16 height;
+};
+
+/* The contents of a selection are returned in a GtkSelectionData
+   structure. selection/target identify the request. 
+   type specifies the type of the return; if length < 0, and
+   the data should be ignored. This structure has object semantics -
+   no fields should be modified directly, they should not be created
+   directly, and pointers to them should not be stored beyond the duration of
+   a callback. (If the last is changed, we'll need to add reference
+   counting) */
+
+struct _GtkSelectionData
+{
+  GdkAtom selection;
+  GdkAtom target;
+  GdkAtom type;
+  gint    format;
+  guchar *data;
+  gint    length;
+};
+
+/* The widget is the base of the tree for displayable objects.
+ *  (A displayable object is one which takes up some amount
+ *  of screen real estate). It provides a common base and interface
+ *  which actual widgets must adhere to.
+ */
+struct _GtkWidget
+{
+  /* The object structure needs to be the first
+   *  element in the widget structure in order for
+   *  the object mechanism to work correctly. This
+   *  allows a GtkWidget pointer to be cast to a
+   *  GtkObject pointer.
+   */
+  GtkObject object;
+
+  /* The state of the widget. There are actually only
+   *  5 widget states (defined in "gtkenums.h").
+   */
+  guint8 state;
+
+  /* The saved state of the widget. When a widgets state
+   *  is changed via "gtk_widget_set_state" the old state
+   *  is kept around in this field. The state may be
+   *  restored using "gtk_widget_restore_state".
+   */
+  guint8 saved_state;
+
+  /* The widgets name. If the widget does not have a name
+   *  (the name is NULL), then its name (as returned by
+   *  "gtk_widget_get_name") is its classes name.
+   * The widget name is used to determine the style to
+   *  use for a widget.
+   */
+  gchar *name;
+
+  /* The style for the widget. The style contains the
+   *  colors the widget should be drawn in for each state
+   *  along with graphics contexts used to draw with and
+   *  the font to use for text.
+   */
+  GtkStyle *style;
+
+  /* The widgets desired size.
+   */
+  GtkRequisition requisition;
+
+  /* The widgets allocated size.
+   */
+  GtkAllocation allocation;
+
+  /* The widgets window or its parent window if it does
+   *  not have a window. (Which will be indicated by the
+   *  GTK_NO_WINDOW flag being set).
+   */
+  GdkWindow *window;
+
+  /* The widgets parent.
+   */
+  GtkWidget *parent;
+};
+
+struct _GtkWidgetClass
+{
+  /* The object class structure needs to be the first
+   *  element in the widget class structure in order for
+   *  the class mechanism to work correctly. This allows a
+   *  GtkWidgetClass pointer to be cast to a GtkObjectClass
+   *  pointer.
+   */
+  GtkObjectClass parent_class;
+
+  /* The signal to emit when an object of this class is activated.
+   *  This is used when activating the current focus widget and
+   *  the default widget.
+   */
+  gint activate_signal;
+
+  /* basics */
+  void (* show)                (GtkWidget      *widget);
+  void (* hide)                (GtkWidget      *widget);
+  void (* map)                 (GtkWidget      *widget);
+  void (* unmap)               (GtkWidget      *widget);
+  void (* realize)             (GtkWidget      *widget);
+  void (* unrealize)           (GtkWidget      *widget);
+  void (* draw)                (GtkWidget      *widget,
+                               GdkRectangle   *area);
+  void (* draw_focus)          (GtkWidget      *widget);
+  void (* draw_default)        (GtkWidget      *widget);
+  void (* size_request)        (GtkWidget      *widget,
+                               GtkRequisition *requisition);
+  void (* size_allocate)       (GtkWidget      *widget,
+                               GtkAllocation  *allocation);
+  void (* state_changed)       (GtkWidget      *widget);
+
+  /* accelerators */
+  gint (* install_accelerator) (GtkWidget      *widget,
+                               const gchar    *signal_name,
+                               gchar           key,
+                               guint8          modifiers);
+  void (* remove_accelerator)  (GtkWidget      *widget,
+                               const gchar    *signal_name);
+
+  /* events */
+  gint (* event)                   (GtkWidget         *widget,
+                                   GdkEvent          *event);
+  gint (* button_press_event)      (GtkWidget         *widget,
+                                   GdkEventButton    *event);
+  gint (* button_release_event)    (GtkWidget         *widget,
+                                   GdkEventButton    *event);
+  gint (* motion_notify_event)     (GtkWidget         *widget,
+                                   GdkEventMotion    *event);
+  gint (* delete_event)            (GtkWidget         *widget,
+                                   GdkEventAny       *event);
+  gint (* destroy_event)           (GtkWidget         *widget,
+                                   GdkEventAny       *event);
+  gint (* expose_event)            (GtkWidget         *widget,
+                                   GdkEventExpose    *event);
+  gint (* key_press_event)         (GtkWidget         *widget,
+                                   GdkEventKey       *event);
+  gint (* key_release_event)       (GtkWidget         *widget,
+                                   GdkEventKey       *event);
+  gint (* enter_notify_event)      (GtkWidget         *widget,
+                                   GdkEventCrossing  *event);
+  gint (* leave_notify_event)      (GtkWidget         *widget,
+                                   GdkEventCrossing  *event);
+  gint (* configure_event)         (GtkWidget         *widget,
+                                   GdkEventConfigure *event);
+  gint (* focus_in_event)          (GtkWidget         *widget,
+                                   GdkEventFocus     *event);
+  gint (* focus_out_event)         (GtkWidget         *widget,
+                                   GdkEventFocus     *event);
+  gint (* map_event)               (GtkWidget         *widget,
+                                   GdkEventAny       *event);
+  gint (* unmap_event)             (GtkWidget         *widget,
+                                   GdkEventAny       *event);
+  gint (* property_notify_event)   (GtkWidget         *widget,
+                                   GdkEventProperty  *event);
+  gint (* selection_clear_event)   (GtkWidget         *widget,
+                                   GdkEventSelection *event);
+  gint (* selection_request_event) (GtkWidget         *widget,
+                                   GdkEventSelection *event);
+  gint (* selection_notify_event)  (GtkWidget         *widget,
+                                   GdkEventSelection *event);
+  gint (* proximity_in_event)      (GtkWidget         *widget,
+                                   GdkEventProximity *event);
+  gint (* proximity_out_event)     (GtkWidget         *widget,
+                                   GdkEventProximity *event);
+  gint (* drag_begin_event)        (GtkWidget         *widget,
+                                   GdkEventDragBegin *event);
+  gint (* drag_request_event)      (GtkWidget         *widget,
+                                   GdkEventDragRequest *event);
+  gint (* drop_enter_event)        (GtkWidget         *widget,
+                                   GdkEventDropEnter *event);
+  gint (* drop_leave_event)        (GtkWidget         *widget,
+                                   GdkEventDropLeave *event);
+  gint (* drop_data_available_event)   (GtkWidget         *widget,
+                                   GdkEventDropDataAvailable *event);
+  gint (* other_event)             (GtkWidget         *widget,
+                                   GdkEventOther     *event);
+
+  /* selection */
+  void (* selection_received)  (GtkWidget      *widget,
+                               GtkSelectionData *selection_data);
+
+ gint (* client_event)            (GtkWidget         *widget,
+                                   GdkEventClient    *event);
+};
+
+struct _GtkWidgetAuxInfo
+{
+  gint16  x;
+  gint16  y;
+  guint16 width;
+  guint16 height;
+};
+
+struct _GtkWidgetShapeInfo
+{
+  gint16     offset_x;
+  gint16     offset_y;
+  GdkBitmap *shape_mask;
+};
+
+
+guint      gtk_widget_get_type            (void);
+GtkWidget* gtk_widget_new                 (guint                type,
+                                          ...);
+GtkWidget* gtk_widget_newv                (guint                type,
+                                          gint                 nargs,
+                                          GtkArg              *args);
+void       gtk_widget_set                 (GtkWidget           *widget,
+                                          ...);
+void       gtk_widget_setv                (GtkWidget           *widget,
+                                          gint                 nargs,
+                                          GtkArg              *args);
+void       gtk_widget_destroy             (GtkWidget           *widget);
+void       gtk_widget_unparent            (GtkWidget           *widget);
+void       gtk_widget_show                (GtkWidget           *widget);
+void       gtk_widget_hide                (GtkWidget           *widget);
+void       gtk_widget_map                 (GtkWidget           *widget);
+void       gtk_widget_unmap               (GtkWidget           *widget);
+void       gtk_widget_realize             (GtkWidget           *widget);
+void       gtk_widget_unrealize           (GtkWidget           *widget);
+void       gtk_widget_queue_draw          (GtkWidget           *widget);
+void       gtk_widget_queue_resize        (GtkWidget           *widget);
+void       gtk_widget_draw                (GtkWidget           *widget,
+                                          GdkRectangle        *area);
+void       gtk_widget_draw_focus          (GtkWidget           *widget);
+void       gtk_widget_draw_default        (GtkWidget           *widget);
+void       gtk_widget_draw_children       (GtkWidget           *widget);
+void       gtk_widget_size_request        (GtkWidget           *widget,
+                                          GtkRequisition      *requisition);
+void       gtk_widget_size_allocate       (GtkWidget           *widget,
+                                          GtkAllocation       *allocation);
+void       gtk_widget_install_accelerator (GtkWidget           *widget,
+                                          GtkAcceleratorTable *table,
+                                          const gchar         *signal_name,
+                                          gchar                key,
+                                          guint8               modifiers);
+void       gtk_widget_remove_accelerator  (GtkWidget           *widget,
+                                          GtkAcceleratorTable *table,
+                                          const gchar         *signal_name);
+gint       gtk_widget_event               (GtkWidget           *widget,
+                                          GdkEvent            *event);
+
+void       gtk_widget_activate            (GtkWidget           *widget);
+void       gtk_widget_reparent            (GtkWidget           *widget,
+                                          GtkWidget           *new_parent);
+void       gtk_widget_popup               (GtkWidget           *widget,
+                                          gint                 x,
+                                          gint                 y);
+gint       gtk_widget_intersect           (GtkWidget           *widget,
+                                          GdkRectangle        *area,
+                                          GdkRectangle        *intersection);
+gint       gtk_widget_basic               (GtkWidget           *widget);
+
+void       gtk_widget_grab_focus          (GtkWidget           *widget);
+void       gtk_widget_grab_default        (GtkWidget           *widget);
+
+void       gtk_widget_restore_state       (GtkWidget           *widget);
+void       gtk_widget_set_name            (GtkWidget           *widget,
+                                          const gchar         *name);
+gchar*     gtk_widget_get_name            (GtkWidget           *widget);
+void       gtk_widget_set_state           (GtkWidget           *widget,
+                                          GtkStateType         state);
+void       gtk_widget_set_sensitive       (GtkWidget           *widget,
+                                          gint                 sensitive);
+void       gtk_widget_set_parent          (GtkWidget           *widget,
+                                          GtkWidget           *parent);
+void       gtk_widget_set_style           (GtkWidget           *widget,
+                                          GtkStyle            *style);
+void       gtk_widget_set_uposition       (GtkWidget           *widget,
+                                          gint                 x,
+                                          gint                 y);
+void       gtk_widget_set_usize           (GtkWidget           *widget,
+                                          gint                 width,
+                                          gint                 height);
+void       gtk_widget_set_events          (GtkWidget           *widget,
+                                          gint                 events);
+void       gtk_widget_set_extension_events (GtkWidget           *widget,
+                                           GdkExtensionMode    mode);
+
+GtkWidget*   gtk_widget_get_toplevel  (GtkWidget *widget);
+GtkWidget*   gtk_widget_get_ancestor  (GtkWidget *widget,
+                                      gint       type);
+GdkColormap* gtk_widget_get_colormap  (GtkWidget *widget);
+GdkVisual*   gtk_widget_get_visual    (GtkWidget *widget);
+GtkStyle*    gtk_widget_get_style     (GtkWidget *widget);
+gint         gtk_widget_get_events    (GtkWidget *widget);
+GdkExtensionMode gtk_widget_get_extension_events    (GtkWidget *widget);
+void         gtk_widget_get_pointer   (GtkWidget *widget,
+                                      gint      *x,
+                                      gint      *y);
+
+gint         gtk_widget_is_ancestor (GtkWidget *widget,
+                                    GtkWidget *ancestor);
+gint         gtk_widget_is_child    (GtkWidget *widget,
+                                    GtkWidget *child);
+
+void         gtk_widget_push_colormap    (GdkColormap   *cmap);
+void         gtk_widget_push_visual      (GdkVisual     *visual);
+void         gtk_widget_push_style       (GtkStyle      *style);
+
+void         gtk_widget_pop_colormap     (void);
+void         gtk_widget_pop_visual       (void);
+void         gtk_widget_pop_style        (void);
+
+void         gtk_widget_set_default_colormap (GdkColormap *colormap);
+void         gtk_widget_set_default_visual   (GdkVisual   *visual);
+void         gtk_widget_set_default_style    (GtkStyle    *style);
+/* Tells other Gtk applications to use the same default style */
+void         gtk_widget_propagate_default_style(void);
+GdkColormap* gtk_widget_get_default_colormap (void);
+GdkVisual*   gtk_widget_get_default_visual   (void);
+GtkStyle*    gtk_widget_get_default_style    (void);
+
+/* 
+ * see gdk_window_shape_combine_mask
+ */
+void         gtk_widget_shape_combine_mask (GtkWidget *widget,
+                                           GdkBitmap *shape_mask,
+                                           gint       offset_x,
+                                           gint       offset_y);
+
+/* 
+ * When you get a drag_enter event, you can use this to tell Gtk of other
+ *  items that are to be dragged as well...
+ */
+void         gtk_widget_dnd_drag_add (GtkWidget *widget);
+
+/* 
+ * These two functions enable drag and/or drop on a widget,
+ * and also let Gtk know what data types will be accepted (use MIME type
+ *  naming, plus tacking "URL:" on the front for link dragging)
+ */
+void         gtk_widget_dnd_drag_set (GtkWidget     *widget,
+                                     guint8         drag_enable,
+                                     gchar        **type_accept_list,
+                                     guint          numtypes);
+void         gtk_widget_dnd_drop_set (GtkWidget     *widget,
+                                     guint8         drop_enable,
+                                     gchar        **type_accept_list,
+                                     guint          numtypes,
+                                     guint8         is_destructive_operation);
+
+/* 
+ * used to reply to a DRAG_REQUEST event - if you don't want to 
+ * give the data then pass in NULL for it 
+ */
+void         gtk_widget_dnd_data_set (GtkWidget     *widget,
+                                     GdkEvent      *event,
+                                     gpointer       data,
+                                     gulong         data_numbytes);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_WIDGET_H__ */
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
new file mode 100644 (file)
index 0000000..e97708a
--- /dev/null
@@ -0,0 +1,1195 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <string.h>
+#include <limits.h>
+#include "gdk/gdk.h"
+#include "gdk/gdkkeysyms.h"
+#include "gdk/gdkx.h"
+#include "gtksignal.h"
+#include "gtkwindow.h"
+
+enum {
+  MOVE_RESIZE,
+  LAST_SIGNAL
+};
+
+
+typedef gint (*GtkWindowSignal1) (GtkObject *object,
+                                 gpointer   arg1,
+                                 gpointer   arg2,
+                                 gint       arg3,
+                                 gint       arg4,
+                                 gpointer   data);
+
+
+static void gtk_window_marshal_signal_1 (GtkObject      *object,
+                                        GtkSignalFunc   func,
+                                        gpointer        func_data,
+                                        GtkArg         *args);
+
+static void gtk_window_class_init         (GtkWindowClass    *klass);
+static void gtk_window_init               (GtkWindow         *window);
+static void gtk_window_arg                (GtkWindow         *window,
+                                          GtkArg            *arg);
+static void gtk_window_destroy            (GtkObject         *object);
+static void gtk_window_show               (GtkWidget         *widget);
+static void gtk_window_hide               (GtkWidget         *widget);
+static void gtk_window_map                (GtkWidget         *widget);
+static void gtk_window_unmap              (GtkWidget         *widget);
+static void gtk_window_realize            (GtkWidget         *widget);
+static void gtk_window_size_request       (GtkWidget         *widget,
+                                          GtkRequisition    *requisition);
+static void gtk_window_size_allocate      (GtkWidget         *widget,
+                                          GtkAllocation     *allocation);
+static gint gtk_window_expose_event       (GtkWidget         *widget,
+                                          GdkEventExpose    *event);
+static gint gtk_window_configure_event    (GtkWidget         *widget,
+                                          GdkEventConfigure *event);
+static gint gtk_window_key_press_event    (GtkWidget         *widget,
+                                          GdkEventKey       *event);
+static gint gtk_window_key_release_event  (GtkWidget         *widget,
+                                          GdkEventKey       *event);
+static gint gtk_window_enter_notify_event (GtkWidget         *widget,
+                                          GdkEventCrossing  *event);
+static gint gtk_window_leave_notify_event (GtkWidget         *widget,
+                                          GdkEventCrossing  *event);
+static gint gtk_window_focus_in_event     (GtkWidget         *widget,
+                                          GdkEventFocus     *event);
+static gint gtk_window_focus_out_event    (GtkWidget         *widget,
+                                          GdkEventFocus     *event);
+static gint gtk_window_client_event      (GtkWidget         *widget,
+                                          GdkEvent          *event);
+static gint gtk_window_need_resize        (GtkContainer      *container);
+static gint gtk_real_window_move_resize   (GtkWindow         *window,
+                                          gint              *x,
+                                          gint              *y,
+                                          gint               width,
+                                          gint               height);
+static gint gtk_window_move_resize        (GtkWidget         *widget);
+static void gtk_window_set_hints          (GtkWidget         *widget,
+                                          GtkRequisition    *requisition);
+static gint gtk_window_check_accelerator  (GtkWindow         *window,
+                                          gint               key,
+                                          guint              mods);
+
+
+static GtkBinClass *parent_class = NULL;
+static gint window_signals[LAST_SIGNAL] = { 0 };
+
+
+guint
+gtk_window_get_type ()
+{
+  static guint window_type = 0;
+
+  if (!window_type)
+    {
+      GtkTypeInfo window_info =
+      {
+       "GtkWindow",
+       sizeof (GtkWindow),
+       sizeof (GtkWindowClass),
+       (GtkClassInitFunc) gtk_window_class_init,
+       (GtkObjectInitFunc) gtk_window_init,
+       (GtkArgFunc) gtk_window_arg,
+      };
+
+      window_type = gtk_type_unique (gtk_bin_get_type (), &window_info);
+    }
+
+  return window_type;
+}
+
+static void
+gtk_window_class_init (GtkWindowClass *klass)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+  GtkContainerClass *container_class;
+
+  object_class = (GtkObjectClass*) klass;
+  widget_class = (GtkWidgetClass*) klass;
+  container_class = (GtkContainerClass*) klass;
+
+  parent_class = gtk_type_class (gtk_bin_get_type ());
+
+  gtk_object_add_arg_type ("GtkWindow::type", GTK_TYPE_WINDOW_TYPE);
+  gtk_object_add_arg_type ("GtkWindow::title", GTK_TYPE_STRING);
+  gtk_object_add_arg_type ("GtkWindow::auto_shrink", GTK_TYPE_BOOL);
+  gtk_object_add_arg_type ("GtkWindow::allow_shrink", GTK_TYPE_BOOL);
+  gtk_object_add_arg_type ("GtkWindow::allow_grow", GTK_TYPE_BOOL);
+
+  window_signals[MOVE_RESIZE] =
+    gtk_signal_new ("move_resize",
+                    GTK_RUN_LAST,
+                    object_class->type,
+                    GTK_SIGNAL_OFFSET (GtkWindowClass, move_resize),
+                    gtk_window_marshal_signal_1,
+                   GTK_TYPE_BOOL, 4,
+                    GTK_TYPE_POINTER, GTK_TYPE_POINTER,
+                    GTK_TYPE_INT, GTK_TYPE_INT);
+
+  gtk_object_class_add_signals (object_class, window_signals, LAST_SIGNAL);
+
+  object_class->destroy = gtk_window_destroy;
+
+  widget_class->show = gtk_window_show;
+  widget_class->hide = gtk_window_hide;
+  widget_class->map = gtk_window_map;
+  widget_class->unmap = gtk_window_unmap;
+  widget_class->realize = gtk_window_realize;
+  widget_class->size_request = gtk_window_size_request;
+  widget_class->size_allocate = gtk_window_size_allocate;
+  widget_class->expose_event = gtk_window_expose_event;
+  widget_class->configure_event = gtk_window_configure_event;
+  widget_class->key_press_event = gtk_window_key_press_event;
+  widget_class->key_release_event = gtk_window_key_release_event;
+  widget_class->enter_notify_event = gtk_window_enter_notify_event;
+  widget_class->leave_notify_event = gtk_window_leave_notify_event;
+  widget_class->focus_in_event = gtk_window_focus_in_event;
+  widget_class->focus_out_event = gtk_window_focus_out_event;
+  widget_class->client_event = gtk_window_client_event;
+
+  container_class->need_resize = gtk_window_need_resize;
+
+  klass->move_resize = gtk_real_window_move_resize;
+}
+
+static void
+gtk_window_init (GtkWindow *window)
+{
+  GTK_WIDGET_UNSET_FLAGS (window, GTK_NO_WINDOW);
+  GTK_WIDGET_SET_FLAGS (window, GTK_ANCHORED);
+
+  window->title = NULL;
+  window->wmclass_name = NULL;
+  window->wmclass_class = NULL;
+  window->type = GTK_WINDOW_TOPLEVEL;
+  window->accelerator_tables = NULL;
+  window->focus_widget = NULL;
+  window->default_widget = NULL;
+  window->resize_count = 0;
+  window->need_resize = FALSE;
+  window->allow_shrink = FALSE;
+  window->allow_grow = TRUE;
+  window->auto_shrink = FALSE;
+  window->handling_resize = FALSE;
+  window->position = GTK_WIN_POS_NONE;
+  window->use_uposition = TRUE;
+}
+
+static void
+gtk_window_arg (GtkWindow *window,
+               GtkArg    *arg)
+{
+  if (strcmp (arg->name, "type") == 0)
+    {
+      window->type = GTK_VALUE_ENUM(*arg);
+    }
+  else if (strcmp (arg->name, "title") == 0)
+    {
+      gtk_window_set_title (window, GTK_VALUE_STRING(*arg));
+    }
+  else if (strcmp (arg->name, "auto_shrink") == 0)
+    {
+      window->auto_shrink = (GTK_VALUE_BOOL(*arg) != FALSE);
+    }
+  else if (strcmp (arg->name, "allow_shrink") == 0)
+    {
+      window->allow_shrink = (GTK_VALUE_BOOL(*arg) != FALSE);
+    }
+  else if (strcmp (arg->name, "allow_grow") == 0)
+    {
+      window->allow_grow = (GTK_VALUE_BOOL(*arg) != FALSE);
+    }
+}
+
+GtkWidget*
+gtk_window_new (GtkWindowType type)
+{
+  GtkWindow *window;
+
+  window = gtk_type_new (gtk_window_get_type ());
+
+  window->type = type;
+
+  return GTK_WIDGET (window);
+}
+
+void
+gtk_window_set_title (GtkWindow   *window,
+                     const gchar *title)
+{
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (GTK_IS_WINDOW (window));
+
+  if (window->title)
+    g_free (window->title);
+  window->title = g_strdup (title);
+
+  if (GTK_WIDGET_REALIZED (window))
+    gdk_window_set_title (GTK_WIDGET (window)->window, window->title);
+}
+
+void
+gtk_window_set_wmclass (GtkWindow *window,
+                       gchar     *wmclass_name,
+                       gchar     *wmclass_class)
+{
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (GTK_IS_WINDOW (window));
+
+  if (window->wmclass_name)
+    g_free (window->wmclass_name);
+  window->wmclass_name = g_strdup (wmclass_name);
+
+  if (window->wmclass_class)
+    g_free (window->wmclass_class);
+  window->wmclass_class = g_strdup (wmclass_class);
+
+  if (GTK_WIDGET_REALIZED (window))
+    g_warning ("shouldn't set wmclass after window is realized!\n");
+}
+
+void
+gtk_window_set_focus (GtkWindow *window,
+                     GtkWidget *focus)
+{
+  GdkEventFocus event;
+
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (GTK_IS_WINDOW (window));
+
+  if (focus && !GTK_WIDGET_CAN_FOCUS (focus))
+    return;
+
+  if (window->focus_widget != focus)
+    {
+      if (window->focus_widget)
+       {
+         event.type = GDK_FOCUS_CHANGE;
+         event.window = window->focus_widget->window;
+         event.in = FALSE;
+
+         gtk_widget_event (window->focus_widget, (GdkEvent*) &event);
+       }
+
+      window->focus_widget = focus;
+
+      if (window->focus_widget)
+       {
+         event.type = GDK_FOCUS_CHANGE;
+         event.window = window->focus_widget->window;
+         event.in = TRUE;
+
+         gtk_widget_event (window->focus_widget, (GdkEvent*) &event);
+       }
+    }
+}
+
+void
+gtk_window_set_default (GtkWindow *window,
+                       GtkWidget *defaultw)
+{
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (GTK_IS_WINDOW (window));
+  g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (defaultw));
+
+  if (window->default_widget != defaultw)
+    {
+      if (window->default_widget)
+       {
+         GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
+         gtk_widget_draw_default (window->default_widget);
+       }
+
+      window->default_widget = defaultw;
+
+      if (window->default_widget)
+       {
+         GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
+         gtk_widget_draw_default (window->default_widget);
+       }
+    }
+}
+
+void
+gtk_window_set_policy (GtkWindow *window,
+                      gint       allow_shrink,
+                      gint       allow_grow,
+                      gint       auto_shrink)
+{
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (GTK_IS_WINDOW (window));
+
+  window->allow_shrink = (allow_shrink != FALSE);
+  window->allow_grow = (allow_grow != FALSE);
+  window->auto_shrink = (auto_shrink != FALSE);
+}
+
+void
+gtk_window_add_accelerator_table (GtkWindow           *window,
+                                 GtkAcceleratorTable *table)
+{
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (GTK_IS_WINDOW (window));
+
+  gtk_accelerator_table_ref (table);
+  window->accelerator_tables = g_list_prepend (window->accelerator_tables, table);
+}
+
+void
+gtk_window_remove_accelerator_table (GtkWindow           *window,
+                                    GtkAcceleratorTable *table)
+{
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (GTK_IS_WINDOW (window));
+
+  window->accelerator_tables = g_list_remove (window->accelerator_tables, table);
+  gtk_accelerator_table_unref (table);
+}
+
+void
+gtk_window_position (GtkWindow         *window,
+                    GtkWindowPosition  position)
+{
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (GTK_IS_WINDOW (window));
+
+  window->position = position;
+}
+
+static void
+gtk_window_marshal_signal_1 (GtkObject      *object,
+                            GtkSignalFunc   func,
+                            gpointer        func_data,
+                            GtkArg         *args)
+{
+  GtkWindowSignal1 rfunc;
+  gint *return_val;
+
+  rfunc = (GtkWindowSignal1) func;
+  return_val = GTK_RETLOC_BOOL (args[4]);
+
+  *return_val = (* rfunc) (object,
+                          GTK_VALUE_POINTER (args[0]),
+                          GTK_VALUE_POINTER (args[1]),
+                          GTK_VALUE_INT (args[2]),
+                          GTK_VALUE_INT (args[3]),
+                          func_data);
+}
+
+static void
+gtk_window_destroy (GtkObject *object)
+{
+  GtkWindow *window;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_WINDOW (object));
+
+  window = GTK_WINDOW (object);
+  g_free (window->title);
+
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+static void
+gtk_window_show (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_WINDOW (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
+  gtk_widget_map (widget);
+}
+
+static void
+gtk_window_hide (GtkWidget *widget)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_WINDOW (widget));
+
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
+  gtk_widget_unmap (widget);
+}
+
+static void
+gtk_window_map (GtkWidget *widget)
+{
+  GtkWindow *window;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_WINDOW (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_UNMAPPED);
+
+  gtk_window_move_resize (widget);
+  window = GTK_WINDOW (widget);
+
+  if (window->bin.child &&
+      GTK_WIDGET_VISIBLE (window->bin.child) &&
+      !GTK_WIDGET_MAPPED (window->bin.child))
+    gtk_widget_map (window->bin.child);
+
+  gtk_window_set_hints (widget, &widget->requisition);
+  gdk_window_show (widget->window);
+}
+
+static void
+gtk_window_unmap (GtkWidget *widget)
+{
+  GtkWindow *window;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_WINDOW (widget));
+
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
+  GTK_WIDGET_SET_FLAGS (widget, GTK_UNMAPPED);
+  gdk_window_hide (widget->window);
+
+  window = GTK_WINDOW (widget);
+  window->use_uposition = TRUE;
+}
+
+static void
+gtk_window_realize (GtkWidget *widget)
+{
+  GtkWindow *window;
+  GdkWindowAttr attributes;
+  gint attributes_mask;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_WINDOW (widget));
+
+  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+  window = GTK_WINDOW (widget);
+
+  switch (window->type)
+    {
+    case GTK_WINDOW_TOPLEVEL:
+      attributes.window_type = GDK_WINDOW_TOPLEVEL;
+      break;
+    case GTK_WINDOW_DIALOG:
+      attributes.window_type = GDK_WINDOW_DIALOG;
+      break;
+    case GTK_WINDOW_POPUP:
+      attributes.window_type = GDK_WINDOW_TEMP;
+      break;
+    }
+
+  attributes.title = window->title;
+  attributes.wmclass_name = window->wmclass_name;
+  attributes.wmclass_class = window->wmclass_class;
+  attributes.width = widget->allocation.width;
+  attributes.height = widget->allocation.height;
+  attributes.wclass = GDK_INPUT_OUTPUT;
+  attributes.visual = gtk_widget_get_visual (widget);
+  attributes.colormap = gtk_widget_get_colormap (widget);
+  attributes.event_mask = gtk_widget_get_events (widget);
+  attributes.event_mask |= (GDK_EXPOSURE_MASK |
+                           GDK_KEY_PRESS_MASK |
+                           GDK_ENTER_NOTIFY_MASK |
+                           GDK_LEAVE_NOTIFY_MASK |
+                           GDK_FOCUS_CHANGE_MASK |
+                           GDK_STRUCTURE_MASK);
+
+  attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
+  attributes_mask |= (window->title ? GDK_WA_TITLE : 0);
+  attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
+
+  widget->window = gdk_window_new (NULL, &attributes, attributes_mask);
+  gdk_window_set_user_data (widget->window, window);
+
+  widget->style = gtk_style_attach (widget->style, widget->window);
+  gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
+}
+
+static void
+gtk_window_size_request (GtkWidget      *widget,
+                        GtkRequisition *requisition)
+{
+  GtkWindow *window;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_WINDOW (widget));
+  g_return_if_fail (requisition != NULL);
+
+  window = GTK_WINDOW (widget);
+
+  if (window->bin.child)
+    {
+      requisition->width = GTK_CONTAINER (window)->border_width * 2;
+      requisition->height = GTK_CONTAINER (window)->border_width * 2;
+
+      gtk_widget_size_request (window->bin.child, &window->bin.child->requisition);
+
+      requisition->width += window->bin.child->requisition.width;
+      requisition->height += window->bin.child->requisition.height;
+    }
+  else
+    {
+      if (!GTK_WIDGET_VISIBLE (window))
+       window->need_resize = TRUE;
+    }
+}
+
+static void
+gtk_window_size_allocate (GtkWidget     *widget,
+                         GtkAllocation *allocation)
+{
+  GtkWindow *window;
+  GtkAllocation child_allocation;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_WINDOW (widget));
+  g_return_if_fail (allocation != NULL);
+
+  window = GTK_WINDOW (widget);
+  widget->allocation = *allocation;
+
+  if (window->bin.child && GTK_WIDGET_VISIBLE (window->bin.child))
+    {
+      child_allocation.x = GTK_CONTAINER (window)->border_width;
+      child_allocation.y = GTK_CONTAINER (window)->border_width;
+      child_allocation.width = allocation->width - child_allocation.x * 2;
+      child_allocation.height = allocation->height - child_allocation.y * 2;
+
+      gtk_widget_size_allocate (window->bin.child, &child_allocation);
+    }
+}
+
+static gint
+gtk_window_expose_event (GtkWidget      *widget,
+                        GdkEventExpose *event)
+{
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (!GTK_WIDGET_UNMAPPED (widget))
+    GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    if (GTK_WIDGET_CLASS (parent_class)->expose_event)
+      return (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
+
+  return FALSE;
+}
+
+static gint
+gtk_window_configure_event (GtkWidget         *widget,
+                           GdkEventConfigure *event)
+{
+  GtkWindow *window;
+  GtkAllocation allocation;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  window = GTK_WINDOW (widget);
+  window->handling_resize = TRUE;
+
+  allocation.x = 0;
+  allocation.y = 0;
+  allocation.width = event->width;
+  allocation.height = event->height;
+
+  gtk_widget_size_allocate (widget, &allocation);
+
+  if (window->bin.child &&
+      GTK_WIDGET_VISIBLE (window->bin.child) &&
+      !GTK_WIDGET_MAPPED (window->bin.child))
+    gtk_widget_map (window->bin.child);
+
+  window->resize_count -= 1;
+  if (window->resize_count == 0)
+    {
+      if ((event->width != widget->requisition.width) ||
+         (event->height != widget->requisition.height))
+       {
+         window->resize_count += 1;
+         gdk_window_resize (widget->window,
+                            widget->requisition.width,
+                            widget->requisition.height);
+       }
+    }
+  else if (window->resize_count < 0)
+    {
+      window->resize_count = 0;
+    }
+
+  window->handling_resize = FALSE;
+
+  return FALSE;
+}
+
+static gint
+gtk_window_key_press_event (GtkWidget   *widget,
+                           GdkEventKey *event)
+{
+  GtkWindow *window;
+  GtkDirectionType direction = 0;
+  gint return_val;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  window = GTK_WINDOW (widget);
+
+  return_val = FALSE;
+  if (window->focus_widget)
+    return_val = gtk_widget_event (window->focus_widget, (GdkEvent*) event);
+
+  if (!return_val && gtk_window_check_accelerator (window, event->keyval, event->state))
+    return_val = TRUE;
+
+  if (!return_val)
+    {
+      switch (event->keyval)
+       {
+       case GDK_space:
+         if (window->focus_widget)
+           {
+             gtk_widget_activate (window->focus_widget);
+             return_val = TRUE;
+           }
+         break;
+       case GDK_Return:
+       case GDK_KP_Enter:
+         if (window->default_widget)
+           {
+             gtk_widget_activate (window->default_widget);
+             return_val = TRUE;
+           }
+          else if (window->focus_widget)
+           {
+             gtk_widget_activate (window->focus_widget);
+             return_val = TRUE;
+           }
+         break;
+       case GDK_Up:
+       case GDK_Down:
+       case GDK_Left:
+       case GDK_Right:
+       case GDK_Tab:
+         switch (event->keyval)
+           {
+           case GDK_Up:
+             direction = GTK_DIR_UP;
+             break;
+           case GDK_Down:
+             direction = GTK_DIR_DOWN;
+             break;
+           case GDK_Left:
+             direction = GTK_DIR_LEFT;
+             break;
+           case GDK_Right:
+             direction = GTK_DIR_RIGHT;
+             break;
+           case GDK_Tab:
+             if (event->state & GDK_SHIFT_MASK)
+               direction = GTK_DIR_TAB_BACKWARD;
+             else
+               direction = GTK_DIR_TAB_FORWARD;
+              break;
+            default :
+              direction = GTK_DIR_UP; /* never reached, but makes compiler happy */
+           }
+
+         gtk_container_focus (GTK_CONTAINER (widget), direction);
+
+         if (!GTK_CONTAINER (window)->focus_child)
+           gtk_window_set_focus (GTK_WINDOW (widget), NULL);
+         else
+           return_val = TRUE;
+         break;
+       }
+    }
+
+  return return_val;
+}
+
+static gint
+gtk_window_key_release_event (GtkWidget   *widget,
+                             GdkEventKey *event)
+{
+  GtkWindow *window;
+  gint return_val;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  window = GTK_WINDOW (widget);
+  if (window->focus_widget)
+    return_val = gtk_widget_event (window->focus_widget, (GdkEvent*) event);
+
+  return return_val;
+}
+
+static gint
+gtk_window_enter_notify_event (GtkWidget        *widget,
+                              GdkEventCrossing *event)
+{
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  return FALSE;
+}
+
+static gint
+gtk_window_leave_notify_event (GtkWidget        *widget,
+                              GdkEventCrossing *event)
+{
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  return FALSE;
+}
+
+static gint
+gtk_window_focus_in_event (GtkWidget     *widget,
+                          GdkEventFocus *event)
+{
+  GtkWindow *window;
+  GdkEventFocus fevent;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  /* It appears spurious focus in events can occur when
+   *  the window is hidden. So we'll just check to see if
+   *  the window is visible before actually handling the
+   *  event
+   */
+  if (GTK_WIDGET_VISIBLE (widget))
+    {
+      window = GTK_WINDOW (widget);
+      if (window->focus_widget && !GTK_WIDGET_HAS_FOCUS (window->focus_widget))
+       {
+         fevent.type = GDK_FOCUS_CHANGE;
+         fevent.window = window->focus_widget->window;
+         fevent.in = TRUE;
+
+         gtk_widget_event (window->focus_widget, (GdkEvent*) &fevent);
+       }
+    }
+
+  return FALSE;
+}
+
+static gint
+gtk_window_focus_out_event (GtkWidget     *widget,
+                           GdkEventFocus *event)
+{
+  GtkWindow *window;
+  GdkEventFocus fevent;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  window = GTK_WINDOW (widget);
+  if (window->focus_widget && GTK_WIDGET_HAS_FOCUS (window->focus_widget))
+    {
+      fevent.type = GDK_FOCUS_CHANGE;
+      fevent.window = window->focus_widget->window;
+      fevent.in = FALSE;
+
+      gtk_widget_event (window->focus_widget, (GdkEvent*) &fevent);
+    }
+
+  return FALSE;
+}
+
+static void
+gtk_window_style_set_event (GtkWidget *widget,
+                           GdkEventClient *event)
+{
+  GdkAtom atom_default_colors;
+  GtkStyle *style_newdefault;
+  GdkAtom realtype;
+  gint retfmt, retlen;
+  GdkColor *data, *stylecolors;
+  int i = 0, j;
+  GdkColormap *widget_cmap;
+  
+  atom_default_colors = gdk_atom_intern("_GTK_DEFAULT_COLORS", FALSE);
+  
+  if(gdk_property_get (GDK_ROOT_PARENT(),
+                      atom_default_colors,
+                      GDK_NONE,
+                      0,
+                      sizeof(GdkColor) * GTK_STYLE_NUM_STYLECOLORS(),
+                      FALSE,
+                      &realtype,
+                      &retfmt,
+                      &retlen,
+                      (guchar *)&data) != TRUE
+     || retfmt != sizeof(gushort)) {
+    g_warning("gdk_property_get() failed in _GTK_STYLE_CHANGED\n");
+    return;
+  }
+  /* We have the color data, now let's interpret it */
+  style_newdefault = gtk_widget_get_default_style();
+  gtk_style_ref(style_newdefault);
+  stylecolors = (GdkColor *) style_newdefault;
+
+  widget_cmap = gtk_widget_get_colormap(widget);
+  for(i = 0; i < GTK_STYLE_NUM_STYLECOLORS(); i++) {
+    stylecolors[i] = data[i];
+    gdk_color_alloc(widget_cmap, &stylecolors[i]);
+  }
+
+  gtk_widget_set_default_style(style_newdefault);
+  gtk_style_unref(style_newdefault);
+
+  /* Now we need to redraw everything */
+  gtk_widget_draw(widget, NULL);
+  gtk_widget_draw_children(widget);
+}
+
+static gint
+gtk_window_client_event (GtkWidget     *widget,
+                        GdkEvent       *event)
+{
+  GdkAtom atom_styleset;
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  atom_styleset = gdk_atom_intern("_GTK_STYLE_CHANGED", FALSE);
+
+  if(event->client.message_type == atom_styleset) {
+    gtk_window_style_set_event(widget, event);    
+  }
+  return FALSE;
+}
+
+static gint
+gtk_window_need_resize (GtkContainer *container)
+{
+  GtkWindow *window;
+  gint return_val;
+
+  g_return_val_if_fail (container != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_WINDOW (container), FALSE);
+
+  return_val = FALSE;
+
+  window = GTK_WINDOW (container);
+  if (window->handling_resize)
+    return return_val;
+
+  if (GTK_WIDGET_VISIBLE (container))
+    {
+      window->need_resize = TRUE;
+      return_val = gtk_window_move_resize (GTK_WIDGET (window));
+      window->need_resize = FALSE;
+    }
+
+  return return_val;
+}
+
+static gint
+gtk_real_window_move_resize (GtkWindow *window,
+                            gint      *x,
+                            gint      *y,
+                            gint       width,
+                            gint       height)
+{
+  GtkWidget *widget;
+  GtkWidget *resize_container;
+  GSList *resize_widgets;
+  GSList *resize_containers;
+  GSList *tmp_list;
+  gint return_val;
+
+  g_return_val_if_fail (window != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
+  g_return_val_if_fail ((x != NULL) || (y != NULL), FALSE);
+
+  return_val = FALSE;
+
+  widget = GTK_WIDGET (window);
+
+  if ((*x != -1) && (*y != -1))
+    gdk_window_move (widget->window, *x, *y);
+
+  if ((widget->requisition.width == 0) ||
+      (widget->requisition.height == 0))
+    {
+      widget->requisition.width = 200;
+      widget->requisition.height = 200;
+    }
+
+  gdk_window_get_geometry (widget->window, NULL, NULL, &width, &height, NULL);
+  
+  resize_containers = NULL;
+
+  if ((window->auto_shrink &&
+       ((width != widget->requisition.width) ||
+       (height != widget->requisition.height))) ||
+      (width < widget->requisition.width) ||
+      (height < widget->requisition.height))
+    {
+      if (window->resize_count == 0)
+       {
+         window->resize_count += 1;
+         gdk_window_resize (widget->window,
+                            widget->requisition.width,
+                            widget->requisition.height);
+       }
+    }
+  else
+    {
+      /* The window hasn't changed size but one of its children
+       *  queued a resize request. Which means that the allocation
+       *  is not sufficient for the requisition of some child.
+       *  We've already performed a size request at this point,
+       *  so we simply need to run through the list of resize
+       *  widgets and reallocate their sizes appropriately. We
+       *  make the optimization of not performing reallocation
+       *  for a widget who also has a parent in the resize widgets
+       *  list.
+       */
+      resize_widgets = gtk_object_get_data (GTK_OBJECT (window), "resize_widgets");
+      gtk_object_set_data (GTK_OBJECT (window), "resize_widgets", NULL);
+
+      tmp_list = resize_widgets;
+      while (tmp_list)
+       {
+         widget = tmp_list->data;
+         tmp_list = tmp_list->next;
+         
+         /* referencing needed? */
+         GTK_WIDGET_UNSET_FLAGS (widget, GTK_RESIZE_NEEDED);
+         gtk_object_unref (GTK_OBJECT (widget));
+         
+         widget = widget->parent;
+
+         while (widget &&
+                ((widget->allocation.width < widget->requisition.width) ||
+                 (widget->allocation.height < widget->requisition.height)))
+           widget = widget->parent;
+         
+         if (widget)
+           GTK_WIDGET_SET_FLAGS (widget, GTK_RESIZE_NEEDED);
+       }
+
+      tmp_list = resize_widgets;
+      while (tmp_list)
+       {
+         widget = tmp_list->data;
+         tmp_list = tmp_list->next;
+
+         resize_container = widget->parent;
+         while (resize_container &&
+                !GTK_WIDGET_RESIZE_NEEDED (resize_container))
+           resize_container = resize_container->parent;
+
+         if (resize_container)
+           widget = resize_container->parent;
+         else
+           widget = NULL;
+         
+         while (widget)
+           {
+             if (GTK_WIDGET_RESIZE_NEEDED (widget))
+               {
+                 GTK_WIDGET_UNSET_FLAGS (resize_container, GTK_RESIZE_NEEDED);
+                 resize_container = widget;
+               }
+             widget = widget->parent;
+           }
+
+         if (resize_container &&
+             !g_slist_find (resize_containers, resize_container))
+           resize_containers = g_slist_prepend (resize_containers, resize_container);
+       }
+
+      g_slist_free (resize_widgets);
+
+      tmp_list = resize_containers;
+      while (tmp_list)
+       {
+         widget = tmp_list->data;
+         tmp_list = tmp_list->next;
+
+        GTK_WIDGET_UNSET_FLAGS (widget, GTK_RESIZE_NEEDED);
+         gtk_widget_size_allocate (widget, &widget->allocation);
+         gtk_widget_queue_draw (widget);
+       }
+
+      g_slist_free (resize_containers);
+    }
+
+  return return_val;
+}
+
+static gint
+gtk_window_move_resize (GtkWidget *widget)
+{
+  GtkWindow *window;
+  gint x, y;
+  gint width, height;
+  gint screen_width;
+  gint screen_height;
+  gint return_val;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
+
+  return_val = FALSE;
+
+  if (GTK_WIDGET_REALIZED (widget))
+    {
+      window = GTK_WINDOW (widget);
+
+      /* Remember old size, to know if we have to reset hints */
+      width = widget->requisition.width;
+      height = widget->requisition.height;
+      gtk_widget_size_request (widget, &widget->requisition);
+
+      if (GTK_WIDGET_MAPPED (widget) &&
+         (width != widget->requisition.width ||
+          height != widget->requisition.height))
+       gtk_window_set_hints (widget, &widget->requisition);
+
+      x = -1;
+      y = -1;
+      width = widget->requisition.width;
+      height = widget->requisition.height;
+
+      if (window->use_uposition)
+       switch (window->position)
+         {
+         case GTK_WIN_POS_CENTER:
+           x = (gdk_screen_width () - width) / 2;
+           y = (gdk_screen_height () - height) / 2;
+           gtk_widget_set_uposition (widget, x, y);
+           break;
+         case GTK_WIN_POS_MOUSE:
+           gdk_window_get_pointer (NULL, &x, &y, NULL);
+
+           x -= width / 2;
+           y -= height / 2;
+
+           screen_width = gdk_screen_width ();
+           screen_height = gdk_screen_height ();
+
+           if (x < 0)
+             x = 0;
+           else if (x > (screen_width - width))
+             x = screen_width - width;
+
+           if (y < 0)
+             y = 0;
+           else if (y > (screen_height - height))
+             y = screen_height - height;
+
+           gtk_widget_set_uposition (widget, x, y);
+           break;
+         }
+
+      gtk_signal_emit (GTK_OBJECT (widget), window_signals[MOVE_RESIZE],
+                       &x, &y, width, height, &return_val);
+    }
+
+  return return_val;
+}
+
+static void
+gtk_window_set_hints (GtkWidget      *widget,
+                     GtkRequisition *requisition)
+{
+  GtkWindow *window;
+  GtkWidgetAuxInfo *aux_info;
+  gint flags;
+  gint ux, uy;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_WINDOW (widget));
+  g_return_if_fail (requisition != NULL);
+
+  if (GTK_WIDGET_REALIZED (widget))
+    {
+      window = GTK_WINDOW (widget);
+
+      flags = 0;
+      ux = 0;
+      uy = 0;
+
+      aux_info = gtk_object_get_data (GTK_OBJECT (widget), "aux_info");
+      if (aux_info && (aux_info->x != -1) && (aux_info->y != -1))
+       {
+         ux = aux_info->x;
+         uy = aux_info->y;
+         flags |= GDK_HINT_POS;
+       }
+      if (!window->allow_shrink)
+       flags |= GDK_HINT_MIN_SIZE;
+      if (!window->allow_grow)
+       flags |= GDK_HINT_MAX_SIZE;
+
+      gdk_window_set_hints (widget->window, ux, uy,
+                           requisition->width, requisition->height,
+                           requisition->width, requisition->height,
+                           flags);
+
+      if (window->use_uposition && (flags & GDK_HINT_POS))
+       {
+         window->use_uposition = FALSE;
+         gdk_window_move (widget->window, ux, uy);
+       }
+    }
+}
+
+static gint
+gtk_window_check_accelerator (GtkWindow *window,
+                             gint       key,
+                             guint      mods)
+{
+  GtkAcceleratorTable *table;
+  GList *tmp;
+
+  if ((key >= 0x20) && (key <= 0xFF))
+    {
+      tmp = window->accelerator_tables;
+      while (tmp)
+       {
+         table = tmp->data;
+         tmp = tmp->next;
+
+         if (gtk_accelerator_table_check (table, key, mods))
+           return TRUE;
+       }
+
+      if (gtk_accelerator_table_check (NULL, key, mods))
+       return TRUE;
+    }
+
+  return FALSE;
+}
diff --git a/gtk/gtkwindow.h b/gtk/gtkwindow.h
new file mode 100644 (file)
index 0000000..ff22527
--- /dev/null
@@ -0,0 +1,105 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __GTK_WINDOW_H__
+#define __GTK_WINDOW_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkaccelerator.h>
+#include <gtk/gtkbin.h>
+#include <gtk/gtkenums.h>
+#include <gtk/gtkwidget.h>
+
+
+#define GTK_WINDOW(obj)          GTK_CHECK_CAST (obj, gtk_window_get_type (), GtkWindow)
+#define GTK_WINDOW_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_window_get_type (), GtkWindowClass)
+#define GTK_IS_WINDOW(obj)       GTK_CHECK_TYPE (obj, gtk_window_get_type ())
+
+
+typedef struct _GtkWindow       GtkWindow;
+typedef struct _GtkWindowClass  GtkWindowClass;
+
+struct _GtkWindow
+{
+  GtkBin bin;
+
+  gchar *title;
+  gchar *wmclass_name;
+  gchar *wmclass_class;
+  GtkWindowType type;
+  GList *accelerator_tables;
+
+  GtkWidget *focus_widget;
+  GtkWidget *default_widget;
+
+  gshort resize_count;
+  guint need_resize : 1;
+  guint allow_shrink : 1;
+  guint allow_grow : 1;
+  guint auto_shrink : 1;
+  guint handling_resize : 1;
+  guint position : 2;
+  guint use_uposition : 1;
+};
+
+struct _GtkWindowClass
+{
+  GtkBinClass parent_class;
+
+  gint (* move_resize) (GtkWindow *window,
+                       gint      *x,
+                       gint      *y,
+                       gint       width,
+                       gint       height);
+};
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+guint      gtk_window_get_type                 (void);
+GtkWidget* gtk_window_new                      (GtkWindowType        type);
+void       gtk_window_set_title                (GtkWindow           *window,
+                                               const gchar         *title);
+void       gtk_window_set_wmclass              (GtkWindow           *window,
+                                               gchar               *wmclass_name,
+                                               gchar               *wmclass_class);
+void       gtk_window_set_focus                (GtkWindow           *window,
+                                               GtkWidget           *focus);
+void       gtk_window_set_default              (GtkWindow           *window,
+                                               GtkWidget           *defaultw);
+void       gtk_window_set_policy               (GtkWindow           *window,
+                                               gint                 allow_shrink,
+                                               gint                 allow_grow,
+                                               gint                 auto_shrink);
+void       gtk_window_add_accelerator_table    (GtkWindow           *window,
+                                               GtkAcceleratorTable *table);
+void       gtk_window_remove_accelerator_table (GtkWindow           *window,
+                                               GtkAcceleratorTable *table);
+void       gtk_window_position                 (GtkWindow           *window,
+                                               GtkWindowPosition    position);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_WINDOW_H__ */
diff --git a/gtk/line-arrow.xbm b/gtk/line-arrow.xbm
new file mode 100644 (file)
index 0000000..493ecf3
--- /dev/null
@@ -0,0 +1,4 @@
+#define line_arrow_width 6
+#define line_arrow_height 9
+static unsigned char line_arrow_bits[] = {
+   0x00, 0x00, 0x04, 0x0c, 0x18, 0x3f, 0x18, 0x0c, 0x04};
diff --git a/gtk/line-wrap.xbm b/gtk/line-wrap.xbm
new file mode 100644 (file)
index 0000000..8242803
--- /dev/null
@@ -0,0 +1,4 @@
+#define line_wrap_width 6
+#define line_wrap_height 9
+static unsigned char line_wrap_bits[] = {
+  0x1e, 0x3e, 0x30, 0x30, 0x39, 0x1f, 0x0f, 0x0f, 0x1f, };
diff --git a/gtk/marble.xpm b/gtk/marble.xpm
new file mode 100644 (file)
index 0000000..1ef2607
--- /dev/null
@@ -0,0 +1,408 @@
+/* XPM */
+static char *granite07[] = {
+/* width height num_colors chars_per_pixel */
+"   384   384       16            1",
+/* colors */
+". c #000000",
+"# c #111111",
+"a c #222222",
+"b c #333333",
+"c c #444444",
+"d c #555555",
+"e c #666666",
+"f c #777777",
+"g c #888888",
+"h c #999999",
+"i c #aaaaaa",
+"j c #bbbbbb",
+"k c #cccccc",
+"l c #dddddd",
+"m c #eeeeee",
+"n c #ffffff",
+/* pixels */
+"aacfedbbcbbaaaaaaaaabaabaaaaabcbcbbbabbchfdcccbbabbbaaabaabcbaa#aa#######a#aaaabcddeefhec##dgbabbaaadabbcfbaa##########aaabbaaa#a#####a#aa###a#aaabbbbcbbbccdedaaaaa#aaaaa#a#abaaabbabbbeddbbaaaaaca##a#aaaba########aaaadcababbabdehd.##.a######.cgdcb###b##.##.##aaaaa####abcba######a##aac#a##a####aa#aa##babbbcfccbbbcdccccecbbbcbbbcdccddcbcdfeecbhhjihhgffc.aaa####.#######aaaaaaaabbaaaaa",
+"aaacedccbbcbaaaaaa#bbaabbbaaaabcaabbbbbbafhfccbbbbbbabacbacbaaaaa##########a###abbcdeghhhcagb#ababaaccbacdfca#a####aa###aaaaabaaa#####aca#aabaababbcccccccbcdfdaaaa###aaaaaaaaaaabbbbbbccccccbbcbcaaa##aaaaabaaaa###abdaccceebaaaabehja####a######..#aeec#bb##########aa#####abba#########aaca########aa#aa###aaaabddbbbbbbbbbbccbbabbbbabbabbabcbcbcefhfeddccefhhijheecb#...a####aaaaaaaabaaaaa",
+"aaabccccccdbabcbaaa#aaaaaaaaaaabbabbbbbccabefdccabcbbabacccbaaabaa######a######aaabceiiiihije#bbabbaaeaabcedcaabaa########aaaabaa##a###ab#aabcababbccccccdeeeecc#a##a##aaaaaaaaaabbbbbbbcccbbbdcbbcdaa#a#aabbaaaaa###acbaa#bccaa#abcfig.#######.#######acddgefdda#######a########a#######aaaaaa#a######aaaa#####aaacdcbabbaaabbbcaaaaaaaaabbbaaabbaabbbcbcbabbabcdeefghjkjgc#..####aaaaaaaaaaaa#",
+"#aaaaaacbccbcabbbaaaaaabcaaaaabbbbbbabbbcbaabffccbccbccbbcbaaaabaaaa#aa#aa##a#aaaaabbikkjhijicabbbcc#faaacdebcbda#########aaaaaaaaa####aa##cacccabcccdccccdddfdcbaa##a##abbbabccbbcbbbccccaaa#abbaaba#a##abbbbbaaaaaaaaaaccaaca##aabcfic.###aa#######a####bddeeddb####.##.###aaa#########aaaa###aa####aaaa#######aabdbbbbcabbbaaaa#aaaaaaaaabaaabbbaabbbbdbbaaabccccccdcefhhkhda##aaaa#a#aaaaa##",
+"#aaabaabcecbaa##bcaaaaaaaababbabaaabbabbaabb#chhfdccccbcbecaaabaaaaaaaaaa####aaaaaaabdgjkkijijdabbdcabfaabcecbbec###########a#aaaabaa#######abbaaaadddedddeeefeccaa###a#aabcccdcbcbbbbccbbbbaaaaa#aabbaaaabbbbbbaaaaaaabbbbbaaa####acegha##a#aabbb####a##adccdedbcc#######.###a###a#######aaa#a#aa##..#aa#########abdbaabbabbbaa###aaaaaaaaaaaaacbaaababbdbabbabcbbcbcbccbbdegjkgb#aa#aa#aaaaaaa",
+"##aa#aabccccaaaaaaaa#aaaaaabbaabbbaaaaabbbcbbcfhhgfcccbbbbccbaabbaaaaaaabaa#aaaabaaaabbcehkljjdabacccbgbaaccdb#adea#########aa#abaaaaa#####ac#ba##accdedddefffeaba##a#aaaaacccccccbbbcccaabaaaaaaaaa#aaaaabcbbaaa#bbbbaaefccdbaaa#aaacdei##aa##aabbbaaa#a#cdcccccbcea.#########bbaaa######a###a#aaaa.#aaba####.###abcbaaabaabbbaa###aaaaaaaaaaaabbaaaaaaaaaaababcbbcbbaabbbdddeghheba##ab#abaa##",
+"#####bbaaaaabaaaaa##aa#adccaabaaabbbbabbabbbabccbccfdbccbbbbbcaabcaabaaabbaaaaaaaaaaaabbbcglli#accbbbddgabcddbbaacea#a##########aaa#aaa##aaaa####aabcddeeefffgdbbaaaa###baabbbbbbcdabdcbcaaabaaaaaaa#aaaaaabcbbbbadfbbbaejhhebbccaaaaaccfi.aba##abaaaba####ecbbccba#fc.####.##.bba#a#######aaaaaaaaaaa##aaaa######abcdaa#aaaabaaa###aaaaabaaabbbaaba##aaababcbbcbbbbbcbaaabbccccddgggeb#aadca###",
+"#####bcaaaaaabcbaaa#aaaabcccaaaaaaabaaabbbbbbbaacbabeeddddccbcbbcccbabaaaabaabaaaaaaaaabbbbglmdbcbaabebdgdbcecbbaabdbaa#########aabbaaaa#aa#a##a#aabbdceeedccdcbbaaaaa##aaabbcbbbabaaabbababbaaaa#aaaaaaaabcdccbbbabcbbbcfijfbcdcabb#abcbif#abb##aaabaaaa##fcccbbcaa#db#..##.##.aaa#########ab#aaaaaa#aabaaaaa#####abdbbaaaabbaaaa###b#a#aaaabaaaaaaaaaaaaaabbabbbbaabbbaaaabbbbbbbceffecccbaa##",
+"#####abaaaaa#accbbbbaaabaaaaaaaaaaadcbaabbabbbabbdcaacgfddddcdddcadfcaaaabcbbabaaaaaabcabbbdjliacbababcbdfcdeeaaaaaabba########a##aa#aabaa##a######abddeggca#bcbaaaaaa####aaaaaabbbbbcbbbbbaaa##a#aaaaaaaabcbccbbaaaabaabfgfiecccccbbaaaccicbbbcbaaabaaabb#ceccccdca##aacdb######aaa###a###aabaaaaaa#aabca#abba#####abca##aaaaaaaaa##a##aaaaaaabaaaaaaabaaaacbcbacdbaaabaaaaaabaaaaabbcddccbaa##",
+"####aa#aaaaaaabccbabbaaaaaaaaaaaaabfaaabbcbbbbbabdebaabdffddedefedccecccdcbbbbbccbccbbbbbbccekldaabaaabccbfaaaaaaaaaaaba########aaaaaaaaba##aaa###aabbccfgfaababbbaaaaa#aabbaabaaccaabcccbcbaa##aaaaaabaabbbccbbbaabbbbbbdddghdbbbcccb#abcdebcccbaabbbabbcbaecddddbaa##.#acdeca#######a#aaaaaaaaaaaaaaabba##abba####aacba##aaaaaaaaaaaaa##aba#abaaaaaaabaaaabbbbbbcbabbaabbaaaaabaaaaaaaaccbaa##",
+".####aa#aabaa##bccbaabbbba#aaaaabbaefdaabbbbccbbbaddaaabadeeffhhhffdedddeecbbbbcccbbabcbabbcfjjlkeaaaaacdadcaa#aaaaaaa#ab######ba#aaabbabcaa#aa###babcddcedba##acbaaaaaa#ababbbacbbbcccdfffbaa#aaaacbaabcbabccbbcbbbbbbcbbccedbbbccdccbaabcgb#bccbbbababbbcccdededcb#a####...addcba##aabbbbbbbbaaaaabba#aaa##abba####abbaa###a#aa#aa##aaa#a##abaaaaaaaaabababbcdbcb#baaaaaaaaaaaaaaaaaa#aaaaa###",
+"######a##aaaaaa#accbaaabbbaaa#aaababdcaaabbbbcccbbbdbabbbacdccgecadbbbcdccddeddcccccbaabcbbcgjhhjgeb#aacdcccaa#aa#aaa#a#aaa##aaaaa#aaabbaabb#aa###aabccddeccbbbaabcbbbcbbb#aacbbadbabcccddbaaa#aaaaabbbbabbbbcdbbbabbcddcbbbccaabbbccbbaaaadi##abbbbbbbaabbbacdeedbd######aa####bceda#aabbabaaaaaaaaba#aaaaa#aabaaa###acaaaa####aa##aaaaaaaa#aaaaaaaaaaababaaaaabcaaaaaaabbcbaaaaaaaaa###aaaa###",
+"##########aabaa#accbbabbbbbba##aaaabbcbbbbbbbbcbaaabdbbbbbbddccbbbbaaaabbabbbbcefefdcbaadbcddje#debgfbabecdc####aa##a###a#aa#aa##a##aaabbcabbaa###aabbcceedbcbaaaabdcccbabaaabbbbabbccbbaaaaaa#aaaaaaaabbbbbcbccabcccccdcccbbbbabbababbba#abfe#aaaaaaaabccbbaaaedddc######adcaaaa##dfcaaaaaaaaaa#aaaaa##aabcaaabbaa#aaab###aa###aaaaaaaaaaaa##aaaaaaaaaabaaabaaabcabaaaaaaabcbaabaaa##a###aa####",
+"#########aaaaaaabbcbbbbabcbaacbaa##aaabaaabccccccbaabecabbbcddbacdeba#aaaaabaaabbdfgedcbaccdcgica#aadghdbddd#aa#aaa#a###aaaabaa#####aaaaabbbbbba#aaabccceecbddbaa#bbccabcbbbbbacccdbbdabbaaaaaaa#aaaa#aabbbbcccdcbcbbccccccbcaababbdbabbba#bbgaabaaa#aaacccdcddbeedba#a##a#aba#aaaa##decbaaba#aaa###a#a###abba#bba###aaba####a####aaaaaaaaaaaa#aaabbbaaabbaabbaabbaaa#aa#a#abbaabbbaaa#aaaa#####",
+"############aaaaaaacbbbbbbbaa#aaa#a##aaaaaaaacbbbbbbabdcabbbcdbaccdba#aaaaaababbcbbdddedccddefihaa#aaahiiiffd#aaaa#abaa##aaaaacaa##a#bcaaaabbbcaaaabccdddecabaaaaacbbbabbccccccbbdbdfdaabbaaa###a#aaaaaaaabbbbbbbaaabdcddccbbbbabbbccaabbbaabfdaaabaa#aa##aabbbbbddba##aa#a#aa##aaaaaabcdbbaaa##aa#####a#aaabbaaaaa##abb######aa###aaaaaaaaaaaaaaaaabaaaaaaaabbbbaaabaaa#aaaaaaabbbaaaaaaaaa####",
+"###########aa#aa#aaaccabbaaaaaaabb#######a#aaabcbbbabbaeebbccbcbacdaaa##a#aabbbbccbbcbcdegifdfgifba##aaaagigha#aaaaabbaaaaaaaaabaaa##acaaaaabbbbbbabcdddefeba####abbaabccccbbbcbadcbcbaabba#aaaa#aaaaaababacccbaadbabbccedcccbbccbbabaaaaa##ade###abba#aa##abbba#cebb.#a####.#a#aaaaaaaaacfca#aaa###aa###abaabaaaaaaaabbaa#######aaaaa#aa#aaaaaaaaaaababdaaabbbbbababaaaaaa#aaaaaabbaaabaaaaa###",
+"##########a#aaabaaaaccaaaaaaabaaaaaaba###a##abaaabbababaccbcbbcccaaba#a###aaabbccdccccccdeegggfigaabb#aaa#fffcba#abbaaaaaaaaaaa#abba##aaa##aabbbcbbbbcdeegfeb####aabaabacbbbcbccaabbabaaaaaaa##aa#aaaaababbabbcbcdbbcccbddcdcccabcbbababba###afba#aabba#acaaabbbbaddb##aa####.####aabbaaaabffcaaaaaa##a##bcabbaaaaaaabbbc#a#a#######aaaaa#####a##ababbbbbaaaabbcbaaaaaaaaaaa#aaaaaabaaababaaaaa#",
+"#######a#####a#aaaaabcbaaaaaa#aabaaaaaa###abbabaaaaaccaaabdbccbccbaaca#####accddcccccccddeeefikjeabcca#a#abfifbaa#abbbbbaaaaaaaaa#bbba#bcaaaaaaaccbcccceffeccaa##aaabbbcabbacbddbbaabdbaaaaaaaaaaaaaaabbbaabbbbbbbbbcbbccccdcdcccabbbbbaaba###dcaaaabbaaabaabcbccaadba#aaa########aaaa##aaaacgdbaaaa####cfffda#a#aaaabbdbaa#aaa########aaaa#aa##aaabbabbbaaabbbaaaaaabaaaaaaaa#aaaaabaaaaaaaaa#a",
+"a###########aaaaaaaabbaabaaa###abaaa#a##a###a#aaaaabacaaabccbbbcbbbcbb####a#bdfbbccccccdefecdgiiddaabbaaaabacfeaaaaaabcccbaaaaaaabaaacaa##aaaaaaabccddcfgfgbabaaa#aaabbcccbccbcddbbacabbbbbbbbaaacbaaaabcbabbbbbcbbcbccbccdccdccdcbaabbbaabaaade#aa#baaabaa##abbcbacdb#.#abbccc#.##aaa####aa#aeeaaaaaaabbabddfgfba#aabcd#aaaa########aa##a##aaaaaababbaabbbbbabccbababaaaaaaa##a#aaaabbaaaaaaaa#",
+"#a###a######aaaaaaaacdaaaaaaaa#aaaaaaaaaa#####a###abbbbaaaaccbbbcbbbbaa#aaaaaeecabcccbccdedcdfgigeaaaacbaaabaacbaaaaaaabcbbbaaaaaaaaabccaaaaaaaaaacccceffffbabb#a####aaaabcccccddcdedbbbbaabcabbbccbccbcbcbbbbbbbbbcecbccccceccccdccbbaaaaaaabce#bbaaa###aaa##ababcacda#abb##a#######a#########bfdca#abcbaabaabcffddbabdc#aaaaa##########aa####aaaaaaabbabbbbbbbcbbbcbaaaaaaaa#aa#aaaaaabaa##b##",
+"##a#########aabaaaabcdbabaaaaa##aaaaabaaba######a##ababbbbbabbbbcbcdddbbaa#abceecabccccccdddfedgjgdbaaabaaabbbaaba#aabaabaccaaaaaaaabbccbbbaaabaaabcddefgfebbbb#aa####aaaabbcccccbbfeccbbbaaababbbbbbbccba#abbbabbcdccdcbddcddcccdcddcbaaaaaabcfbadaa#######a#abbacbbcc###a#a########a######a##aabdcabccbbababaaaacdfededbbaa#aa##aa######ba#aa#aaabbabaababcbbcbcbbbabbaaaaaaaa##aaabaaacba#a##",
+"##########a#abaaaaabbbcbbbcaa###a#aaaaa##aba#######aaaaaabbdccbaabccdddecaaaabccdbbacccddcdefdfgiifcba#bbaaabbaaaababbbbbbbabbaabaaaacbbbcbbaaaaaaaceeeefffbaaaa###a##aaaabbcbbbddcddddcbcbbaaabbbbababbabaaabababbbbcccdccddcddccccdecaaaa#abccfbbaaa#######aabbaacabe###a#aa#a#a##.aa#######a#aa#cfeecdcccccabbbabacggcabbaaabbaaaa####aabb#aaaabbababbbbbbcccbbbbbcccbbbaaaa#aaaaaababbaaaa##",
+"######a####abcbaaaaabbccbcbaa###a##aaa##a###aa######aaaaaabdgebaaabbbccacbaaaaabbbaaabccddcdeeffgigbaaaaaabaabcaaababbbbaabbacbaaabbaaaababccbabbabbdffefhdcaaa###aaabba#aababcbdeeccceccccbababbbbabbabbaaaaaabbaabbcbcccccdcddddccccdcaaaababcdeaba#####.###aaabaab#b####a####a##aa#b########aaaaabedddcccccaaaabbcabeaaaabbccbaaa#abbaaabbbaaaabbbaaacbcbcbbdccbaabbacbbbbbaaaaaaaaabbaa#####",
+"######aaa#abbcbaaaaabdccbbaaa#######aaa#####aaa##a#a##aaaababcbbaaaaabdebbbaaa##aaaaaaaabccddeefggieaaaaaaaacabaabbbabbbbaaaabbaaaaaaabbbabbccbaabbbdfgghebbbaa#####abba#aabbbcbccdcbbbcddcccbbbabbabbbabbabaaaaaaacbbabcbbccccddddccbcccaaaaaabbdcbc##########aaacbbaa####a####aa###a#aa###aaa###abbceddedcccbaaaacccdca##a#abbbabaaaabaaabbba#aabbbbbbccbbbbaaacccbbcbbaaabbbbbbabaaabaaaa####",
+"#######aa#aaccabbabaabdecbb#a########aaaa####aaa#aba##a#aaaaaaabbdcaabdcbcaacb####abb#abaabccdeffghfdabaaaa#acbbbbcbabcabcbaaaabbbabaaaabbbbbcccbbbccdfedccbbb#########aaaababbacccbcbbbddbdcccccbbbbaaaabbaabbaaaaabaabbbbccdcceedccccacbaaaabbbbddb####aa######aabbaa####a####aa#aa###a#####aa#aabbddeccddccbbbabbbbceb###aa#aaaaaa##aa####aaaa#abbbbbccacccbaa#accbbbbbaaababbabaaaaaaaaa####",
+"##a#####aaaaaabbbbabacdddccaa########aa#a#####aaa#aa#aaaaaaaaaaaabcabbcbbbbababa###baaaaaaabccdeeehifbabaaa###abbcbbcaccbcbbbaabbbbabaaabbbbbbbbcccccddbccbbbbba#######aaabbbaabbcccbdcbbdbbddcdcccbabaabaaaaaaaaaaaaaaaabbcccddecccbbacccbbbaabbbceca############aaaaa#############a#############aaaaabccddcbbbabbbbbbba#####a##a####aaa#######aaa#babaabbcbaaa##abbbaabbcbbbbaaaaaaaabbaaa####",
+"#########abaaabbabbbbbddeccca##aa######a#aa####bbaaaaaaaaaaaaaaaaaabccbcccebacfdb#####aaaaaaabcdddcfgfccbaa##a##abcbbcbbdcccccabbabaababbbbbbbbbbcdccddbabbbbbba########aaababbbacdccccaabcbbcabddddbbaaabbabbbaaaaaaaaabbbddcddecbccbbbdcbabbbaabbcda#############abaaaa############a####bb##a####aaaaabcffdcccbbbbbbbb#######aaa###aaaa#######aabaaaabbcbaaaaaaaa#aaaaaabbccbbaaaaaabbbaaa####",
+"#########aaabbabcbbbbbdddcbaaaaa###############aabaaaa#aaaaaaaaaaabbabbdefffccbba###aa##aaaaaabcdceecggdcbbaa##aa#aacbb#bcdddddabbbbbabbbabbbbbbbccfeedbbbbbbcbba#a#####a#acababbbdcbcbabbabaabaabeedcaaaaaaaabcbbaaaaaaabbcdfdddccbbbbcbccbabbbaaabcda########a#aaaaaaa#aa#####aaabaaaaaaacb##aaa#aaababbcdefddbbcbccbaa#####aaaaaaaab##a########aa#abbcccbaaaaaa###aaaaabaabccbbbaaaaaaaaa####",
+"########aaaaaaabbbbbbcdedbbbbabaa##########aa###bbb###a##aaaaaaabbaabbbdfeedb##a#a##aa###aaabbbbccdefbfecbbbaaa####a#adb#acdecdfcbaabcbbbbcbbbbbbcdeffbcccabbcdbbba#a###a#aabaaaaaccccbaaaaabbbbaabdfedaaaababbbbbaaaaaaababbcedcccbbbbaccccbaaaccbbabeb######aaaaa#aaa###a######aaaaaaabacbca#aaaaaabbbbccdegfeccccccbcbaaa#####aaaa#aaaaa###a###aaaabbbcccb##a#aaa#aaaaaaaabbdeddcbabaaaaa####",
+"#########a#aabbbbbbbbdddccbbba#aaaa##aa##a####a#bba#a#a#aaaabaabbbabbeedeeefdaaaa#####bb##aaabbabcddehgifffdcbaaaa#aa#aaaaaccdeddcabbbcbbbccbabbccdceeecdcaaaabbcccaaaaaaaaaaaaaabacdddbaabaabbbbcccccfdbaabbaabbcaaaaaaababbcccccbbbbbbbccbcca#acbbbbbda#####aaaa####ab##a######aaaaaaabaccbaaaaabbbbbbccceffcdeedcbbbbaaaa#aaaaaaaaa#aaabaaaaaa##aaaabbbcbbcbaa#####aaaaaabbbcccddcbbaaaaa####",
+"##########a#aabbcbcbbcecccbbbabaaaaaa#####a#aaaabbaa##ba#acaaababbbbbbbcdcfgdbbbaa####aba##aaaabbbccdfefhfgedecaaa##abaaaaacbabebbbbbbbbcccbcbbbbddbedbddcaaaaaabdccaaba#aaaaaa#bbbbbaddccaaabcbbdcbbcbddabbbbbbbccaaaaaaaaabcddcbbbbbbbbbbbbbbaaaabbaabe#########a####bb#aa#####aa#aaaabccdbbbbabbcbbbccccdccbaaeffdbca#aaaa#aaaaaaa#aaaaabaaaa#aaaabaabbccbbcceb#bcaaaaaaaabbbbcdcbbbaaaaa####",
+"#######aa#aaaaabbccbbcdccddcabaaaaaaaaa###aaa#aabcaaa#bba#aabaabbbbbbabcccdfedcaa##aaa######aaaabbbbcdddghhgfedcbaaaa#aaaaabcbbbccbbbbbbbcbccdcccccbeebccbbbaaaaaccccccba#aaaaaaabaaabbbddbbbbcccbcccbaceeacbbbcbccbaaabbabbbbceccbbbbbabbbbbbbab#aabbbbcc#.######a####.bcbcba####aaaa#bedccbbbbbbbaabccddedaaaaa##beeda#aaaaaaaaaaaaaaaaaaaaabba##babbabbbbcbbbccccbbaaaaabbabaabddcbbbaaaa####",
+"##########aaaabbbbccccbcddddbaaaa##a#a#a###aaaa#baabbaaaaaaaabbbabcbaabccbddfebaaba#ba######aaaabbbbbcddfiiigggedbaaaaaaaaaabcbabccbbbbbbbcccddddccceecccccbbaaaabccddbbba#aaaaaaaaabcbbbcccdccbcbabcbabceecbabbbbbbaaaabaabbbcddbbbbbbbbaabbbcbbbbaaabcbdc########..####ccccba#abbaaaabddbabbbcabbbbcccceeca###aaa##aaa##a#aaaaaaaaaaaaaaaaaaaaa##aabcbbbbbbbccbbbbcddaaaaacbaaaabddbbaaaaaa###",
+"############aaabbabcddccdbcdcbcbbbaaaaa##a##aaaa##abaaabaaaaaaabbaacaabddabcefc#aabaaa###a####aaabbbbbbddgihhfffgeaaaaaaaaaaaaabbbcbbbbbbbbbcddeeedceccdcccccaaaaabcbddbaa#a#ab#aaacbbbbbbddebbbbccbbbabbbedbaaaaaaaaaaaabbabbccecbbbbccbbbbaabbbbcc#aaabbcc######a#####.bccabbacbababaabdcabbbabbabbbcbdecabaa##aaaa####aaaaba##aaaaabaaababa##aa#aaabbbbbbbbcbbbbacbedbaaa#bbaaaabcbbbbaaaa#aa",
+"#######a####aaaaabaabbcccbabbbbbbbcbaaa######a#aa######aaaa#aaa#acbbbabeeebabddbaaabaa####aa#a#aababbbbbcehhgeeffdca##aaaaaaaaaabbbbabbbbbbcdcdddfgfhcbbcbbbcbaaaaabcccdbba###baaaabcbbaabcdeecaaabbbbbbaabddecaaaaaaaabbbbbbbccfcbcbbbbbbbaaaaabbbcca#aabacc#######a####acdcbbbbbbaaaabbccaabbbbbbbabbceecabb#aa#aaaa#######aaa##aaaaaaabbaaaaaaaaaaaabbbaabccbbcbaaacgdaaaa#aababbbabbbbaaaaa#",
+"###a#####a#aaaaaabcbacbbddcaaabbbbbbbaaaaaa##a#####a####aaaaa#aaabdbcbbedefcaaabaaaaabaaa#a##abaaaaababbbcfgggfeefea##aaaaaaaaaaabcbbbbbbbbcdcdddefgeabbbbaabccaabaaceddeeaaa##aaaaaabbbabbcdedbabbbaaaaaaaacfecaaaaabaabbbbbbcdfdbccbbbbbaaaaaabbbcdbaa#aabdb#########a#acdcccbaaab#aabccbbbbbbabbbceedccbcbbaaaa#baa#a###a#a##aa###aaaabaaaaaaaa##aaaabbaaabcbbbbbabbdfeaaaa#ababbcbbaabaaaaaa",
+"#####a#####aaaaaabbbbbbbcddcbabccaaabbaaaaa#a##a##a######aaaaaabaaaaacbbbffeaaaababbabbbbbaa##bbaaaabbbbcccghghgeffbaaabbaaaaaabbabccbbbbbbcdddefggecccbabaaabbbacbabbdddecbaa####aabaababbcccdcabaa#aaa###abceedcaaaaabbbbccddefdccdccbcbbaaaaabbccdccdb#abbd###a#####a#a#cddcccaaaaaaaaabccbbbbdeefbba##aabaaa#aaaaaa#aa###aaa##a####aaaaaaaaaaaa##aaaabacbabbbbbcbbbbcfgbaaa#aa#abbab#aaaabba",
+"##########abaaabbbbbcbcdcccdcbbbcbbbbbba#aaaaa#a############aa#aaaaaaababbdeaaaacbbbbbddcbaaa##abaaaabbbbcccghhhedecababcbaaaaaababcbbbbbccbddceggffecccbbbaaabca#aaaadddedcb#a##aaaabbbabbbbcccdd###aaaa#aa##bcefeddcddccefdddfdcccccccccbbaaaaaabccccdddaabbda########ab##bbbddcbbaa#aaaabcbbbcdddccaaaaa#abaaaaaaaaaa#aa#aaaabaa#####aaaaaaaa#######aabaacbabbbbbbcbbbbdfbbaaaa###baabaabaaba",
+"###########aaaabbcbbbcccbddbcdccbbbbcabbaaaaaaaaa###a##aa###aaaabaaababbccbbdb#abccabddbbbba#aaaabdbbaabbbbcdehihbaabbbbcdcbbbbaababbedcbbaccdddeeefedabbabaaa#aaa#aa#beeeeffca###aaabbbcbbbbbbcced#a###a##aaa#abffgfedcccfhcbdebcbccdccccbbaaaaaabbcccccddbaabdcb#.#aa#aaa##abdddcbbbaaababbbbbcbdbabbbbbb##ababbbaaaaa#aa#aa##aaa######ababaaa#####a#aabcbbbabbbbbbcccbbbeabcbba###aaaaaaaaaab",
+"b#########aaaaababbbbabbbbdebcccccbbbabaaaaaaaaaaaa########aa#abbaaabbabbdbcbbbaaadcbcbdbabba##aa##abcb#aaabcdcfhgdabbbccdcbcbbbbbbabcgdcbdbbdedeeehfgdbbbbbaaaa#aaa#abddddgeedcaaaaaabbbdccccccbceeaa###a###aaaacfghhgedccggefbccccccccccbbbbbbaabbcccccccdaabaaccb#aaa###a##adedccbcbaaabbbbcbbcddbaaabbbbaadbbaabbaaa##abaaa#aaaaaaaa#aaabaa########abbadccaaabbbcccccbbdcbcbbba###aaaaaaaabb",
+"aa##########aaabbbbbbbaabbaccbceeebbaabbaabaaabbbbaaa###aaaba#aabaaaaababbccggcbaabccbbbccbca##aaaabdbbabbabbcdddghbabbccddcbbbcbbbbbccgfcbccceddddeddedddcbababaaaaaa#accdeffedbaaaaaaaacccccbbbccffb#a#####aaaaabfhgghhhhgghecbccbccccccccbbbbaaabbbbcbbbcdcbbabbcb#####abca#abccccccabbbbbbbbbdddbaaaaabab#cdba#aabaaaaaaaa#aaa#a#aa#####aaaa#######aabbbbccbbbabbdeddcbbeaabbcb###aaaaaaaaab",
+"baaa######a#aaabaabdbbcbabbaccccedaaaaaaaaaaaaaaadbaa#aaaa##aaaaaaaaabbbcbcccdbaaaaabdcbacbcdcaaaaaaaabaaccbbccdddhgcabcccdecbcbbcbbabadedbbcdedcddeeccdddeeedcbbcbaabbbabbcddddec#aaaaaabbcccccbccdffc##a##a#aaaaaafheffhgeccefcbbcbcccccccbbbbaaabbbbccbbddedbabbcc.##a##abc###cdcccbcbbbabbbaddccababbbaaabaddba##aaaaaa#aaa#a#aaaaa##aa##aaaa#######abbbbccbcbbbbdefeeccecaaaaa####aabaaaaaa",
+"bb#a########aabbbaaababcccdaacdbbaba#aaaaaa#aaa##acaa###aa#aaaaaaaaaaabcdcccaaaaaaaaadbcbbbbacc###aaaaaaaacbbccdcdfggbbbcccdecccddcbbbacdfdbcdebbbcccdcccccdcbefccbaaaaabcbbccabdfcaaaaaaabbdddccccccefe##a##aaaaaaaadfghhhdbbcccccbcbbccdccbbbcaaaabbbbdccddeeba#bbda######.acabbddccabcbbbbbbbddccaaaaaaaaaaabdca#a#aaa#aaaaa##a#aaaaa##aa##aaa#a##a##abbbbccbbdbbccefffeccd#a########abaaaaaa",
+"aa##########aaaaabaabbaaccdcaacbbaab####aaaa#aaaaaa#a####abaaaaaaabcaaabddcacda#aaabacbbbbddddcbaaa##aaaaa#abbdcccdegfbbcdcdefccddccccbcbbfdccecabccbcbbbcdddcbffdcccb#aacbaabcbbeecaa#aaaabcedddccccddfeb#####aaaaaabbehhfcccbcccccbbccccccbcbcbbaaabbbcdcceddcbbabba########bcbbcdcbbbbbbbbaacccccaaaaaaaaaaaabcba####aba##aaaaaa#aaaaaa##a#aaaaaaa#aaabaabbcbbbbbbbdffffeeeaa########aabcaaaa",
+"aba#a#aa####aaaaabbabbabbaccaaabaaaa#######a####aaaaa####aaa#bbaaaabaaacbddcbccaaaaaaaaaaacdeabcbba#a###a#aaabccccdeegfcbcdddeedcdccddccccfedddcbbccbbbbbbccddedecccdca#aaaaaaabacedcddcbabaabccccccccceccd####aaaaaabaacdghhfecccccbbccccccccbcbbbaabbbcccccddcddceaca########cdccdccbbbbbbbbbccbcdcaaaaaaaaaaaaaaba#####aaaaaaa###aaaaa##a####aaaa###aabbbbbbccbdbbbcdefffgaa#a#######aabaaaaa",
+"aa#####aa###aaababbccccbbbbcbaaababa#######a#aabaaaaaa####aa#abbaaaabbaabbdcbbcdbbbbaaaaaabcddbcbba#####a#aaabcdccceefhgbbdcceeeeccccccddeefeeecccacccbcbabbccdefdbcebaaaabaababbbcdcdfffdabbbbbcccccccecade#aa#aabaaaabaackijkidbbbcbccccccccbcbbbbaabbccccccccddegfdaa#######ceedcbbcaacccccbcccccbaaaaaaaaaabaaaaaaaaa####aaa.baa######aaaa####baaa#aaaabbbbbccdcbbcddedfgfb##########abbaaa#",
+"#a########aaaaaaccbbcdcccbbbba#aaaaaa#####aa#aaab#aaaa#.###aa#aabababcbabaccbccdedaaaa#aaaaabccacbaa#a######aacbcccdffhigeccccdeedddccbcddffdefcbabbbcdecbabbbbcddecddbbaaabbabbbcccddeeffabbabbbbcccccdecdedb#a#aaabbaaaaahifgikfcbcccccccccccbbaaabbcbbbccbbbbcccdhea#a#####aedfebccccbbcbcccccccbaaaaaabaa#aaaaaaaaaba#b###aaa#b#######a####aa##abbbabaaabbbbbcdecbbcdedefghc#########abcedcb",
+"a############a#abcbbbcddccbbbcaaaaaa#a####a#a###ba#aa#######aaba#bbbbbccaabcccddeebaaaa##aaaabaaabaaaa#####a#aaaabcbdeggihfccccdddffdcbcccdfcbcbbbbbbccbbbbabaabcdfebcbbca##aabbbbcdcdfffeeaabbbccbbcccdeeddeed##aaabaaaaachgcccfijebbcccccccccbbaaaaabbbaabbaabbcbbcfecaaa#aaadcddbbdcccabbcccbbbabbaaaa#aaa###aaaaaaaaaaaaa##aaaaba######a######a#abbbbbbabbcbbbddcabcddddefgfa########aacedcc",
+"#######aaa#####aaaccccddcdcccbbaaaaa####a####a#aaaa#aa#######abaaabbccacdaadccdddccba#aa#bbaaabaaabaaaaaa#aaaaaababbbdeffiiebcccdddeedcccdcfbcbbbbaabcbbbbbbaaaabcdeefeeddedbaaabcbdccefffffabbbbbbbbbcdcdddddefbaabbbbabaeidccddcejgbbccccccccbbbbaaabaaaaabaaabccccdffebaabbaaddcc#cdccabcccccbbbbbaaaaa#aaaa##aa#aaaaaaaaabaaaba#b##a####a#a#a##a#aabbabbaabbbbddecbbdcccddeega.##.#a##aab###",
+"#########a#####ababccbbbdcccccabbb##aaaaaa#aaaaa##aaaaaa#..###aaaaaaccbbdcbbccdbccdaa##a#a#aaaaaa#ba###a#a#aaaaaaabbbcdeefhgeccedbbcdedeedgebbbbbbbbcdcbbbaabaaabacccddccccbdcaabbadddeefffgfbabbbbccccccccdddbggbaabbbbabhefcccddddihdccccccccbbbababaaa###aa#aabbbcdeeffa.##abcfedabccbcccabcbbbbbbabaaaaa###aaaaaaaabaaaaaaaaaaaaba#######aaab#####aaabaaaabbbaceffecbccddccdec#####.##aa#aa#",
+"#aa########a####abbccbbccdcccbbbbba#a##aaaaabaa#aa####aaba#.##baaaabccdabdbabbbbbcccbaa####aaaaaaa#aaaa######aaaabbabccdfeehihfggfdbceedddeddfdccbbcbbbbbbbbbbaaabaccccbbccdddecababedefffffhgdaaabccbcccccdddbfhfbbbcbbackdeeccdddccfhgbccccbbbaabaaabba#####a#aabbbdeddeda.###aeddcbaaccccccccbbbbbabaaaaaaaaaa##aba##abbaaaaaaaaaab######aa##aa###aaabbbaaaaabbbeffffdcdcdeffda######.###aaa#",
+"#aaa############aabcdcbcdcfedeecbbaba##aaaaabaa###b#a##aaaa####abaaacdcaacdaacbcaaaaaaaabc##aaaabaaaaaa######aaaaabbbdddeddfhhhhhhfcccffffdbaabcbdbabbbbbbbbbbaaaaabbcccbbbbcfdedbbadeddeefdefhffecbbcbcccccceddgibbbbbbdecccbbccccddddhidccccbbaacaaabba########aabccedddeda####cdcecbccccddddcbbbbbabbaaa#a#####a#######abaaaaaaa#aaaa#a##aaaa#a####aabaaaaaaaaabccddfgfddefge################",
+"##aaaaa#aa######aaabdccbccdeefebbaccb###aaabcbaa########aa######aaba#bdbbbcabbbbbbaaba##aba#####ababaaa##a#a##aaaabbcddedddeeefhghfddccdhecbbbaaaababbbabbabcbaaaaaabbccbbbbbbeefdbbbddbddffdggihiebbbcbbcccccedeicbcbbcdccccccccddddddcfifccbbbbabbabbbaaa####aa#aabcedddefeb##.bdcdeccbcccdddcbabbbbaaaaaa#aa############abaa#aaaaa#aaaaaaaaaa#######aabaaaaaaaabbabbcefgecbcc############a#a#",
+"##aaaa####aa##a##aaabcdcbbccdcdccbcaba##aaaabbbaa#aa#a####a######aabaaabaaaaaaaabbba#aa###a##a###abbbaa#aaaa#a##aabbcededddddeghggcdfedffddcbbbaaabbbbbccabbbbbcaaaaabccbbbbbbeccefdbcdbcbcefefhgghdbbcbcccccccdcefedbadccbbcccccddddddddeggcbbbaacaabbbaaa######aaaabdcdeedefbaa#deddcdcbbcdedccbbbcbaaaaaa##################aaaaa#aa##abaaaa#aaa#aa##aaaaaaaaaabaabbacdbacbaaba###############",
+"##a#aaa####aa##a##aaabbbbbcdeccbbaaaaabbaaabbaabaa###aaaa#########aaab#aaaaaaaaabbaaaa#a#a#aa#a#aabaaaa###abb##aaaaabcdeeddefghhhebbbfebbdddccbbbbbaaabdcbcbcbacbaaabbabcbbcccddbbcefecdcbbbcddehgggcbbcbcccccccdddffbbdbbbbbccccddddddddddegcbbaabaaabbbaaa######aaabbbcdefdeca#ddedcdddbacadedccbbbbbabaaaa###############.####aaa##a###a##aaa#aaa#abaabaaaaaaaaaaaaabcdbaaaa#a########a##a###",
+"a##a#aaaa#####aaaaaaabcccbbcdebbaaba#a#bbaaabbaaaa####aaa#####aa#abaaaaaaaabaaaaaabbbaaaaaa#aaaaaababaaa####aaaaaaaabcddddefedhhgbbbbcefbcdedcedabbbababbbcbbbbbbaaabbaabbbbbcbcddbbbcdcebbbbdcabehhebbbbcccccccceddhfddbbbbbccccddddddddddcdfdaaaaaababbaaaaaaaaaaabbbbccddcdfededffddddcbcabcddccbbcbbaaaaa#####################aa##a#a#######aa###aaaaaa###aaaaaaaaaabbccaabaaaa######a######",
+"aaaabaa##aa####aaaaaabbccccbcccaabbba#a##aaaabbb######aaaaba##aaaaababb##aaaaaa#aabaaaa#aaa#aabaaaaaacbaa####aaaaaaabcdeddefefhheabbbbbdfgfgedcfaaabbbbbbaaaaaacabaa#baaabbabaabbdeeeccabdccbbbcaachifbbbcccccbcccddejkeabbbbccccddddddddddccceebabbaabaaaaaaa#aaaabbbcbbcccddefgedfedddcccbaabcdcccbcbcaabaaaa########.##.########aa###a########aaaaa#a###a###aaaaaaaaababccaabaa#########aa#a#",
+"##aaaacb########aaaaabbbbcccbdcddbbcbc#aaaca##a#aba######abca#aaaa#aa###aa###aaaaaabbaaa#a###aaaaaaa##bcbba###a#aaaabbceedddehgfdaaabaccbfhiihffcaaaaccbaaaaaaacabaaabbaabcbbbbbbbcbdeffedfdb#acaabafjgbbcbcccbccccdefiicbbbbacccddddddddccccbbcfbbbbbabaaaaaaaaaabbbcbbbbccccdegfecfdbaabdabbbbcccdcccbbbbaaaa###################a#aa##a#a##a####a#aaaaa###########aaaaaabbbbbaabaa#######aa###",
+"###aaacba#######abaabbdcbbcdcbbefcbabcbbaaaaa####aa#a#a#a#a##aaab###a#aa####abb#a#aacbaa####aaaaaaa#aaabdcbaaaaaaaaabaceefeeffffbaaabbabccehigfeeddefdbabaaaaabbbabaabaaaaabbbbbbabccbabdedda##aaabbachhbbcbccccbbcccdeghebbbaccddddddddddccccbacecbabaaaaaa#aaaaabbbccbbbbcccdcdgfdfebbbbbcccbcbcddccccccbbaaaaa################aabbaaaa####aa###a##aba#############aaaaabbbddbbaba##########.#",
+"####aaaba#######aaaaabdfdbbcccbbdebbaaaab#aaa#a###aa###aaa###aba#####aaa#####aba#aaa#baaa#####aaaaa###aabcccaabbbbbcbbbdfffgeccebaaabbbbcbbeffedccfghhebaaaaaabbaaaaaaaabaabbabbbbbacbbbbcbdda####abbabghabbbccccbbccddddghdaabcddddeedddddcccbbabdfdaaaaa##aaaaaabccccccbbccddcbefdffdcbbbcdccbbccddcccccbbbaaaa################bbccbaabaa#aaaaaa#aabba##a#########a#aaaaabbccbcabaa###########",
+"#####aaaba#######aaacccefcccbcdccbcbbaaaaa#abcba#########aaaaaaa######aaaa####aa##aaa#aaaaaaa##aaaaa##aaaccddcccdddddcceeffdccdccbaaaaabbbbcfggdddfffggfebaaaaaaaaaabaaabccbbbbbbbabccbbbbbcbdb###aabbbbghbacccccccccccdddfigdbcddddddeddddcccbbbabbfeabaa#####aaaabcccccbcbdddecegfffcccabbccccbbccdcccccbbbbaaaa############a#aaaababaaaaaaa#aaa##aaaa#aaa##########aaaaaabbcccbbdba#########.",
+"#####aaaaa######aaabddefcccbabdccccbaaaaaa###aaa######aaabaabbba#######aaaa####a###aaaaaa#a##a#aaaaaaaaaabcddddcdeeedefgfefecdaabbaaaaabbbbbadfebcfdfgffeeecaaaaaaabaaacabdbaaabbbcdcbbbbbbbbccb#a###abbaegcabccccdcccccdddcfihfdccdddddddddcccbaaaaaddbaa######aaabccccbcbccdddhfcfgecccbbbbcbccbccbccbcccbbbbaaaa#a##########aaaaaabccbcba#aa#aa#aaaaa#aaaaa###########aaaabbaddedaa##a#.#####",
+"####aaaaaa#######cffdabcbcdcbbadfbcbbaa###a#aaa#aaaaaaabaaaababaa#######a##a#########aaa##aa##aa#aaaaaaaaabdeddccddddddffeeeec#a#aaabbbaaabbbcggdcfeeeeegfdccbabccbbaaabbbcaaaaabbbcdbbbbccbbbdbaaa###abbccebabbccccbcccccddcdfhjhedddddddddccbbaaaaaabdda#######aaabbddccbbdddedccdgeeedccbbccdccbccbcbccccbbbaaaaa#########.##aaabbaabbbcbaaa###aaaaaaa#a#a#a########aaaaabbaccddeb###########",
+"########aaa######acddbabcbbcccabcddcaabbaaa##aaaaaabbbcaaaabbaaaaaba########aaa#aa###aaa###aa##abaaaaaacbbbcdffeddeccdffffeddbaaaa#abbaaaabaabegebdfeddeffeddddcdddcabbacbcbccbaabbacccbcdbbbcdb#aa##aabbbbbffbbccccbccccccdddedfkkidddddddcccbbaaaaabbabdb#a#####abcccdbccccddfcccdfgeedccbbbcbccccbbabbcccbbbbbbaaa############a#a#aaaacacbaaa####aaa#aa###a##a######aaabaabbbbbbdfa##########",
+"#################abbcbaacccccbccaacbcaaaaaaaaaaaaaaabccabbbbaaab##bb######a#aba##aa##aaaaa##a#a#acabbbacdcbcddffffdgeefefeddcb#a##aaaaabaaaaaaddfdcfdccccccdcbcbcccecbbabccdddddcbbbbccccccbbbceb#aa###aaaabbfgbacccbcccdcdddeedgjkihccddcccccbbaaaabaabaadca####aabbcccbcddccefdcdeeeedddcacbccccccbabaaabbbbbbbaaaa###########.#####aaaabacbba##aaaaaaa####a####a######abbabbcbcbcdb###a##.##.",
+"###########aa#####bdbaaaaccddbbdcba#bbaa##aa#aaaabbbbbbaaabaaaaba##aa.####aaa##a#aaaaaabbbaa#####abaabbbbbccdddeefeffddefdccaa####aaaaaaaaaabaeefdedeccbabbbdddbbccccabbbbbbbbcdcccbcccccccccbaaaa#a####aaaabacgcabbcccdddefffedgijfehdcccccccbbbaa#aaaaaaabcbaaaaaabbccdcdddefgecddeefedccbbbabccbbbbaaaaaabbbbaaaaaa################aaabcbabbaa#aaaaa#aaa###a####a####aaabaabcbbbcbba###aa####",
+"############a#####abaaaaaabddccbcdddbaaaa###aaaabaaabbbaaaabbabba###b######aa######a##aacbcbba##a##babbccccdddddeeefgfeedccdb####a#aaaaaaaaaaadefedecbabbbbbcddddbcddcaabaaaaaabbbbbaabbccdcccbbbcb#a##aa#aaabbbfdbbccddddeffffefggeedjhedcdcccbbaaaaaaaaaaabbcaaaaabbcdcccdeefgdcccdefeccbbbbbbbccbbbbaaaaaaabbbaaaaa#######aa######aaabbbcab#a#aaaaaaaa#a##a#####abaaa#abaabbbbbbdccc####aa#.#",
+"###aaa###a#a#a####aabaaaaaabdbbbcecdcbaaaaaaaa#aaaaaaaaaaaaabccbb###a########a#a#aaaaa##aaaabca#a##aabbccccccdcccbbbbcbcabbbb#a#a#a#aaaabaaaabbeffddeabcbbbbcccccdccbbbaaaaa#abaaaaaaaaaababbbbbcbb#a##a##a#aaaabefcbdeeddeffffffeddfbchjieccccbbbaaaaaaaaaaaacfcabbbbcdddcdehggffeeddgfecbbccbbbccbcbbaaaaaaaaabaaa######a##aaa####aaaaaaabbaa##aaaaaaa#aaaa#####aabbaaaabbbbbbccccddbaaaa####.",
+"####aaaaa#aaaa#aaaaaaabbaaabccbbbcddbbdcbaaaaaabaaaaaabbbbaaaaabaaa###############aaaaa##a#aaaaaaaaaaabbccccdcbbbaaaaaaaabaaa#######aaaaabbbabaacffffbbbbbbbbbbbbccccbaaaaaaaaaaaa##aaaaaaabbccca#######aa###aaaabcgfcdeeefgggggggeffcbbehkjebbcbbaa##aaaa#aaaadheabbbcdddcegfbccdfffgggedccccbbbbbabbbaaaaaaaaabaaaaaa######aaaaa#aa##aaaabaaaaaaaaaaaaa##aaa##aaa#acbaaabababbcccdecbaaaa###a#",
+"#######a###abaaaaaaaaaaabbdccccbbbceefebcaaaaaa#aaaaaabbbcccaabaaa###aaa#######a###aaaba##aaaaaaa#aaaabccccccbbbaaaaaaaaabaa###a###a#aaaaacbababa#eeedbbbbcddbcbccbccccaaaaaaaa#a#aaaaaaaabbbbcba########aa####aabbbghdeeegggggghggfedbbbcdikgbbbbbaa#aaaaaaaaaabheaabccddegdccccdddccfffddbbabbbcbbbbbbbbbbbaaaaaaaa########a###aaaa#a#abaaaaaaaaaaabbabaaaaaaa#a##ccaaaaaaaaaabcccbacaaabaa###",
+"##a#aa#####aaaaaaaaaa#aabbbabbcbbabcdeedcbbbaaaaaaabbbccdddccccbbccbdcbcca########aa####aa##a#aaa###aabbccdccbbbaaaaaabaaaaa#########aaaaabcaaabaa#dfcccbcccbcccccdccccdbbaaaaaa###aaaaaaabbbcb######aa###aaaa###abbcfheeffghhghhijifcbbbbbehjhcbbba##aaaa##aaa##afgdbbcefecdcdccddddddeedcbabbcbbabbcbbbaaaaaaaabaa######a#a#a###aaaa#aaabaaaaa#aaaaaaaaaaaaaaaa#a#bcaaaaabaaaaabbcccbcabbbaaa#",
+"aaaaaaaaaa#aaaaaaaaaaaa#abaa#aaaaaaaaabcbbaabbbabbbbccddddddefdbcdccdecddcaa##aab######baaaa##ab###aaaabbbcccbbaaaaaaaaaaaaaa########aaaaaacdbaabaa#dcabccdddcccccdeeddddddbaaaaaa###aaaaabbbca#a#########a###a##aaabcegefgfhhggiiihddbbccbbfegihfb###aaaaa#aaaa##adgfefecbddccccddcedccefdcbabcdcaabbbbbbbaaaaaaaaaa#a####aaa#aa###aaaabaaaa#aaaaaaa#aaa##aaabaa##abcbaaa#aaaaaaabbbbdddbbbaaaa",
+"aaaabbabaaaaabaaaaa#a#aaa#abaaaaabaaaaaaaaababbbbccdddeeefdfffedccbbbbcccccaaaaacb#abaab#aaba#aaa###a#aaaabccbaaaa##aaa#abaa###a##a#aa#aaaaacca#abaaadbabddddfededcbbcaaabcddcaaaaaa###aabbbcdca######a####aa##aaaaabbcdkgghhhhhgiigecabbbccffedgiida#aaaaaaa#aaaaaabfecbccccbbbabbbddddddccbaaacdcbbcbbbbbbbaaaaaaaaa##################baaaaaaaa######aa#aaaaa#a##abbbbaaaaabbaaaababbddcbbbbaa",
+"aaaaabcccbbbaabaaaaa#aaaaa#aaaaaaaaaaaaabaaabaaabbbcdffefgffdcccdddcccccbaabaaacbab#aa##aaabb#a#a##aaaaaaabbbcaaa###aaaa#aaa#a###aaa#abaaaaaacccbaaaabcbaaccbbdccbbbababba#abccbaaaaaaaaaabdeabaa##########aa####aaaabbceghghhihiihhgcbbbbbbegdcdedhhdd#aaaaaaaaaaaaabdccccccaaabbbbcddddfeffdbbabcbbbbbbbbbaaaaaa###a#########aa#######acbaaa#####aaaa##aaaaaaaaa#a#aaaaaaaaaabbbbaabbccddbbbba",
+"aaaababbbccbbcbaaaaaa#aaabba#aaaaabaaaaababbbbbaaaaaa#aabbcaaabbbbbbbbbcbaaaaaabaaaa####a##aaaa######aaaaaabbbbb#######a#aaa#a###a##a#aaa#aaacbbcbabbabcabbbcddbaaabbaaaa##aaaabbaaaaaaaabbcdbaaa###########a####aaaaabbbcfihghhhihhhdabbbbbbeeccccbdehfaa##aaaa#aaaaaabedccbaaaabcdcddcbfeffddeedccbbbbbbabbaaaaa#############aa########ababaa###aaaaa###aaaaaaaaa##abaaaaabbbbbbbbbbbbcdffabaa",
+"aaaaabbacbbbabaaaa#aaa#aaaacba###aaabaaaaaababaaaaaaaaaa##aaaaaaaaababbccc###aabaaaa##a##aaaaa#aa##aa#abaaaacccb##a#a#a#aaaaa####aaaa###a#aa#ababdbbbabcbabbbbbbbbbcbbaaaaaaaaaaba#a###aaacbcdaaaa#########.#####aaaaaabbccfkjgfhhifdfdaaababbffcbbbbbacgda#aaaaaaaaaaaaaddcba#aabccccdbbdeefeddfdfecbbacaaaabbaa##############aaaaa#######a#aa###aaa####aaaaaabaaaaaaaba#aaababbbcccddddgihcabb",
+"baaaaababccccbbaaa##aaaaaaa#cddb#####aabbbbaaaaaaaaaaa#####aaa##aa#aabadedca#abbaaaaaa####aaaa#a#aaaaa##aababcbca#aaaa#####aa###a#aa##aaaaa#a#aaacbaabbbcbabcccbbbbcbabba#aaaaaaaa#bbaaaaabbadb###################aaaaaabacbgkkihhggfedaaaaaaaceecbaaaaabffgeca#aaaaaa###acdca#aaacbbccbcbeeefffdabdfecabaaababbaa#a##########aaaaaa#######abaa##aaaa#####aaaaaaaaaaaaaabaaabaabbbbbcdegghffdabb",
+"bbaaaaaabbcccccbbaaaaaaabaaaabccca###aabcceebaaaaaaaaaaa#a##a#####aa#aaaddbbaaabaaaaaaaaaaaaabb##abb#aaaaaaabcbba##aaa###aaa#########a#aaaaaaaaaaaaaabbbccbaabccbcbbbbbaaaaaaaaa##aaabaaaaccbed#################.##aaa#aaaaacekljihhhdbaaaaaaabdeedbaaaaaabceffdaaaaa#####abdd##abbbbccccbcedfeddbbbbdddbbaaababaaa#################aa#aa.###aa##ba##aa###aaaaaaabaaaaabaaaaababbabbbdfhjifeecba",
+"bbbaaababaabbcccbaaaaaa#aaaaa#aaba##aaabcbbccbaaaaaaaaaaaaa#aa####aaaaaabccbaaa#aaaabaabaaaa#abdca#acaaaaabaabbaba#aaaaaaabba##aaaaaaaaaaaa##a#aabbbbbbbccbbbacbcbabbbbbaaa#aaa##aaaaaacbccccdbbba#a########a#.####aaaaabaaaaafklljhfcaaaaaaaa#dcgfcbbaaabccccdggcbaaaaa#aaaacdaabbbbbbbbcbddeeddccccbbcecbaaaaaaaa#a##############aaa##a####aa##b###aa#aaaaaaaaaaaaaa#aabaaaaaabaabbdggghhfbdeb",
+"bbabbaaaaaabbcbccbabba#aaaa##a#aaa#a#aaabbabbbaaaaaabbabaaaa#a#####aaaaaadcba###aaaaaaaaaaaaaaabbaa#abaaaabbbcbaa#aaaaaaaaaaaa#aaaaaaaaaa#aaaaaaaabbbbbbbcbababbbcbbbbaaaa###a###aaaaaaaccddcddbaaba#aaaa####a#.#.#aaaaabbaaa##djlljc#aaaaaaaa#afdfebaaaabccccddegfdbaabbbbbbabddbbbbbbbbbadceedcdcccbbabdebaaaa#aaa#############aaaaaa#ab####a##ba#####aaaaaaaaaaaaaaaaaaaaaaaaaabcdfebbbabbbcc",
+"ecabbaaaaababcdcccbbbcdbaaaabbaa#aaaa##aabcbbbaabaaabbaabaaa#aa###aaaaaabecbaa#a#a#aaaaaaaaaa#aaaaaaaaaaaabbcbaa###aaaaabaaaaaaa#a####aaa#aabaaaaaabbbbbbdcbbabbbcbbaaaaa####aaa#aa###aaabcccccbaabbba##a####aa#####aaaabaaaaa##ahlkfa#aaaaaaa##fbbecaaaabccbcdddceghecbbccccbbbccddbbabaa#ccedddddccbbaaacfbaa#a##a############a##aaaaaaaaa##a###ca#aa###aaaaaaaaabaaaacabbaaabbbbddea###aaaabc",
+"abbcbbbbaaaabbccbbbbaaaa#a#aaaabcaaaaaa#aabbbbaabaaccbbabaaaaaaaaaaaabbabdcbaaaaa###aaaaaaaa#aaaaaabbbaabbbabaa#aaaaaa#aaacbbaaa##aa##aaaaabcbaaaaabacbccccabaabaacbcbaaa####aaaaa####aaaabdccdba#abbaaa#######a######aaaaaba#####dljfa#aaaaaaa#ddaadcbccbbbbccccdccehihfddccccccbbdfaaaabbbceefedddcbbbbaaaecaaaaa##a###a####a##a##aaaaaa####a###ba#aa###aaaaaaaaabbbbacbbbbbaaacccdd#####aaaab",
+"babbbcccbbbaacdbccbbbaaaaa######aaaaaaaa##abbbbabaaabbaaaaaaaaaaaa##abbbdcccbaa#aa#####aa#aaaaaaaaaaabcbabbabaa##aaaaaab#accbaaaaa#aaaaaaabcddbaaaaabbbccccbaabbbbaabbbbaa###aaaaa#####a#abceeeaaa#aaaaba#######a#######aaaaaaa###.cgjgb#aaaaaaaafcaacdcdcbcbbcbbccdeefeeghfeccccbcddc#aabaaaeffeccccbbbbbaaacdcaaba##aa##a#aa#aaaa#aa###a####a####b#a##aaaaaaaaaaaaabbbbcababbbbcdddeb#a#####aa",
+"bacbbcddcbbbbacddccbabbaaaaaa#a##aaaaaa####aabbaaaaaaabaaaaabaaaaaaaaabbcccbbabaaaaa#a#aaaaaaaaaaaaaaaabbccbbba##aaa#aaaaaabbbaaaa#aaa##abbaabbcbaabbcccccbbbbbabbbabbbbaa#############aaabbcedbaaaaaa#aaa######a########a#aaaa##a##adhjc#aaaaaaacdb##bddcbbbbaabbccefgecceffgfcbceccedabbaaacffdccbbbbbbbbbaabccbbaaa#aa####a###aaaaa#a##bb##a###ab##a###aaaaaaaaaaabaaabbbcbcbbbcefeb#####aa#a",
+"aaccbcddcbbabcbcddcbbbcbaaaaaaaa#aaaabaa##a#aaaa##aaaaaaaaaaaaaa#aaaaaaaaabbccaaaaaaa#aaabbaaaaaaaaaa##aabccccbaa#aaaa#abaaaaaaaaaaaaaabbbbaabbaccbddedcbbbbbabbbcbcbbcaaaa############a#aacbcba##aaaaaa#aaa#a###########a###aaaaa####adid#aaaaa##eca##addcbbaaaabbcddefddefddgiedccccffbaaaaaefeccbbbbbbbbbaabacdbbba####aa#a##a##aaaaaaccbba###.aa#aa#ba#a#aa#aaaaabbabcbccbcbcccegc######ba#a",
+"abcbbccdedcbbbabdddcbabbbbbaa##aa#aaabaa######aaaaaaaaaaaaaaa#aa#######aa#aabcbbaaaaaaaaabcaaa###abaaa#aaabcbcb#aa##aa#abbaaaaaaaabbcaaaaaabbgecbbbbccbbbbbabcabbcbbbbaaaaa##############aaabaaaa#aaba#######a###########ba#aaa#aaa###aabffcaaaaaabeb####cdcbaaaaaaabbccdeffeeegihfddddffcaaaabefeccaabbbbbbbaaaabdba#aa####aaaaa###aaaacccbbba#######aaaa#aa#a##aabbbbbbbccccccccddgf#aa##a#aaa",
+"aabcdddddddbbbccabcdccbaaaaaa#####bbaaaa#######aaaaaaa###a#####a#########aaaacbbbaaaa#accdddba#a#aaaaaaaaabbbcbaaaaa#aaaabaaaaabba#bdaaaaabeecbbcbcbccbbbbabbbbbbbabbbbaa#aa####a########aaaaacaabaabaa#######aa########abbbbaa##aaaa###aaegfb#aa##dcaaaabddbaaa##a##aaabcdfgffgiggfffedefea#aabffccbaaabbaaabaaaaacbaaaaaaa####a##aaaaaabbabaaa##aa##aaaaa######aabcbaabbccccbbddedeeaaaaa#baaa",
+"aabbdeedeedddaccbbbcbcccbaaaaaabbaccaaa#a#aa###aa#aaaa#########aa#a#####a##babbbbbcbbcfdccccbbaabaaaaabaabbbccbbaaaaaaaaaabaaaaaaaaacfcaaabcbbaaababbcaabbbabbbbbaaacbabaaa####a##.########a#abd##baaaaaa##.###aa#######abbadb#a#########aaeiib####bca#aabadcba########aabccdgghgfeddddeedegdaaabdedbbaaabbabbaaaaa#cbaaaaaaaa#a##a#aaa#abbbbaaa#aa##aaaaaaa#####aaabaabbbbccbbbcdecef######acaa",
+"baabcccddedddbacccbccdcbbbbaa####aa##aaa###a###aaaa#a#####aaaa#a#aaa###aaaaabbbbbabcgjfdccbbbaaaaaaaaaaaabbacccba###aaaaaaab##aaaabbbdfdbaabdecbbbabaabbbbbbbbbbbbababbaaaaaa######.########a#acdb#aaaaaaa######aa######abbccb####aa######afiifa###bca#aaaabcbba#a######aaabcdeefcbcedccccceffaaaaacdbaaabbbaabbabaaabcbbaaaaaaaaa##a#a##abbaaaa#ba##aaa###a####aaaaaaaaaaccbbbcccdeff.######aaa",
+"a#aabbbcdeddcccbcccccdcbbabaaaa##a###aa#a#a#####aa##a###a##aaa####aa#a#a#aaabbaabbbbbffdccbbbabbaaaabbbbbabcbbbaaa##aaaaaaaaa###aabcbbcdfdaacebbbbbaaabbbbbbbbbaaaaabbabaaaa###aa############abcdcaaaabbaaa######aa#####abbbdc#############adghf###cdaa##aaaabbaa##.##.##aaabcdecedbbcdecbbbccebaabacdaaaaabbbbbbbaaaaabdcbaaabaaaaa##aa#aaabaaa#bcaaaaaa###aa#a#a#aaaaaaaaababccdceec##########",
+"###bbbbcdeddddcccccbccbccbbbaaa#####.#a##aa######a##aaaa###aaaaa##a###aaaaaabbbbbbbccddcdcbbbbbcdbbbadecccccbcb###a###aaaabaaaa###accbbccfhcacbbbabbabbbbbbbbaaabbbaabbbaa####aa#########.####aabcbaaaabbaaaa#####a#####aabacfb###############dhhc.ddb###a###bbca#.#....##aaabcdccecbbccedbbcccedbabbdcbaaaaaaaabaaabaaaacccaabaaaaaaaaaaa#abaaabbcaaaaaa###########aaaaaaababbbceeda.#####a###a",
+"#baaabbcdeddddddddbbcccbcbbbbaaaa################aaababba####aaaaaa###aaaaaaabbaabbdecbccccccbbbccccbcbbbcbbddeeca###aaaabccaaaaaa##abbbbcdedbbabbaaaaabbbbbbbbaaaaaaabbaa#######aaa##########aabbbaaabbaabaaa########aaaaaabdfb####aa#########cghhceba###a##aabaa#.....###aaabcdceebbbbbddcbccbcdcabcedbbaaaaaaaabaaaaaa#cddbbbaaaaaaaaaaaaaaaaccbaaaaaba#a#a######a##a#aaaaaaccdeed####aa####a",
+"aaabaabccceeddeedcabbbcbbcbbbbbbaaaaa#########a##aaaaabbcbaa#aa#aaaaa#aaaaaaaaaaabbcddcbbbbbbbbbbbbbabbbbbbaabbdgfba#aaaaabbaaa##aaaaaabbbcceedaaaaabbabbbabbbbbbaaaaaabba#######aba#########a##abbcaabcbaabbba########aabbaabddca#aaaaa#########adjhaaa#aa#####aaa#...####aaabbcccfdabbbbbddcccbbccacffccbaaaaaaaaababaaa##bccccbabaaaaaa#aaaaabdcaabbaaaaa#########a#a#aaa###bcddhga####aa####",
+"##aabbbbcdffeddeebdcbbbbbcbbcbcbaaaaaa##.##aa######aabbbbaaaa#aaaaaaa##aaabb#aaaaacddfbcbabbccbccbbbaabbaaba#abadfdbbaaaabcaaaaaaaaabbbababbceedaaaabbabbbbbbbbbbaaaaaaaaa##.#####aa#########aaa#aacdabbbaaaaaaaa#######bbbbccdcddbaabbaaa####aa###bhgea#######.##aaa#####aaaababbbcebababbabdeccbbbceffeecbaaaaaaaaabaaaaaaa#bcccbbbbaaaaaaababbbbbaaaabaaa#######a##a#aa#aaaaabddhg###########",
+"#a#aaabcdddffdddeeedbbbbbcbbbbcbbbaabaaa#a##a##aacaaaaaaaaaa#a##aaaaacdaaaabaaaa#accdeaaaaabbbbccbbbbaaaaabbbababcdddcccbbaaaa#aaaabbbaaaaaabdeeeaaaaaababbbbbbaaaaaaaaaaaa###a####ba####a####aaaaaabecaa######aaa#####a#ababccccbcbabaaaaaaa###a####dijdb########a#a###aa##a#abbbbddbaaaaabbabdddcfeffffeccbbaaaaa#aaaaaaaaaa#abccbcabaaaaaaaabbaaababaaaaa#aaaa###aaa#aaaaaaaaabchga#####aaa##",
+"#a#a###abccdddefdeeecbbbbbbaabbbbbbbbba#########abaa#aaaaaaa##a#aaaaaccbaaabbabbcbbccfbcaaaababbbbbaaaaaaaaaaaabbbabbabaabaaa#aaaaaabbabaaa#abcdfea#aaaabbbbaaaaaaaaaaaaaaaa#######bba##########aaaabcedbb#######aa#####a##abdcbbccbaaaaaa#aaaaa#aa###bgjjga#######aba#aadba##aabbbccbaaaaabbaaabedffeffffdcbbaaaaaaaaaaaaaaaa#aaaccbbbaaaaaaaaaaaababbbaaaa#aaa#####aaaaaaaaaaabbbghc#####aaaaa",
+"a##a#aa#aabccbdfgeefeccababbbaabaabbbaa#a##.######aaaaaaabba##aa##abbbcbcbbccacbbdedgheccbbabbaaaaaaaaabbaaaaaaaaaaaaaaaaaacbbba#ababbbbaaaaaaabdeeca#aabcbaaaaaaaa#aaabaaaaa####.##ba###########aaabbceeba########a#########cbbbabbbaaa#aa#aaaaaaaaa###djkjb#b#..#abbcaaabcba##aaabbcaaa#aaaaabaacfffffedffccbaaaaaaaaaaaaaaaaaaaabcbbaaaaaa##aaaaabaaabaa#aaaaaaa#a#a#a#aaaabbbbccgc######aaa#",
+"##aaaaaa##aaccbaeihfgggcbabbbaaaaacbbceceeca########aaaaaabaaaaaaaabbbdcccdebbcbbabacedecbbbabaa#aaaaaabbbbaaaaaaaaaa#aaaaa#abbbbacbbbbbbaaaaaaaccddbbbbbbbaaaaaaaaa##aaa#a##a#####aa#############aaabbceeea########a########aaaaaaaabbaa###a###aaa######agjkhgfb.#aabddaaaaaaa###aabdb##b###aaaaa#cffffeeeeeccbaaaaa#aaaaaaaaaaaaaabcbaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaabbbbbdfeba####aaa#",
+"#a#aaaaa###aacca#cjjhhjebcbaa##a##acegebdcbdb#.#cbcaaaaaaaaaaaaaaaaaabbcdgiecbbaaabbbcbcdcbbbbbaaaa#aabaabcbaaaaa#aa#aa#aaa###aaaaaa####a###aaaabcddbcbbbaaaaaaa#aaaa#aaaaa##a#####baa#.#######a##aabbcdddffa##.####aa##.####aaaaaaaaaabaaa###########a####chhiihc..ceffbabaaabaaaaabccaacc###aaccbbegfffededdccbaa#a#aaaaaaaaaaaaaaaabcbbaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaabcccefeaaa###aa#a",
+"aaa#abaaaa##aaba##eiiikhccbddefeeffgecccdccdeffefddc#aaaba#aaabaabbaaaabcdhfbbbbaaacdecbbaabbbcbbbbaaaabbbbbbaaaaaa#######a###aaa#aaaaa######aaaaaccbcbaaaaaaa####aa##aaaaa#####a##############a##aaabcccccdfb##.#####a######aaa#aaaaaaaaaaa##########aaa##.#aejjifb#cffacbbbaaa#acbbcc##ddda##cddeefgfffeedddcabbaa#aaaaaaaaaaaaaaaaaaacbbaaaaaaabbabbbcaabaaaabbabbbbabbbbbbbbbbbdfc####a##aa#",
+"#aaa#a#a##a####b###dgkkjgccfiifdfdeeccddddcdcccccbca#aa##aa#aaaaabbbaababeggdbaaaaadfcbbbbbbcccbabcbaaaaabcabbbcbaaaaaa##########a#a########aa##a#accbbaaa#########aa###aaaa###aaa####.#########b##aabcbbcddfb###############aaaa###abbaaba#aaa#########aa#####djjjifbcebccdcba#bbacbcb##addccdcdeeefgfffeecbccbbbaaaaaaaa#aaaaaaaaaaaaaabbaaaaaaabaabbbbbaabababbbbbbbbbccccbbbbcced####a###aa#",
+"a##aaaaaaaaa#a#ba..#agkgfecfikgddcccdcccbcccbcbcbbdba##bccaaa#bbccccbaabbefffcaaaabdfbbbbbbbbccaaabaaaaaaabcbbbabbbbaaaa#######aaa############aa###abbaaa####a############a####a#######.#####a##aaa####aaaacfa#######..######aaaa###a#cdcbbbabcbaa#aab#########.chiiihfcddeghhgdccdabdaa#addcddceefeeffeeeedbbcccbbaaaaa#aaaaaaaaaaaaaaaaabbbbaaaaaaabaabbaaaababbbbbbbcccdccdcbbceea####aa###aa",
+"a####aaaabaaabbab#.#aaeecdhfijfcccddcccbbbbccbbbccaaa###.a#abccccbcbcbbbbbff#a###abcebabbbbccbcaabbaaaaabccbbbbbbbbbbbaaa#aa####aa##############aaaa#ababaa##############a#a######a####################aabbcacaaab#####.#.##abbaa###aaabcacbcaaaaaaa#aa#########.bgihiifcdgijjjiidaaabe#a#bdcbccccddddddecdecbbbccbbaaaaa##aabbaaaaaaaaaaabbbbbabbbaaaabbbbbaaabbbbbbbccdddedddefeffa####a#####a",
+"#######aaaaaaaaaa#.#abcdaahkkjgbbcccbbbbbcbbcbbbbaaaa#a######abddedccccbbacffcbb##acccacdcabbdccdbabaaaa#abbbbbaabbbbcba###a############.##.###########ababaa##################a##a###.################aaabcbcdbbbaa##.#.#.#aabaa###abcdcaabaa####aa#aabbb###a###.#bgjhacegijjjjjjhedfgea##cbbbccbbbcccccdcccbbbccaabaaaaaaaaaaaaaaaaaaaaaabcbabaaabaaabbbbbaababbbbbbccddddedffceedb######aa###",
+"aaa#a####a##aaa##a.##acda#cejjfdbbbbbabcbaabbcbbaa#aaa##a#a###baecbdfedddefhhgefea#cedbafecbbcbecbbccbbbbabbbbbbbccabbcdcaa####################.#######aaaaca##########################.########a######aaaaccccbbca#a########aaaa####bedcaabaa##aaaabaaabc########..#figefhikjihhhhiijiihd##bbcdbcccbcccddebcbbbbcdbaaaaaaaaaaaaaaaa#aaaaaabbcbbbbbbbabbbbbbbabbbbbccddedeedffa###a#####aaaaaaa#",
+"###aa############a#.##bccbbbbehhaabbbaaabbabbcbaba#aaa#######becdda#fgecddeehghegdabdecaabedbcaacbbddbbbbbbcbbbbbbdbaaccccba#########a################aaaaabcaba###############################a#####.###aaaabccbcb##a######aab##a###accbca#b#####aaaaaaaaa###.####...diihiiihfgeffeffhijid##ddcdccccccddddccbbaabddcaaaaaaabaaaaaaaaaaaaaaabbcbbabbababbbbbbbabbcbccdddedefc.##########aa#aaaa#",
+"#aaaaa#aaa##a######.#abbccaaaabgfb#ababa#aaaacbaaaaabbbab####edeefeccgedcddehhfacebadecaaaabcccbbbbcbabbbbbcbbcbccccccabccdb#######abb###a##############aaaacbccba##########a######.########a###a#########aabcceccb###a#####aaaa##aaaaacbb##ac######aaaaa##aaa#######..diihffffffdeddddefiigaaeddddbbcdddccdccbaaabcedbbbaababaaaaaaaaaaaaaaaabdcbaabbababbbbbbbbbbbbcceeegc.#############aaaaaa",
+"aabcbbaaaaaaaa########bbcdbaaaaaffa#aaaaa#aaabbaaaabcdeddabaefcdddefcgfddddeghcccffddbaaabbbbbccbccdbcbabbbbbbcbbbbbdcabbbddb########bca#a#######a##a###aaaaaaabdbaa#aaa####aca##...###aa####a##a########aaabbbdecc##aaa############aa#abba##a#########aa#aaaaa########.bgiedcccdccccccccdhigdeeeeedcdddccbcebaaaaaaceebbbbbbbababaaaaaaaaaaaabcccccfedcbbbbbbbbbbbbabcfffe############a###aaaaa",
+"a#aaedbbbbaaa#a#######abddca#aaaadcaa##aa####aabababbbccccfggcbcccccfgeccccdddffedfecddcbbbbccbbccdcddbbbbbbcbbbaabbcc#abaacba########aa##..#######aa####aaaaa###bbaaa#aaaaa#cc###a.####aa##aaa#########aaabbbbadcdaaabba##########a#aa#bbaa##a#######a#aa#aaaaaa#######.ageccbbbbbbbbbbbcbehigffeedddddccbcccbbaaa#accdcbbbbbbaaaaaaaaaaaaaabbcbccdbaadfdcbbbbbbbcbcefccba#################aaa#",
+"#aaacbaabbcbbbaa#######abcca##aaabbcba########abbaaabaabccdcbabbbccbcedccccccccccccedbbcdbbbccbcbbcbcbbbbbbbbbbabbbbcccbbaaaaaa##a####a#aa####.#####aa##a#aaaaa##abbcaaaabbbabcaaa#.#.###aa#a##a########aaabccabbddbaabaa####.##.aaaaaa##bba##############aaaa##a########.#bddbbbbbbbbbaaaaabfhhgfeedddccbccbdabaaabbbccddcbbbbbbaaaaaaaaaaabacbbcceb#a#babcbbbbbbcbce##.####################aa#",
+"aaaaaa#aaaababba#######abcccb#a#aaacddb######aaaaa#aaaaabbbbbbbcbbbbcdcbcbccbccccddbababcccccccccbbbbaaabbbbccbdcbbbbabcbbaa######aa#aaa############aa#####aaaaa#acbabaa#baabbcb#a##.#####baaa#########aaaabcdcccccbaaaa##########abaaa###aa##############a####aaa########.##dcbbbbbbbaaaaaaaabghgffedccccccbbcabbaaabbcbdedbbbbbbaaaaaaaaaabaaabccdecbcabbbcbbbbbcbeea###aa####################",
+"aaaaaaaaaaaaaa##########acceeba###bbbcda#######a####aaaaabbbabbabbbbbcccccccccbcbbcdcbaabbcbcccccbbbbbcabbbbddegebbbbbbbcaaaaa#########a######aba#####aa#####abaaaabcbb#aa##abaaba#####a##aaaaa######aaaaaaacccccbccaa##a#######aa#aabaa##aaa####aa########a#aaaaaa###########addcbbbaaaaaaaaaa#fieeeddcccbbbbbaaabaabbaaabdedcccbaaaabaaaaabbaabbbcdebaaccbbdddcbbcdc#aaaa###########.########b",
+"aaaaa#aaa#aa#############abcdfdaaaabcdf###aaaa##a#####aaaaabbccabbaaaabbbcccccbcbabbccbbbbbbbbbbbccbbcccbbbcdcdedecabbbbaaaaaaa########abb##aa#aaabaa#aba###a#aa#aabcccbabb###aa#aaa######aa##aa######aaaaaaaccccdaba###########aaa#aaba#aaaa#aa##a########aca##aaa######a######cffaaaaaaaaaaaaa#ehfeeedcbbbbbbcbaabbbbbbbaadeeefedcbaabbabbccbabbdcbcaabdcccccceedffb##aa####################a#",
+"aaaaa###aaaaaa#####.####aabccfgbaabbcfeda##aaabaaaaaa#aaaaaaaccbccbaaabcccbbccbbbbbbcbbbbbbbcbbbbbcabcccbababccdeccbabbbbaaaaa#aa########aaaaaaaabedaa##a#aaabaaaaabaccbaaaca###aaaaaa#####a###aa###a##aaa#aaaccbbabaa############aaaaaaaaaaaaa#########a##acdaabaaaa############acecaaaaaaaaaaaaafhffeddcbbabbcbbabbbbbbbbaabbdeddfeddbabbbdcabbabbababbbcbcbccddffcdaaaa##a###################",
+"aa#a#####aa#aaaa#########abcdcfeaaacbdccfcbbbdddbbbbbaaaaa#aaaabcbaabbbcccbbbcbbcccccccccbbcbcccbbbbbcccbbabbacddedcaabbabaaaaa##aa########cb##aa#cfdaa##aaababbbbaaaabbbbaabaaa#abaaa#####a#bbaaaa##a##aaaaaabbccdaaaaa#####bb#####aa##aaaaaaaa############aabbbbaaaa##aa##########deaaa###aaaaabcgiggddccccccccabbbbbabbaba#aabcaacccccbbcdbaacbbabbbbabcbcdddd####abaa#a##a#a#aa############a",
+"aaa#####aa#a#aaaaaaa######abccdfa#bbcddbcccdcdaaccdecbbbbbbbaabccbaaabbcccbbbccbccccddccccccddccbbbbbbcccbbbbbcccdddbabbbabaaaa########.####bba##a#aca###aaaaaaaaaaaaaabbbaabaabaaabba#######ababba.##aaaaaaaaabcdcb#aaaa#####a##########aaaaaa#a####aaaa##.##abbba#aab#aba#aa#a#####cgeaa####aa#aabfiigdccccbccccbbbbaabbbbaaaaaabccbbccccdabcbccaaaaabbbccdebdbaaaaaaaaa#a######aaaaa#########",
+"#aa#a###aaa####aa##a#####aabbbbeb#abbceeba#a####aaaba##cdbbbcccdccbbbbbbccbbabcbbbcbcddccccccddddddccdcabbbcbccbbbddcbbbbbbbaaaa#########.####aaa####a#a#aaaaaaaaaaaaaabbbbaaabaaaaaaba####a#.a##ab##.a##a##aaaabbddb##aa#####aa######.##aaaaaa#aa####a#aaa###abbb###acaacaaaa##a#####bff###a##aaa#aacghhfccbcbcbbcbbbbbbbcaaaabababbdccccddbbccccaaaaaabbccee##aaaabbacaaaa######aaa#aaaaaaa###",
+"#aaa##########aaaaa########bbbbbea#babcea#a######aaa####bccddcddedcccccccccbcbccbbbcbcddddcccbbbcccdefedcbaacbbcbbbbbbbbababaaaa############.###aa#a##aaa#aaaaaacbba##abbcbaaa#aaa#aa#########a#######a##aa#a#abbcbcc#a############aa####aaaaaaaaaa#######aa###aabaa##bbaaaa#a##aa######dea#####aaaaaa#behhdccbccacbbbbbbbcbbbaabbabbbcdcccdddbbbba#aaaaabbddb#######bcaaaaaa######aaaabbbaaaaaa",
+"aa#aa##########aaa########aabbbbbedbaabddcb#aaaa#aaaa####cccaacdeeggecccccccbbabbbbbbbbccddcccbbbbcbcddeedcbaaabbabbbbcbbbabaaaa###########.#####aba#######aaaaaabbba#aabbbbaa###aa##a#####.#a#.#.####aa##aa#aaabccbca#aa#..########a######aaa##aaa#########aaa#aaaaaabcaaaa##a##a###a#a#bdb#aaaaaaaaaaabcfhfccccabbcbbbbcbcbbbaabaabbabcddcdcccbba##a#a#abddb########aaaaa#aaa####aaaaaaaabbaaa",
+"aaa#aa##########aa#a#a#######abbabgebaabacca#ba#aaabaa#########a##bdeddeedddcbbbbbbbcbabacdddcccccbbbcdcdcdcabbbbbbababbbccbabaa###############aaabb####aa##aaaaabbbaaaa#abbbaa###aaaa###a###a##....###a##aa##aaabbbca##aa#.#######aaa##aa######aaa#########abaabaaaaaacbaaaaaa##a###a##a#afb##a##aabbbaaaaeggecebcbbbabbbcbbabaabbbbbbabbdddccccccabaaaaaaccc#####a#aaaa#a#####aaaaaaabbbaaabaa",
+"aaaaa############aa#a########.#abbcffcabbceccaaaaaaaaa###a###aa#######aaeebccccccbbbbcbbccbdddccccccbbbccbbbbbbbcbbabbbbbccbbbbaaa########.#aaa#a##aba#aa##aaabbbabbbaaa###abaaa#########aa##a############aa###aabcc#aa#aaa#######.##aaba#aaaaaa##aaaaa######baaaaaaa#aaaaaaaaaa###aaaaaa###ebaaaaaaaaaaaaabbfhgedbbbbbcbbbbbbabbbbbbbabbbbddecbcbbbbbbcbbbceaa#####aabca#a#a#a##a#aaaaaabbbbbaa",
+"aaaaaaa####aaaa#aa###########..#aabdddbbcccccaaaaaaaaaa##a##aaa###aa#####eddedddcddccbccbccccbbcbbcedbbcccccbbbbbbbbababbbcbbcbaaaaa############a#a#aa#aaaaabbaabaabaaa#aaa#abaaa#######aaaa#a###########.#aab##aacc#aa####a######..##aa#aaabbaaa##aaaaaaabbaabaccbaa###aaaaaaaaaa##aaaaa##a#ccbaaaaaa###aaaadgggfeababbcbcbcbbaabbbbaaabbbccddbcbbbbbcdccccca#a#a###aaaaaaaaaaaa#aaaaaaababccba",
+"aaabaaa#a#######a#aaa####aa###.###bcdcbcbabddbaacbbababaa#a##aaaa#aa#aacdccbddddddbbbbbaa#aaa######bfggfdcccbabbbbabaaabcbccabbaaaa#########a#aaaaa#######aabaaabbabbaa####aaaabaaa##aa##aaa#b####.#########abb#aaee##a###.##.##.###..####abccccbaaaaaaaaabcdaabbccba##a#aa#aaaaa#a#aa#aaaaaaaabebaaaaa#a##aabbfghhgedaaabbbccababcccbbbaabccbcccbbcbbcdcdcaaa########aaaaaaaaaaa#aaaaaaababbccb",
+"abaaaaaaaaaa######aaa########aa####bbccbbaabceaa#cbbbbbba#a##aaaa#aa###debacb#aacabaa##aa###########.#afhgeecbccbbbabaacbcccbbbbbbaa#a#########aa#aaaa####aaaaaabbbbbbbaa###aaabbba###a##aaa###.#######ba##aaadbaabeaa##aa#..###.##########abaaabdbaaababababbaabddbaa##aaaaaaaaaaa#aaaaaaaaaaa#aecaaaaa#aa#aaabdghhhfecccbcbbabbacccccbbbbbcbbbbbcbabbdcbcba########aaabaaaa##a###aaaaaaaaaabbb",
+"baaabbaaaaaaaaaaaa###########aaa####acccbaaaabcbcabbbbbbba#####aaaba#acbcaa#aaaa#abaa############.#####.dhihgeefccbbbbaabccbbbbbbaaaa##########a#aa#aa####aaa#aabaabcbbaa####a#aaaa###a#aaa################abbeebbbdd##a#######..####.######aaaaabcbbbbbbbbbbb#abcccbaaa#aaa#aaaaaa###aaabaaaaaaa#bcbaaaaaaaaaaaabehhhfedaaabaaabbccccbabbbbccbbabccbbbdcbbaaa#######a#aabaaaaa#aabaaaaaaaaaaabb",
+"bbaaaaaaaaaaaaaaaaaaa#########a#a####bbcbaaaaabeecbbaaabbaba###a#aaa##cedb#aaabaaaaa##a#########.##.###a#bfgedeffdccccbaaacdccccbbaa###########aaa######aaba###aabaabbbaaaa#####aa#a##abbaa####.##.####aaa#acbddddfega#a#######.######.##a#aaaa#aaaaaaaabccddebaba#bcba##aaaaaaaaab#aaaaabbbcaabaaaaccaaaaaaaabaabbehhfgebaaaaaaacdcccaabbcbbcbbbbbcdcbbcaaa#a######aa#abbaaaaaa#abbaaaaa#aaaaab",
+"bbbaaaaabbbaaabaa#aaaa###.#######a####abb#aa#a#cfecaabbaaaba#######aaa#bddcdaaabaaaa#a#aa######.########ba.a####bfddcccbbacdccccccaa############aaa######adb###aaaaaaabaaaaaa###aaaa##abaaa#####..#####aaaaabbcdeedfgd#aa########.#######a##aa#aaaa#a###a#abeedecc##aaba#aaaaaaaa#bbaaaaabbbbaaaaaaaaaccbaabaaababbadgggfdb#aaaaaabcbbbbbbccccdcaabbcdcccbaaa#######aaaaaaaa##aa###aaaaaaaaaaaba",
+"bbbbaa#aaaabaaaaaaaaaba#a######.#######abbbca##acdedcaabca#a#.###a######bddcfcaabaaa##a##a#####...##aa####a####a#abbccddcbbddedccccbaa####a######aaa#####acb###aaaaaaaaaaaaaa###########aaa####.####a##aaaaacdeceeeedc##aa########..#########aaaaa##a###aaaaaabcdedcb##aa#aaaaaaaaacbaaaaabbbbaaaaaaaaadfdaabaaaabbbbcdggfebaaaaaaacccbbbbbbccdcccbbbdcecba#####a####abbaaa#######a#aaabbaabaabb",
+"bbaacbabaabaaaabbaaabbaabb#.####.#######abbcba#aabecdbaccaa#a#.##aa##a###acacecbaaaaaa##########..######..abaa#aa####aceeddceggeddccbaa##########a#aaaa##aaa##a##aaaaaaaaaaaaa#########aaa####a#aaa####aaaabbdffffgebca#ab#######.#..#aa######aa###aa####aaaa#baabbdcc##b##aaaaaaaaabaaaaaabbbbaaaaaaaabcegcabaababbbbabgfgfdaaaaaabbabbbabbbcdddbcbccccdbaaa#a##a###aaaaaaa#########abbbbccbaab",
+"baaabbaaababaabbaaaaaaaaaaa##############abbaa##aadd##abbaaaa#.##aaa##a####aabcbaaa#aaa###a######..####.#..cdcbbbaa###abdcdedfghffddcbba###########aaaaaaaaaaaaaaaaaaaaaaa#aaaa########a#aaa#####aaa#a#aabbccddghhhfcca#aa##########...##########aa#aa###aaa##aaaa#a#bb####aaaaba#a#aaaaaaaabbcbbaaabaaabbefdabaabbbbbbbbfgggfdcaaaaabbbbbbbccdbdbcbcccbcbba##aaaaaa###aa#aaaa########bbabbbbaaa",
+"aa#a#aaaaaaaaaaaaaaaaaabbabaa#######.#.####aaaaaaabdeb#aababaa####aaa#abba#####aaaaa###a##bdba##a######....acdbabbaaaa#####cddaeggffedcba##########aaaa###aaa#abaaaababaaaaaaaaa##a###abaaaa###.#bbaaaaabdcddeefhhifdda#bb#aa##aa######..########ab##a###a##a#aaaa#abaabaaa#aaaaaaaaaaaa#aaaababbbbaaaaaaabcffbbbabaabbbaacefggdba#aabbbbcbacddccecbbbcccbba##aaaaaaaaaaa#a##a#a#######aaaabaa#a",
+"ba###aaaaa#cbaaaaa#abababa#a################aabbbbbbbea#aaabbaa#####a##adc##aaaaaaba##a####a########.#####...aca###########.####cffdcdecaaa#######aaabaa##aaaaaaa#aaabbbaaaaaabaaaba##babba######accbbbbbfccdeegdgfggeb#dc#####aaa#####...#######aaaa#aa##a#aaabaaa#bbaaaaa##aaaaaaaaaaaaaaabaabbbbbaaaaababbegdbbaaababbaabffffecb#aabbbbcbbcdddecbaabcbaaba#aaaaaaaaaaaaa###a########a#abbaabc",
+"a#######a###aa#abaaaabbccba###.##############abcbcbbcbea#aaaaaaa#######.##ba#a#aa#a#a#a##a####.###########..###ba##############a#aeedbadfcdddcbb##aaaaaaa#aa#aaaa#aaccbbbaabbbbbabcbbcdccb######abcdbddeeefddddb#afdcfebdca#####aaa######.#####aaca####abaa#aa#abcb#accaaaa##aa#aabbaaaaaaaaaaaabbbaaaaaaabbbbbgdbaaabbbbaaaccffgfdcaabbccccccddddfcbaaaaaaaaa#aaabbaaaaaa#a#aab####aa##aaa#bcc#",
+"aa###########aa#aaaaabbabbaaaa##..###########abdcccccbcdcaaaaaa#a##########aabb#abaa##########...#.########.######################.bfdaaccefddddbaaaaaaaaaaaaaa#aaababcccbbbbbccbbcddcabca####aaacdcabeggfdda.##.#cc#aefdbaaa###aaa###.##.####aaaaa#a###abd##a###ababbdc#aa#aaaaaaaabaaaaaaaaaaabbcbbaaaaaaabbbbgfbaaabbbbaabbbcefffddbabbcdccccedcabaaaaaaaaaaaaaaaaaaaaaaaaaaa#####aaa#aaaaaaa",
+"aaaa##########a######.#a#abbaa##########a####abdedcccccccba##########a######aaaa#abaaaaa#######..################aa#aa###############ddabedcgededbbbaabbabaaaaaaaaaaabbccccccbccdddba###abacbbcccba####aaaaaaaa##.###acfcaaa##aa#a############aa#####a#a##aea#aaa#aabbcda##aaa#aa#aaaaaaabaaaaaaababcbaaaaaaaabbbgfbabbbabaabcdcbdefffdbbcccccccdda#aaaaaaa##abaabbaaaaaaaabbbaaaa####a##aaaabaa",
+"aaaaabaa#######a###a##.###abbaa###############acdeccbbccdga##########a######.#aabaaaaaaaaa#a############.###aa###aaaaa###############.cdbbdefhhhfdccccbbbaaabaaaabbbbbccccdddcdccdb#####bbcbcddba####aa####a#a#####.##aedaaaa###aaa#######..#########a###a#bbbbbaaabbbbaba#aaaaaaa#aa#aaaabbaaababbabccbaaaabaabbbggdabbbbcbbbddcbcbdffdcaccccacccd#aaaaaaaaaa#abbbaaaaaaaabbabbabaa#aa####aabaa",
+"aaaa#aaa##########a###.##aaaaaaa####.##aa#####abccdcaabccffa##########a###aa####aabaaabaa#aaa####a######..###a#####aaa############aa###bdddeeddfgfeeeddcabaaabbbbbbbbbbcdddddeeeecaa####abbaaaa#######a#a########.###aaadaaaa#####aa########.#..##.##a######aaabbba#bbca##a###aaaaaaaaaaaabbaaaabbbaabddcaaaaaaaaabfgdaaabbbabdacdbcbdfffdbbdccbc#cbaa##aaaaaaa#aaaaaababaaaa#abbaaaaa#aaaaaaa#a",
+"###a#aaaaaaa######accbaaab#####aaaa####a#######accccabacccfe##.############aa####aa###aaa#aa####.#########.##########a############abca##bfcfabbbcaafffffdbbbbbbbbbabbcccdeeedefcaaaaaa##aaaaaaaa################a#.###abbcaa#aa#aaaaa#######....########aa####a#abba#bbbbaaaaaaaaaaaaaaaaaaabcabbbbbbabeedaaaaaaaaacfgecaabbabbacdbabcffffccccdda##aaaaaaaaababaaaaaaabaaaaaaaaaabaabaa##abb####",
+"a########aaa#######cddebba########aaaaaa#######abccccbabcdefea#.########aaaaabb##aaa#####aaa##.....#.##.##############a#####.#####aabcbaabfc######.afggggcbbbcbcccbbbccceeeeffhgccbaaa#aaabbaa#a######aaa########a#.##aacdba##ab#aabb##.#.####...########aa#####aaaaaaaabbaaaaaaaaaaaaaaaaaaccbabbbbbbabefdaaaaaaaaabeffabaaababdedabbcfffecccddaaaaaaaaababaaaa#aaaabbbaaaaaaaabbaaa#aa##ba###b",
+"#####aa#####aaaabbaaaacdb.#a#########aaa########abcbbbbbcdeeeefc.######aaaabaacbaaaaa##########..#..#....##############a###########abbbba#bd#a######aabbcfedccdddccccdddeeeeefgiedeebaaaaaabaaaa#aaaaa#aaaa###########aabcca##aabaaabba#....#....##.###.#aaa#######a#abaabbaaaaaaaaaaaaaaaaaaddbbbabaabbbddaaaaaaaa##adfecbbbbacddedbbccdffdccddaaa#aaa#bbaabca##a#aaabbaaaaaaaaaaaabb#aaaa###a#",
+"####aaba######aa#abbaaaba###aa#############.####aabcabcbbdegfebc.########abbbaaaaaaaaaa#########.....#.#.######.#######aa#####.#.##aaabbbbbc##a#######..##ehfeeeedddcedeffeeeeehf#abcecccbabbbbbaabaaaaaaaa########a###aacdba#aaaabaaaaa#..##..##.#..####aaa##a####aa#aaaabaaaaaaaaaaa#aaaaaabeeccbababbbbbaaaaaaaaaaaabcffbbbbcdccdcbbbcdfgfedcabaaaa##bbababa#####abbaaaaaaaaaaaaaaaa#aaaaaa##",
+"#a###aabaaaa###ba###ab##ba###a#############..###aaabcaabbdedefgb####aaa###aaaaaaaaabaaaa###########...#.############################aabbbadcaaa#####.######bfhhgggffffffffeeeefhhcaa##acfffeedddbaabaaaabaa########a####abebaaaa#a#a#aa############.###..#aa##a###aba##aaaaba#aaaaaaaaaaaaaaaaccdcdcbbbbabbbaaaaaaaaaaaaacfeaabbbbccdabccbdfffed#aaaaabaaaaaa#aa###aaaaabaaaaaaaaaaaaaaaaaaaaa##",
+"###aaa#aaaa#a##.a##a#aba#aa###########.#.#....####abcbbbbccdffegb...##aa###abaaaaaaaa#a#aa#######aaa###.####.#####################a##abbcfda#aaa###########.#acfhihhhijiiiihgfhhgcaaaa#..acccddccecccbaaabcb#######aa###abcdbaaaaa#aaa#aa##########.##########aa##aaa#aaaa########aaaaaabaaabbaaababaacbbabbbaaaaaabaaaaa#cefdabbbabbcbbbccdfggeb#aaaaaa###aaa#a###aabbaaaaaaaaa#aaaaaaaaaaaaaa#",
+"#aaaaaaaaaa##aaaaaaaa#aaaaaa##.###aa###.###...####aabdbbabbcfeced.#########aaaba#aaaaaa##ca#######aaaa######.########.########a#####aaabdhgfeaaaa#############.#aaba#addfghiiiiheb###aaaa###.####bdbcdcdcbbca##a##a##a##aabbdbaa####aaaaaaa#############a#.##aaaaaaaaa##aaa##a#a#acbaabbabbbaaaaaaaabbbbbaabbbaaaabaaaaa#a#bfgebaaababbbbbbbcggfeaaaaaaaaaaaaaaaa####aabaaaba###aaaabaaaaaaaaaaa",
+"a##ba#abaaaaaaaa####aa###bbaa##.#######b#####.#.###aacbbaabcdeccc##.########aabbba#a##aaa#bba######aaaaa#################.######aa##aabbfhhihdabaa##############aa######.##a#bgfb###aaaaaa########cbacccdfeecaa###aa##a#aaabcdbab##ababaaaaa##########aaa#####aaaaaaaa#a#aaba##aabfdaa#aaaaabbbabaaababdbbbbbbbbbbbbbaaaaaaa#dffcbaabbbbbbbbbcefgdba#abaaaaaaaaa#aa##abbbaaacba##a###aaaaaa##aaa",
+"aaaaaaaaaaaaaaaaaa#####a##aaaa########ab##.####..###aadccbbacdcaa###.######aabaaabb#aaaa###############aa#####a#####.##############aabbbehhhfcaaaa#####.########aaaa##aaa##a#.#caa####aa##########cdbbbbbcedefdcbbaa##aaaababbdbaaaaaaaaa#aba#########aa######aaaaaa#a#aa##aaa##addbbaaaaa#aaaaabaaaaaaccccdcbbabbbcbaabaaaaa#cfgdbabbbbabbbbbcfgedda#aaaaaaaaaab#a##aabbbaaaba#aa###a#aaaaaa#aa",
+"aaaaaabaaaaaaaa#accb#########babaa###aaa##.##a##.####abcbccabdeaaab#..######aaaaaaa#####################aaa####a#####.############aaaabdgihgcbaaa################aaaaaaaaa#aa###a######a##########dbaaaaaaaacbcefgfddcccddegdcbdbaabaaaaaaaaaaa######aaa####aaaaaaaaa#############aaaaaaaaaaaacaaaaaaaaabbbbdeccdccbbbbaabaaaaabefecbbbabbbbcbcegededcaabaaaabaaaaaa##aabbbaaaa#aa#aaa#bbaaaaa#a",
+"a##a#aaaaaa###aa#bbcbaa##aaa#aaaca##abb########a#####aacbbccbdeaaaba#########aaa##a#a####.################ba#########.##..######.bbabaaehhhgbaaaa#################aab#aabaa#aa###a##########a.###.ab#aa#abababbbcbcdcaacecccdefdc##abaaaaa##aa########aaba#aaa#a#aaaaba#a#aa#a##.##abaaaaaaaaabbabbaaaaaaaaaaccbbbcdbbbbaaabbbabbdgfdbbbabcbcccdddeeedcaaaaaaaabaaaaa##aabbaaaaa##aa####aaaaaaa#",
+"####aaaaaaa######abbcca##aaaaa##abbabba#a#####aaa######aabccedfaaaab#########aaa###.#######################b########.#ba#...##.#acbccccfgggebaaaa##a###############aababaaaa#a##a#a####a##a########c#aaaaaaaabbaaaaabccdebabbbdgeaaabbbaaaaa##a#######aaab##a##aaaaaabaaa###aaaa####ba#a##aaaaaabbaaaaabbaaaaacbbbcbbbcbbaaabbbbcbcfgecbcbbbccddccceddccaaaaaa#bbaaaaaaaaaaaa#aaa##a#aa#a#aa####",
+"##a###aaaaa#######aaaaaaaaaaaaa#aabbcaaaaa#a###aa########aabeeea###aaa#######aabb#####a######.#######aa##.######aaaabedccbbb##bbbbaabbbbccdeaa##a##a########aaa#####aabbbba#a#aaa#a####a###########caba###ababbbaabbabcdcddcbabehcaaaaaaaaaa############ab##aaaaaaaaaaaaaa#baaaaa###bb#a##aaaabbbbbaaaaabbbaabbbbcccbabbbaaaabbccccbfffcccbccccbccccddeedaab#aaaabaaabaaabaaa###aaa###bb##a#####",
+"aaaa##aaaaa#aa#######a#abbaaaab######aaaaa#aaaa#aa#######aabdefb#aaa#bc#######abcb#####a#################aa#a..###aabcdfffggfdcbbbbbaaaaaabdeaaa###########aaaa#####aabbbbbaaa#aaa#####aa#a##.#####aaaaaa##abaabcbbbaaabaabbbbcdefaaaabaaaaaa##a######aaa######aaaaa#aaaaaa##aaaa###aa#aaabbbabbaabbaaaaaaaabbbbbacccbaaaaaabbccdccdefegffdccecbccccdeeddcbaaaaaaabbbcbaaabaaaaaa#######aa######",
+"#aaaa##aaaa#############abaaaaaba##aaaaaaaabaaaaaba#####a##abdgca#aaadeb########bba#####aa#aaaaaa###aaa#ab#aa#.###.#acfhfddgccbaa#aaaaaa#abcfaaaa#######aaabbaaa#####aaaaaaaaa#aaaaa#aaaa##########aaaa#aa##aaa#acccabaaba#a###acdbaaaaaaaaaaa###a##.##aaaa###a###aaaaaaaaa###aaaa#abb#aaaabbbbbbbabaaaaaaaaaacbbbccbbbbaabaaacccccdfdbdfgeefcddabccbcedddccbbaaaaaabbbababbaa#aaaa#a##ab##a####",
+"##aaaa#############aa#####abaaabda##abaaaababbaaaaba####aa#abbdeaaaaaadf###############a#aaabbbbba#aa#aaaa#baba.#accbffffgddcbbaa#####aa##acfeabaaaaa###aabcdcbba######aaaaaaaaaaaaaaa#aaa##########dbaa########bbdcaab#abaaa##abceaaaa#a#aaaaaa#a###.######a#####aabaabb#aa#####a#bcbaaaaa#aaaabbbbbaaaaaaaaaaccccbccabacaaaabceeeeggdcdfffccccca#bbcbddeccccca#abbbbbbbaaabaaa#a#aaaaab#######",
+"##aaaa####.##########baaa##aaaaabda#aaaabbaaccbaaaa#####aaaaabbcbbaaabdgfe###aaa#######a##aaabbabbb#a#a#aabdceeedcabcaeddcfhecdb#########aacdhcbccbbbbbbbbdehhedba##aaaabbbbbaaaaaabbaaaaaaa########cba#######a#abbda#aabcbaa##aabceaaa######aaa##aa########aaa##aaaaaa#aaa###.###aabaaa#aaa#aa##abbbaa#baaaaaaabbbbbbdbbabaaaacaddacbbbbddccccbbda#cbbcdcddeccccbaabbbbca#aabaaaaaaaaaaaaa#####",
+"#aa###a####.##########aa#a##aaabaccaba#aabbaccbaaaaaaaaaaaaaabbccabaabeffeebbcb#.####.#aaabbaabbccccccccdddcec.#aaaaaaadccbbcccca.#######aabdhecdddeeeddeefecbbeedcaaaaabbbbbbabbbbcbbaaaaaaaaaba##aba####a####aacdccaa#ccbbaa##aabcdaa########a##aa########aaaa##aaaaa##aaa#########aaa##aa#aba#aabbbaaaaaa#aaaaaabaaaccbaaaaabccababbbb###bcbcbbecabbccdcddcdcccaaababbbbaaaaaaaa#aaaaaaaaa###",
+"#aa#aa##########a######a#####aaaaabc#abaaaabbcbbaa#a##aa#baaabbbbbabbcfffgghebdcbbacacbbbbbbbcbccdccfdaaabdedcaaabaaaaacccbbbbbbcb########abcfgedeffeeeegfcbbcbadgdddaabbbbbbbbbbcccccbbaabababbbaacbaa#########abcccbabccbbbaa##aabcb#a#######aa######a#a##abbbbabaa###a#aa########.bbaaa#aaaaaa#aaabbbccbaaaaabbbbbbbaaaaaaaaabbbccccaaa###bcdbabcbbbabcdddcbddccbbaaaabcccabaaaa#aabaaaaaaba#",
+"#aaaaa#######a####a###aa##.###aaaaabc#abaaabbcbba###aa####a#aaabbbaabcdcdeccdecccccba##aaabbaaaaaa##beaaabacfdeaabdecb#bdcbbbbbbaca#######abcdegeeeeffgfdabbccddeehhhfdbbbddeeccdcccdccbbbbbbcccbcca##a###a########aa#.aceccbbaa#aa#acb###.#####aa#####aba###abcdcbcbaaaaaaa#####a###bc#abaaaa#aaa#ababbbbccbaaaaabbcccbcbaaaaaabccdacccb#a###abddbbbbbbabbcebcbbdcccbbaabbabcabaaaaabcbaaaa#aaa",
+"aaaaaaaaaaa####aa#####aaaaa.###a#aaaccaaabaabccaa##aa#######aaaaaaaaadc##abaaaaa###a#######a#########cb#aaaacdddb#bbdda#becbbbbbbac#######abceffhffffda##babcccdeeddbddeecdcdebdeeccdddeddcccdeba#b###aa##a#########a###bedbbbbaa#a##aca###.#####aa####aaa####bbcdddbaaaaaaaaa#######adbbabaaa##aaaaaaacbabbccbaabaabbccccaaabbcbdcbcecccaa#a#a#adcabbbbbcbbcbccaabccdcbbbbcacbaabbaabcbaaaabaab",
+"bdbaaaabbaaaa#aa##a#aba#############abcaabababcba##aa#########aaaaaaabdb##aaaaaa###a##################b####aaccdeaabcbbaaeddbabbbabb#######bdfhghhgda###aabbcccecbbbdcccefdbbcbcb#eefgghggfeegdaa##a###aa#######aaa#####bedcabbaa#####acb##########a##aaaa####acbccccaaabaabbbba####a##dbba#aaaaa##aaaabdababbccbabaabbcddcbacbbccdacdbba#####aaaabcbbbbbbbccbbababbcddcbabbbabaaabcaaabaaacabaa",
+"aacdbaa##.##a##aa#aa#aba###.#########abca##aabbbca#..###########aaa##aab######aaaa#########aaa#a###aa#######aaccdfbabbaaaeeddbbcbbbdbaa#abcdfhjigca######abccbadb###cfbcbbecabbba#begfhggddcggdbbaaa##############a#aa#.cddccbaaaa#####ab##########aaaaaba####accbbbbaaabaabbbabb#######aba###aaa#aa#aaabcaaaaabccbabbcccdedcbdbbacdcdccaa##a#aaaaabcbbbbbacccbaaaabaccccbaaaaaaaabbbbaaaaababba",
+"aababbaa#####a##a##a###a####.##########aba###abbbbba####.#.#######a###aab######aa#a#########aaa#####aaaaa#####bbceebbbba#ceedccedcegdcbcddedbcbed#######aabccdbdda##adeeb##abbaaaaacbadeddfdghdcbbbaaa###########abbbcdbbdcbbca##aa#####bd###.#.###aaaaaaaba##abbbbbbbaaaaaaaabbaaa#######aa###aaa#aaaaaabcaabb##abcbbaabcedccdcbaaccccba####a#aaababcbaaaabbccbbaaababccbaa##aa##aaabaaaaaaabaa",
+"aabaaaaa#a#####a###aa##########..######aaba####aaaabb#.###############aaab##.###a#a#######aaaaaaaaa#a#aa###a##aacdceddfgfcfffgdccdeeefggdbaabbbbdcaa###aaabbcddeb##a#adfeaaaaaaaaa#bbaaccbeedhecbabbaaa#########.adccbcdbdbbcbba#######a#cda########abbaaaba##abbacbbaabaaaaabaaaaaa########aba##aaaaaaaaabcaaa#a##abca#aaabdefecbaadbbbaa##aa#aaaaaabdcbaaaaabcbaa#aaaabbbaaaaaaaaaaaaaaaaaaaaa",
+"aaabbaaa#########a##aaa###########.##.##aaaa#####aa#cba################abcb.####aaaaaa##aaaabbabaabbbaaa##aaaaaccgghggecdfihhg#a####a#a#abbccccacdcabbbbbacccdfeba#####aaaaaaa###a#ababbccadcgedccbaaa############ccbabccbcacabaa#####a#bacd###.####aaaaaaa###aaabbccaaaaaabbabbaaaa###.##..#bbb###aaaa#aaaaaaa########a#aabccceecbbdbbbbaa#aaaaaabbaadccbaabaabba#####aaaabaabaaa##aaba#aaa#aaa",
+"aaaa#aa##############bba##########..#.############aaaaaa#####.##########abca..####abaaaaabbbcccbbccddbbabbbbbcdefebdfd##a#.bedaa#########aabbbcbcddddcbbbcdeffd#########aaaaaaaa#aa#baaabcbacegedbbaaa##########bcdbaabbcccbbbaaaaa#####abbcca####.##aaa####aaabbcccdbaaaaaaabaaaaaaaa####.###abba##aaaa#aa##a############aaaa##cfebdcabcb###a##aaaabbabacbaaaaaba#a####aaa#aaaaaaa####aaaaaaaaa",
+"abbaaaa####a##########aa###################aaa####abaa#a################aabc#.#####aaaabbbcdddcdfffefgffeddfgdcdcb####aaaa###bb#######a##aabacdcddbdccacdefecc#a##a#####aaaaaaaaaa##aaaaabbbabfgdcbaa########aaacbbbbabbbbcdaba##a#####a#abccda####aaaaa#aaa#abaaaccbbbaaaababbaa##aaa#########bbba##abaa#####aa#a##aaa#a###aaa##defdcabbbaa##aa#aaaabbbaaccaaaaab######aaba#aaaaab####abaaaaaaa",
+"aaabaaa#################abba###############aaaaa##aaaaa#a###############aacaca.#####aabbbbccddfda#adeca#####b###aa#aa#aaaa##aaba#a####aa#aabccdccedebaacccb####aaaa###a###abaaabaaaaa#aaaaaababdgdbb##########cabbdbbbaaaaaccaaaaaaa##aaa##acdc#.#aaaaa##a##aabaa#ccaaabaabbaaacbb##abaa######..abca##aaaa#####aa#aaaaaa######abaabdggcaaa#aaaaaaaaaaacba##bbaaaabba#aa#aaaaa##aaaba###aa#aaaaa#",
+"#########.#################aaaa#.#.##aaa###aaa##aaa##a##aa###############abbbba#.##.#aabbbbcefc####...#####aa#####aa###aa####aa#######a#aaacbacbbdddbbccdfecbcc###aa####aa#aaaaaa###aaaaaaa##aaacfdaaa#####aaaabbabbbbaaabbabbaaa###aaaaaaa#abce..##ababc####aaaaabdaabbbbbbaaabbbaaa#a##.#######abaa#aaaba##aaaaa#a##aaa###aaa##ababehcaaaa##aaaaaaaadc####abaaaaaba###aaaaaaa###aaaaa#aaa#####",
+"####a######################aab#....##aacaaa#aabbaaaaa#####a##############aabbbcb##.###abbcceca###################aaaaaa#a#aa##a#aaaaaabaabbbbbacaaabbabaafddcbcb###aaa#aab##aaaa######a#######a##cfeaaa#####abcbbbbaaaaaabbabba###aaaaa#aaaabaaee#.##ddaaa####aaaaacaaabdcbbbbaabaaba#aa##.#######aaaa#aaabaaaaaaa##aaa#a##a#aaaaaaabbcgebbba#aaaaabaabbaba###aaaaabbaaaaaaaa#aaa##aa#a##baa#a##",
+"####a##aa##################aabda#.#####bcaa#abaabaaaaaa###################aaabcdb.####bbbdea##########.###########aaaaa##aaaaa##aaabbbbcbccbbaaaaaaaabbbaaaacdcbbbaaaaaaaabaa#aaa################abecaa####aadcabcaaaaaaabbaab#####aab#aaaaabaaade#..#ca.#a####abcbbb#abbccaaabbbabbbb#a############aa#aaaaaaaaaacaa##aaa##a#aaaaaacabccfebbbbaaaaabbbbaaba####ababacbaaabaaaa##a#aaaaaa##aaa###",
+"#####aaaa###.#a######a#######aab##..####abbbbbbbbaaa#aaa####aaaaa##########aabddea.###abda#################a#########a#####aaa###aaabbcdcbdbbaaaaaaaaabbbaaaaacddcbaaaa###abaa######..############abeda###ababbbccbaa#aaaaaabaa##a###ab#aa#aaaaaacec##ab.########babbaaaabbababababbcda###############a#aa###aaabcbbaaaaa###aaaa#ababbcdcdecaabaaababbaaa#######aaabbbbaaaaaabaaaa######a#aaaaa#",
+"a#######aa#a######aa#a#aaa###aaac#########abddccbbaaaaaaa####aa#aa########.abehghhc##abca##aaa##################################a#aabccb#aabaaaaaabbbaaaaaabaaabbbdba#aa###aaa##################aa#abefccaabbbcbabbaaaa#aaaaaaaa#aa###abaa##aaaabbcfdaba.#a######bacc##aaaabaababaabcbca##.#####a#####a#aaa#####aaaaab##aa##aaaa#aaaabccebbffbaaaaaabcaa###a#####bbbbbbbaaaaabaa#aa######aa#aa#a",
+"#baa#aaaaa###a#a#aaaaaaa####b#aaba#########aacbdcccaaa##a###aaa#aa##########bbfikjicacc###aa#aaaa#############a###################aaabccca##aaaaaabbaaaaabbbbaa#aabcbbaa####a#################a#aabaabdfbdcccbbbbbbbbaaaaaaaabbaaaaa#a#aaa#aaaaaabbcfdbb#######a#aaac##a#ababaaaabbcdaaaa##########a#aaaa#a#aa##a#aaaaaa#aaaaaaaaaaabbccdcaaegcbaaaaacaa#####a####bbbbbbbaaaabba##a###aaaaaa####",
+"####aa#aaaa##a#aaaaaaaaa##a#####aba##########aadcbbba####a####a#aa##########abcdfhiigc#a##aaaaaaaa#aa#####################a#######aadccccaba##aa#abaaaabbbcaabaaba#aaaaaa####a###a#a###.#####acbbcbaabcehfdccccbbbbbbbaaaaaaabaaaaaabaaaa###a#aaaabbcddca####.#####aa##aaacbabbbbaabcba#bc############aaa##aa##aaaaa#baaaaaa#aaaaaaaabccdeba#cgfbaaabca#a###aa#a###bcbbbbbbaabbba##b###aaaa#a###",
+"###a#aaaaa#aa######aaaaaaaa######aaaa#######a##aaaa####.###aaaaa#a###########abacdhiiga##abbaaaaaaaa##############a########a##a##abbcabc#abbaaaaaaaaaaaaaacaaabaa###a###aa###a###aaa########bbbbcbbbbddceihebbcbbbbbabbaaaaaaaa#aaaaaab#a#####aaaabbcccfb#.########aa##abaaaaaaabbaaaabbcbc#####a######ba##aaa###aa###aa##abbaa#aaaabbbdcccbbabdhebcbaaaaa####a#####accbbbbcbaacba#aa###a#aaa###",
+"#a####a#aaaaa#aaaaaaaaaaaaaa#######aba#######a####ab########aaaa##a#a##.#..#####aehhjihb#abacba#aaaaaa############a#a########aa#aabdcc####abaa##a##aaaaaa#ababa#a##aaaa#######a#aaaaaaaa##aacaabcccbcbabbcghgdbbabbbccba##aaaaaaaaaaaabaaa####aaaabcbcdccaa#########.##aaaaaaaaabababbabaa#######a#a##abbba#a######a###aa#aaaaaabbaabbcdbbbbabbadffbbaaaaaa#a##a####aabcbbbccabbabaaaba##baaaa##",
+"##aa###a#aaa#a##aaabbaaaaaaaaa##aa###a#############bba#.###aa#aaaaaa#######.####adfehjif###aaaaaaaabbaaa#a########aaa###a######abbbbcca.###a###########a###aa###a#############aaabbbbbaaceb#aaabbbccbaaabbbdggdcbbabbbbaa###aaaaaaaaaaba#aa#a###aabbbbcdc#####aa#######aaaabbbaaabbbbbbba#aa#######a##aabbaa#######aa###aa#aaaaaabbbbbccaaccbbbccdfgedaaaaaaaaaaaa##aaaccbcccbbccba##aa##abaaa##",
+"########a#aaaaa#aaaaaaaaaaaaa#aa#ba###########a####aaaaa#.##aaaaaaa##a#a########bbceeijfc####bbababaaaaaaa#########aa##a#aaaaabbadcccba####.############aaa#aa#############a##abbabbbaa##ceaaa#aaaabbbaaaaabbdgfbbbbbabba####aaaaaa#aaaaa#####a#aabbbccdccca#aaaa######aaaaababbaaabcabba##ba##a##a#aaaaaaaaa#######a#a##aaaaaaaabbbcccaabbddcaabbabdffdbbbaaa#aa####aabbccbbcbbddbaaa####acbaa#",
+"#######aa#a#aabbaaaaabaaaaaaaaaa##aa#a#############abaaaa####abb###aaa#a########babcfhiiea###acbbabbaaaaaaaaa####aaba#aaaaa#aaabaccbcbaa###############aaaa###a##############aabaaaaaa####bbbabaaaabbbbaaaabbbcffbbbbbbbbaa##aa##a###aaaa####aa##aabccefcadda##aaaabb#aaaaaaaaaabbbbbbbba##abb######aaaabbba###############aa#aabbcccbabbaabdccccaabacfggccbaaaaaa##a#aabccbbcaabdbacba####bbaaa",
+"aaa####aaaaaaaaaaaaababaaaaaaaaaaa#aa##############abbbbaaaaa##bbbaaaaaaa######ab#bccehiic###abcaabbbaaaa#aaaaaaaa#aaaaaaaaabcbccacba########.##########aa###############a#aaa#aa#a##a#####acbddcbaaabbbbbaaaabbefcbbbabaaaaaaaa######aaa###aa#####abcdghedcbbbbbcccdcbbaaaaaaaabbbbbbabaa#.acca#a###aaaaaaa########a##a###aaabbcdcaaaaaabbaccddaaaaacaadggfdbaaaaa#aaaaaabccbbaacbaababaaaabbaa",
+"aaa#a#####aaaaaabaaaabbbaaa#aaaaaaa###aa#######.#a###abbbaabbbbaaaaaaaaaaaa####a##ababchie###aabbbaaaaaa#aaaaa#aaaaaaaaaaaabccccbccb####a#############aa######.###########aa###aa#aaaa#a###abcccdbbbbaaaabbaaaabbceebbaabbaaaaa#########aaa##aa#####acdfdefebcddcbbdffdcbaabbaabbbbbcdbbaaa##abca#####aaaa#a##a#aa####a#a##aabbdedaaaaaa#aaccbeda#aabbaaaacefgfdbaaaa#aaaaabcccbccabaaabbaaaacc#",
+"##a##aa###aaabbbaaaaabcbaaa#aaaaaaa#a##########a#####aabbaaabaabaaaaaabcccca########aaacfhc##aaabccba#aaaaaabbaaa##abbababbcccbeecba#####a########a####a#a#####.##########b######a##a##aa###aababaaabbaaaaabaaaaaabdfcababbaaaa##############.#######bddcbdeffcbbba##dihdcbaaaaacaabbbdcaaabaa#aba#####aaa######aa##a###aa#abcdccdb#aa###aaaccdcbaaaaaaabbaaabehhebaaaaaaabaccbcbbbaaaaaaaaaaacb",
+"a##aa#####aaaabbbaaaaaababaaa#abaaa#############.###aaaabcaabaaaabbbbacdedaaaa######a##bccdccaaaaaacdcaaababbbaababbbccbcbbcdcceedc####a##a###########a#aaa######..####.####.###aa######abbaaaabaaaaaaaaaaaaaaaaaaaacfeedbbaa############.######aaaa#abbaaaaccbabaaa###igdccbbbaaaaaaabcbabcbcb##a######a####a#aaaaa####aaaacb#abdcaaa#a###a#acddcbaabaaaaaaaaadfhhedaaabbabbcccbbaaaaaaaaaaaaaa",
+"ba##a##a#aaaaa#aaabaaaaaaacaabcbaaaa#aa#########.#########aaaaaa##ababdefcab#aa########aabdfgbaaaaaacdcaaabaaaaabbbbabbcbbbcccddaaaa####aa#aa########a#aa#########..##.##..###.###aaba###aaaaa#abaaaaaaa#aa#aaaaaa#aaaegdcbbbaa###########.######aaa##aaaaab#abaaaaaa#.febaaabcccbcbbcbbaaadbcecbaa#####a#aaaaa###aaa#aaaaabaaaabccaaaaaa#aa###adbbbcbbaaaabaaaabbchifbabcccabbccaacbaaa##a#aaba",
+"#ba########a###aaaaaaa#a#aaa#abaaaaabaa##a#aa###############aab####aaaaabccaaa##a#.#####abcdfb#aaaaaaaaabaabbbcbbbbbababbcdddfedcb#a##aaa#aaaaa###aaaa##aaa##.######.###.###########a#########aaaabbaaaaaaa###aaa##a###bfedcbbaaa############a####a######a#aaabcbbbaaa#gdaaa###bcddcecccca#addefgfddca###a##aaaaaaa##aabaacb####bbdcaaaaaa#aa###ccbbbccbaaaaaaaaabaadhieabaabbccdcbabbaa#####aaa",
+"#aab####aa###aaaaaaaaaaaaaaaa#aaaaaaa#####aaa#a##.############aa#abaaaaaaabaaaaa########abccdfcaaaaaaabbbaa#abbcbbaacabbbbcddecdcc####aaa#aaaaa#aaaaaaa##aaaa###..######.#####a########aaa#a####aaaaa#aaaaa########aa####dedbbbaaa##############a###a#####ababccbaaaaa#gcaaaa####bdebbbbbca#bddcbaabccaa##a##aa#aaaaaaabbaca####abdbaaaaaaaaaa#a#ccbbbbbbbaaabbaabba#adhgcbaccccccdccba######aaa",
+"a##aa#a###aaaaaaaaaaaaaaaaaaaaaaaaa#aa###aaaaa###.#############a##abababbaaaaaba######aaabbcddhcaaab##baaababaabaaabbabbbbcdddffeeb###aaabcaaaaaaaa###aaa#aa####.######a#######b#####aaacb#######ababaa#aaa##aa########a#aaeecbbbaa##################a##a##bbaabb#aaaa#cd#aaaaaaaace.aaa#bdccdcaaabcacbaba###aaaaaaaabaabccaa#aaabbd#aaaaaaaaaaa#bcccbbbcbbaaaaaaabbaabbhidbbcccbdeddaaa#aa#aa#a",
+"aaaa#aaaa##aaaaaaaaaa#aaaaaaaaaaa######aa#aaa####..#########.###aaabbbcbbbaaaaaaba#####aabbcccegcbaaaaaaaacbaabbaaabaaaabcccdeeffddaaaaabcbbbcfffecdcba#abb#############aa#a##acbbcba#bbaa########aabba###a##########aa#aaa#eedccbaaa#####a#a###########aaa#aaa#bcaaaaaafaaaaaaaaacfa##a#aaaba#abaaccbcbbccbaaaaaaabbbbbbaaaa#a#abccc#aaaaabaaaaaadcbbbcbcabbbbaaaaabaaccfjgbccbcccccaa##aabaa#a",
+"#a#aa#aabbaa#aaaaaa##abaaaaaaaaa##aaabaa##aa#a###.#.##############aabbbcacbaca#aaca#####aabbccdeedbaabbaaaabbabababaaaabbccdddffedffb###bbccefebccbdeda#aaabbaaa#######aaaaa###aabcca#adaaa#####aba#aaaa##aa################.cedcbbbbaaaaaaaaa##a######aa####aa#bbaaaaaadc#aaaaaabbee####abaaa#aa##abaaabbabdcccdcbbaccbcb##aaaaabbcdbaaaaababaaaacbccbbccbaaabbbbaabababadjiedccccbbbaaaa#aa#a#",
+"aaaaa###aaaa##aaaaa####abaa#aaa#a###aaaa######aa#################a##abbbcccbbbaaabba##.#aabbbbddedd#aacb#aaaaaaaaaaaaabbbccdddggffghecbbaabbbddabaa#aaaabaaa#bbbaaaaa##a##aba###aaabb##bbaa####aaaa###########a########.#####aaeecbaabbaaaaaaaaaaaaaa###aaa##a##aa###aaabeabaaaaaabchca###a#aa#a###a##aa####bca#abdecbcdbaaba#aaabbdcaaaaaaaabbaaaaccbbbccdbabaaabbbabbbabacjkjgfdccbaaaabbaaa##",
+"#a#aaaa###caa#####aaadb#aaa#aaaa#aaa##aaa###aaaa#a####a##a######a#a##aabbbbabba##aabaa##aaaabacdececaaaba#aaaabaaaa#aaaaccdeeefgeeefbcbbbcbbbcbaaaaaaabaaaaaa##abba##a#####aaa###aaaa##.#ba##.###aa############.##.#############dedcbaabbaaaaaaabaa###a###aa##aa#aaaaaaa#dbbbbbbbaacgg#b####a####a##aaabaaabbcaa#abacdcaaaabaaaaabbccaaaaaaaabbbbcbabcacccccbabbaabbbabcbbaaejklhfcbcbbaaaa#aaaa",
+"####aaaaa##aaaaabaaaaabbaaa##aaaa###aabbaa###aa#aaaa###aa#######aa#a##bcccaaabbaa#acaa###aaaabbcdcdcbaabaaaaaabaa##aaaabbccdfffghffdaabbaabccddbabaaaaaaaaaaaaaaaaa##a#######a####aaa###.aba######a#################a############bfedbaabbbbbaaaaabaa##a#########abbbba##dcbabbbaaabcgdc#####aabaa###a#bbbbbbbbbbaaabbcbbabbbaaaabbbdebaabbbaabcbbbbacbabbabbbbabbbaababbbbbghillgcbbbbbaabbaaa#",
+"###aaaaaaccdcaaaaaaba##aaaaa##aabaabaaab########aaaba####a###a##aaaaaabccbba##bbba#bca###aaaaabdcddcda#abaaabaaaaccaaabbbccefgfghffaaaabbaaabefbcbaaaaaaaaaaaabaaaa##aa#########a########aaa###a##############.##.#.############a#abdebabcdcbbcbaabba############acdea#abecbaabbbaabbdfc##aaaa#a#aaa##abbbcaba#adebaecabbaccdcbbabbcbdddbabbbabccccbbacbbbbbabccbbbbbaaaabcbcfijjkjfddcbabdebaaa",
+"db#bdccbbcb##aabbbbaa###aaabbbbaccaaaabca####.#####baba##a#aaaaa#aba#accbbbbaaaaaaaacbaaaaaaaaacccdccc##abaabbaaabdbabbcccdffffhggbaaaaabdbaaaababbaaaaa#a#a#aaaaba#a#a################aabaaaaa###########.#####...#####.##.####aaaa#bedcccaaaaabbaaaaa##a#####aaaaddaabdebabbbbbabbbbgcaa#a#aaaa###aaabdaddabaadcfdfgdacbaabcbbbcccbdcdffdacdcedccbbbacbbbbcccccbbbbabacabbdgigbbgjjedcbbbccaaa",
+"#bbbaaaaaabaaabbbea#aaa#abbbbabaaaaaaaaba#############b####aaaaaabaa###abbbbbaaaaaaaacbaaaaaaabbcccccdd##cbcbcaaaaaaabcdeffgggiigabbbbbaabcaaaaaaaaaaaaaa#aaa##aaaaaaa################aaba###baaaa#######.#####....#########.#a##aa##a#adfca###abbaaaaaaa#####a####bdbacfdaaaaaabbaacedfa#aa#########abefeddcccdebccfggfedaaccbacddecdccdeddccefddcccccccabaabbabaabbaabacbbhijgdbacfkjeedcba#a#",
+"###aaaaa#abbaaaaaaa#a####bcaaaba###a#aaaa######a####aa######aaababaaaa##aabbaaaaaaaaabcaabbaaaaabcbccccbcbaaaaababbcccdefgfgghkgbaabbcbccbaaaaaabaaaaaaaa#aaaa#aaaaaaaaa####a########aaabba#aaaa#####a#.###.######.#####.####.##a#abaaa#aaddaaabbaaaaaaaa#########aabgggfbaaaaaabbbabbcfea#a#####aa##afghhfggghhgccddffhfffcccbccdfgeeeceec#aabcddcdddccebaaabaaabaaacbbbb#ejhjgbbceceikibbceba#",
+"aaa##a#aabbabbaaaaaaab####bc#aaaa#aaaaaa#ab##aaaa##a#aa######aa#baaaaaaaaaaaaaaaa#aaaaacbaabaaaabbcccccdbaaaabbbbccddeeefeegjheb#a#aabaccdcaaaaaaabbabaa#aa##aaaaaaaaaaaa#######a###aaaabba#abaa####..###.###.####..#####.#######aa##ba#####bcbaaabbaaaaaa########abdfggebabaaaaaabbbbbchfaaa######abbfegggefgghgffeecefggfhheecdddeeefdcefcabaabccbaabcbcbaaaaaaabbabbbbbbfghggdbcbcbbgkjfbbecb",
+"#aa#a###aababbbaaaaaaac###.acaaaba#aba####ac#aba###aaaaaaa#aa##a#a########aaaaa#aaaaabbbbbaabbaaabbbccccebaaaabbccddddedegggfhbaaa##aaabcccaaa#aaabbbbcbaaa#####aaaaaa#aaaaa#####a###aaaaaabbdaaa########...##.###..########.#####aa#aba###a#accbaaaaaaa#######aaaaabccdeeccbbaabaabbbbegfgeca#####adefffefgggfghggfeeccegihijigedbccfeceddfeaaabcacbbaaabbaaabaaaabbbbbcbchgghfgdabbaa#bgkjgcdd",
+"d#a#a####aaaabbbabaaaaaa####abaabaaaaaaa###acdbaa#a###aaaaaaaa###########aa#a####aaa#abbbbbaabaaaaaabcbccdaaaaabccddeefefhgefgbaaaaaaabaabbaa##ababbaaabcca#aa#aaaaaa##aabaaa####a####aacba#bcb#aa#.####.#...##.##..################a########a#adbaaaabaa#aa##aaaaabbbcdeddddcbabebbcbbffeefdec##adeeefeffefghgghghhgfedfheabfghhfdcegecbbbbccaaaabcaaaaaabaaabaabbbbabbcdfffgffffabbbbbcabgkjec",
+"cdaa##aa#aaababbbaabbaaaa####bbabcaaaaaaa##.acaaaaaaaa#aaaaa#ba###########aaa#a###aaaababbaabaaaaaaaabcccdgbbbccccddeffefgfeffbaa###a#aaaaaa#aaaaaaabbbccaaabaaaaa##a###aaabfd#####aaaabbaba#aa########.###.##.###############################bacedcbbbbabaaaaaaaaabcccccddedddbbdeecdefeededdeeffdegffeddefgfgggggcb##abbca###bbefeefeddcdcbeeaaaaab#a###babbbbbababcbccfgfeeefegcbaaabbca#afkh",
+"gdcbaaaaaabbbaaabaaabbbbaaa###bbcbaa#aaaa#####a###aaaaaa#aaa#aaaaa##a#####a#aa#aa#a#aaaabbaaacaaabaaaabccdfgddddddccdfhhffddfbaaa####aaaaaaa##a#aaaaaabbdb#aaaaba#a#######aacegdbaa#aaabaabbb########.#.##.##..#...####.#######################babedededcbaaaaaaaaabccddeedefecfffeeffddddddeddeeeddeggfddeeffbaaaaaaaabdb#baa#a##cbdfeaaabbcdfbaaaaa####a##abbbbaabbbbdcgfgeeedeefabba#aaaaaabg",
+"gjgccbaaaaabbbbbbbbaacbaaaaa###aaaaaaaaaaa####aaa#####aaa##aaa#a#a#######aaaaaa##aaaaaaaabba#acaacbaaa#acccfgdefefcdecfhhddbcaaa#a#####aaa#aa###aaaaaaabbeebaaaaaaa####.###aaacdcbaaaa#aaabba#############.#.#.#...###########..###############aacddeeededceeedccefggfgggfedggghfdfecdddccccddeeeeefddfffddddbabbbaaaaabefcdb#aa##aaabcaaaaa#bdgb#abaa#######ba#bbaabaaeegfgfeeeecfcaaa#aa#aaaa#",
+"#bgifcbaaabbbcbbbbaabbbaba#a#aa##aaaaaaaa######aaaa##a#aabaaaaaaaaabaaaba##aaba###aaaaaaaaabbabbabaa#a#abcceffeecb#cddeeggcdb##a##aa##aa#########aaaaaaa#bedaaaaaa##########abaa#aaaaaa#aaabaa#####a####################..######.#a##.#########aabcccbcda##afgggffdbbbabdhheghifedddeecbccdcdefffeeffdfggfdbaaaaa#aababbacdddb#bb#aaa#a####ababbdebbbaaa####a#babbaaacddfgffeefeeddcbabbaaaa#aaa",
+"a##ehiecbbbccdccbbbbaabbaaa#aaa##aabaaaaaaa####aaaa#####aaba#aabcbbbaabbba##abaaa######aa#abbacbaaaaaaaaabcccdfcaa##bbbbceabaa######aa##a##aa####aaaaaaaa#abaaaaaa###a######abbbaba##aaa#a####aaa###a############.########################a####aa#dcddcdb#a#dedeedcaa#baacgegiifedddddddcdddefeffggfgeedbba#aaaabbaabaaaaabceebbdaaaaa######aaaaabdddb#aaaaaabacbbbaabdfffgfgfeeeeddgcbaaaaa####",
+"#b##adiifdbcefedccccbaabaaaa#aaaaaaaaaaaaaaaa##abaa######aabbaabbcbbaaaaaaa#abaaa#######aaaaabcca#aaa##aaaabbccc#########a###aa##a###aa########aaa##aaa#aaa#aa#aba##a#######aabbabcaa#ababbca##aa####a#####a.#########################a###a##acba.ddeecccba#cfeeedcaaaaabccbaigfeeeddddcbcdcddfeffggeedaabaaaabaaabbabaaaaa##cffedeaa#a#aaa#aaaaaa#abfebabaaaaaacadcaaffecffffgfffeeggaaabaa####",
+"#caaa#.ahjgffefgggffecbbbabaaaaaaaa#aaaaaaaaababaa#aa#a#aaaabaaaacccaaaaaa#a#aaabaa######aaababaaaaaaaaa#aaaabccb####aaa##ab###aa#####a#a####.#aabaaaa########a##aba########acbbaaaaaaaaaabbbaaa################a###a####aa############aaccb#adcbbdddccbcdebdedccba#a#aabdcbaggeeddedcbbbccdeeffffhggfcbaaaabbbcaabaaaba####a#debceea#aaabaaaaaba#aaa#cfgcaa##aabcbcbdffedfeeeefefeedhcaaaa#a###",
+"####aa##.behhgfeeeddefedbbbbaaabaaaaabaaaaaaaabaaaa#aaaa#a#abbaaabbcbbaaaaaaaaaaaba####aa#aaabaaaa##a#aa#a#aaabbcc.##ab##aabca##aaaa############aabaaaaa#a#a#####aaa#bb#.####bccbaa##aaaa###aaaaa######a#######bbabba####bb###a#a###a###bcccccdcdccddcbbabcdcddccba####bdddb#bdcecdedcbbbbbcceeeeehhcdaaaababcbcaaaaabaaa#####ab#aabb###bb##abcaa###a##adfeba###aabaaefefffedddeedefefhbaaa###.#",
+"#####aaaa###chikjiigedcegcccbabbaaaaaabbaaaaabaa#aaa#a#a##aaaaaaaaabaa#aaaaaaabbbaa######aaaaabaaaaaa##aaba##aaabab.###aaaaaabaa#aa#a#############a###aaba########aa#cbb####abcbaaa##aaa#a######a#.####aa###bbccbbdccbaaabb###a#aaaaa###cbbbaccccbbcccaaaabbccccbbaaa#accdcb##bacgeeedccccbccdeeefggebdaaaaabbbbbbaaabaa#####a#a#aa#####aaaa##ca#####a####beeca#b#abadgefffedeedfdcffeff#a#a###.",
+"..######a#aaadd#acdhihecdgecbcaa#aa####ba#aaa##aa##aaa###aaaaaaa##ababaaa#aaaaabbbaa######aaaaaaaabaaaa##baa##a#a#b######aaaaaaaaa#################a#aa#bcb#####aba##a######bbbcbaabcaa#################a#abcdbdefededcbcbaa##aaa#a###bcbababbccbbbbbcaaaaabcccbaabaaaabcdbba###bhhfhgeddccbccddfhhhfbbaaaaaabbbccaaaabaa####aa#a#####b####aa#aa#ab###a##aaabefd#a#abbfgfeeeeeedeeddefggbaaa####",
+"##.######aaba#abaaaabeiiebceddcbaaaaa###aaba#########a##aaaaaaaa###aaaaaaaaabaabbbbaaa###aaaaabbbaaabbaaaaa###a###bb#####aa###########a######a#####aa#baaaba##abcedcbaa##a##bcccbaaaddccaa##############a##bbceffgfededdedcbaa#a#aaa#bcabaaabbbccbbbbbbaaaabbcbbbbaaaaabbcda#a##ehgfeeeeecddbcddfhhgcbbbbbbaaaabcbbbaaaaa###.#a#a#a####aaa###aa##a########aabbbedbacfegggfeeefeddccddgihdaaa####",
+"##.###a####aaaa#bacbaa#chidccdfdbbabaaa#ababaaa###a###aa#aaaaaaaaaba#aaaabccccbcccccabb###aabaabbbcbaabaa########aaab.####aaa##################a####b##aaaabb#aacdddcbb#######bccaaaabdbba#####aa#a#########abccccccddcffhigcbaaa#aa#acaabaabbbbaaabbbbbaaaabbbbaaaaaabcccdda#a#higheddefedeecdffffeeaaabbbbaaabcbaabaaaa#########a####aaaa######a#######aaabdcbadgfdeddegfgfeedcccccehigaaa####",
+"###########aa#####aacdb##ejgcbbfedcaaaaaacbabaa#####aaaa#aaaaaaaaaaa##abbbbbbaaabbcddddbccdcccbababaaaaaab#########aba..####aa###################aa########aa##aaaabbbba##a####ccaababdaa#aa#####aa##########aaaaabbccdfgjjihdcaa#aaaacbaabbababbaabbbabaabbbbbbbbbbbbbcccddebadhggfffeeffffeeeffdccddaaaabaaabbabbbbaaaa######..######aaaaaa#a###a#aaa###aaaccc#ceggedddcffffedcbabccdfgebaa###",
+"#########aabaaa####a#aabbachjgbacdedcccbabaaaaaaa#####aa#######aaaaaa#aaaaaaabaaaabbccdccddcbbbabaaaaaabbaa########aabb.#######a##################aaa##########aa##abaaaaa######bbaaaaba#a#a#.##.#a#aa###aa###aaaaaabcddgijijjigeba#abdcbbcdcabbbbaabbabaaabbbbaaabbbbbcacddee#dfeeeffeccdghhfffebccccaaaaababbbbaaabba#a########.###a##aaaa##aa##aaaaa####aababbddceggfedcdffedcbaabcdeeffaaaa#",
+"#######a#aaaaaa#a#####aaaabcdiibaaacecddcbaaaaaaaaaa##aaa########a#aa###aaaaaaaaaaaaabcccbbaaaaaaaaabaabbaaa######aaaaca.###.##a#a####a########aaaaaaa##...###a###a##a#aaaa#####bdaaaaaa########a########a##a##aaaaabbbbegfeedeghgeccddeeefgcbbaaaabbbbaaaabbbaababbbbcccbceeebegdddeffedbdeiihecbcbdbaabaaababcbbaaabaaa#a#.############aaaa##b#a##aaaaa##aabbbbccdceghgeddefedcaaaaccdedfaaaa#",
+"########bcaaaaa##########aaaa#gidaaabedcccbbbaabdbaa####aba#a#############aaaa###aaaaaaacbbaaaaabbabbbbbcbbabaa######aabb..##.####aa#aaa######aaaaaaa####a#.####aa##ba#aaaba#####dbaaaaa######aaa#aa######aa###aaa#aaabccebabaabbdfhhhgfghggdbaaabbcaaabbaaabaaaaaaabccccccedchigdcdddcedccabghdbaaabcaaabaaaaabbbbcbbaa##a########a##.#aaaaaaaaa#aaaaaaaca#acbbbbbcccdefeddeecdcbaababcfdfeaa##",
+"########baaaaba#aaaa#####a####aciib#aacdddbabbaabbb#aa#####aa#############aaaa##aaaabaaaabaa##aabababbbbccbbbcb#######aaaa#...##.#####aa########aaaaa######a############a#aaaab##abbaaaa#######cb############aa#aa#aaaaabaaa#######bfhigihhfbaabaaaaaabaaaabbaaaabaaaccbccdcchiihhdbcddcddccbbeeaaaabbbaaaababaabbbeeeaa#####.###.aaaa#aaaaaa#aaa#aaaaaa#bbadccbbbbccccbcddddcbcccbaaaaddddge###",
+"########a##abbaaa#########a#aaabcfjhaaabcdecaabaaaaaaa#######a########a#aa#abaa#####aaabaabaa##ba#abbccbaccaaca########abcb..######################aa###ceb#######aaa#####a#aaa###acaa#aa#######b############a#a##aaaaaabaa########abacfhhfcbbaaaabaaabaaaaccaaaaaaaacbcbbcffgfgcegeddeddcdccbcd#aaababbbaaababcaabaaccba########a#abaa##aaaa##aaaaaaaaaababcbbbaccbbcbccdddcbbbcbbcbbadcdeehd##",
+"########bb####aaba#########a####aabfjfbbcbcfdbabaaaaaaba######aa######aaaaaaaaa##a#####aaa######aaaabacbbaaabaa#########aadc...#######.##########aaaaaa#ddeb#a####aaaabeb######a###bbaaaa##b####aa#.##########a#a#a#aaaabaaa##b###.adbaabeecbaaaaaababaaaaabcabaaaabbbbbcdcfgeddgbbggeedddcccccc####aabaaaaabbaabaaa#acda############aaaaaa#aaabaaaaaaaaaabcbabbbabcbbbbcddccbcbbbabbbbccdfggf#a",
+"aaaa####bc##a#aaaaaaa###.#####.####aciiecccbceebaabbabbb######a#a####a##aaaaaaa########aaa#######aaabcbbabbaaaaa#########acfc..####.#.###.###aa###a#a#aaabcaaaa###aaaa##########a##bdcaaaa#ba###baa##########aaa####aaa#bbababdcbaacbbbaaaabbaaa##aaaaaaa#aabbbaaabbbbbbcdcccddcdec#adfedddcccbe#####aaaaaaaaaabbbaaa#bdb##.#######.####aaaaa###aaaaa##aaabccbbbaababbbbbcdccccbcbbbcbbbdcefghc#",
+"########a#####aa#bbaaaba######...####adhifegfddfdcabccbaa###aaaaaaa######aaaa##aa##a###b##########aa#aaaaaabaaa######a###abdfb..#######.##.#####aaa#a###baaa####aaa#########a####a#bddcbaaaa####aaaa####ad##aaaaaa#######abadddccccdcba##a#ababa###aaaaaaaaabaaabbbbbcbbcbbccdccbaba##afedddccbfa######a#aaaaaabbabaaaaab#####.##..#..a###aaaaa#aabbaaaaaabcccbbbabbbbbbbbddccbbcbbbcbbcfdeeffha",
+"##############aababaaaa##########.##.#..chjjhjifffdeccdbaa#aaa###aa#####.##aa#######.#######a#########aaaaaaaaaac########acchc.....#..###########aa##aa#abaaa##aba##a######aaaa##a##bdcbaaaa#####a#aa###bd###aaaa#aa##a####adgdcbbcddbb###aaa#a#####aaa##aaa##abbaabbbbcbbbcccddeccc#a#bhggfedaec##########aa#aaababaaaaaa#####.##.##.####aaaaaaaaaaaaaaaabdcbbbababbabbbabddcbbbbbbccbbdifdefge",
+"a###a##########abb#aaab#a#######...#####.##a#acgkigfeefdcaaa##aa#aaba####..######.#a###a#aa#aa##.#######aaaaaa##ba#####aaabbeha...###.###.#######a##aaa#aaa#a#aaaa###aa#a###aa###a###cdcaaa######a#####abb####aaaaa####a####deebbbccdbba##aaa#aa####aabaa#a#aabbbaaaaabcbcbbccbcedbba###cdffffeefba###########aaaaaabcaba#####.####.#######a#aaaaaaaaaaaaacdccabbababbabbaabcccbbbbbbbccdeeedefh",
+"f#######aa##a##aaa#aa#bba#########..############afkjgfgfeeeba#aaa##a#######.####.#.#####abbbaa##########aaaa##a#a#######abbcdhe#...######.##a####aa#a###aa#a#aaaaa######aaa###########bdbbaaa####a######aa##.##aaab####aabdecdcbaabbbaba##aaa#########abaaa##abbbaaaaabbbcdbaccbcebaa####adghfedeeba#############aaaaabbcb##########.######aa#aaaaaaa###bcdccbbabbbacbaabbbbbbdcccbbbbbcccccddeh",
+"hc#####aa######aa####aaaa#####a###.......##aa##a###gijhhhggeb##baaaa####...#####.#..a###acccaaa##########aa#####aaa####aacdddhf#..###.#..####aaaaaaaaaa###a#aa#aaaaa#####aabb##########cecaaa####a##############aabb##aabacddbcbbabbbaaaaaaaa##a#######baaaaa#abbaaa#abbbabcbbbcdgd####a##adcgfecdeb######a########aaaa#baaba########.######aaaaabbbbbbcbccbbbbbbbbbaaaaabbbbbbccbcbbbbcccccdeed",
+"egb##baaaaa####a##aa#aaa#a#######.#..###.###########adfilkhfca#abaaa#####..##....#....###bbccaa##a##aa####aaaaa##a##a##abbcfhjfb#..#####.######aaaaaaa######aa##a#abbbba###aba#aa#######cecaaaa###a#.#######aa##aa#aa###aaabcbcbbcbbaaabb##aaaaa#######abaaaaaabbaaa#abbbbbabbabdfeaaaa##a#ca#eecccfcaaaaaaaaa#a#a######aaaaabca########a####aaaabababbbbbbbbbbbbbbbaaaaaaabababccccbcccdccbdffd",
+"cfhd#acaaaa##a#######a#a##a###a##.....######.##########bddjkidca#########..###....######acaacbbb#a###ab##aaaaaaaaaaaaa#aabcfgejfa#.###a######a##aaaa#aaa#a###aa##a#abbcba#####aa####a###aeedbaaa##aa####...#aaaa#bcaccbaaaabcdccabcbbbaaca#aaaaa#########aaaaaaabaaaaabbbbbbbaaabbecbbcaaaaaa#adecccedcaaaaaaaaa##a###########abaa######a####aaaabdbbbbbbbaabbbbbabbaaaaaaaabbaabccbccbccdccdefg",
+"fedfea#a####a##a#a#######a####a#.##..#.####...########aaaaaeikhea#####################aaacbabbdfdbbaa#aaabbcbbaabaaaaaaabcdfbbeica..#a########aabaaaaaba#a###aa#######aaa#####aaa#.aa###adffdbaaa##ca####.#########abbcdeeeefcdcbabbbbbaacbbaaaaaa##a##a##baa##aa###aaaabbabbaabaadfb#bbbbbaa###feccbeecbbabaabaaaaaaa#aa###a####a########a##aaaaabbbbbbcbabbaaaaaabbbaaaaaaabbbabccccccddddeeee",
+"fggehdaaa######a##########aaaaa#.##.####..#..##.#######aabbaadjljgda.#################aaaccbccddcccccccccccccdcbbccbcbaabbcfdcbgf#...#aa######abcbaaaaabaaaaa############.##aa##a########dffedcbaa#cc##########a####bbbbcdffeedaaabbbbbcbabbaaaaaaa#######abaaaaaaaaaaaabbabbaa#a#bdcbbbaaaaa###cfeeehhecabbbbbbaaaaaa##aaa##a###a########aa#aaaa#bbcbbbabbbbaaaaabbbbbabaaaaaaaabbbbbcccddddeee",
+"edehhg#aaa######a#a#####a##abbaa###.###################aaabbcaacjllkhbaa#######a######bbaefddddcbbbaaaababefeedddccffdccdfgeeeefec#...#ab#.####abccbbba#aaaaaa###########..###a##########bfdfdccaaacfb.######aababaaaccccbdffebbbbcbbaacccbabbabaaaa######aaaaaaaaab#aaabaaaabaaaabbeffcaaaa####aeeeefiihfcabbbbbbabaaaaaaaa##a######aaaa####abbabbabcbaaaaccbbbbbbbbcbcaaaaaaaaaaaacbbcdddddede",
+"eefgghcaa#######a##aa######abbbcc#.############.###a#aaaaaaaaccbafjllkjecbaaaaaaaa##aabcccgefeecccbba#aaaa.acffffffcacdccbbbfffefda#.##########aabcedba##aa#a#####a#####..#####aa###.####bceecccbaabdfa##aabbbaabbbbdcbbccdcceebabbbaaabcdcbbbbbaaaa######a##aaaaaaacaaaaabbaba###acdeegcbbb#####aeffgfgijkgcbbbbbbbbabbaaaaa##a#aaa#abaaaa##aacdbabbccbaaa#bbbbaabaabccbaaaabbaaaaabbbccdeedddd",
+"deeffdfd#####a######a#######aaaca#a############bdca###aca##aaaceddfijjnligdcbbcbaaaaabcddchgedddbccaaa#aaaaa##accfbbbaa####bdhfedhd#.###########bbcccdba###aaa#####a##a#.#####a####.####.#abedebdcbbcfe#####adcbcddbbdbaaacbcbccbbbaaa#bbcbbbbbbaba#a############aaaaaaaaaabaaaaaaabdfcccbbba#####aceffgiijihedccbbbbbabbaaaaaaaaaaaaaaaaa#####aabaaabbbaaaaaabbaabbbbbcabaaaaaaaaabbbbcccdddddd",
+"ddddecbdca###a###a##baa#aa##abaaba#a###.#####.#aabaaa#aaa##aa#acdhilmklmlmkheegecbbbbccbcefgedcdcbbbbaaaaa#aba#a#cdabcbaaa#achihggfa############abdb#bcaa##aaa#########a###.######..########beddecbcdffc###.#acdfffdabcca#aabacbbbbbaa#abbbbbbbbbaa#############a#aaa#baaaaaba###aaadfd#babacababbbcegfhhiihgfdddcccbbbaabbaaaaaaaaaaba#aaa###a#aaaaaaaaaaaabbabbaabaaabcbbbaaaaaaababbccdddddcd",
+"deddddcacaba###a####aaaaaa#aaaa#aaa###aa#########a##aa#aaa##aba#.cfehhjkjllmllihfedcccbbdefgdcccecbbbccbaaaaaaaaabdbbbcbaaaabhjjhggea#.####a##a#accaa#cdaa#aaa#.#############a##a##.###a####.cedccccefbbaa#####deffeaacdaaaa#aabbbbbaaaaaabbaaabbaba#####a.###a###a#a#aaaaaaa#a##aaacdecaaaabaa#aa#bdgfeeefhhfdccccddcbbaaababaaa##aaaaaaaaa###aaaaaaaaaaaaaaaabbaaababbbbabbbaaaaaabbbbcdcdccdd",
+"dddcccdbbbcba#bb#aa###aa##a##a####a##.####aaa##a#aa##a#a#ba######.fffkjlhkkljmmmlieeddccefaeeeccdedbcdccbcbaaaaaabaccbccaaaabeijjigieba.#######aacbaa#accaaaaa##########a#a###aaa#############decabdeeeaba###..adeddcaabcbba##aabbbaaaaaaaaaaaaaaaaa#####a###########aa#abaaaa##a#abbcdeba#b#aa#####cefedcbbdeedcccdddcbbbaabbaaaaaaaaaaabaaa###aaaa#aaaaa###aaaaaaaaaabbbaabbcbaaaaaabcccccccdd",
+"ddccbcccbcedaddaaaaaaaaaa#aa#a######...###########aaaaaaaaaa####..cfhjjkmlmklkklmnjfeedeefebdeddegheeedddccbbbaaabbccbcbbaabbbgjkjjhifda.#######aaaaa###abaaaa####aaa###########aa##########..adccaddcecbabbaa##dedddcbabcbca#aaaabbaaaaaaaaaaaaaaaaaa###############aabaa##a####aacbcddebaaa########cffecdcbceeefdddddcbbbaabbbaaaabaaaaaaaaaa###aaa#a#aaaaaaaaaaaaaaaabbbaaaacbbaaabbbbcdcdccb",
+"cdcccccbbcdbaacbbbbbbaaa#aa#aaaa#####..#..##.#####a#aaa####aa######eigfcfgijjjlmmmmnlhfhiggdddeefgegfgffdeddcdcbaaccccbcbaaabbcfjkkkijgfb#######a#aa######a#############a###aaaaaba############abcc#ddcccbdecdcaddddddecbbbccaa###aabaaabaaaaaa#aaa#########.####a##a##a#aa#a######abccdgbb#ba#a######cffgfdefffehgdddeccccbaabbbaaabbabaaaaaaaaa###aa##aaaaaaaaaaaaaaaaaaaaaaaabbba#aabbacddccc",
+"cddcccbbcccaabbabaacbaaaaa#aa#aa#.#...#...#..###a###a#########aa##adeaaa#abedefijlkmnnlkkjdddfdcebb#degfaefgfeddcbdcddbacbbbbbbdjjklkkihgc#aa#####aa################aaa##a#aaabaaaaa###########aabdbedcabdddeeddddedcccddccbbbca###aaaaabba#a#####a#a###aaa###.###a#######aaaaa###aabbbbcdaaabaa##a####aeghhhggghhhfedddcccccbbbbbbbbbbbbbbaaaaaa####aaba#aca#aaaaaaaaaaaaaaaaaaaaabaaaaabbbcddd",
+"dddcccbbdedaabdaaaabbabbbbaaaaaa#.##.##.#.#####################aaaddbbaa#aa##a##aceejnllkkhfhfccfbbaaaabafabdeffgfcdddcabbbbabacgjkkllkhjhbaa#####aa############a##aaaa###aaa#aa#a#####.####a##aa#deedcabdeeeedeeddeedbccdcccdcb####aaabbbaaa#####a##a##a####################aa####aabbbcdea##a########aaabehiiiiiihfedfdccccccbacbbabbbcbbbbaaaaaaaa##ab##bbaaaaaaaaaabaaaaaaaabbbaaaaaabbbbbdd",
+"ddccdbcbedcaabbbbaaaaaabbababbaa#################a##########a###a#ecbaababaaaa#####abkllllljgbaaccbababbabaaaa#cedfheedcabbbbbbbchkkkklkhggeba###aba####.####a####a##aa##aaaaaaa##aa####.####a####dfdcba#bdeeeeeefedddcbbcdbbadcba###abaaacaaa###a##a###aa#####.####a######.##a####abbbbccbbc#ab##a#aa#ca###cfggihhihffffedcccccbbabccccdccbbbaaaaaaa#aa#aa#aaababaaabbaaaaaaaaaaaaaa#aa#abbcccc",
+"dedcccbcecaaacbababbbaabbbbbcbaaa#..###.#########a##############.cdabbbbbbbba###aabcddilmmljeaaabcbbbbbbbbbbbabaabcefgfecbbbbbbcdfjjkkkmkhfgecbaaabb########a######aaaaa####aaa###################befcbaabbadfeeeeffededcbbccabccccaa#aaa#abaa#######a########...###########.##..###abbbbcbbf#aa###abaa#a#####acfgffgfggefddcccccbbabcecbbbcbbaaaaaaaa##aa#aaaaababbbabbbbbcbbabaaaaa##aaaaabbcc",
+"cddecccccdcaaaaaabbbbaaaabbbbaaaa########.####################..aaababaaacbba#abddbcdfeejmllf#aabbbaabbbbbbaaaaaaa#afffdedcbbbddffjfijjkkkhgfed####aba#######a####aaaa#aa#####a######a############adffddcaa#befefedeeddccccbcbaacbaabbaa###aba####a###############.###########.######aabcddcefbb###bbaaaaaabba#cffffghhgfffedccccccbcbbebbbbbbbaaaaaaaa####aaba#aaaabbbbbbcbaaaaabbcbaaaaaaaabcc",
+"dddddfebdfeba##aaaaaaabbbbabaaaa####.#########################.abbaaaaaaaaabbaaabba##aceeilmme#aaaaaaaabbbbaaaaabbbbbefgeddcddddegiighiiggjggfdba##aaaa##############ba#b###aaaa#######a##a#aaa####dfgffgcaabefeeededccccdddcbbbbbaaacbab###aaaaaa########a#a########.#########..####aaabdcdecbdc#aa###aabbcccaacegggfgghggfeeeddddcccbccbbbbaaaaaaaaaaba#aaaabaaaaaaaaaaaaaaaaaaabbaaaaabbabbbc",
+"bcdeeeeedeeda##aaaaaaaccbbaaaaaaa####..##.#########a##########aaaaaaaaaaaaababba#aa####abbdhkmgbbbaaaaabbabaaaaababbbaehfcdeeeegghkkjjigdeehfeccaaaabcba########a####aaa#####aa####a####aa###baba##adfgfffdeeffdcddddddbcccdccbbbbbbb##bdb###aadb#a##############.##.######.##########abcdcedecegdb#a#aaabbcddaa#adfghfghgffefeefeeddcccccbbcbaaaaaaaaaaa#aa###aaaaaa#aaaab##aaaabbbabaaaabaaabb",
+"cbceeeefffffd#aaaaaaaaaddbaaaaaaaa#############.#############cbbaabaaaaaaabaaaaaaaaa###aaa#achlkigdaabbabbbbaabcaacaababccdbbdedcdfehkkjgeceheccda#aabbba###.######a#aaa#####aa######.#a#aa##aa#aa##adgggfeeggffdcccddcccbbcbccbbbaaa####ca##abcba#aa##########.#####a######.#.#######abbcbddbdfhgeaaa##abbcdcaaa##aaceghdfgffffffeeddddcccbbbaaaaaaaaaaaa##aa#aaaaaaaaaaab##a#baabbabbbaaaababb",
+"ccddefgfefffd#a##aaaaaabccbabaabaaa##########...############acbaabaabaaaaaaa#aaa#aabaaaa#aaaabgkjiifbabbabbaaaabaaabbabaaaaaaabcc#####cgkmjgfhfcbcaaaabcbaa########a#aa###a###########.####a######aa##bghfefgeddeccbbbccccccbcdcaaa#a##a#aa#a#aaaacbaa##.############aa########.#######bbbccddddggfbaa###abbcbaaaa#aaabeeeeggghgggffeedcccbbbbbcbaaaaaaaaaa###aaaba#aaaabbaa#a#abbbbbbabdbbaaaab",
+"bcceddefhgfcbaa#a#aaa###aaabbbaaaaa#######################aababaaaaa#aaaaaaaaaaa#aaaaaaaa#aa###cefllgabaaaaabbbaaaaabaaabbabaaa#ba######bfjljhghcac##aaacaa########a###############aa#.##a#############afgfgfedcccccbbccccccddcccaa##a####aa#aaaaaabaa#################a#a##.#########aaabccccddeegfbaa###abbaaa#aaaaaabdfceghhhhhhgfedddcbbbbbbbbaaaaaaaaaa###a##aaaaaaabbbaaacbbabbbbbcccdaaaa",
+"bbcccdefhiea###a##aaa######aaaa#aacb##############a####aaabcbbabbaaaaabaaaaaaaaa##a#aaabaaaaaaaaabekljbaaabbaabaabaaaaaaaabbaaaa#a#aa#####aekkhhiba###aabbbb#####a.#########a#a#####a#######aa####.#aba##gggfeedccbbbbbbcbaabccbcbaa##a###aa##abaaa#aa###..###########.###a##.#######aaaabbbcdddcefgaaaaa##abaabaaaabbaabdeffghighhgfffeeccbababbbbbaaaaa#aaaa#a####aaaaaabbaabbbbbbbcccbcccdbaa",
+"bcccccdefgeaaaaaaaaa#a#a#a##aaa#a#aba#######a#.###aa######bcaaaaaaaaaaabaaaaaaaa###aaaaaabbaa#aaabbchkkc#aaaaaaaaaaaaaaaaaaaaa#a#aaa#a#######dkklibca#aaabcdca#a#aa#################a######aaaa######aab#cghhgfddcbbbbaabaaaaabbca##a##abaaa##abaaba#a#aa############...##.###.#..####aaacbbcdccdcdedbaaa#a#acbaaa#aaaaaaabcffffghhhfggfeddbcbbbaaaabbaaaaaaaaaaa#aa#aa#aaabbbcccbbbbbbbbbbcdccb",
+"bbbccccdfcec##aaaaaa####a####aa#aa#aca##a####baa#######a##bbbaaaaaaaabbbbbaaaa#aaaa##aaaaabbba#aaaaaadijgaabaabbaaaaaa###aaaaaaaaaaaaaa#######behlidcdbaaabbcecaa######a###aaa###########a####a#######aaacghihgfedcbaaaaaaaaaababbbaa###aaa####a#aba##a#a#####..######......#...#.#.####aaccbcccdcdehhdaa####bcba###aaaaaaabaaadfeeegihgecdedcbcbaaaabbaaabaaaaaaa##aaaa#aaabcbbbccbbbbbbbbbcbbb",
+"babbcdddddde######aaa###########aaaabda##a####abaaa#####abbaaaaaaaaaaaaaaabbbaaa#aa##aaaaaaaaabaaaaaabcdkib#aaaabbaaaaaa####aaaaa#aaaaaa##a##a##acgjhfgefcbbacccbaa####a######aaaa########a#############bfffhjigedddbaaaaaabaabbbbccaa####aa###a##aa#################a##.....#..#########aabbbbcccddfheaaa####bba####abba#aaaa##bca.#bghfedecbccbbbaaaaaabaaaaaaaaa#a#aaaaabbbbbbbbbbbbbbbbbbaba",
+"bbabbdcdddcec#####aaaa#a####a###abaaaaaa##bda##aaa######aaaaa#######aabbbaaaaaa##a##aa#a#aaaaaaaabaabacbdjjbaaaaaabaaaaaa##########a#aa##aaa##a#a##cfhhededabbdcbcca##########aaaaa############a######a##dffgjiiheedcbaa###bbaabbbddba#########aaa####################a###..###..##..###aaaabbbbcbcfffebaaaa#aabaa##a#aaaaaaa#####aa#.bdegfeccbbaabbaaaaaaaaaaaaaa#aaaaaaaababccbcbaabbbbbbcbbab",
+"dbbbbcdcdcdcea###a####a#aab#aaaa##aaaaaaa##a####aaa###.##aa###########aaaabaa#aaaaaaaaaaaaa#aaaaaaabbaabbbhkfcaaaaabbaaaaa##########aaa###aaba######.ekjgddbabbaabccbba########aaa####.#######aa##aaa#####dgfgghgggedcbbaaa#aabbbcbedba#######aaa#a####################aa#.......##..####aabbbbcbcdefeebb#aaa#aaa##ab###aaa#######a###.##cgefdccbbabbbaaaaaaa#aaaa#a#aaaabbccbbcbbbaabbbbcbccbbb",
+"bcabbcceffabbc########aaa#aaaaaaba#aaaaaaaa########.#####aa######aa####aabbbaaaaaaa##aaaaaa###aa#aa#aaaaabbfkjhdaaaabaaa#aa##aa#####aa#a#a#aaaa######aikjjhbaaabbaacbaaa###############.###################bfhggggggfedcabaaaaabbcdeccaa########aa##########aa######a#a##a##..#.#...#####aabbbbbcccecdgccb##a####a##a############aaa######agfedccccbbaaaababaaaaaaa####aabbaaaaabbababbbccccbbcb",
+"ababbccdffdbbbba###aa#aaaaaaa#baaaaaaaaaaaa#########.####ab###########aaaaaaabcbbbaa###aaaa#ba###aaa###abbbbflljeaaaaaaaaa###########aa##aaaaa#######.afikkiba#abbaaba##########a############################ehffgggfeedcccbaabababcccbaa######aa##aa###.###aa####...#########...########abbbbcbbbcdecfgdaa#######################aa##a####bfeeddccbbbbbaaaaaabaaa#abaaaaaaaaabaaaabbbbbbccccccc",
+"adbbbbcdddecbaba#a#######a#a##aaaaaaaaa#aa##########.###aac##########a##aa#aaaabcbbaaaa##aaa####aa#aaba#abbbbdillhcaaaaa####aa####aa#aaaa##aa#########.#chkli#aaaaabbaaa########a#aa###a###############.###aa#fggffgffedeecbbbaaabbbbcbaaa#####aa###a############################.######aababbcbbbccedcfccaaaaaaaa###############.####a#####bffeddccbbaaaaaaaabaaa###aabaaaaaaaaaaababbbbbbbcccc",
+"ccbbccddeeeccaaca##a####aaaaaa##aaaaa#a#aaaa#########.###ab####.#a###aaa##aaa#aaaabbaaaaaaaaaaba#abaaaaaaaaaaachkklfbaaaa##########a##abaaa############..#bimiaaaaaabaaba##########aa#babaa##############.##a##aegfcbdeedfedbbbabbabbcbbbaa#####a#####aa######################.#########aabbbbbcbbacddddccaaa#aaaaaa###a#####################afgeecdccbaaaaaaa#abccbaaaaaaa#aaaaaaaaaaaabbbccbcc",
+"ccedcdddeeeccbbbcba#a###aaa#a#a#aaa#####aa#a#############ab#####.#####aa#a#aabaaaabbbbabbba##aa###acb#aaaaaaaaacfihkida##a#a###.####aaaaaaaa##a###aa######.ahljc#abaaaaaaa###.####a######abaaa############.#####.bababeedegdcbccbcbabaaabba#a##aa####aba#aba#a###################.####a##ababbbcbbbcdddedea#aaa#a####aa#######.###.######a##a##fgfedddbbaaaa#bcdccbbba####aaaaaaaabbabbbbbbbcbbc",
+"cddeddddeefddcbbcc#a#aa#aaaaaaa#aaaa####aaa######aa######ab#a########aa#a#aaaaaaaaaaabbaabba#aab###abb######aaabbcfheihc######a#####aa#aaaaaaa####aaaaaa###.aikjcaaaaaaaa#################aaccbaa#a################aaaaaaabdddcbccbaaaaaaaaaaa##b####abbcccb##.###a#############..###aaaaaabbbbbccbbccccddecaaa#aaaa###a########################effedccaabbaccbbaaaacc####a#aaaa#aabbbbbbbbbbbcc",
+"dcdcdcdeddfecdcbcdaa#aaa##a###a###aa##############aaaa###aba#############aaaabaaabaaaabbabbaaa#aba####a##a###aaabccefadhhb##aaa#####aaaaa#aa#a##aaa#aaa#####.aflkcaaaabaa####################ddcbaaa#################a#aaa#bdddbbcbaaaabaaaaaaa#a####a#baa####a###a###aa#############aaaabccccbcccbbcdcdedefb##a###aa##aa###############a##aa####efddcbcecbccabbaa#aacc###a##aa#aaaabbababbbbccc",
+"ccdddcbcfhfddcdcbbc#####a#aaa##a########a#a#aaa#####aaa##abaaa##.#######aabbaabbaaaaaaaababbaaa#aaaaa###a#a#a#aaabccdha#diga##aba#####ca##aa####aaaaa#a#######acildaababbaa###########a#######abccbaa#########.#########a###cdedbbdcbbabba#aaa###a####aaaa#aab###a##a#aa######aaa######aabbccccccccccddddeddfca#aa##aaa#aaa#####a####.###aa#a##a#cfeddedacaaabcaa###aacc###########aaaaaabbbbbcc",
+"ccccddccdeffdcccdccb########aa##########a#aaabaa#####aa##ab#aa###########aaaaaaababaaaaaaaabaabcabba############aaabcffb.afjfa#aba####a#a########a#a########aa#abhjb#aaaba#a##########a#######aabcccbb####.#..###aba#########abddbcecbbcbba#aaa########aaaa#a#a###aaa########aaaaa#####aabccdcddccccccccddedcec###ba#a####a#a##########.######aa#adedcbbaabaaabbaa###aabca##aaa#a##aaaaaaabbbbbc",
+"cccccdcedcddfebbdcbdb#######################abcbba#######bbaa######.######aaaaaabbabaaaa##aaabababaaaaa########aaaabbcfiea#bgjeaaa######aa#a#############a####a#acgigaaabb##########.##a#######aaa#adcba##########ba#a#a#####a#adfcddbcccbaa#aaa######aaaaaa##aa#aabbab#aa####aaaa#####aaabbccdddcdcbbbbcccddegd##baaaaa#########a################abbcccbbbbabbbba#####abca##aaa####aa#aaabbbbbb",
+"bbbccddcdcddefdbcdadcaaa#####################aabbbba#a#aabba#aa##########aaaaaabbaaaaaaaaa#a#aaabbbbbaaaa###a#aaaaaaaabfifa##ejgbaaa########a##################acbcfigba#aa###########a#########a#aaabbbba#######.#a#a#######aaaaffddccbccba##aaa##########a######aabaaa#.####aa######aaabbbccdeeefggecdedcdfedcbaacbaaaa##a#a####a############a##aa#accdcbcbbbbbba#####aaca#aaaaaaa###a#aaabaab",
+"bbbbcccccddddfecbccbdc#a############a###aaaa#aaa#aa##aabcccc###########aa#aaaaaabaaaaaaaaaa#aaa#aaabbbbbbaa###a#aabaaabbbhie#.bfhfbaaaa###aaaaaaaaa#######a####aaabdhifbaa########aabaa###a######aa#####bccaa#####.#####a########afgeddccdcba###aa########a#a#######aa######.##########aabcbcccdffghihgdcddcbacbbeabaaaaaa#a###################a##aaaa#bcddcdcbbbab##a##aaaba#aabcaa####a#aaaaba",
+"bbbbbbcccccdefedbbcacdc####aa##a#.##a#.##abb######a##aabbccc###########aa#aaaabbbbaaabaaaaaaaaaaaaaaabbbccbaa##aaabaabba##diic##adhebaaaa#aaa#aa##aa##########aabaaagjjf#a######a#aaaaaaa#a#######aa#a###bdddaa#a###.#a###########adcdddddcba#aaaaa#a###a##a##ba#b###aa####.###aa#####a#abcdcbbcdghihhgdcaaaaaabcfdccaaaaa#aa###################a##a#a##acbcdcbbcba#a#####aaba##abaaaa###aaaaaaa",
+"aaaaabbbbbcddeedccebaccb###a####a####a#..aba##########aaaaccb.############aaaabbaabbaabbaaaaaaaaaa#baaaccbbaaaa#aaaaaaaa####fjfb###egebaabcb##aaa##############aaa#achkjbaa######aaaaaba#a#aa###a###########abba###################abaceddcbaaaaaaaa#####a#####a####a##a######.###a##abaaccddedeeffdghfaaaaaaaabbdfcabbaaaaa###############.#########a###bccbedcbdaa######a#abaaaba########a#aaa",
+"#a#aaaabbbbbbcdedcccbabbb##aa######.######ba#############abcc##############aaaaababaaaaabbaaaaaaaaaaaaabbcbbccba#aaaaaaaaaaa#beihb##afgdbbcba#aaaaa######a######aa#abcilheba#####aaaaabaaaaaa#########a####a##a#aaa###############a#aaadedbbaaaaaaaaa##aa##a#######a##aab######.##aaaababceefcddcb#.#gfaaa#aaaaabcfgcaaaaaba########.#####################aabddcbcabaa##a##aaabaaaa######a######",
+"##a#aaaabbaabbccdcbcbbbacb###a###########.aba#######aa###aacf#######.#######aaaaaabcaaa#acaabbaaaaaaaaabababbbcdcbaabba#abaaaaabfje#a#aehdaaaaaaaaba#####ab#a####aabaabijiebaa##aaaaaabaaaba##aa#####a#a###########a###a###########aaaaaabbbaaaaaabaaa#aaaaa#####a##abaaaaaa########abbabcdgeba##.##.bdaaa#a#aaaacfgcaaaaaa########.a########.#######a#aa###abccbbbaaaa#aa#abbab#abaa####aa#####",
+"#####aaabbaaaabcbccccbbbcca###a############a#########aa##aaacb###.#.########aaaaaaaaabcbaaabaaaaaaaabaaaaaaaaaabcaaaaabaaaaabaabaejhbaa#aggcaaaaaaaaa####abb#a###aa##aabhigddbababba#acbabaaa###aa####a#c#a#############a#a########aaaaaaaabbaaaaaaaaaa#aa##a#####aaaaaa###aaa######aabbabege##b#######aa#a##aaaaaceecbaaa############################aaaa##aaacbbbaaa##aaa#aaaaa##aa#####a#####",
+"####aaaaaaaabbabbdcbcdccbbba#aa####a##a####a######..##aaaaabab###.###########aaaaaaabbbbbbaaaaa#aaaabcbaabaaabbaaaaaaabbaaabbabab#bghcaba#dhfaabaaaaaa#aa###aa##aaaaaaaabeegbccbaaabcbbbaababa######aa#aaaaa##aa#.######aaa#########b#aaaaaabaaaaaaaaaaa#a##aa#aaa#aaabbab##a####ab#aabbbbcfhaaca##############abbabddbbaa####################.###a##a#aaaaa#aabbbbbaaaaaa###aaaaaaaa#######a###",
+"#####aaaaaabbbbbccdbccdcbcca##########a#####aa##a######a#aaaabc###############aaacaabbabbbbbaaaaaaabccbbaaaaaaababcaa#bbaaaaaaaa#ba#eiebabaafhb#aaa###a#a####aaabbaa#baabbbigcebaaabcbbcdbbbcca#a##a###acbbaa#ab##########aaaa########aababbbaaaaabaaaaa##a###a#aa###aaaca##a#aa.bc#abbdccbdga#####.###########abbbbcdebaa##a##a##########a####.###a#aa###aaa##aabbabbba#a#####aaaaaa########aa#",
+"#####bbbabbbabbcddddcccbbbcca#a##aa###a#################aaaaabb#a####.########aaaacaaaaaacaaaaabcaaabbcdcbbbcbabbbabbaaaaaaaaa####aa#cijdbababhfa#aa###aa##a##a#aaaaa#aabbbflggfaabacbaabbbaacbba##aa#abccbbaa###aaa#####a#aaaba###a#aaaaabbacbaaaaaaaaaaaa###aaaaaaaaaacaaaa#bbab#abbcccccbdc#################aabdceedebaa#########################b#####aa#####bbbabbaa#a####a#aa##ba########a",
+"aa##aaabbbbccbbcccddcdccabbdfa####a###########aa######a#a#aacc#######.#########aaabababbaaaabbaaaaaaaabbbbaaaaaaabaabbbaaabaaaaacba#a#beijbaaaaehfa###########aa#abaaaabbbbdhjghffedccaaabaabaabbaaaacbcbcccbaa#aaaaaaaa#aaaaaaaa####aaaabbaadebbaaaaaaaaaaa###aaabaa#a#aaaaabbbbbbbabcdcccefe####.##.#######.##a#aacccccaa#aa#####.###############aaa###.#a###a##bbbbbaa#a########aaaaa##a#####",
+"###ab#ababbccbcbccdddccccbbbeda##aaa######aa###abaa####a###abdb#a###.######aaa#aaabbbaaaaaa#abbbaa#aaaaabdaabbcbabb#aaaaaaaabaaacbcba####ejdbbbacgjd##aa#aa#####aaabbaabaabbejiiiihhggfbaabbbaabcba#bcdcdddddcaabbbbcbaaaaabaaaaaaa##aaabbbbcdedbcbaaaaabbaa#aa#aabbaaaaaaabccbbbbbcdccddffebb####################aabccccca###########.#########a####aaa####a##aa#abbaaaaaa########aaa####a#####",
+"#aaaaabbbabbcccccdedccccedccdebabaa#aa###########baa##.##aaa#aca#######.#####aaa#aaabaaaaaabaaaacbaaaaaaabaaaabcbaabaa##aaabaaaaabaaaa###.cjgcbbbadiib##aaaaa####aaabbaaaaabdhlijjiiihfefcbaabbbbbbababdedfddedccbccdccbccdccccbaa#aaaaababcccdddcccbaaabbaaba#aaaabbaabbaccdddcdefffedeeed..################.######abcbdfbab#a###########################a#a#####aaaaaaaa##aaaa######a##.#a####",
+"###aaaaabcbabccccdcddcccccbbccebaaaa##############a#a####aaa##abb##############aabaaababaaabaaaabbaaaaaaaaaaaaaabbcbabbaabaaaaaaaaaaaa####.afhdbbaabfihb.#aa###aa###aaba#aaacclljjiijigddecbaabccbabbbdbadcbeffffeffgghhhighgfhgffcaaababdbbbbcfddddcbbbbbccabaaaaaaababddehggfegjiedaaaa#a####a##############.######bcdcddbaaa##a###################a#a#####aa####aaaa#aaa#a########a#######aaa",
+"aa##aaaabaaabbbdddccdbcddcccccdd##a#aa##aa########a######aaba###ab##############abaaaaacbaaaabaaaaaaaaaaaaaabbaabbaccbaaaaaaaaaaaaaa#########bfgbaabbdije.######aa#abbaaaaaaabellkkkkllkiiigfdcdcbabbcbcdcbcgijkjhhhhijjic#dcbcbddghffeeeihiggfgddedcccbcdcdcbcbcbabadeeffghhhebegdddb#########a#a####################babbbcbbb##a##################aa##a####aa#a###aa#a#aaa##a#######aaaaa##aa#",
+"a#aaaaabaaaaaabcdcceccefcadgeceebba###a#aaa########a#####aabaa#aabda########a####aaaaaaabbaaaabaaaaaabbaaaabbbbaaaaaabbcbaaaabaaaaaaa#aa######.eiebbbbcfihc#.###abaaa#aa##aaaabellkjlkjklmnnmlkgfccbbdddeefghjijkkllkhd#cfeabcbbcbbdgjjhgecccehieeededccceeedddddefcdffcedbacdec#bbaba#########aaaba#########.#######aaaacccdbbaa####################aa##a####aaaaa#aaaaa#a####aa######aa#aa##aa",
+"a#aaaabaaaaaaaabcccdddggedbdfccecaaa###aaba#a#######aa#.##aabba#aabc###########aaaaabcbaaaabaabaabbbabaaaaaabbcccaaaabbbbbbaaabaaaaaa#aa#aba###.bigbbbccdilid.##aaaaaa####aabbbcekmljgdfiijikmlmnkgdeefeeegieeddgdcghgdbabcfdebcccceffggfcbbbbbcefgedddcceeefdedcbccefgb####babedcaa##aa#######aabcda##.#############aaaaabcdcdbaa#########a########a###a###aabbbbaa#aa#aaaaa##aa######aaa##aaa#",
+"##aaaaabbaaaaaaabcdceeffedccfgedcaaa##aaaa###a#a#####aa..##abaaaabbd#########aaaaa#a#bbbbbbaaaaaaabbbbbaaaaaabccbbaaabaabbbbab#aaaaaaaaa#aaaaa###ahibbcdccgjkg####a#aa####aabbcddegkhddgihhghiibdilmljjjjiiihfaaa##aeeedcbbdghfdbbdfedfedccbbbbdbffhfededeefhhfc#####cea#####aaabdfda.a######.##abdfb##########.###a##aaaabadefecb#a##########aaa####a##aa####acbbbaa##aaaaaaaaaaa#####a######a#",
+"a##aaaaaabaaaaaabacddeddfdccefffd#aaaaabbaa#a#####a#.aaa###aaaa#abbdb########aaaaba#aaaaababbaabbbbbbbbbaaaaaaa#abcbaaababbbbcb#aa#abaaa###########fhdcccdcehihb###aa######a#bccdefggiglkjjhiihba#cglkjhiihgebcaaaaaa#aacdbbdefhfdbbeedbccbbbabdcbgjifefedeggfgfa#aa#a.aa######aaaacffba####.###abdeca######a###########aabbegffgedaaa##########aa####a##aaa#####aaaab#aaa##aaa#aa######a#######",
+"##aaaaa#aaaaaaaaabbcdddceddeeecdfbaaaaabbbaa#####ab#########aaaaaabbc########aababbaaaaaaaabbbaaaabcbbabbaaabaaaaaaabbbbaaabaabbbcaaaaaaa##########.bhfcccdddefigc#abaa#aaaaaacccdegeiihkihhjhbbaa#.#a##a#..##aaaaaaaaaaaacaabaacefedefbbedcbaccdbcfgiihhfdec.addb#ba###aa######aaaaadgeca#######aceaaa#################aaabdgeeghffb########a######aa####abaa#####a#aaaaaaa#aa###a#.######aaaa#",
+"a##a####aa#aaaaaaabccbccdedefebbef#baaaaaabaa#####a#aaa####aaa##aaaada########aaabbbaaaaabbaaaaccbbcabbbbaaaabaaaaaaaabbbbabbbbaabcb#a##a#########a##bifdccdddefgjeaaabaaaa##accbbcddfhehijhdb#aaaaa#a####a#abaa#aa##aa#aaaaaabbbaabefigffefdbcccdcbaacbbdhhfeaacbabb##a##########aaaaadhgb#####aabecaa########a###########baegfefgfeca##a#######a##aaaaa#aaaaa####aa#aabbaa#aaa###a#.#####a#aaa",
+"#aa#####a#a#aaaaaaacccbbccdcdedbcfcaaabbbaaaaa####a###a###abdb####aaeda######a#aa#aabbbabbaaaaacddbaaaaabaaaaaaabcbaabbbaabbbbbbababa####aa###aaa#####dihecccdedeejgaabcbaaaaabcbbbcdeheggeabaaa####aa########aa###aaaaaaaaaaaaaaccbaabdegedddddddccbbbba#abaabcbbaaaa##a##.#.#####a#a#abefb#####abdfaaa#####aaaa#a########aaadfeeffffc#######a######aa#aaaaaaa#aa##aa#aaabaaaaaa#######.###a#aa",
+"aaaaaa#aaaaaabaaaaabbcbbabbbcceedffdbaabcaaaa##abaa##aa###acefa####abdaa###.####a##aabbbcbcbaaaaabba##aaabaaaabaabbbaabbbaabbbbabbcbba#a##aa###aaa#####bhjgccdddefdhheabbaaababcbbabcdehfcaaaaaaaaa#aaaa#######aa###a##aaaaaabcdaabbbbabbbefedeccddcbbbaababbbcccca#a####aa#############aaceda###aabfebaa####aaaaa##########aaadefedegca########aaa##aaa#aaaaaaa##aaa##aaaaaaa#bcba#########aa##",
+"#aaa#aaa#aaaababcbbbbccbaaabbbbdgffgbaabbbaaaa#aaa####a##abbgea##aa##bca#########a#a#bcbabbbbaaaaaaaa##aabaababbbaabaabbbbbbbbbaaaabbaa##a#####aaa######adhidddddfhdfigbcba#aaaaaaaacbcfdabaaaaaa#aaaaaaa#######bb#####aaa##aabccaaabdcaaaeeefeddefcbbbbaaaabcbbbcdba#####a####..#######a##abdb#aabcefdaa####a#aaaaa#######aaaaaabacefc#########a###aaaaaa##aaaaaaaaaaaaabaaaa##aaaa###.#####aa#",
+"#############aabaaaabcbbaaaabbcceeeeeaaabbaa##a###ab#####abddb#####a##cb#######aa#a##aabbbbbbbaaaaabaaa##bbabbbaaabaabbbacbcbbbcbbbbaaa###a######aa##a#baaagkecdeegfeehfcbba##aaaaaaaaccdcbaccbaaaa#aaa##aaa#########a##a###aaabcaaaadeddbbdcdeigfdbcccbaa##cbabcbcdaaa####aaa######.######aa#debaacfdcaa#####aaaabaa########a##aabccdd#############aaaaaaa###aaaaaaaaaaaaaa###aaaaaa#########aa",
+"#############aabbbcbbccbaaaabbccddeedca#abaaa#aa###a##.##aaaa#######aaaca############aaaaaabaabaaaaaa##a#aaaaabbaaaaabbbabbbcbbccbccbaba##########a##aaabaabejfddddehddhgdbbba##aaaaabbbcccaabaaaaa#a#a##a#aaa###############aabcaaaaaegeddcecacdghfdccbaaa#cbabcbac#######bba#################bcdcbeebaaa###aaaa#aa#a###a####abaabdcdcba#a##a####aa###aaaaa##aaaa#aaaaaaaaaaa#aaa##aa#########a",
+"aca##########a#aaabdbcccbaaaabbccddeedbaaaaaa#aa#########abca#######a#aca############aaaaaaaaaaaaaaaaaaaaaaaaabbabaabbbbbabbbcbbbbcabbbba##########aa###aabbbeidbbccehefhhcbbaaa#aaabbaaabbcaaa#abcaaaaaaaaaaaaa#####.########aaabaacbedfdbbbdccccfhebaabaaa##a#acaba######daa###.######a####aa##acfdfdaa####aaaaaaaa###aca#aaaabaabccdeaaa###aa#aaaa##a#aaaaaa#abaaaaaaaabaaa##############.aab",
+"aa#bb#####.######aaabcccbbaaaabbbcddeebaaaa########.#####abca##########abaa####a#####aaaaaaaaaaaaaa#aaaaaaaaabcbbaaaaaaaabbbbbbbbbccabbaa#a#########a#####aaaachdbccdefehgiebbbaaaaabaaabccacbaaaacbaaaaaaa#aaaaaa#############a#baaaaceddbaabcbebbefdcaaaaa###ba#baa#####.aba##############a#a##aacfghdcaaaa#abaaaaaa######acbababbbdbaa###aaa#aaaa#a#aa#aa#aa##abaaaaaaabaaaaa##############ba",
+"a#aa#a#####.###a#aaabbcccbbbaabbbccccge#aa#######.#######abbba#######aaabbaa####bba###aaaaaaaaaaaaa#######aaaaabbbbabaabbaabbbbcbbbcbabbbaaa#a##a##########aaaabeccccddfgefhgaccaa#abbabbbbabbbba#aa#aaaaaaaaaaaaa#######a#####aaaaaabacdccabbbcecaacdfecbbaaaa#aaabaaa#####aa########aaab####a###aabeggbaaaaaaaaaaaaa#a##a###aaaabcccccaa###aaaaaaa#aa#aaaaaaaa#abaaaabaaaaaaa#a###########a#aa",
+"###aaaa###a######aaaacccbbbbbbbabccccehb#a########..#####abbca#######aaaacaa####cca###aaaaaaaaaaaaa#######aaaabaaaacdbaaabbbbbbbaabbbbcbccaa############a#aaaaabaccbdccegeccffbbaa######.#abaabbbaaaaaaaa#aaa#aaaaaaa#a##########aaaabbcc#abbabaabaddcbceebbba#aaaaaba######a############aba###a##aaaccggbaaaaaaabaaaaabaaaaa#a#bbabbccdb#aa###aa#aa#aaa#a#aaabaaaaab###abbabaaa###a#a########aa",
+"###aa#a######.######aacccbbbbbabbbccccfheaaaa#############bbcaa#######aaabcaa#####aa####aaaaaabaaaaa#aaa##aaabaaaaaacdcbaabcbbcbbbabbaabbbbca#a######aaa##a##a#aaacabccdeggacge.#aa####a#baaaabbabaaaaababbaaaaaaaaaaaa#########aaaaaaabda#aaabbbacbcdbbcdeca#a#aaaaa#a#aa#aa#############aa#####a#aaabcfgcabaaaaabaaaa#aaa#####babbbcccc##aa#a#aa#aaaa###aa#aaaaaaaaaaa#aabbaaaa###a#a#####abba",
+"###aa##aa##########a#acbcccbbbbbbbbbcceffebaa#############accbaaa######a#bdcaaa####aa##aaaaaaaaabaaaaaaaa#abbbaaaababcddccbcccccbaabaaabbbbbca####a######aaaaa##a##bbabcbdgefeed########a#a###ab#aabbbaaaaaaaaaaabaaabba#####a#.#a##aaaabca##abbbaccbbdcbcdedb#aaaaabaaa###aaa#########aa#aaaaaaaaaaaaabceecc##aaaaaa#a#aa########abbacccc##aaa#aa##aaaa###aabaaaaabaaaaaaabaaaa####aa#####a#a#a",
+"b###aaaaa#######.##a##abbdcbaabbbbaabccdegea########a#####abcbba###aa####acccaa######a#####aaaacbbbabbccbbaaccaaaaabbbcccbcbccbbaaaababaaaaabc###a#aa#####a#aa#a#aabdaaacbbafhgbfa.#####aaaaaaaaa#aabaaaaaaaaaaaabbbaaba###a###########baba##aaaabacaabccbccdeeaaaa#aaab####.########.##aabbbaaaaaaaaaaabccaccba##abbaa###a##a###a#aabbccca#aaa#a#abaaaaaaaaacaaaa#aaaabbaaaaa#aaaa#a#######a##a",
+"baabaa#######aaa#####aabbccbbaaabbaaabccdfeba#######aaa###abcabbaa##aaa####ddbaa######a###aaaaaaaaaabbcbbbbbccaaaaaabbbbbcccccbbbaaaaaaaaaa#abca##a#aaaaaa##aaaaaaabcaaaabaabgicce##.#a##aa#a#aaaaabaccbaabaaaaaaaaabbbaaa#aabb##########aa#aaaaaaaaaaabccccddfebaaaaabbaa################bbbbbbaaaaaaaabbbc##acbbaaaaaa####a#####aabbbcccb###aaaaaabbaaaa#a##aa####aba#bbaaaaaaabaaa#######a##a",
+"baaaaa#######aa#######aabccbabaabbbaabbbcdgdb#a########a##abdbbaaaa##aaa##abdcbaa#############aaaabbbbbbbbbabccaaaaaaaacbbbcccbccccbbaaaaaaaabbca#aaa#a#aaaaaacbabaa#aaaaaccbbjgabc###bb######abaaabbcccbabbbaaaaaaaaaaaaa##aaaaaa#######aa###aabcbaaaabbbccdeeefebaccbbbbb#.####a####.###abaabbbbbcbaa#aaabca.##acccbaaaa########aaababbcba##abaaaaaaaaaaaaaaaa#aaa#baaababa#bbaaaaaaa#######aa",
+"aa##aaa###############a#abcbabbaaaabaabbbcffcaa##aa##aaaa#abbbbaaaaaaa##a##abdbaa##############aaaaabbaacbabbbcaaaaaaaabbbaaabacbccbbbaaa#aaa#aabb#aaaaaaaaaaabbbbaaaa##aabbbadiabbc.##c#######aaaaaabbccbbabbaaababaaaaaaaaaa##aa#######a#####aabbaaaabcbbbcddcefhgceeaabba##############abbbbbbcbaa###.###aca####aacdba#a#a######aaaabbcbbaa##aaaaaaaaaaaa#aaaaaaaaaaaaaa#bababaaaabaaaaaaa#ab",
+"cb####aa################abcbbbaaaaabbaabbbdgdb##a#aa#aaaaa#abaabaaa#bba####aaddba#######a#########a#abbaaccccccbaaaaabaabccbbabaabcbbbbaaa#aa###acda####aaaabaaabbcbbaaaaa#bcbcebbccd#.aba######aaa#a#acbaaabbbbbaaabbdbbca##ba###abc.#.####.##a#bbaaaaaaccccdecdefghgfccccb#.####.#...###aaaabbabddba###...##bb#####a#bcba##########aaabbccaa###aaaaaaaaaaaaa##a#aa#aaaaaaaa##ababbaabaaaaaaaab",
+"ec##########a##aa#.#####abbcbbaaa#aa#ababccfffcaaa#aabaaaaaabbaaaaa#aba###aabbfdaa###.#############a#aaabbccbbccaabbaabbbbbbbbabaaabbbbbaaa#a###aacdba##aa#abbacbbcbbbaabaaabbceabccde.#c#aa######aaa#aaa#aaababbabaabbdefecd#aaaaaaec#.#########aaaaaa#aacdcbdbabdfegddffdba##.#.###.###aabbbbabbccbba###.#.##bc#######abbba########aaabbbddcaa##aaa##aaaaaaaaaa#aaa#aaaa#aaaaaababaabbaaaa##ab",
+"bca######.#####aa#######abbbbac#a##aa##abcdcehfaaaabbbaa#abcbbbaaa#aaba#####acegdaa####.############aaaaabbbbccccbabababcbbbbbaabbcbbabaa##aaa###aacebba###bffcdbcbbcbbcaaaabbbhbabbcee.##aa##aaa#acaabbaaaaaaabccaaaaaabdefge##aaaacea###########a######abdfdabaaaaababaceeb###.#...#.##aaabbbabbbaabaaa###..##bea###a##a#aca#a#a#####aaababb####aaaa##aaaaaaaaaaaabaaaaa#aaaaaababaaaaaaa###ab",
+".#a###########.b########aacaaaacaaaaaaa##acdffgbaaabaaa##aaehdbaaaa#aaaa#####acfgbaa#########.########aaaabbabcdecbaabbabbbbbbbaaababaaaa######a##aaddbaaaaab##a##abccccccbbaabfhaababgd.######aa#aaaaaaaaaaaaabacdddbaaaaaaddeda#aa#ba######..##a########abdcaaaaababcabbbcddb#a###..#.##aaabccbbaaaaa#########abed#########cb#a#a####a#aaaaacb###a#aaa##aaaaaaaaaaaabaa#aaaaabaaaababaaa######",
+"#########aaa###a########abbaaaaaaa#a#aaaaaacdegeaabaaccbaa#acefcaa###aabba###aadfdbbaa####.#############ababaaabcccaaaaabbbbbbbabaaabbbbaaa#####aaaabdeaabbba########aabdedcbabbffaababhd########a#aaaaaaaaaaaaaaacedbabaaba#bfggcaaa#########..#.########aabcb#aaaaaabaababccddba#..##.####aaabbaaaaaa##...#####acecb########abba#aa#a#aaaaabbca##aa#aa#aabbaaaaaaaaaaaaaaaaaaabaaaaaabaaa#aa##",
+"##########aa###a#####aaaaaaa##aaaacc#a###aabbcefbabbcfcddddbabgfa#a#aaaadbaa##abdedcaaaaaa#############a#aaaabbbbaacbbabbaabbaaababbaabababa##a##aaaaaccbbbb########.###abbacdcccgbabbbcida####aa#a#baaaaaaaa##aaabccaaaaaacbbabggb#a#####aa##..##aa######aabbcbaaaaaaaba#aabbcccca#.########aaaaaaaaa###...#######abdec########abb#aaaaaaaaaaabcbaaa#####aabbbb#aaaaaa#abba#aaaaaabaaaaaaaaabb#",
+"###########aaaaba###aaaaaa####aaabdebca###aabbcfgfbacdccdeheaadgea###a##dcabaaaabdedcbaa##################aaaaabbbccbaabcbaabbbbabbabbbaaabaa#####aa#abddbcb##a########a##.##accdeedbcccejcbaa####aaaaaa#a#aaaa###aabbbbaa#bdbb#chfa####a########.###########babbaaaaaabaa#aaaaabbcdc#..######aa#aaaaaa###.#..#####a#abdeba#######bbbbaaa#aaaaaabcca#aaaa#aaaabbbaabaaaaaaaba#aa#bbaabbaaaa#####",
+"######a##a###a#aaaaa#aabaaa##aaacddbbcaa##aaaabdifdadeeddfffaabdddbaaaaabd#aaaaaacfedcaa#################aa###aaaacccbbabbbbaaabbbbbbbbbaaaaa######a#aaacdddaaa#########a######aabbicceedghcbb##aa#aaaaaa#aaa#a####aaabbaa#adffbafgd####aa###################aaaaaaaaaaaaa#ababaaabbbcb#.####aaaa#a#a#a##..########a#aabbcdd#.###a##bbaaaaaaaaabbbbba######aaaacbb#abaaabaa#a#aaaabaabbbabaa####",
+"######aaaaa####aaaaba#abaaa###a#bddccaaa######abcfgghhhfdfffcacbabdecca#bca#aba##aeffeba##############.########aaaaccbbbabcbbbaaaababbbbbbbaaaa######aaaabeeaa#aaa######a###a#aaaabfgdbbddhhccb###aaaaaabaaa###aa##aaaaaaaa#bffgd#cda##a#a######a#a###########aaaa#aaaaabb#abaaaa#aaaabbca####aa#aaaa####.#############aaabcdc#####a#abba###aaabababc#aaa##aaabcaaaaabaaaaaaacaaaabaabbbbbaaa###",
+"a######aaaa##a#aabbaaaaacba##a##acccddbaa#a##aaaaacccdefefefdacaaaacgebcdb#a##aacbbegfdba#aba##############aa###aaabcdbccbbabcbbbbbbbaabbabaaa###a###aaaabcdb#baa#a###########aaabddgcdcbbcfidbcb#aaaaabaaa#a#a#abaa###a#aa##dfffeaa#####a#####aa##b.######.###aaaaaaaaaacbacaabaaaa#aaaacccaa####################a########abceca###aa#abaa#aaabaaaacda#aa###aacaaaaaabaaa#aaabaaaacbbbbacaaaaaa",
+"aa##a###aaaa#a##aaaaabbbbbbba####bbbacbaaaa##aaaaaabccbdedcefaccaaa#accccaa##aaabcddfgefeeffea################aaaaaabbcbcbbcbabbbaabbaacaaaa#a#######a#aaaacfcaaa##a############aacdee#a####eifccc#aaa#ccaa###aaa#ba###a###a#befffd######aaab###aa############aaaaaaaaaabbcbcdbbaa###abbaaabccdca...#######aa#a####a######aaaabcdc######aaaaaaaaaaabbcdbaaa##aababaa##aabaaaaaabaa#abbbbaaba#aaa",
+"#aaaaa##a#.###a#aaaaaceccbbbab##aaaaaaaaaba#aaaa#aaabccbcdddgfdaaaa######aa##a#aaaeggihgeefeddeca###############aaaaababcbbbbaabaaaaabacbaaa##a#####ba#aaabadgeaa#a##a####a##a##aabbeeaa#####bhibaca##aadbaaaaaca###########aadfddfda###abaabb#aaba#####a######baa#aaaa#abdc#bccbaaaa###ba#aaabdfeec#########aa#aaaa####aa#aaaaabde###a###aaaaba#aaaabbccbaaaaaaaaaa#a#aaabaaabbaaaababbbbaabaaa",
+"##aa####a#####aaaaabcccbbbcbbaa##aaaaaaaaabb#baa##aaabbcccdefgiecbaaa##aabba###a#affghihfccdddddeca################aaabaaaabaaaaaaaaa#aaaabaa########aaaabaabcgcaaaadda#aa#######aacdde#######aegbbdbaa#adbbaabcaa#aa#########acfeeecaaaaaaaabbaaaba###########aaaaaaaaabddfbaaababaaaaaaa##aba#acefgca###aa#####abb######aaaaaaabcfa##a###aaaabdaaaabbbbdb###aa#aaaaaaaaaabcbbbbbbabaabbbbbbaa#",
+"####aaaa#a#####aaabccccbaabcbcca##aaababbabbabaaaaaabcccbacddefffdccabccdedaaaabdeeffgggeccddccdcdca#a##############aaacaaaabaabaaaaaaaaaaaaaaaa###aa###aaaaacdgcaaabaaa#######a##abdchaa######.cfcbcb#a.bffcbbbab###aaaa###a###ceedddabcbaaaabbabbaaaa##..#####aa##aaaa#acecbbcbaaaaabaaaa##aba#aecbccdcabaaa##abbaa#a##aaaa##aaaabdd##aa##aaa#aaababbbbbdb#a##aabaaaaaaaaaaaaabbbbbbcbbbbcbbaa",
+"aaabaaaa####aaaacccbbcbbbaaaabdaaaaabcaabcbbbbbaa##abcddcbcdefedffedbdccdeec#aafffdddeffcccbcdcccccccaa#############aaaab##aacaaaaaaaaaaaaaaaaaaa###aba#aaababdefaaaaaaa##a###aaaaabccgcaa#######bgcdeca##bhgbabaac##a#aaa##a###befddfdddbddbaacabbbbaa####.#######a#aaaaaacbaabbbaa##ababa##aa##acaaaabbcb#aa#a#aaa##aa#####a#a#aaaabeca#aaaaaaaaabaabbbbbdb#aaa#abaaaaaaaaaaaaaaaaaabcbaababaa",
+"aaaaaa#aa#####abbbcbbabcccbbaaabbccccdbabccbbbbbaaabbcddcbceeeddeggddfbcdeec###dffedddeddcccedccccbbcdb#################aa#aaabaaaa#baabaaa#aaa######aaaaaaaabbcdfaaaaaaa#a####a#aaaabge##########bhcbccaabdeeaaaa###a###aaaaaabceedefeeedeeccabbabcbbaaaaa##.#.#######aaaabbb#aaaaaaaaaabaa##a##aaa#acbcabca###aa####aa#########a##aaaedb#abaaaaaaabbabababccb#aaaaba#aaaaaaaaaaaaaaaaabbbbbaaa",
+"aaabaaaaaa###aaabbbbbaaaacbbbbbcccddefdaabbbbccbbbbabbccbcdddddeeeffefcedffedbabeeecddcbcccbdbbbabbbabba#aaaaa##a######aa#a##aaaaa#a##aaaaaaaaa###aa##aa###aaabbdedaaaaab#a####aaaaabbgha#a########becaccdfgddda#aa#aaaabaaa#a#addeecdcdfeeeddcacbbbcbbaaaaaa###########aabacbaaaaabaaba#baba#aa##bbbdbacaabcb##aaaaaaaaaa#########a#aaabddbaaaaababbbbbaaabcccbabaaaabaaaaaaaaaabaaabaaaabbbbaa",
+"abbabbaaaaaaaaaaaabbabaaaaabbcbbcdedfggccbaaabbbbccccbccddeddccdddcddecddeffddecddccacbaacbbbbaabaabaaaaaaaaaaaaaba####a###ba#ba#aa#####aa#aaaaa############aabbcdebbbaaaa########ababdhf#a#########afecfffebceaa###aaa#aaaaa##abeeddddeegffdcfdbbabcccbaaaaba###########aaaabaaaabbaaabbbaabbaaaaacdcaacaaaabca##aaa#aa#aa#aa#######aaaaacee#bbaababbbbbbbbbccdcaaaabbaaaabbbaaaaaaaaaabaaaaaab",
+"babbaaabaaa#aaa#aaaaaaaaaaaabbbbcdbadccdbbbaabbbbbcbbccdeeedeabcccccccccdeedfddcccdbcbaaaaaaabbbaaaaaaaaaccaaa#aa##aaaabbaab#a####aa####aa##aaa###############abcdedbcba#####aaaa#aabbdhie.#####a#####fgffececeda###aaa#aaaaaa#cddecddcddefeegefeccbccccbaa##aaa#.#####.##aaaabaa#aaaaa#aab#bcccbbccbbaab#aaaabcbbaa#aaaa#a#a######aaa##aaabdfdbbbbabbbbbbbbbbccccaaaaaaaaaaabbbbbaaaaaaaaaaba#b",
+"bbaaabbaaaaaaaaaaabaabbbaaaabbabcedcbbabccaaaaabbbaabbceffcccbbcbbbbbbbbddcdddbbbabbbbaa####aaabaaaaa##aacfeaa######a##aaabbbaaa##aa#a#####bcca#a##aab##aaa#aaaacccgdbbb#######aaaaabbbdhhb###########aeifddbbceda#aaa##aaabaabefffcdddccdeeeedeffefeddccbaa##aaa###.###..aa##aba##aaa#aaabaaabccddcccaabaababaabcca###aa#aaaaa####aa#####aaacffbbbbbbbbbbbbbbbbcdcaaaabbaaaaaabbaacbaaaaaabbbab",
+"babbbabbaaaaaaaaaaaaabbbaaaaabbbceddcbaaabbbbbaaaaaaabcdffdcabbccbbaaaabbbbbbbbaaaaaabaaa#a##aaaaaaa####aadd######a########abbaaaa##a#####a#aa########aaaaaa#aabbbbdgcaaa###aa##aaaaabadfgb######aa###aadidcdbaceca#aaaaaa#abcdeeeccdeddccddeadeefffffffecbaba#######.###.##aa#abaaaaaaaaabcaaabaabcbd#abaabbbbaaabdba#a#a##a###aaaa#########aacefdbbbbbbbbbbbbcbcccaaaabaaabbaabaaccaaabbaabbaa",
+"baababbbbabaaaa#a##aaabbbaaaaabccehdbaaaaaaabbaaaa##aabdgieccccbcbaaaaabaaaaaaaaaabaaaaaaaaabaaaaa###a###aaa################aaaaaacba######a#a##########aaaa#abbbbbcdhb##a####aaaaaaaacbfe.##aaaaa#####aadhcbbaaefbdb##aaccddfgedbddccccbbcdedceceggfeefefdcbaaaa#####.###.###aaaaaaaaa##aba#aaaaababdb#aa#aaabaa###bcbaa#######aa#############abdffcabbbabbcbbcbcbcdcbbaaabbbbbbbaacabaaaaaaaaa",
+"bbbbabbbbbbbaaaaabdcabdcaaaaaabbcdffcbaabaaabbbaaaaa##bcgjfbbbcdddcbbbbbbbbbaaabaabbbaaaaaaaaaaaba#########a#a###############aaaaaabaa#######a######aa#a##aaaabcbabbcceda#aaaaaaaaaaabbbec.a#aaaaaaa####aadhcabbbeecbaaadefggfeddcddcccccbccdccdddeghggeeeddcbaaaaa############abbaabaa#aaaaaaaaba#ba#aaaa#abaaaaa##aabbb###aa#a#a##a##########abbcffdcabbcbbbcccbbccccbaaaaaabbbbaabbabaaaaabba",
+"bbbbbbbbbbbbbbaaabfdcccbcbaaaaacdceebaa####aaabbbbaa##bdghfcbaaacdddccccccccccbbababbbaaaaaaabbbaa#a##aa#a#b##a#aa###a#######abaa###aaaa##a################aaaaabbbcbbcffaaa#cbaaaaaaaacec.#####aadea##a#aabgdababdfda#adfggeddccccbbbaccbbcbcddddgghigffffbabbaaaa##########ab#aaaaaaaaaaaaa####aaaabaaaaaaaaaa####a##aaca##a######a#########acbbbbcdefdabbaabccbbbbccccbcbaaabbbaaaababaaaabcc",
+"bcbbbbbbbbbcbbbbbcecccbaccedaaabddcaaa#######aabcbbbaabdfhfdcaa###acdcabdfeeedcccccbbcbbaaaaaaacbaa###aaaa#aaa#####a#aa##aa###ba###aaaaaaaba############aa#aaaaaaaaaabbbfgaa#adbaaa#aaaaehaa###aa#adea#a#aaabgbabacefdb#dfffedccbbaaaaaaccbbcdecdggihihhfdffcbbaaaa###aa###..#aa####baaabaaaaaa#####aaaaaaaa#aba#a###abaa#cbaa##.##aa####aa##aa#baaaacccefdbbabbcccbbbdccdbaabbbbbbbaaabbaaaaabc",
+"cabaabbbbbbcbcccccddb##abaccbabbdbcaa#a##a####aabdcdbbcdddghcbaaa####bcacigggecbbbcbcbbabcaaaaaabaaa#a##abb#########a##aaaaaaaaaa###aaaaaaa########aa##aaaa#####aaaaa#acegfaaa#aac##aaaachfc###aa###aabb###a#bbabccddefdceffedbcaaaaa#aaabbbbcdegihhhhgggdcffecabaaaa##a##.###abca#aaa##aaaaaaaa######a###b###baa####aaaaaaaaabca###############aaaabbbbbbdfebbabcccbcdcbbdcbbaababbabaabaaaabbb",
+"febaaaabbbbcdcccccb#####abbabbcccbbaaa####aa#a#abdeccbddeeehgcaa#a#aa#addhifdddbbccbcccbbbbaaaaaababaaa#aaba####a##a#a##aaaa#aaaaa#a##baaaaaaa#####b###aaaaaa##a##aaaabcefihefc##aaaaaabbdha####aaaa#ab######aaaabbccdefegffdcccaa#a##aaaaaabbehhhhffffcddbdcdbbba#ac######..###bb###a#abaaaaaabba#####aaa######a#aa#####a#####bbca###########a##aaabbbaaaabdfdbaccbccbcbbccdcbbbbaaaabaaaaaaabb",
+"dedbbbbbbccbcdccddb#####bbbaacccacbaaaa###aaaaaaacfdcbcdegghigbaa#aaaaaadfhgedcccccbbbbbbbbbbbbbbbbaaaaaabbba########aa#aaaa#abaaa####aaaaaa############aaaaaaa###aaaabcfghgihfbcb#abaaabbge####aaaaab######a#aaaaaaccdeeddfdbcbaaa##a##aabaafhgggfedccccdccbaaabaaaaaa#########a#####a##aabaabcaa#aaa#a#####.####a###########a#aaaba##a####a#aba#aaaabbaaaaabdeecccbbcbbccccdcbabaaabbbaaaabbba",
+"bccdcbbbcccccbcdfda#####acbabcbaabaaa#a###aa#aabbbefedcdffiihhcaaaaaaaabacfffefedcbbbbbaaaabbbbbbbbcaaaaaabaaa####a###a##aaaaaaaaba#####aabaa###########a#a####a###baabccghfhiieaa##aaaaabdga##a#a#aaaa######aabbaaabbbcddegdcbbaa##aaaaaaabbfedfddecbbbbbbaabbabbaaaaaaaaaa####aa####a#a#aaaabcbaaaaaaaa##############.######a#a#aabbba#a####a#aaaabaaabaaabbabcfedcbbbcbccccccbabbabaaaaabbccb",
+"bbccccbbcccccdddeca####aabbccca##aaaa##a#####abbbbeeffeeccfjjifbaabaaabbbcdecdeffdbcbbbaabbbccccbbdcbaaaaa###########a#a#aaaaaba#a######aaabcaaabaa###aa#aaa######acedbcdfihfhifba####aaaadhc###aaa###########a#bbaaabbccccfecaaacca##aaaaaccffdfccedbbab#a#aaaabbaaabababaa###########aaa###bbaa#aaa#abaa##########.########aa####a#aabba#a###a###aaaaabaabaaabbbcdfedbcccbcccccabbbbbbabbbbbbc",
+"bcdcbbcccccddddddba####abbbbdca#a###a###aa####aaabcededcbbgiijjhcabbaaaaaccddddcceedddddddeeefedbbcbcccbbbbaaa#a###aaaaa###aaaacaaa##a###a##acca############acaaaaa#abbccdghccggfcaba#aaaacggdaaa###############abbbaabbdeefedbaaaadda##aabbchedeefedbaaab#####aabbaabacbabaaaa########aa#a###aa####aaabba##a##.#############a#a####aaa##abdba#########aabbaabbabbaabdeddcbbbcccccbbbbaabbbccbba",
+"bbddccbccdccdcebcbb#####abccbcd######aa##a######abcddcdddeggiihhhdaaaabcccceedccbbcbbccbccdeeeggfeddccdeccbbaaaaaaa#a##aaa###aaaba#a##aa######a#####a######aaaaaaabaaababcehb#adcbdbba#aaabdceaa#################abbbbbacgeeecca###bedcaa#adfhccdffbbbba###a####aaaaabbbbaaaba###aaaa##########aa#.##aaaaa#aa#b######a#######aaaa##aaaa###abcdb######a#aabcbaabaabbaaabcdedbbbcddcbbbbcabbbccbbb",
+"bcdfdddcccdddcecbb####a#aabccabaa#####aaaaa#####abbccdedeedcijfggfabaabbbbccddccbbbabaaaaaaaaabbbgihihffedccbbbbbbbba#a#aa####aaaaaaa##aa#######a###aaaa########abaabbbbaccega#cdaaabaaaaabbfea#a#################abbbbbaeedddcbaaabacceccefihdccedcbaa##########aaaaaaabbbaaaa#####aaa##a############aa####aaaa######a#####aa##a##aaa###aaa#a#abc#aa###aabcaaaabbbbbbbbbbcddcbccddcbbbbabcccdcc",
+"ccbcffhfdddddccadbaa#####aabbaaba##########a##aaabbaacdddfeehjifgha#aabcbacddccbbbbbabbaaa#aabcccefgdddeffeecdedbbbbcba###aa####a##aaaaa##a###aa###aba#aa######a#aaabbba#abbfcbcccccbaaa#abbfjg#aa###########aaabbaaabbcbdedcdbbaaabbbcceghhiiedcedbbaa######a###aaaa#abaaaaaaaa##aaa##a##############aa####aaaaa#####ab#####aa##a###aa#aa#a#####aaaa##aaaaabbbbabbbbbbbbbbbbdddccddccbcbbbcccdd",
+"eecbdggfdddedcacda####a###abbaaca######aa##aaa#aabcababcdeeedgigdfgbbcbbbbbcccbbbbbaaaaaaaaaccddddefdecccbbcbbddcbccddedcaaa#a#aa##########a########adbaa#########aabbbcbcabbdcdcbbbcbaa##abbfiaaa##############baaabbbbccedcccbaa#abbbbbefgihfdcccbaaaa###a######aaba#abaaaaaabaa#aaaaaa######...#a#.#####aa#aaaa########a##aaa###a###aa#aa#aaaa#aabbabaaaaabcbbbbbbbbbbbbbbbccdeddcccbdccccdde",
+"eedfhhfcba#abb##a#####a#aabcaaccbc#####a#aa#aa###ccbbbabcdfffhgifehfebbbabbcccbbbbbbbbaaaa#ccdcddfghfeccccbbbbabcddegcbccdcaaaaaa###a###a######a#a##accba#########aaaabbccbbcbcehb###cbba##bdehe###############aa##aabbbccdcbccba##aacccbcceffedcbbaaa#####a######aaba##aaaa#ababcbbbbcbaa########.#.##a####a####aa######aaa###aa####a###a##a#aaa####aaadbbaaacccbbbbbbccbcbcccbcceeeeededcdbccd",
+"dgghigdb##a#a########baaa#abbcbdbbb#####aa#aaaaaaabaababcdegiihdggffdcbaabbbbabbbbbabaaaaa#ccdccdegedccbbbbbbcbbbbaadbabaacdb###aa###############aaaab#aa##a#######aaaaababbbabbfieaaaa#aaa#chke.#########..#aaaaaaaaababbccbbcbaa#aabbcbabcdeedcba###a#####a#a##.###baabbaaaaaaaabbaaba#########....#.#######ab#a#######a######a#########a##aabba###aaabbbbbbacdcbbbbcbcccccbdddeededegeddddcdc",
+"dhghhfa##a######a######aabaacccedaaa#######aaaaaaaababbbccdghgfedgfgcabaaaaaaabababaabaaaaabdcceeeecdbbbababbbbccbbbbbabdbabcba#a############aa##aaaaab#aa###########aababcbbaabeggh######aaagj##############aa#####abbaabbbbbabbbabcabbaaaabcddccba#######.###########ccaaa###aa##aaaa###a###..##....#.aa##a############aaa#####a#####a###aaa#aaaa#aaacaabbbbbbeccccbbccddccdegghhgfeegd#bddccc",
+"ffhhhe###########a#####b#bcadddcbaaaa#####abcca#aaaaaaaaabdhihgddfgfgcaaaaaaabbbabbbaabaaaabedcefecbbbbbbabbbaaabbacdca#aaa#bbdb#aaa#########aa####aa#a###a#####.###aaaaadbbaabaddcggbaaaa#bbdia#a##########aaa###aaabaaaabbbbbbaacefebaa#aaaabcccbaaaa###########.#.##ad#####.##aaa#aa#aa#####...#...###ab#ba######a###a##ab#####a###aaa##aa#aaaaaaaabbbbbbbbbbceddeeccbccccddfhijjhggghb#bba##",
+"#afhgcaa###########a#a##aabcddca###aa######abbbabaaaaabaaaeiiihgbbgeddaaaaaaaaabbaabbbaaaaabdcccddddccabbbbacaaaaabbbaaabaa##acdd###a######..a#a#####a#aa##a########a##aaecb#abbbcccfgaaaaaaaeia#a#a##############aabbaaaababbababdgeca####aaaaabcbbba#####a####.#######da##############aaaa#######.##.#.#ba########.#a#aa##abba##aa#aa#aa###aaaaaaaaaabbbbbcbccccefgeeccbccbbbbdfiihgggeb#aaaa#",
+"##bhgd###############ab#ababcdd###aaaa####aaaaaaaaababaaaadhhigebabfddcaaaaaaaaaaaabaaaaaaabcbbbcbbcecbbbabbbaaaabbaaaaaba###abadea#########.#a##########aa#a###a###a####aabbabbaadccghbbbaaabfi#a##a###aa####a##a#aaabaaaaaaaabbacfdba##a#aaa#aaaabbb######a######.##a#######aa#a##a#a####aa#####a#.#a####aa#########aaaaa##aaa###aa#aaaaa#aaaaabaaaabcbbbbccccceeceeeefedddcbbceeffhgfebaa####",
+"##.dhdb#########ab###bdababaddc######a###.#a######aabacaaaadghfdbbabecdba###aaa#aaaaccabaaacababbbbbbbcbcbbcbaaaaababaaaba####abbcfbaa#aaa###.###ab#####aaaa##a######aa#ba#aabbbabdcabefbcaababhe#a##aa##aa###a#####aabba#aaaaabbbefcba###aaaa#aaaaaaaa#########a#.##############aa#bb#aaa##a####.###########aaaaa#######aaaa###a####a##aabaabaaaaaaaaaabbbcccddebbbbdedefdcccccbceeghgfdaaba#aa",
+"aa#aeea##########c####ba###aca#####aba#############abcabaa#acdefccbacdbdc##aaaaa###aabdbaaabbcccbbbbbbbccbabcabaabbabbaaaaa###addbcdba#a################a####aaaa#aaaaaaaa#aaacbabdcbbbehca#abbeh#aa######aa######aa#aacfbaaaaaabbdgdbaa###aaaa#aaaa########.###aa#a.###########aaa#bbaaaaaa####a#.##.#######aba#####a#############a#aaaaabbba#bbbbaaaaabbcddddddbaabcedccbaadfdcceeggdbaaaaaaa#",
+"aa##ada#a########aaaa###a###a######abaa#########aa#abbbaaaabbcddeeebcdbabb#aaaaaa####aaaabcccbccbaabbbabccbaaaaaaaabbaaaaaaa##aabcccfeb##############a####ab#aaa##aaabbaacababaaaabcdbccffc##abeh.##aa###a#########aaaaacbabaaaccddfgdbaaa##aaaaaaa#######.##.#######.#########aaabaab########a#a##.#########aaa#####aa##a#aa###bdaaba#aa#aabaaaabbbabbbbcddefecbcbaabbdcbaabcecccefgcaaaaaaaaa#",
+"aaa#aaaa#aaaaa#####aaaaaa###########a#####a##ab#a##aacabaaabcccbdhedfdbbabc#aaaaaaaba##aaaeheaaaaaaabbbacddbbaaabbbaaaaaaabc#aa#a###cfgb#a#########aa###aaaccaaaaaaaacbabcdaacbaaabcddcccgfcaabeg.#a#aa#a###aaaa####aaaaabaaaaaaceefhfdbaa###aaaaaa########.####.###.####.####aa#abcbaaa####aaa#############aaaaaaaa#aaaa#ba#babffb#acb#aaaabaaabbccabbcccfgdaa##bcbbaaacbcbacebbbcddbbaaa#a####",
+"accccedaa#aa#aaa##a#aabda#################a#a#a##aaaabbbabbcccdcccfcfecbaaceca#aacdbcccba#ahgabaaaaababbbccccbaabbbbbbbaaabcb###aca#aabcc##a##########a###a#abaaa#aaabbddddbbbcbaaaaabcdddhecccg######ba#a##.#a###aaceca#cbaaaaacdefhgfcaaa#aaaabba#########..#####...#.#######aaabccbaaa####aa########.####abb##aa#aaa#a#ba#abbefba##bbbaaaaaabbccc#ccddeffcaaaa#baaaaabebbbbcbbbbcbbbbbaa##a##",
+"#abeeebaaa###aa###aa###aaa###################aa###a#aabbbbcddddccefegfcca#adhbaacccaaabcbcdecaaa##aaacabdabdcbaabbabbaaababbcb#aabb#aa##dea##aa#######aaa##a##aabaaaacacdfebbbbbbabccccfeddfgfed...#a##aa###########acdbabbb#aa#acddegfecbaaaaaaabaa#########...#####.#########a#abbbabba##aa#####.##....#####a##aaaaaaaa#baaaceeebaaaaeedbbbabbbccb#cedddcccbaaaaaaabaa#bebbbbbbbbbbbbbaaaa####",
+"##aadba#aa##a#######abbda################a#######aaaa#ababccdeeddffhhgccbaabefdbbaaa#aabcbbabca#aaaababbbbcccbaaacaabaaabaaaabbaaaab#aaaaefaaaaaaa#.###a#a#a######bbbaabccabbdcbabbcbcdbbaaaefeiiffa####a#######a##aaaaabbcba#baabdddefffdcaaaaaaaaaa##########...##############aabbbbbdabaaa###.....########aaaaaaaaaaaaabcccbdfebaaaaaacfdccbcddc##baabcbabaaaaaaaaabaaaedbcbcccccbbccbaaaaaaa",
+"a##aba#a####.######a##bgb#######a########aa#######aaa##aabbcceedddeghiebaaabccebaaaaaaaabaabaaabbaaabbaaabbbbbaaabbaaaaaaaaabbccbbcba#####cfebbabbbacaaaaaa#aaaa###acbbbbbbbbcbaabbbccbaaab#.aceffdfghfa#a####aa#aa##acbacbbbaaaaabcedcddedbaaabaaaaaa#######..#.################aabccccdbbb####.#..#..#.#..########aa#aaa#aaabdddbcababbbdeddedeeb####aaaaaa#ba#aababcbbbaeccbcbcbcbbbbaaaa###a",
+"ba#a#####a#############cb#########aa##a###a####ab#aabaaaabbbbedcdccehihcbbbbbbccaaa#a#aaaaabbaaaabbbcbbaaabbbccaaabbaaaaaaaaaabbbbacda####aaedbaaabddba#aaab###aa####aaddcceebabbbcbcdca#aaba#aaabaabfmka##aabaaaaaa#abbabbbbaaa#acccdddccedbbbbaaaaaaaa##a####.#.###############aabddcbbcaaa####.#......aa###aa####aaaa#aa##aacccccbbbabbcdedddea####a##aa#a#bccbccbcbbaaaadddccbbbbbbaa#aa####",
+"ab##aaaa######a##########aa###b##aaaaa##a#a#####ababbbaababbbccccdcdgjifbbabbcccca#aaaaaaaaacaaaaabcccbaaa#bbbcaaaaaaaaaaaaaaaaccbaabbaa#a#a#bcbbaa##a###aaba######aaaaaaddfhgccddddacacaaaaa#aaaaaaabhnk.aabbb##aa####aa#acaabb#aabccddeecccbbbabaa##aa###aa#######.######a###aaaabdddcdedda#########...#####aaaaaaaaa##a###aabcbbccbbbbcddeeefc##a####aaaaaacdccbbaababaaabccdccccbbbbaa#a####",
+"#####a#aaaaa###aaa######ba###aa#bba#aa#abca##bb#abaabbbbbbaabbbbdccceihgecbcdccbcd#ababa##aaabaaaaaabccbaabbddbbaa#aaaaaaaaaaaaaccbaaa#a######aabdcb##aaa##a#a#####aaaa##aabffebccddcb#aa#######aaaaaadlnd#aabbabaaaaa##aaaa####aaaabccdeedbb#aa##a###############.##..#.#####aaaaabccdeecdaa#####.########.###aaa#aa###aaaa#aaabcbccccbbccddeef##aaaaa####aaaccbaabaaaaaaaaba#bcddcbbbbbb#aaa#a",
+"abaa###aaaaa##a#a##a#############a#a#ababda#aaaaaaaabbaabbbbcbbbddbddgifhedbcccbbcc##aabbaa#aaaaaaabaabbbccccdebaa##aa#aaaaaaaaaabedaaaa##########becaaaaa#a#########aaa##abceffdccb##aa########a#abbabilk#a#a######ab#aa#aa#####aaabbcddedbaa#a######a#####################a#aaaaaabdddfgfc##########...a#a###aaa#a#aa##a###aaaabbbbbcbbbcceghfaaaaaaaabbabccbbbaaaaaaaa#abba#aacedcccbaaaaa#aa",
+"bbaa##aa#aaaa#aaaaaaaaa#aaa##########abaaaa#baaaaabbbbbabbbbccccddbddggghhfdbbcaabbbbbaabbaaaa#aaabbaaabbb#bbbaaa#####a#aaaaaaaaaabb##aa##########aabdcbabaaaa####aa###aa#abbcdhhcaba#baaa#######aaaaabhlmc#a#####aaaaa#a##abba#aabaaabcdgfbb################################aabbaabbccdhigca#########.########aaa########aa#a##aaabbbbccbccdgfha#caaa.##fedbbcbaaaaaaaaa#aaa###aaadecccbbaaaaaa",
+"#aa###aaa#a#aaabbbbbcbaa##a#######aaabaababaa#aaaaabbbbbaaababccdecdfhhiihgfdbccbbcbabaaaaaadca##abbaaaaaaa#bb##aaa####aa#aaa#aaaabbda.##########aaaabddcbbaa#a##aa#aaa##aaabbdecca#a#aa#a########aaaaaeili##a######abaa###aaaaaacfeaabddcdbaa##############################aaabbbbbbcdfgjieba####.#####aa#aa############aaaaa###aaabcbbcbbcefggcbbfeedbedbcbabbaaaaaaaaaaaaaaa#aaa#cdcddcbbaaaa",
+"aa#a###aa#a##a#aaaabbccaa#aaa########bacbaaaaaaaaaaaabcbbbbbbcedcdccfhfhkhggfdbbccbbabaabaabdda###aaa#aaaaaaacb#########aaaaaa#aaaabec##########aaaaaaabddcbaaaaaaaaaaaa##aabacbaaaba#####a##a######aaabgklbaaa#####aaaaaaaaaaabbbfdaacddeddcbaaa#########aaab##########a##aaaabbcbbbbeffhjifdcb#####.##acbb#aaaa###########aaaa#aaacbcbbcbcegfaccgghgffdcbbaabbbaaa#aaaaaaaaaba#aaaabeecccbaaaa",
+"aaaa########aaaabbabbbbcbbbaaaa#####.##aaaaaaaaaaaaabbbbaaaaadedcdccegijkifddebccbbccaabaaa##aa######aaaaaaba#aa#########aaaaaaaaa#bccda#######aaaaabbaaabddcba#aaaaaaaaaaaaabcdaaaaa##abaaa#a#a#a##aaaafhlg.aa#a#a###ba##b#acaabcdfaaaccdccedba##########adcbca#########a#aaabbcddccbdefggiigecb########aaaa#abba###########aaaaaa#bdbccbccef#abdeddeeddccba#bbbbbaaaaaaaaaaabcaaaaaa#eedccbbba",
+"aa#aaaaa###aaaaaaaaabbbbbbbbaaaa#######aabaaaaaaaaaabbaaaaabbbfeccccdfiljigcdeccccbccbccbbaaaa#######a#aa##aaa#####..#..#aaabaaaaaaabacb######aaaaaaabbaaaacddcbaaa##cbabaaaaabcbaaaaa###a##a####a##aababchl#.###a#####aaaaaa#aabbdeaaacbbbbdfdccbabb####a#ddbbbba##########abbbccdcccddefghhfcaaa######aab#abaaddaa########ab###aaaacccccdefd#dbgebcccdcaabbbaaaaaaababbbaaabacaaaaaba#eeddcbba",
+"aa#aaaaba#a#a##aaababbccbabbbbba########aa#a#aaaaaaaababbaaaaadcccaddfhkjigdcdecccbbcdcecbaaaa######aca####aa#####a#####.#aaaaa#aabababb######aaaaaabbabaaaaabcdcbaaaaaaaaaabbbcaaaa#a####aa####a#aaaaaababjh.####a#####aaa##aaaabdabaaaabbabdeeeddddcb#.##debaaabaaaba####aaabbccdcccddeffgfgcaa##aa###aaaaaccaddca########a#a###aaaccbbceffbaacgeaabbbbabaaaaaaaaaaabaaaabbcaaabaaaabbbccdedcb",
+"ba#a#aaaaa####aaaaaaaaaaccbcbbaa#######aaaa###aa##aaaaaaaabbbabbcbbefffhjihfcbfcbcbbbcfhgcaaa#####a#deaa##aaaa###############a##a###aaaaa###aaaabbaaaababbbbbbbbedcbaa#abbbbbcccaa##a######aa##aaa##abaa#aabja##.#######a#a###aaabecaaaaaaacccbcaaaabbdddefedcbaa###aaaa#aaaabbbcccccccddfggghdba####aababababcbbddba###a###a#aaa##aabbcccegfbaabcaaaaaaabbaaaaabbaabaacaabbbabbadbaaaaabba#aefc",
+"ba#a#aa#######aaaaaaabaabbebdbbb######aa####a###a####aaaabbaabcabcccddffjhfdbaefcdbbbbdjkjebaa#####bccb##baba#####aa######a###a#a####aaaaa##a##aabaaaaaaabbbbbbabefdbbcbbbcbbbcbaa####aa#######aaaaadaaaaabbdg###a#a####a#aa#aabccccaaaaaabcdbccaaaaabbdeeedcdcba###aa#aabaaabbbcbcccddddeffffdbaa####abccbb#bbccdbccaa###a#aaaa#a#aabbdcdfgdaaaccaaaaaa#aaaaababbaaabbbbbabbbbbcbcbaaaabaa###be",
+"fcb#############aa#aaaaaaadegdacbaa###aa####aaa#a####aaaabbaaabaabddccehieabaabecccbbbbbikkgca####acbb###baba#####aa####aaaaaaaa######aa###aaaaaaabaaaaaaaacbbbbbbeffedccbcddddbaaa##aaaa###a##aaa#adba#aaabbie.#.#aa##aaaaaaacecaaaba###a##aabdb#a#aaccccccccbbba###aaa###aaabbbbcccdddedegcddcbbaaaabbabbabbaabbaaddbaa#####aa##aaabbddefgcabagbaaaaaaaaaaaabbaaacabaaaaabbbbabbaaaaaaaaaaaa#a",
+"bdeba#########aaaaa###aaaaacfebbbbaa###aa#####aa########aaababaacbdeccehhbaaaaaddcbbbbbcgijhea####acb########a##aa#a##a#aaaaabaaaa####aaab###aaaaaaaaaababbccbbbbacbedffedcdeeaaaab#aaa#aa##a##aa#a###aa#aabackc.#.##aaaaaabdefb#a#aaaaa#a####abc####abcbbeecbbaaabb#aaaaaaaabbbbcbcdededdefdcaccbca##aaaa###aaaaabaaeccaaa###aaa#aaabcccdffbbacfc#a#a#aaaaaaabbaaaaeabcbbabbbbcbbabb#aaaaaaa#aa",
+"##aba######aaaaaaaa##a#aaa#fdaabbccb###################a#aaaabbabccccdehibabbbbcfdcbbbabgihc#a####abbaa##a###aa##a#aaaa##aaa##aaaaba###daaa###abcaaabaaabbbbbccbcbcdcdddggfedbcbaaaaa##a#####aaaa#aa#####abbbbdjb.a##aaaaabeecabba##aabda######aa####aaabbdcdcbaa#bcbbaaaaaaaabbbcccddedefffdcbccbab####a#####a#aaabaabeeba######aaacbcddegebbacccba##a#aaaaaaaaaaaaccbbbbbabaaa#aaabbaaaaaaaaaa",
+"aa##baa####aaabaaaaa#####aacaababbccbaa##################aaaaaaaabbccbegifaaaabbcecbbbbaadgb#####aeeabc#.######aa##aaaaa#aaaaa###abaa##edaaaa##aabbaaaabbbbbbbccbbdccccdddehhdabbaaaaaa##a###aaaabb######cebcbcgj#aa##abdfggcbbbaaaabdfea####aaaaa##aa###aaa#aaaa#aaabbaaaaaaaabbccddeeddeffeeeefcabaa#aa#####aa#aabbbacccbaaaaaaaabcccdegfbbbceaacb#####aaaaaaaaaaaacccabaaaaa#a#abbccaabbaaaa#",
+"#aaa#daaaaaaaabbbaaaa####abbaabaabcbbbbb##aa################aaaaabbbddehecacbaaaabecbbbbabaa#####adcca#########a#a##daaaaacaaaaaa###aa#aca#aa##aaaabbbaabccbbbbcddaccdeddecfhgcabaaa#ab#a####a####aaa#aaaabbbcbcijdchihgighedbcbbcdfdabbbbccaaaaaa###caa#aaaa#a#a##aaaaaaaaaaaaabcccdddddeeedeeeffbaaaaaa##aa###aaabbbabcdeabaaaabbbbcdegibabbfaabca####a#acca#aaaaaaababbbaaaa##aaababbaaabaaaa",
+"#####adcbbbaabbbaaaa#a#a#####aaaabbaaabcbaa#################aa#aaaaabddgeadbcaaaaabccbbbbba#####a#a##aaaaa###aa#aa#bccaabaac#aaa#####a#..#####aaaaaabcbaaabbbbcdccdcddedceefgfccbaaaaaa#aa###aa##accaaaaaaaabbbbdjkfdfgjjhgfeeeeeedcaabaabaaaaa#####ab#a#aaaa###a####aaaaaaaaaaabbccddccccdccdeeegfbcbcaaa#aaba#aaabdcbbbababbbaabbcccdghg#aadbaabbaa###a##acdaaa#a#aa#baaaaaaaaa#a#aaaccbaabaaa",
+"a##a#aaedbbcbabaaaa##a##aa####aaaababbaabacaaa###a#######a####aaaaaaaccehbbbbcbaaaaacdbbbcb#a#a#a#.####aaa##a#aaaaaaabaaaaab##aaaaaaaa#####aaa##aa##abbaaabbbccbccbcdcdcddeffcaabaaaabba#aa####a##bcbaaaabababbbbejib#abccdcbbccba##a##aaaa##a######a##aaaaa#a###a#####aaaaaaaaabbccccccccccccdeegfcdabbaaaaaaa#aaaabccbbbaccbabbbcddefedea#cd##a#aaab#aaa##bcb###aaa##abaaaa#####aaaaabbcbaabbb",
+"aa##aa#bhgccbbccbbaaaaa########aaaaabcbaaaabbaaaa###aa#####a#a#aaaabbbbcega##acbabababecccdabaa##########aaaaaaaaaaaaaabaaa####aaaaaaaa##.##abaaa#aaaaabbbbbbbbcdbbccddcdcegeaaaab#aaaaaaaaa####aabbabbcbbbcaaabbcegiaaaaaa##abbcbca##.###aaaaa####aaa##abbaa#aaaaa####aaaabbaaabbbbccccbcccdddedfddcaaaaaaaaaaaaabbccdbbbcecbbccdefged#a###fa######aaaaaaaabaa#######aab#aaaa#aa#aaaaaabcccabaa",
+"aa##aadafhhfeccbbbaa#aaa##a####a#aaaaaaaaaaaaaaaaabaaaabaa#aa###aaaaaabbcfd#a#acbaaaaabeecdcc#############abbaaaaaaaababbba###aaaaaaa#a#####aa#aaaaaa#aaaabbbabcccehgeecdegebaaaaaaaaa#aaa#aa###aaaaababccbbaa#aabceggaaaaaa#aaaabcb####a###aaba######a#a#####aaaaba#####aabbaaaabcbbbbcbbacceeddeebabdbabbaaaaaababcdccdccdcbbccefecb#####cc#########aaaaaaaaaa##ba#aaaaabbbbaaa#aaaaaabcccdgdb",
+"##aaacdggggghgdbbbbbaaaaa#aa###a###aa##aaaaaaaaaaaaabcbbaaaaaa#aaaaaaabbbdfd#aaacdaaaaaadgefc#######a#a###abb##a#aaabaaaaaa#######aaa#a########aaaaa##aabbbbbbbbccefhfeeegfbbba#aaaaaaaaaaaa####aa##abbcdacbaa##aabcehfaaaa###aaababa##.##a#aaaca#a#aaaaaa#aaaa#aabcc#####aaaabbbbbadcabbbbbbceedefcaabcecaaabaaababccdcdddccbbcceda#####baeaa#aaa#####ab##aaaaa##aaa##abbbbbbbbaaaaaaaaabbbagig",
+"f#aaaehhfffeffhfbccbbaaaaaaa####a#aaaaa###aaa#a#abaabccabcbabbbbabbaabbbbcehdaaaaaaaaaab#dgeaa##a###########aa####aaaaaaa######a####aaaa###a###aaaaa###aabbbbbacccdedddfgebcbaaaaabbbaabaaba#########abcbdabaaa#aabcdeibaaa######aaaca######aabbb####aaaaaaaaaaa##bbdb####aabbbbaaaacdcaabbbbcceddeccccaba#aaabaaaabccddddddceddeec#aca#aabebaaa#######aaaba#######aaaaabbbabbbbbaaaaaaaaaba#dii",
+"hd#aaejiedefeeddedccbaaaaaa########aaa#######a#a#aaaabbaacbbababccbbabbbbbceidbaaaaaaaacbcgeca#############aaaaaaaaaaaba######.a############a##aaaaaaaaaaaacbbbccccedbcfcbbbbaaabbbbaaaaaaababaaa#baaaabababbabaaaaabdfhaaaaa#aa##b#bbaa#####abb##a##aaaabbba#aaaaaacda#####abbbbaa####a#abaabccbdecdbbaaaaaaaaaaaabccceeedcdfgffeba#aa#aa#bcaaa##########aa##a####aaaaa#aaabbbbaaaaabbbcbbbeefh",
+"ggecdhjkiefeeddcdefdababaaa########aa##a########abaabaabcdabbcdccbcbabbbbccchiecaa#abbbaaaadeca#####a#######aabaaaaaabba###a##.#############a##aaaaaaaaaaabbbccdddbbeccdbbcbbbabbbbbbcbbaaaabccaaaabaabcabbabaaaabaabcefeabaaaaa####aaccb####aaa###a###aabbab#a#aaa##aaa#####acbba#a######aaaabbbbfefdaaaacaaaaaaaabbbcefffeefbed########a##dbaaa#######a#############a########aaaaaaaaaccfgfhdf",
+"efddegijmkfeeeddccdgdbcccbaaa####a#aaa#####a####a###aabbcbabacccdccbbbbbcbbdfijhbaaaaabb###cedbaa###aaa#####aabbccbaaaaa###accb###a##########aaaaaaaaaaaabcbbccddddcddaaaabbbabbbbbbcbaabbbbbaaaabbaaaaabbbbaaa#ccaabbddheabaaaaa####abca#####ba##a####abcaaaaaaaaaa#aaaa#####bbaaa##aaaa##aaabbaaadfdbaabcbaaaaaaabbacehhhhcaaaa#####a#ab##ccaa########aa#############ba#a#aaaa#aaabdaaeffghgff",
+"eddcbcdefijgeedcccbbdeccccbaaaaaaaaaa#a#########aaa##a#abcaacccccccbcbbccccdefikibaaaaaaaabbdddca#a#a#aa####aaabbbaaaa##a##aaaba##aa##a######aaaaaaaaaaabbbbbccccddddaabbaabcdbbbccbacbabcbbccbaa#aaaa###baaaaa#a#aaabcdfjb#aaaaaa####abaa.####a##aa####bcbbaaaaaaaa#####aa##abaaa#a##aaaaaaaaaaaaabecbaababaaaaabbbcbcehhcaaa##aaa#######b#.cbabaa#####aa##a#####a#########aa#a#aaabdefffggfefe",
+"ddcaaabdefhihecdbbbbacdecccbbaaaaaaaa############aa##aa#ababbcbcbbbababccdceeegijgaaaaaba###bfcdc##aaaaa######aaaaaaaaa#aaaaaacba#aaa#a#ba#aa#aaaaaaaababcbbbbbcedabbaabbaaabbbabbdccbbbaabbbbbaaa#aaaaa##aaaaaa#####abcehka##aaa#####aaaa###..a#aba#####abcaaaaaaa#a##a##a###ba########aaaa####aa#deaaa#aaaaaaabbbbbccefcbaba##abaaaa.#a#ba##dc#a#a####abaabb#a##aa##a###a###aaaaabaceecddhhedd",
+"cccbabbcdfffhheccbbbbbcdfccbbbbaaaaaa###############a##aaaabacbbbbaaaacccddcdefhjjhbaaaabaa##dfbbc###aa#aa######aabaabaabbbbbabdb#aa#a###bba#a##aaaabbabbbbbcbbcedbaaaaaaaaabbbbbcbccbcebbbbaaaaaaaaaa#####aaa####aa#aabdegj.############a##a##a#aba####a##baaaaaa#a###aa#aa########a##a#aaaa####a#eeaa###aaaaaaaaabbcdgfdbaa####aabbcb#aabc###cda#aa##aababcbb#a#aa###a##aab#aaaaababdecbcdheed",
+"cbbaccbcddeffeedcbbbbbbccffdbbcbabbaaa#aa########a###ca#abaabbbabaaaaabcccddcdgiikjgbaaaaba##afcacba###aa########abbbbaabbbbbbbcbbbb#aa#a###aa##aaaaababbbbcbccdca#a##aaaaabaaabcccbbcbcbaabba##aaaaaba#####aa####aabbbddcdjd.#########.#..#######aba######aaaaaba########aa#######aaa#aba#aaa###aacaaaa##aabaaaaaaabbcefcbbaaaaa##aaacabaaaa###bca#####aaaaacaa#a###a##a#aaa#a#aabbbbcddcccegdd",
+"cbbabbbbccddeedddcbbbbbbbbdfheccccbaaaa###########aa#bd##baaaabaaaaaababcddcccggijjjbaaabbaa##bcbabba##aa#######aaaaaaabbbbbbbbbcccaaaa##a##aaa##aaaabbbdbcbbcdfbaaa#aaabbbbbbbbbcccbccdedaaa#aaaabbaaaa#a#aa####a#abcccdccfi###########....#######aa##aaaaaaaaaaa##########a###a##aa#aa#aaa#####aaa#aaaa##abbbaaaaabcdefbbaaaaabaa####aa####a#a#dba#####bb##b###########aaaaa#aaabbaabbbccddede",
+"baabbbbbccccdeedcccbbccbcbbcdiheccbbbaaaaa#aab##aa###aa###aaaacbaaaaaababccccdfhjjjl#abbbaaba#abeaabb######a#####bbaa#aaaabbbcbbabbaa###aa####a###aaaabacdcccdceaaaaaaaaaababbbbbbbcbbbcbdba###aabbbaaa#aa##########aabbabccgb.###.#########.########a#aaaa#abaa#########a##aa#####bcaabaaba###aaaaaaaa#####aaaaaabbbdhidabaaaaaaaa###########a###ebbb###aaa####a###aa#aabcaabbaaababaaabbbbbdcb",
+"abcbbbbbbbccbbcddbcbbbbbbbbbcfeghfccbbabaaaaabaaaa####a#b##aaaabbaa#aaaaabccbceefhegdedaaaaaaa#abdaaba#aa##a#####aaaabaaaaaaabbbaacc###aa#aa####a#aaaaaaabcccddfbba#aaaaaabbbbabbccccccbcbdaa#####ac#####a##########aa#aabcbdh..#########.#####.####aaa#aaa###abb###########accaa###a##aaabbbba#a##a#abba####aaaaaccegcbbaaaaaaa#aa###.##a########aeaaaa###a#a######aaa##aaaaaaaabbaabbaacaacced",
+"cadbbbbbbcbccbbacbbbbbbbbabccdeehgffccbcbaaabaaaaaa###a####aaa#aaaaaaaaaaabccbdeeffeehgcaabaaa##adb#aca##aaa#####aaabaaaaaaaaaabaacdb##aaaaaaa#abbaaabbbabbdecffbaaaaaaaaaaaaaabbaccbcbcccdcaa#############aabb######aaaaabbbehd..###d#.#.######.####adbaaaa##abba########aaaaaaaaaaaaa#aaaaaaa#a#aa#abaaa####aaacdeheaaaaaaaaa##aa#aa#####a####a#.cdaa######a##a###########aa##aabb#aabaaabbadf",
+"cabdabbbabcccdccbccbbbbbbaabdcdefdcfgccbbbbaabcbaaa###aa##aca####aaa##aabbbccccddffhihhfbaba#c###bdaaagaaa#a######aabaabaaaaaaaa#a#aa####aaaa#aabbaaaabbbbbcddfeca###aaaaabbaabbabbcbccbbbccdada###aa######aaba####a###abaabcafjlf..defe##...#########bbaaa###aab#a#######aaabcb#aaaaaca##aaaa####a##aab###a##aabdfiida###aaaaa##ca#aa#####a####a###ecaaa########a##a#####a####a###aaaaaaaaaabab",
+"ccbbbbabbaaabccdcbbbbbbaaaabcdbbbeeadgeccbbbbabbbaaa##aa#abedbaa####a####bbbcbccddehhhfdaa###da#a#ddaabhaa###########a#abaabbaa######a####aaaaaaaaaabbbbbbcbdeefcb###aaaaaaaaaabbbbccccbbaabbcaaa############aacbaabaaaaaaabccbdejkbd..bgccdcba########aa######aaa#a#######aaaccaba#bcaaba#a##aaa#####abba#aa#aabdgkjkihgdb#.cedcbb#.###dc########b##ebaaaa#########################aaa#aaaaaaba",
+"abeecbbaababbbabbdbabbbbbaaabcccbdcb#ehedccbbaabbbaaa#abaaaedba###########acbbbcceeeggdaaa#bacaa#aadabbdf#######.#######aaaaaa######bca###aaaaaaaaaabbbbbbbccfffbaaaa#aaaaa#aaaabbccabbcccbbbbaaaaa#######a#aa#acaaaaaaaaaaaabccceglh.#....#baacca..####ab########aaa####a##ababbbba#ceaaaaaa###a######aa##acbbbbchgcddfgjihddigefegfffba#affeecbbaaabda#aa######a#a################aaaa#aaaaaab",
+"babfdcbcbabaabababbbaaaaaaaabcccdbaaaacifddcbbbbbbbabaabaacecabaaaaa######aaabbcdeeedifba#adcbaaba#bcabbfe#aa####aaa###a#abaaaa######aaaac#aaaaaaaabbbdbbbbcceebbba##aaaaaaa#aaabbbbbbcccdcabaaaaab##a#aaaaaaa######abaaaaa#abbbbddei#####a####.#ee######aa######aaaba######abaaaa#a##bc##aa#a####a###a#aaaabcbbbceecbbcbdeffgfdccccdefeefgffedcefeb##cdbcba########a###########a###aaaabaaaaaaa"
+};
+SIMPLE  =                    T                                                  BITPIX  =                    8                                                  NAXIS   =                    2                                                  NAXIS1  =                  384                                                  NAXIS2  =                  384                                                  HISTORY Written by XV 3.10a                                                     END                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             3"3wUD3D3"3""3"3"333""""""""3DDDU3""""DªwUUD3333333"3""3""DfD"3"""""\11\11\11\11\11\11"""33DUfffUªw3"\11"UD3""3"\113D"33wf\11""\11\11\11\11"""\11\11\11"\11"3""""\11\11\11\11\11\11""""D\11""""""""333U3333DDff333"\11\11"""""""\11"""333333DDDUD"3"""""3\11\11"\11"""""""\11\11\11\11\11\11"3"""""\11"3333UUfª\11\11\11\11\11"\11\11\11\11\0\11ff\11\11\11\11\11\11""\11\11\11\11\11\11"""3"\11\11\11\11\11\11"3""""\11"\11\113D\11\11""\11"\11\11\11\11"\11\11\11"\11""""3D333DffD33D3Ufww\88wUDDDDUfwffw\88wwfUDfwf3\11\11DU3D3"\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11"\11\11\11""""3""""""""3ffD33""3"333"33U3"33333"""3DDD3UD3\11f\99fUDD33""333"""\11"3"""fU3"\11\11\11\11\11\11\11\11\11\11\11"D333DDfff\88\88U"""\113"D""\11""U"33Uw\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11""""""\11\11\11\11\11\113D"\11\11\11""""""""""3333333DDwww3""""\11"""""\11""""33DD"33DDD3333"""""\11\11\11\11\11\11\11"\11""\11"D""""""""""""3DDDf\88Ý\99\0\11\0\0\0\0\113""DD"\0\0\11\11\11\11"3\11\11\11\11\11\11\11\11"""\11\11\11\11"\11\11"3"3333"\11Df""""""\11\11\11"\11\11\11\11\11\11""\11\11"D3333D\99\88DUUw\88»ª\99UUª\88fwf\88www3"\11"wwffD33"""3U"\11""\11\11\11\11\11\11"\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""\11""""""3DD3333"33"""3DDUD333333""""3DU333ff"U\88fDD3333"333"""\11\11""\11"3fU3""\11\11\11\11"\11\11\11\11333D3DDUUf\99\99\99wU""\11\11\11U"\11"\11UU""3\99""\11\11\11\11\11\11\11\11\11\11\11"\11"3""33""\11\11\11\11\11\11"\11\11\11\11""""""""""333333D3UffwD3\11\11\11""""""""""3333DDDD33""33D"""\11\11\11\11\11\11\11\11\11\11\11\11""D3""3"""""""3DD3Uf»Ì3U\0\03\88DDUD3"\11\11\11\11\11\11\11\11""\11\11\11\11\11\11"""\11"\11\11\11\11\11\11\11"""DD"3"\113D""3"\11"\11\11"""\11\11\11\11\11"33"\11""\11""3U\88̻̪\99\88U3\11\0DfUD33\11\0\11\11\11UD\11\11\11\11\11\11\11\113\11\11f3""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""\11""""""3"D"3U"333"3DDDUDD3DD333333""3UDUfwUDw\88DD3333""3D3"""\11\11\11""\11\11"D"\11\11\11\11"""\11\11""333DDDDUUww\99ª\99\99w3"3"\11D\11\11\113U"""\88"""\11"\11\11\11\11\11\11""3""3""""""""\11"\11""\11\11\11\11""""\11""33""""33333DUUwfD"\11\11\11"""""33""33"33D3DD333DDU"U"\11\11\11""\11\11\11\11\11\11""3"\11\11\11\11"\11\11\11"3""3D"w»Ýw\0\0Ufwf\11\11\0\0\0\11\11\11\11\11\11\11\11\1133"""\11\11\11""3\11"\11\11\11\11\11\11\11"""3D3\11"""""D"\11\11""""\11\11\11\11"\11\11""3\11\11\11"\11\11""3UwªªU"\11\11\11"""""\11\11D"\11""\11\11\11\11\11"\11\11\11\11"\11\11\11fD"""\11\11\11\11\11\11\11\11"\11\11"\11\11\11\11\11"\11\11\11\11"\11\11\11""""""""""3"3D"U333333D3DD33"D33333333"3DDUff\99\88wwDD3D3"""3""""""\11\11\11"\11\11\11\11"""\11"""""""""""3DD3Uffwwff\99\88D""3"""\11\11"U3\11"D"\11\11"""\11\11\11\11\11"""3""""""""""3""DU3\11\11"""""""\11"33"""333"33UfDww3""""""""""""""33"DD3D3DDDUD""\11\11\11\11\11\11\11\11\11\11\11\11\11""33\11\11\11\11\11\11"""""333f\99U\0\0\11\11\11U\11\0\11\0\11\11\11\11\11\11\0\11\11\11\11"U3""""\11\11"33"\11\11\11\11\11\11\11\11"""""""""""""\11"""""""\11"\11""\11"3"""\11\11\11\11"""DUf\99f"""""""""\11\11""\11""\11\11\11\11\11"\11\11\11\11"\11\0DU""\11\11\11\11\11\11"\11\11"\11\11\11\11\11\11\11\11\11\11\11""\11\11""33\11""3"""33"Uw"3D3333333DD33DUU3D333333333Dwf\88\99wDD33"3"""""3""""\11\11\11\11"\113\11\11""""33""\11"""""3DD3Dffw\99f\88UfU"""""""\11"3U""3"\11""\11\11"\11\11\11\11\11""""3"""""""333""DD\11\11\11""\11""\11\11\11\11"\11"""""""3DDDUUw33"\11""""""3333"33DDDDDD3D3U""\11\11\11\11\11"D\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11""\11""3D3U\99\0\0\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\0\11\11\11\11"""\11"""\11\11\11"33\11\11\11\11\11\11\11\11\11\11\11"DD""\11\11\11"\11\11"""3333"\11"\11\11"\11"33"\11\11\11\11"""""DDf\88D33"""""""\11""\11\11\11\0\11\11"\11\11\11\11\11\11\11\11"f""""\11\11\11"\11"\11\11\11\11\11\11"""\11\11""""""""33""33""D""DDfU3""33333DDDDUffUDDD33DD3D33DUª\99fDD333"""""\11""3\11\11""\11\11\11""\11\11\11""""D3""""""3"3DDDDUw\99»»»Ý\11"333""3"\11"3f""33\11\11\11\11\11\11"\11\11\11\11\1133""\11""""333D33"33""\11\11\11""\11\11\11\11"\11\11\11""""3"DUDDDUDf""""""""""3"3333333D333D3U3"\11\11\11""333"""\11""\11\11\11\11\11\11\11\11\11\11""33"3DD\883\0\11\11\11\0\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11"\11""""\11"3""\11\11\11\11\11\11\11\11\11"\11\11""\11\11\11\11\113D""3""3"\11\11\11""""""""\11\11\11\11\11""""""333U\99ªU"3""""""""\11\11\11\11\11\11\11\11\11\11\11"\11\11\11f333\11\11\11"""\11\11\11\11"\11\11\11""\11""3D""33"""3"3"""33333UD3D33"3333DDUUffUUUD33333333Uw\99fDDDD3""""\11\11\11\11\11\11\11\11\11\11\11""\113U\11\113""""3""""""3"3DUUDDD\88\88ª»»»3"""33""\11\113D3"33"\11\11""\11\11\11\11\11\11\11"""""""333333333DDD""""\11\11"\11\11"""\11\11""""333U3D33DUw3"""\11"""333333333DDD3DDUfU"""\11""""33""""\11"\11""\11\11\11\11"\11"3DDDUDDwª\11\11\11\11\11\11\11\11\11\11\11\0\0\0\0\11\11\11\11\11\11\11""\11\11"""""""""""\11\11\11\11\11\11\11\11\11\11"\11\11\11"\11\11""\11""\11"""\11\11\11\11\11"""\11""""\11\11"333"""""3DUfw33"""""3""\11\11\11\11""\11\11\11\11"\11"\11U3"\11\11\11\11\1133\11\113\11\11\11\11\11\11\11\11\11\11\11"""""\11"""33""333DDUUfUfD33"DD3DUUfwwffUD333333DDwwU33D3"33"""\11""\11\11\11\11\11\11\11\11"\11\11\11D"\11"3""333"3"""""3DDDUUDU\88ªªÌ»\883""""3"\11\11"wD"D3"\11\11\11""\11\11\11\11\11\11\11\11"3333""3333333D3333\11""\11"\11\11\11""\11\11"""""3"3333D3DDUD"\11"\11\11"""""3"""3DDD33D3D3""33"\11\11"""""3"\11\11\11\11\11""\11\11\11\11""333UUDU»U\0\11\11\11\11\11\11\11\11\11\0\11\0\0\11\11\11\11\11\11\11"3"\11\11\11\11\11\11"""""3"\11\11\11\11\11\11\11\11""\11\11\11\11\11\11\11"""\11"3"\11"""\11\11\11""D""""\11\11""3"""""""33DfwD33"""""\11\11"""D"3""""\11\11\113D"\11\11\11\11\11"""""D""\11"\11\11\11"\11\11"\11"""\11"\11""3333DUUDDDf\88UUDDD3"33DUwww\99\99fDD33333DUwDD3333""""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11""""3"D3333""""DDDUUDUfw\99»»\993""""3""\11\11Uw33D\11\11\11""\11""\11\11\11\11\11\11""3""3""33333"3U3\11""\11"\11\11\1133"\11"\11\11""""33"33333D33DfU3"""""""""33333D3DD3Df3333""""""""""\11\11\11\11\11"""\11\11\11\11""\11""3Uf\88»\0\11\11\11\11\11\11\11\11\11\11\11\11"\11\11"\11\11"\11"3"\11\11\11\11"\11\113""""""\11"\11\11\11""\11""\11\11\11\11\11\11\11\11"\11\11"\11""""\11\11\11\11"\11ff""\11\11\11"""""""""33DU\88wU3""\11\11\11\11""33D3\11""3D\11\11\11DU"\11""\11\11""3"3D33\11"\11""\11\11\11"\11\11""3\11"""""3"3UfD3DU\99ffUUUD"""3Ufw\99ª\99fDU3333"DUfDDD33""""""""\11\11\11\11\11\11\11\11\11\11\11\11""\11\11""\11"3"33D3D333"3"3DDUDfff\88ª»\88"""""3"\11\11\113wDUD\11\11"""""\11\11\11\11\11\11"""""""""\11""""""D3"\11"""\11"\113"\11""\11""""""""3"3D33333DfU"33""33"""333"33UDD333""33333"""\11"""""\11\11""""""\11\11\11\11\11"3Df\99Ì"\11\11"""\11\11\11\11\11""""\11\11\11\0\0"\11"3"\11\11\11\11\11"3D"""""""\11"\11\11"\11\11"\11\11\113"\11\11\11\11\11\11\11\11""""\11\11\11\11""\11Uf"""\11"""""""33333DDfwD3"3"\11\11"3""""\0\11"\113"\11\11UD\11"\11"\11\11\11\11"3""33\11"\11\11""\11\11"\11\11\11"\11\11\11"""""3"DffDUU\99\99fUUfUUD3DUfwª»\88ffUDDD33UfDDDD3""""""""""\11"\11\11\11\11\11\11\11\11\11"""\11\11"\11"3D""DDDDDDD3D33DDDDUfwªÌª3""""""""33UUUD"\11"\11"\11""\11\11\11\11"""333""""\11\11"\11\11"""3"\11\11""\11\11"\11\11\11\11\11\11"""""""""""33333DDDDUUUU""33""3DU333DD3"D3"3D33DD3""\11""""\11\11\113"""""\11"\11"""3DUw»3\11""""""\11\11\11\11"3""\0\11\11\11\11"\11\11""\11\11\11\113D33""""""""\11\11\11\11\11""\11\11"3"""\11"\11\11"""""""""""""3fD3""3"3"""""333D3Df\99\99D"""\11\11"""\11\11\11\11\11\11\113\11\0D3"3""\11\11\11\11\11""\11\11"\11\11\11\11\11"\11\11\11\11\11\11\11\11\11""\11"\11"""3Ufwww\88\88wfwffwUUf\88ª»îÌwfffUUDDU\88U3DDD3"""\11\11\11\11"\11"""\11\11\11\11\11"\11\11\11\11"\11\11\11""33D3"3"DDDUDD33333D33Uwª»\993"""""33\11\11\11DfU3""\11\11\11"""\11\11\11\11\11""33DD3"""""\11\11\11"DD3\11\11\11"\11\11\11\11\11\11\11\11\11\11""""""""""""3D33DDUUUUDUU""""333"333333D3""33333""""33"""""3333"""\11DD""33UU\99f"3"""""\11\11\11\11"3D"\11\11\11\11\113"\11\11"\11\11\11\11"3D""""""""""\11""""\11\11\11\11\1133"""\11\11""""\11\11"""33"""UwU3""3D3"""""""33"Df\99\99\99\99D""""\11\11\11\11\11"\11"3\11\11DD""\11\11\11\11\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\113"\11"\11""""\11"""3U""fww\88\99\88ww\88\88fDU\99»ÌªfwffUUDUfwU"3"3"""\11\11\11\11\11\11\11\11""\11\11"\11\11\11\11\11\11\11\11"3""3""3DU"33DUDD3D3"3333DDD\99ªfD""\11"333""""UfD"\11\11\11\11\11"\11\11\11\11\11\11\11""3""""""33"\11\11\11"\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11"""""""""""333DDUUU33fDDU33D333"333333D33""""3DD""""3""3D"33"3""""3""3Dfwf"3"""""\11\11\11\11""DD3\11\11\11\11"""\11\11\11"\11\11\11""33"3\11"\11"""\11\11"""\11\11\11\11\11"D33"\11"\11\11\11\11\11\11""""3333wfwU""""D""""""""333Dfwwwffw3fU\11\11\11\11\11\11\11\11"\11\11U3"""\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11"""""""""DDw\88w\99Uw\99U\11""f»ªfUfwffUUfUDD3""""""\11\11\11\11\11\11\11\11"""\11\11\11\11\11\11\11"\11"\11""""33""D33"3"3DD33"33333DfªU3""""""""D3D\88fD"\11\11\11\11\11\11\11\11\11\11\11\11\11"""""""""""3"\11\11\11\11\11\11\0"\11\11\11\11\11\11\11\11\11\11\11\11"\11\11""""""""""""D333DDDDfU3DwD3333"""3333"""""""3"3"""\113""""3"3"33"3"""""3Uw\99"""""\11""\11\113\1133""\11\11\11\11\11"33\11\11"\11\11""""333"\11""""""DU"\11\11\11\11\11"3333""\11\11\11\11"\11"3""3DD3UfDU33""""""""""""3DDDfffUDUw\88wwf3"\11""\11""\113D"""\11\11\11\11\11\11\11\11\11\11""\11\11"\11\11\11\11"""""\11"""3333"""""333D333ffw\99w\11"""f\99\99wwwfww\99w3DD33"""""""\11\11\11\11"\11"""""\11\11\11"""\11"\11"3""3DD"3D3"3333"33""3333Df\99U""""""""""3\11U\88f""\11\11"\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11"""""""\11\11\11\11\11\11"\11\11\11\11""""\11\11\11"\11\11\11"""""\11\11\11""33333"DDDUfUUUw\88f3D3"""""333""3""3"\11\11\11\11\11\11\11\11\11"3D3U"3"""\11""3DUfª3"""\11\11\11\11\11\11"""D"\11\11\11\11\11\11""333\11\11\11\11"""""""""""\11\1133U3\11\11\11\11""3333""""DUD""3333DDfUUfDDDD"3"\11"""3""""3DDUUUUUUDfUUffD\11"D"\11""3f3"""\11\11\11\11\11\11\11"""3"\11\11\11\11\11\11\11"""""333"33333"""""""""3"\11Uªª\11\11"""DU\88\88\88\88\88\99\88U33333"""""\11""\11\11\11"\11\11\11""\11\11"""""""""""""3D33""""""\11"""""""333UwU\11"""DU""""""U\88fwD\11\11\11\11\11\11\11"\11"\11\11\11"33\11\11"\11"""3""""""\11\11\11\11\11\11\11"""\11"\11\11\11\11\11\11\11\11"""""\11\11""33333333DDfw\99wfff\88w333"\11""""""""""""\11\11\11\11""\11\11"33DU"D3""\11\11""3Df\99w""""\11\11\11"""3"3"\11\11\0\11\11"\11"""D"\11"\11""""""\11""""\11""3DD\11\11\11\11\11""""33333"UD"333333DffUfwD""3DfD"""3"""3"3DDUDUUUDD33DDfU"\11\11\11\11\113"f""\11"""\11\11\11\11\11"3\11\11"""""\11\11"""\11\11"33333333"""""""""333"\88ª\88""\11\11""U"w\99\99wfDD333""\11"""\11\11"\11\11\11\11"\11"""""""""""""""""3""""3""\11""\11\11\11""""""33DwU\11"\11"D3"""""3ffDUDD\11\11\11\11\11\11\11\11\11\11\11\11\11"33""""""""3"333"\11\11\11"""""""\11"\11\11\11\11\11""\11""""""\11""""333"3DDDf\99\88ffDUf\88f3"""""""""\11"""\11""\11\11\11"""""3"3DD33""\11""3Df\88\88""""""\11""""3D3\11\11\11\11"\11\11\11""3"\11\11\11\11\11\11"\11"\11\11\11\11\11""""3"\11\11\11\11\11""33""""3D3333D33"DDffUUff3"3U3"33""""""3"3DUDDUDDUD33DDfwfD3\11\11\11\11\11DD\11\11\11\11\11\11\11\11\11""""""""""\11\113"\11"""""3333"""\11""""""3DDDU\88U3""\11\11""\113\99\88DD33DD33"""""\11\11\11\11\11\11\11\11"""""3D3""""33""""\11\11\11""\11\11\11\11\11"\11"\11""""3333Df\88"\11\11"D3"3"3"3fDDDU"3""\11\11\11\11\11\11\11\11\11\11""""""""""""""3"""\11\11\11\11""""""""\11\11\0\11\11"3"""\11"""""33333333DU33DDUUDUDf\88f""""3\11"""""""""\11\11\11\11""33"33D333D"""33Df\88ª""""""\11\11"33D3D"\11\11\0\11\11\11"""""\11\11\11\11"""\11\11"33""\11"""""\11\11\11\11""""33"""3333DDDD3DDDUUUfUwUUD"""""""""""""33DDU333DfD33DDUfw\88fU\11"\11\11\11w"\11\11\11\11\11\11""""""""3""\11\11\11\11\11\11\11""3\11""""\11""\11""""""3DDD"3"""\11\11"\11""fU33D3"3""""\11\11"\11\11""\11\11\11\11""""3"33""3"D"""\11\11\11"\11\11\11\11\11\11\11"\11\11\11\11"""""""DDf\993333D3"""""DU333D3\11"\11"\11"\11\0\11\11\11\11"""\11\11"\11"""""""3"""""3\11\11""""""""\11\11\11\11\11"""\11\11""\11\11"33"""333DD3DD3DUDUDUUfwwD""3""""33"\11""\11\11\11\11"\11\113D3""""3"3"3333f»ª3\11"3DDUD33DD3"\11\11"\11\11""""\11\11"\11\11\11\11\11\11"\11\11"""""\11"\11\11\11"\11\11\11\11\11"""""""""33DDDDDDDDDDDDUff\88wDU"33"""""""\11""""3DD333"DD3"333DUUfwfUf"\11DU\11\11"\11"""3\11"""\11\113D3\11\11\11"""\11\11"3""""\11\11\11\11\11"""""33D3""333\11\11\11\11\11"UD333""333""""\11"\11"\11\11\11\11\11""""33"""3D3""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11"""""3UU\88f"U3D"""""3DD33333"\11\11\11\11\11"\11"\11\11"""""\11\11\11""\11""\113DD""3""D\11"""\11\11\11\11\11"\11\0\0\11\11\11\11\11""""""3D3"""3333DUDDUDUUfUDffw\88wDD3""""""\11""\11\11\11""\11\11"DD""""""""3333U»ÌwUw\88»»\99\88wffffffUD""3""3"""""\11\11\11\11\11"3\11"\11""""\11\11\11"\11\11\11\11"""""""""""33DDUUDDDDUDDUfff\88w3D3D"""\11""3"\11"""3UD333"3"333""33DDDU\88\99\88\11""U3""33""\11\11\11"\11\11"DU"""\11"\11""\113"""""""""\11"\11"""DD3""3"""\11"""\11U""""""""333""""\11\11\11\11"33""3""3D33333\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""333UUf\99fD"D3""""3fD3333"3""\11\11\11\11\11"UDD"\11\11\11\11\11\11\11\11\11"\11"\11\11U"""""D""""""\11\11\11""\11"D"\11""\11\11""""333""3DD3333DUU"DDUfUUfDw\99\88D"3"""\11"3\11"\11\11\11\11"\11\11\11\11"""\11""""333D3Dª»UD\99ª\99\88ª\88\99fU3D33DUwU"3333DD""""""\11\11\11D""\11""""\11"\11"\11\11"""""""""""""3DDDUUUUUfffUfffww3""""""\11\11""\11\11\11"""333"3DUf"3""""3333DUf\88ª3"33w""3D"\11\11\11\11"\11"DD"\11"""""""3"333""""\11\11"""3"33"""3""""""\11\113""\11\11\11\11"""3"""""\11\11\11\11\11""D""3"33DD3""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""""""33DD3f\88ªw""""33DfD3333""U\883\11\11\11\11\11"ff"3D\11\0\11\11\11\11\11\11""\11\11"""""\11"""""\11\11\11"3""\11\11fU""""\11\11""33""""3333333DD33UDDDDUUUf\99\99U"33""""""\11\11"\11\11\11""""33\11\11\11\11\11\11Df3D3D\88»\11""\11\11"3Uw\88\88D333""""3Uwf"\11\11\11\11"""""\11\11""\11\11\11"""\11""""\11"""33""""""""33DDUUffUUfwwffffwD"3""\11""\11\11\11\11\11""\11""333"DDD3""""""""3DDDUf\88w333Df""D3\11\11\11\11\11""""""""""""DDD"3"""""\11"\11"33DD""33""""\11\11\11"3"\11\11\11\11\11\11""""""""\11\11"\11"""\11wU""33DD3\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11""""33"3DDDDUf\99ª3"3333DwUD333"3\88ª\99D\11"\11\11\11\11"33""\11\11"\11\11\11""\11\11"\11""""\11\11"""\11\11""""3"\11\11\11U"""\11\11\11"3D"""3"""33333DD3D3DUDUUU\88\88wfU3D3"""""\11\11"\11\11\11\11\11""""\11""\11\11\11\11\11"3333U»3\0"\11\11"""""3ffD"33"\11\11""3U"\11\11\11\11\11\11""\11\11\11\11"""33UDUD3""\113D33""""""""333DDDUUfUfwwwUD3DD3"3\11\11\11\11"\11\11\11\11\11"\11"""3""3ff3"\11\11\11\11\11\11"""D3DUUf\88f33"DDD3"\11\11"\11""""""""""""DD33333"3"""\11"""33""""""""""3Uf3"\11\11\11\11\11\11\11\11\11"""""\11\11\11"""""Dwf3333""\11\11\11""\11\11\11\11\11""\11\11\11\11\11\11\11\11"""3"3""D3UfDDf\99\993"""""UUD33333D\88ª»\99f"\11\11\11\11"D3\11\11\11\11\11\11\11\11"\11\11""\11"\11\11"\11"""""3""""\11\11\11\11"""3\11\11\11""""""""""3"33DD3333"D3fUwwfUDUff""""3\11"""\11""\11\11"\11\11""\11"\11\11\11""\11""3"DÌD\0\11\0\11\11""""""3Ufw3\11"\11"""""\11"\11\11\11\11"3D\11\11\11\11"3D33ffD33"""33\11""""""""3333D3DUfUfUUfwUD"DD3D"\11\11""""\11\11\11"""""3""fDD"""\11\11\11"""\11"""3DDDUww33"DwD\11"\11"\11"""""""33""""f"3D33"3333D33"33\11"""""""\11""wD3\11\11\11\11\11\11\11\11\11\11\11\11\11""\11"""""""Uf\88U"D3""\11\11\11""\11\11\11\11"""\11"\11\11\11\11""""33"""3""3UUDDf\99ªf"3""3fDDD33333ªÌÌ\88D"\11\11\11\11"D33\11\11\113"3"\11\11\11\11\11""\11\11\11\11""""""""\11\11\11\11\11\11""\11\11\11"""""""3""""""""D333333fwwfUDD3DUUUU3"""\11\11""""\11\11\11"\11\11"""\11"U3"\11"""33ªf\0\11\0\11""\11\11"""""""DfD"""3"\11\11\11"\11\11""3U3\11"\11""DDDDDDDD333"\11\11\11"""\11\11\11"""3333DDDUUUfUf\88DUUD33""""33"33"33""33""UU3""\11\11\11\11\11""\11\11"""33UUfw\88D"3"\883""""""""""""33"""D"3"""""3333"33""""""""""""\11"3"\11"\11""\11\11\11\11\11\11\11"""""""3""33f3U333\11\11\11\11\11\11""\11\11\11\11"\11\11\11"\11\11\11\11""""33""3D"3DDDUUww»\99wU3"fwDU3333U»Ì»f3""\11\11\11\11\113DD3\11\113"3"\11\11\11\11\11""\11\11\11\11\11\11"\11\11\11"\11"\11\11\11\11"""""\11\11"\11\11""3"""""""333333"3fwU33D333D333D3""\11\11\11\11""\11\11\11\11\11\11\11"""""U"""""33U\88\11\11\11"\11"\11\11\11\11"\11""\11""3DDDD""""""3DU3DD"""""33UfffUDUD3"\11\11\11""\11""3"""333D3DDDUUUUfwwwwU3""\11\11\11\11"3DD33\1133DDU3DD""\11\11\11"\11""""\11"\11""33UDUw\88U"""DD""""""\11"""""3"33"""33333"33333D3D3""""3""\11\11\113f3"\11"\11"""""\11\11\11\11""""""""""DD3D33""\11\11\11\11\11\11\11""""\11\11\11""\11\11""""""""333"33D33fwww\99»ª\99wD3wD3D333Dw\99\88D"""\11\11\11\11\11"\11Uf""\11\11""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11"\11\11\11"""""\11\11\11""""33""""3"33333333fUD3""\11"33333DDD""\11\11"\11\11\11\11\11\11""\11\11"""\11\11"3""\11""3»"\11\11\0\11\11\11\11\11\11\11"\11"\11\11\11"""3fD"""""""DDD3D""""33UUUfwfUD3""\11\11\11""""\11""""333DDDDDDDUUw\88\88\88\99U3"\11\11\11\11""3"3"3"3D33UU3"\11\11\11"\11\11\11"\11"""\11\11""33DDDf\88w3""3D"""""""33"""""33""3""D""333"33"U3"""""33"\11"fwD""\11""""3"\11"\11"\11\11"""3"33DD3"33333"\11\11\11\11\11\11\11\11""\11"\11""""""""3"33"""""UDDD"UUw\99Ì»ª\88UDUfDDD33DUDfD3""""\11\11\11\11\11\11"D"\11\11\11\11""\11\11\11\11\11"\11\11\11\11\11\0\11"""""\11""3"3"33\11\11\11\11\11\11""""""33"3"""""3DUD3""""""""""333D""""\11"\11\11\11\11""\11\11\11\11"\11""""""3"3»\99\0\11\11\11\11"\11\11\11\11\11"""\11\11""""3U"3""""33"3UfffUUUUD3\11\0\11\11Uf3"""3"""3"\11\11\11\11"""33DDUDDDUUfww\88w\88D""\11\11""\11\11\11"""""DD"UUD"\11\11\11\11\11\11\11\11"\11"\11\11\11"""DD33Dfww3""D\88f""3333"3"""""""""""3""""33D"""3""""333DDUfUD3""\11"""""\11\11\11"""""""""33333333""""\11\11\11\11\11\11\11""3""""""""""33"""""333wfDDDDUwªÝ»ª\88DUfDDDD3DD3DD33""""\11\11\11\11\11\11\11"\11""\11\11"""\11\11\11\11\11\0\0\11\0\0\11"""3"""""""3"D3\11\11\11\11\11\11"""""""33""""DUUD3"""\11\11D3"3"""""3D3"""""\11\11\11"\11\11"\11\11\11\11"\11\11""3"3D\99Ý\11\0\11\11\11"\11\11\11\11\11""""""\11""33Uf"""D3333UwUDD3"33\11\11\11\11"\11UU3333"\11\11\11\11\11\11\11\11\11\11"333DDUDDDUUfw\88\99\99wD"""\11\11\11\11\11\11""3\11"3""UU""\11\11\11\11\11\11\11\11"3\11\11\11""""DDDDDUfwU\11U3\88f3DDDUD""333"""""""3"333"""3"D"""""3"\11ffUUD33"""""\11\11\11\11\11\11\11\11""""33"3333D333""""\11\11\11\11\11\0\11\11"""""""""""""3333"""""UfUDUDDf\88ª»ÌªwUUf3DD33DD""3"""\11\11""\11\11\11\11\11\11""""""3"\11""\11\11\11\11\11\11\11\11\11"""""""""\113DDU"\11\11\11\11\11\11\11"""""33"""3UUD3"\11"""""""""""""3DU"""""\11\11"3"""\11"\11"\11"\11\11""""w\99Ý\88\0""\11"\11"\11\11\113"\11\113\11"D""3DUw"""DDUDDfU3"\11\11\11\11\11\11\11\11\11\11"UD3D"\11\11\11\11\11\11\11\11\11"\11"""33DUUDD3Ufw\88\88ªª\88fD3\11\11\11\11\11\11\11\11""""\11"33"\11\11\11\11\11\11\11\11\11\11\11""""""\113U3DD3DDfw\11"3UfUUffUUDD3"\1133333"""""""""""3D""""""\11ffUDD333"""\11"\11\11\11""\11"\11\11"\11""""33DD""\11"""\11\11\11\11\11\11\11\113"D3""""""""""""3D333333DfUDUDDw\99w\99Ì\99\88\88wU33DD33"3""3""3UU"\11\11\11"""\11"""""""D3\11\11\11\11\11\11\11\11\11""""""\11""""3fD\11\11\11\11\11\11\11\11\11\11"""""""3UUD3""""""""""""\11\11""3"D3"""3"\11\11\11\11\11"\11\11"\11\11\11\11\11\11"""3\88ÌÝ3"""\11\11\11\11\11"""""""""""333wU""DUUfUUD3"""\11\11\11\11\11\11\11\11\11"""3\11\11\11\11\11\11\11\11\11\11"\11\11""""33D3333fww\99»ªwUD3\11\11\11\11\11\0\11\11"D33\11""""\11\11\11\11\11\11\11\11\11\11\11""""\11"""D3D33D3Df\88w"DD\88\88\99\88wwUD33""333"""\11"""""""""3"\11""""3ffDDD3""""\11""\11\11\11"""\11"\11"""33333D3""\11\11"\11\11\11\11\11\11\11"""3""3"3""\11"""""33333"""3"3DDUfDUw\99\99ªª\99\88wU3DD33D3"3""""""UD"\11\11"33"""""""\1133\11\11"""\11\11\11\11""\11"""\11""""33U"\0\11\11\11\11\11\11\11\11\11\11""""3UUD33""\11"\11\11""\11"""\11\11"""33UfDD"\11"\11""\11"\11\11\11\11\11\11\11\11"""""fªÝª\11\11"\11\11\11\11\11\11"3""\11\11\11""""""Dwf""3UUDU3""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""333333DUw\88»ªf3"\11\11\11\11\0\11\11\11\11\11""\11""\11\11\11\11\11\11\11\11\11\11\11\11"""""\11\11\11"""3D33D33Dfw\88\88D33wffU3fU3D3"33"""""""""""""""\11"""\11DUDUUD33""""33""\11\11""\11""""\11"""""""""\11"""\11\11\11\11\11\11\11\11\11\11"3""""\113"""""33333"3333DDDDUU3UU\88\88\88\99\99wU33D""33333""33""""\11"""33"""333\11333"""\11\11\11\11\11"\11""""""""""33\11\11""\11\11\11\11\11\11\11\11\11\11""3UD3"3""""\11\11\11\11""\11\11\11""\11"33DU\99\99D"3"\113"""\11\11\11\11\11\11\11"""""3\99ÝîD\11"\11\11\11\11\11"""""\11"\11\11"33"\11""3"""3DU\88w33\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""33""33DDU\99ª\88D"\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11"""\11\11\11\11\11\11\11\11""\11"\11\11"""3333DD3DDU\88w\99"\11D"""\0\11\11wfU33D3"""""""""\11"""\11\11\11"""UfDDD33"""""""3""\11\11\11"""""\11\11"\11"\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"\11"3"3U"\11""""""""33""3333D333UU3UU\88ªw\99fU3DDD33DD\11\11""33""\11"""""""3""333DDDDUf3""\11\11""\11""""""""""3fU""""\11\11\11\11\11\11\11\11\11\113fD"""""\11"\11\11\11\11\11\11\11\11\11"""\11\11"3DfwwUDD3\11\11""\11\11\11\11\11\11\11\11"\11"33"3ªÝÌ\11"\11"\11\11\11\11\11\11"3\11""\11""\11\11\11\11\11"""33DUUfU3""\11"\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11""""""3UUUw\88wD\11\11\11\11\11\11\11\11\11\11\0\0\0"\11"\11\11\11"""\11"\11""\11\11"\11\11\11""""33333D333DDf\88\99w""""""""33"3DD333""""""""\11"33"\11""DfUDDD3"""""\11""\11\11\11\11\11"\11"""""\11\11\11"""\11\11\11\11\11\113"\11\11\11""\1133"\11""\11"3D"\11\1133\11"3""333333""3333UDDDfª\99\88fD3DUDD3DU\11"3"3"\11\11"""3""""""3DD3""33UU33""\11"""""""""""""DD3"""\11"\11\11\11\11\11\11""3UD3\11\11"""\11\11"\11"\11\11\11\11\11""""\11\11""3wwf3DDUUD3\11""\11\11\11\11\11\11\11""""""UÝÿU\11""33"3"""""\11\11""""\11\11\11\11""""3DDUffU33\11""\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\0\0\11\0\11\11\11\11\11"""""3DDUffDU""\11\11\11\11\11\0\11\11\11\11\11\11\11\11\0\11\11\11"""\11""\11\11\11""""\11"""3D3DDDD33DDUUffw\11\11"""""\11\11\11\11"""DD3""3""""""""3"\113DUUD333333\11"""\11""3\11\11""""\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11""\11\11\113\11\11"""""\11\11"\11"\11\11\11\11\11"3"333""3"333DDDDUDU\88»ªw33"33DDDD"\11"""""""""D"""""3DDD3"""\11333D""""""""""""""""DD3""33""\11"\11"\113D33""\11\11"\11\11\11""3"\11\11\11\11\11\11""""""UUw\99\88DDUUUU"D"D"""""\11"""""""3\99ÿÌ\0""333\11\11""\11\11\11\11""\11"D""33\11""3DDUUffDDD333"3""\11\11""\11\11\11""\11\11\11\11\11\11\11\0\11\11\11\11\11\11"\11\11\11""""3UUUDUfUU"\11\11\11\11\11\11\11\11\11\0\0\0\11\11\11\11\11"""""""""\11\11"\11\11\11""3D33DD3333DUUfffwD\11\11"\11\11\11\11""""""DUDD33""3"3"""3DDUDDDD3333""\11"\11\11\11\113"\11"\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11D3\11\11\11\11\11\11\11\11\11""\11\11"\11\11\11"\11\11\11\11"3\11""3""""3333fUDUDDf\99ª\99D333333DD"""\11"\11"""""33""""333D33"""333DD"""33""""""""""3333"DU"\11\11\11\11""fU3"""3UU3"\11"""3\11\11\11""\11\11\11\11""UUDDff3"333D3DUD"\11""3"\11"""3""3wîÌ"\11\11""3""""""\11"33"3333"""\11"DDDUUUDDfU3333""""""""\11\11"\11\11\11\11\0\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3UUD33D"""\11\11\11\11\0\11\0\0\0\0\0\0""\11\11\11""\11\11\11\11""""\11""\11\11""DDDDD333"33DUfUUUf"\11\11\11\11"\11\11""\11"\113DD3DD3D33""""UUUDD333333""\11""\11\11\11\11"\11\11"3"\11"\11\11\11\11\0\11\11\11\11\11\11"\11\113\883\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11""\11\11\11\11\11\11\11"""\11\11""33DDffUUUf\88\99ªf3"""3DDf3""""""""3""3"""33"""33"""33333"""33"""""""""33DD33D3"\11\11\11\11\11Dwf33"333"D""""""\11""""\11\11\11"D33333333D3""333DD3"""3\11\0"DfwwUw\88\99w"\11"\11\11\11\11""\11""\11\11"D3"D333"""""3DfUDUUfU3"""3""""""\11\11\11\11\11\11\11\0\0\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3DDDDU333\11\11\11\11\0\11\0\0\11\0\0\11\0\11\0\0\11\11\11\11\11\11\11\11""\11"""\11"""3UUU3D"3"333UfUUfUff3\11\11\11\11""""""\113"\11""3"3D333"fDD3D3D3D3333""""\11\11\11"\11\11""U3"\11""\11\11"\11\11\11\11\11\11\11"33U"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11""""\11"3"3DDUffUUww\99\99\88DD3""3fwU33"""\11""3D33"3D"\11""""3"3333DDD3"""D""3"""3""""33""""3\11""""fw"""""""\11\0\11\11\11"\11"\11"\11\11\11\11\11\11333""3DD"33UD3"33D3DU33"""fwfªªww"\11\11\11\11"\11\11\11\11\11\11\11"\11\11"""""33D3"\113""3UUUfwwwUD""""""""""\11\11\11\11\11\11\11\11\11\11\0\0\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11""33333U"3"""\11\11\11\0\0\0\0\0\11\11\11\11\11\11\11\11"""""""""""""3DDD3Uwf3""""""DwUDD3DUUD\11\113""3D3"3"""""""""3"""fU3D3DDDDD33DD3"""""""\11"3fff3"""\11\11\11""\11\11\11""\11\11\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11"\11""3333DUUUUDDfwf\88wDD"\11"U\993""DDD"""3D3DUfD"""\11\11"""D"3U"3UD3""33"33"""3"33D3\11""33\11""\11\11Uf"\11\11""\11\11\11\11\11\11\11"""\11\11"\11\11""3""""D"DUwf333333"3DDDDwfUUw\88wfU\0\0\0\11"\11\11""\11\11\11\11\11\11\11\11\11\11\11"DU3"333\11""\11"DUUf\88wfD3"""""""3""\11\11\11\11\11\11\11\11\11\0\0\0\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11"\11"333"33"\11\11""\11\11\11\11\11\0\11\11\0\0\0\0\11\11\11\11\11"\11\11""""""""\113"""Dfff3""""ffU333"333DD3\11DfUUUDDD3"""""""3""\113f3333333333333""""\11\11\11\11"DDDDfU""\11""\11"""\11\11"\11""3U"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"\11"\11\11""""333"33DDDUDDDwDwfD3""DfD"\11""DU3DDD3"\11"\99\88"3"""""3"333DDDD3""3333333"""3D3\11\11\11"D"\11""3DD\11\11"\11\11\11\11\11\11\11\11\11\11"\11\11\11"\11"3"""\11"""33UUUU333D3"""""3DUUU\99fDDD\88\11\11\11\11\11\113"\11"\11\11\0\11"\11\11\11""DfD"\11D3"""""DUfw\99\88wD"""\11""""33"\11\11\11\11\11\11\11\11\11\0\0\11\11\11\11\11\0\0\0\11\0\11\11\11\11\11\11\11"""3DD3"""\11\11\11\11""\11\11\11\11\11\11\11\11\0\11\11\11\11"33\11\11""\11"""\11"\113"\11"33fw3"\11\11333""""""33DDD\11DDUUfwwD""""\113"""""3f3333D3333D33333""\11\11"\11\11"""\11""""\11"""""\11\11\11\11\11""""""\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11"\11\11"3\11"\11\11""D"3"""3DDD3U\99fUwU33"3D\11"""""""3"\11\11"""f\99f"""""""333"DUU33"""333"""""""3D\11""\11"\11\11\11Dw\883\11"\11\11\11\11\11\11\11\11\11""\11\11\11"""DD""""""""D3"3DU""D3"""3DUUDDD\88wD""3f\88\0\11"\11""\11"\11\11\11""""\11\11\11\11"""""3""""""Dffw\99wU3""\11\11\11""""""\11\11\11\11\11\11\11\11\0\11\11\11\11\0\11\11\11\0\11\11\11\11\0\11\11\11\11""\11"3D3"""\11\11\11\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11""""""""\11""""\113"\113"3ww3\11"D3\11""""3"""33DD"33DDDw\88U""\11\113D33"""D3D3"Df333DUU33"""\11"\11\11\11\11""\11\11"U"\11"\11\11\11\11\11\11\11\11""""\11\11\11"\11\11\11"\11\11\11\11\11\11"3""\11\11\11\11\11\11\11\11\11""\11"333""""33DUUfff3DU3"33\11""""""\11\11\11\11""""3DDD3DD3""333"3DD3""""""""33"""""""\11\11""3DDDwf3\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11"3\11"""\11\11"""33""D"3"3""""3DU3DDwwD\11\11"3f\99\0\11\11""\11\11\11"\11\11\11\11\11\11\11\11\11"""""D3"3"""DDUUw\88U3"""\11\11"""""""\11\11\11\11\11\11\11\0\11\11\0\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11"""3""3\11\11\11\11\11\11\11\11"\11"\11\11\0\11\11\11\11\11\11\11\11\11"""\11\11\11\11\11""\11\11"\11""\11\11\113U""3"\11""\11""3""""333"3333DUUfwfD3D3""33UD3""3DfDDDfw\88D"""""""""\11""\11"ff"\11\11\11\11\11\11\11\11\11\11D\11\11\11\113"\11\11\11"D"\11\11\11\11\11"3"\11\11\11\11\11\11\11\11\11\11\11\11\11"3D"3""\11"DUfwDD3"DU3UD\11\11"""""\11\11\11""3U3"""33DDD3333333DD3"3D"3""33"33"""""\11\11\11"UU3DU3"\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11""""\11""""""""\11"""D3"3UD333f\99D"\11"33f\99\11""\11\11\11\11\11\11""\11\11\11\11\11\11""\11""Dw3""""""33U\88U3""\11\11\11""""\11""""\11\11\11\11\11\11\11\11\0\11\11\11""\11"\0\11\11\11\11\11\11\11\11\11\11\11"""\1133""""""\11\11\11\11"\11\0\11\11\0\11\11\11\11\11\11\11"3"\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"""""333"\113333"""""33DUUUUUU3""3DfUDD3""UwUDDff\88\88U3"""""""\11\11\11\0U\99U3\11\11\11\11\11\11\11\11\11"3\11\11\113U"3"3"UUD\11\11\11\11\11\11"\11\11\11\0\11"\11\11\11\11\11\11""3"D""""U\88\99wU33"3fDU3"\11\11\11"""\11""""DD"3"""D"3"3333333D3D33D3"""""3"3"""3"\11\11\11\11"33Dw3""\11"""\11\11\11\0\11\11\11"3\11\11\11\11\11""""\11\11"\11\11\11\11\11\11""\113"\11""333"3UD"3fw3D""3"3\99f\11"\11\11""\11\11""\11\11\11"\11\11\11\11\11""33"\11"""""333fwD3"\11\11\11""""\11""""""""\11\11\11\11\11\11\11\11\11"\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\1133\11"""\11\11"\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11"""""\11\11\11\11\11\11\11""""\11\11\11"\11\11\11\11"\11\11""3""3""""""""""333DDDUUf3333UfUfwUDDDDD3Dff\88\99\88wU""3"\11""\11\113\99\88U\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"3\11"3"3DUU\11\11\11""""\11\11\11\11"""""""""3"3""""U\99\99ª\88f3"3wUUD""""""""""""3"""""""3D333D33DfD333"333""""33"""""3"\11\11\11"3"Uf"\11\11\11\11\11\11\11\11\11\0\11"\11\11\11\11\11\11\11\11\11\11""\11"\11\11\11"\11\11\11"\11\11\11\11""33"33""UDD\88\99333"""3wª\11"\11\11"\11\11\11""\11\11\11\11"\11\11"\11"""3""""""""33"DwU3"\11\11"\11"""\11""""333\11\11\11\11\11\11"\11\11\11\11\11\11\0\11\11"\11\11\11\11\11\11\11""\11"\11\11"\11"\11\11\11\11""\11\11\11\11\11"\11\0\11"\11\11\11\11""\11\11\11\11\11\11\11\11\11"""""\11\11"""\11\11\11""\11"""""\11"""""3""""3D3333DDDDDffDffffwfUUUD33Dffww\99\88wf3""\11\11\11\11\11"w\99\88D""\11\11\11\11\11\11\11\11\11\11\11"\11"\11\11""3DUUD"\11\11\11""\11\11\11\11\11\11"333"3"""""3"""fªªª\99\8833\88fUU"""""""""33""333"""""3UDDDUUUUDD"3333"D"""""333"""3""\11\11"DUU\11\11\11"\11\11\11\11\11\11\0\0"\11"\11\11\11\11\11"\11""\11\11"\11\11\11\11\11\11\11\11"\11\11""fD3\11"333DDDw\88"""""""fª"\11"\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11""33""""3"33"3"3U\88fD"\11\11\11\11"""""3D333"\11\11\11\11\11"\11\11\11\11\0\11\11\11\11\11\11\11U"\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""\11\11\11\11\11\11\11\0\11\11\0\11\0\113"\11\11\11\11\11\11\11\11\0\11"\11""\11\11"33"\11\11""\11""\11""\11\11\11""""""""""33333D3DDDDfw\88ffDD3DD3333Uwªª\99\88\88\88f3\11""""\11ww\99\99\99f\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\113\113D"UUUD3""""\11\11\11\11\11"3DD"\11"""""""""3U\99ª\99\88UUw\88w\88D"""""""333"333""3""""3fUDfwfD333333"333"""33"DUD"\11"""\1133U3\11"""\11\11\11\11\11\11\11\11\11""\11\11\11\11""\11"\11\11\11"\11\11\11\11\11\0\11\11\11"""""U33""3"UUD\88\883""""\1133Uª"\11"\11\11\11\11\11\11\11\11\11\11"""\11\11\11"""3""""333333""Dfwf3""\11""""3DDD3""""\11\11\11\11\11\11\11\11\11\11\11\0\11\0\11\11"U\11\11\11\11\11\0\11\11"""\11""\11""\11\11\11\11\11\0\0\0\11\0\0\0\11\11\11"3\113"\11\11\11\11\11\11"\11\11\11"\11\11"3\11\11\11\11\11"\11\11\11"""\11\11""\11""""""""3333333333DfUUffDD3DDDDUUw\99ª»»\99\88\88\88\993\1133"\11\11U\99\88\99\99w"\11\11"\11\11\11\11\11\11"\11\11\11\11\11\11""3""DDDfU"""\11\11\11\11\11\11\11""""""""3"333DDU\88\99\88wfU\88w\88D"3"""""""3"3"3""3"""""3UDDffffDU333"3"3333DD33333"3U3"3D3"\11"\11\11\11\11\11\11\11\11\11\11\11\11""\11\11"""""3\11""\11\11\11\11\11\11\11\11\11\11\11""3"3D33""3f\88\88\99\11\11\11\11\11\11"""\88»\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11"33""33333"333"3D"33""""3DUUDD3"\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11DD"""\11\11\11""\11\11""""\11\11\11"\11\11\11\0\0\11\11\0\0\0\0\11\0""\11\11"\11\11\11\11\11\11\11\11\11\11\11\11"""\11\11\11\11\11"\11\11\11\11\11"\11\11\11"""\11""""\11"""D""333333fDDDD33DDUUDDUf\88\88\99\99\88wff\88U\113UUDDDU\88\88\99ª\88U3\11\11"\11"\11\11\11\11\11\11\11\113"""\11"33D3U333\11\11\11\11\11""\11"""""""3""3"3DUf\88ªª\99U\88\88wwUD3""3333"33333"3"""""\11DDUDDUf\88fUDD333333D3333""U3"3""DU3\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""3\11""\11\11"\11\11\11\11\11\11\11"""""3"333"33wªf""""\11"""\11D\99Ìf\0\11\11\11\11\11\11\11\11\11\0\0\11"""""""""3"33DD33D3""\11""33D3"3DUffUD3"\11\11\11"\11\11\11\11\11"\11"\11\11\0\11\11\113""33""""""""33""3"\11\11\11\11\11\11\11\11\11\0\0\0\0\11\0\11\11\11\11\11\11\11"3\11"\11\11\11\11\11\11\11"\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11"\11\11""33"\11\11\11"""333333"DUD3333D3DDDDD3UUUffUfUf\88fUUUUDUDffUw\99\99wD3"\11"33\11\11"\11\11\11\11\11"\11""3D""DD3D\11\11\11\11\11"\11""\11""\11\11\11DD333"3DUwww\99\88ªwf\99wf333"33DDD33333333""""\11DDUDUUw\88\99wfDDDD3333"3DUUf\88D3DDUD""""""\11\11\11"\11\11\11"\11\11\11\11\11\11"\11"\11\11"DD3"\11\11\11\11\11\11\11\11\11""""33DD33D3Df\993\11\11\11D33"\11\113Uf\99f\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11""333DDUD3DD3"\11\11""DDD3DDfwwfUD33"""\11\11\11\11\11"\11\11\11\11\11\11""3"\11\11""""\11"3"3D3333D3""\11\11\11\11\11\11\11\11\0\11\0\11\11"\11\11\11\11"\11\11\11\11""\11\11\11\11\11\11"""\11\11\11""\11\11\11\11"\11\11\11"\11\11"\11"""\11\11\11\11"""U33"""DDD333333DD3D3DDD3DDfffffUfUDU3DDUffD3U\88\88wUUUfUD"DU"\11\11\11\11"\11\11\11"33""D"\11\11\11\11\11\11""\11\11"""\11""3D"3"3DUfffU\88ª\88Uw\8833D33333DDD33333"""""""""DDUUUUfwUfDDD33D33UUD3DDUUfUD"""\11"\11""\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11"U3""\11\11\11\11\11\11\11\11\11""333D3D"33UDUD333D3""\11\11"33wª"""\11\11\11\11\11\11\11\11\11\11\11\11\11\113"""3333DDfUDDD3""\11"33333fw\88ª\99wUDDD3""""\11\11\11"\11\11\11\11\11\11""3"\11"3""""""3""\11""""""\11\11\11\11\11\11\0\0\0\11"\11\0\11\11\11\11\11""\11""""\11\11\11\11\11\11\11\11"\11\11"""\11\11\11"\11\11\11""\11""\11""""\11""33"3"""""3D333333333333333DDUfUUDDD3UDDDDUUfDD3Dww\99wUUUUUDD"U3""\11\11\11\11\11""33""3"\11\11\11\11\11\11\11\11\11\11"\11\11"""33""DUUUwff\99»ªw\88\99"\11""3D3"DUUDD33333"33"""\11""3DDDfw\88UUUfwwffDUfU3333D3"\11\11\11""\11\11\11\11"\11\11"""""\11\11"\11\11\11""\11\11\11"3"\11""\11\11\11\11\11\11"\11"""333"\11"33wD3DDDDD3"""\11"33w»\88\11""\11\11\11\11\11\11\11\11\11\11\11"""33"""33D3UfUDU33"""333DDf\88\99\99ªªfUDfU33""\11\11\11\11\11\11"\11\11\11""""\11"3""""""""\11\11"""\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11"""""\11\11\11\11\11"3\11\11\11\11\11""\11\11"\11\11\11""\11""\11"\11\11\11\11\11""""\11\11"""""3333"333333333333UUUDDUUDD3D333DDDUU3DUwUUUDDDUUUDfD33\11\11\11\11"\11""3DD"3""\11\11\11\11\11"""""\11\11\11\11\11"33DDUfUffUDª»w\88\88w"3""3333DDUUDD333"3"""""""""333\88ª\99ª\99wwfUDD33333333"\11"\11""\11\11\11\11"""""""\11\11""\11\11\11\11\11\11\11"\11\11\11""""\11\11\11\11\11\11\11\11"3""3333"DDf\88"\11DU"""3"""""33wf"\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"33333"ffUUUD3"""3"DDfDDfwª\99UDDfUD3""\11\11\11\11\11\11\11\11\11\11"""""""333""""\11\11\11\11\11"""\11\11"\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11""""\11\11\11\11\11\11"\11\11\11\11\11""\11\11"\11\11"""\11\11\11"""\11"\11"3D\11""\11\11\11""3D""""3333333333DUUD3DDUUD3333"3DDDUDD33UUDD3DDUDDUDf3D33\11\11\11\11\11"3DD3DU\11\11\11\11\11\11""\11\11"\11\11\11\11\11\11"3DUUDUUUf\88\88ªª\99\99\99U""""3DDDDffUDD33D33DD3DDUfff\88\88wfUUDDUfDD33"""""""\11"\11\11"""\11\11\11"""3"\11"\11\11""\11\11\11\11\11\11"\11\11\11\11\11"\11\11\11\11\11\11"""""""3"""3"3Df\993\11"UD3U33"\11"""3UDf""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"33333"D\88fffDD"\11\11\113fUD""\11"Uw\99DDUww3333"\11\11\11"\11\11\11\11"""""3333"""3"\11\11\11""""\11\11\11\11\11\11\11\11\11\11""\11\0\11\11"""""\11""\113\11\11\11\11\11\11"\11\11\11\11\11\11\11""""\11\11""""\11\11\11"3DU3\11\11\11\11\11\11"\11""3D3""3""33"""3DUfU333DUUD3333D"333DD3333DUD33DDDDDUUUUUU3"\11\11\11\11"3333UD"\11"\11\11\11"\11\11\11""\11\11\11\11"""3DfUfUD33\88ªª»»\99D"33"""""DDUUUUDDffUUUUUUUfffwfU33D3DDD3333"""\11"\11\11\11"""""\11\11\11""""D"""\11\11"\11\11\11"\11\11"DD"\11\11\11\11\11\11\11\11\11\11\11\11"D"""""\11"33DDU\88\99DD\88\88wD"3"\11""""D\88\88U"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"333""33UffwfU3""""UU"\11\11""33D\99fUffwfU3"""3\11\11\11\11\11""33""3"D3"3""""\11\11\11\11\11\11\11\11""\11"\11\11\11""\11\11\11\11"""33"\11\11"\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"\11\11\11\11"""\11\11"3U3"\11\11\11\11\11\11\11\11\11""33""33"33""3UfUUD333DDDDD3333""333DD33"33DDDD33DDDDDUUUfD"\11\11\11\11""33DDD"\11\11""""\11\11"\11\11\11\11\11"3333ffwwffDDw»»ªw3""3"""333DUfDUfwwU3D333""333DDDD33UD3"""""\11\11\11\11\11\11\11\11\11\11\11"\11"\11"""""3"\11"\11\11\11\11\11\11"""3D"""3""\11\11\11""\11"""\11\11\11\11\11\11"DfU3DUwª\99w\99ªw3"\11\11\11\11""""U\99D\11\11\11"""\11\11\11\11\11\11\11\11\11\11\11"\1133"""33DDDDwfD"""DD"\11\11"""""DDwwUwDDfU33"3\11"\11""""33"""3"3"3""\11\11\11\11\11\11\11\11\11\11\11"""\11\11\1133""\11"""\11"3""\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11""\11\11\11\11"\11""33"\11"\11\11\11"\11\11\11"""""3""3"""333DUwfU3DDD3DDDDD"333333"333333D3DDUD333DDDDD3DUwU"\11\11\11\11\11"D3"3D3""3"""\11"\11\11\11""\11""333fwfUDUwwªª\99\99D""""""""3"DwwwfwfUD33333""""33333333D""""""3"""\11\11\11\11"\11\11\11"\11\11""""""""3"\11\11\11\11\11""3""\11\11\11\11\11\11\11\11\11\11\11"\11"\11\11\11\11"\11\11\113""3DD\88\99w\99ªªf""\11\11"""""3U\88"\11\11"\11"\11""""\11\11\11\11\11\11""33"""333DUUf\88UD33""\11\11"""""""33wfUwUUfD333333""33"33""""""""""\11\11\11\11""\11\11\11\11"\11"\11""""3D3""""""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11"\11"\11""333"\11"\11\11\11\11"\11""""3"""3"""33"3DwfUD333D3DDDDDD3"33"3"""""33DD3UfU333333DD3DUDDUU3\11\11\11\11\11333""DDD"D3""""\11\11\11"""""""DwUD3DUf\88\88\99ª\883""\11""""""Uw\99\88fUDDDDD3333333333333333""""""333"\11\11\11\11\11\11\11\11""\11""""\11"3"""\11\11\11\11""""""\11\11\11\11\11\11\11\11\11\11\11\11"""""""\11\11\11""""3Dw\88\99\88ª\99w3D3\11"3"""33\88f\11\11\11\11"""""3\11\11\11\11\11\11"\11""""""DDUffUUwU3D3"""\11\11"\11\11""3""w\99\88\88\88wfUDDDDUDD3"""3""""""\11\11\11\11\11\11\11\11\11"\11\11\11\11\11"\11\11""3""3D""\11"""\11"\11\11\11\11\11\0\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11"\11"""3"\11\11"\11\11\11\11"\11"3"\11""""33"""""3UffDDD33D33DDDDUD3"3"""333""""333"wf3""""3333DUDDDDD3\11\11\11\11\11"33"33DDD33"""\11\11\11\11""\11"\11"3UfDD3UUfff\99\88D""\11"\11""\11"UU\99ªwUUU33DD3DDD3333""""""3"3"""\11""3"\11\11\11\11"\11\11"\11"\11\11""""\11"""""\11"\11\113"""""""\11\11\11\11\113\11\11\11""""""\11\11"\11\11""""3Dfwª\99fwD\11\11""""""33U\99"\11\11\11\11""""\11"3\11\11\11\11\11\11""""33DDUfwf\88wwUDDD""\11"\11\11""""""33f\99\99\99\99wwwwDUU3UDU333"\11"D\11\11\11\11\11\11\0\0\11\11\1133\11\11\11"\11"3""""""33"\11\11\11\11\11"""\11\11\11\11\11\11"\11""\11\11\11\11\11"\11\11\11\11\1133D"\11\11\11\11\11\11\11\11\11\11\11"\11\11"""333""""3UwU3"DD3DD3D33DDUD3333""""3"""""""33D"3""333333D3DDDDDUU3\11\11"3"DD3"33U3D""\11"\11\11"\11\11\11\11""3UDU33DUUU\88\99D3"""\11\11\11\113D"Dª\88\88\88fD333D3D33"3D""""""3"""\11"\11\11"33\11\11\11\11\11\11\11\11\11"\11\11""""""""""\11\11\11"""""""\11\11\11\11\11\11\11\11""\11\11""""\11\11\11\11\11"""""\11"Df\88w"""\11""D\11\11""""D\99wD\11\11\11""\11\11\11""33\11\11\11"\1133"3DDUUfwUDfwwfU3D"""""\11"""3333DUf\88ª\99\99\99\99\88\88\88UDwwfD"3""""\11\11"\11\11\0\11\11\11"3D"\11"""\11\11""""""""\11\11\11\11\11\11"\11\11\113\11\11\113""\11\11\11\11"""""""""3D"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""333333Uwf33"3DDD3DUD33UD33""3"33"3""3""""3333D333333333D33333DfDDD3"DDfU"""3UUD"""\11\11\11\11\11\11\11""3D333""3Uw\99wUD""\11\11\11"DUD"3UwfffUDDDDD33D33"""""""D3""\11\11\11""""\11"""\11\11\11\11\11"\11""\11\11""\11\11\113"\11\11\11"""""""3"\11\11\11\11\11\11\11\11\11\11\11\11""\11""""""""""333w\88""\11"U3"""\11""""f\99""\11\11\11""\11"Uf"\11"\11"""3\883"3"DfwU3\11UwwwfUDD33""""""DD33DUfDU\88\88ª\99ª\99\99wUwwD33""""\11\11\11""\11\11\11\0\0\11""\11\11\11\113"""3""""""\11\11\11\11\11""""""""\11"3"\11"\11\11\11"3""\11D3""\11\11\0\11\11""\11\11\11\11""\11\11""\113""""DDDfwU33"33DDD333UDDU3""3333333"""33"""""3D33333333333333"""3wUDDD3D3"""""DUDff3""\11\11\11\11"""3333""\11\113U\88\99wD3"""DUUUDDDDDDDDDD33"3"333"""""""333""\11"\11\11""\11"\113\11\11"\11""\11\11\11"\11\11\11\11\11\11\11"3""\11\11\11""""\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""333D33Dww"""\11D3""""""""DfD\0\11\11\11\11\11""Uf"\11\11"\11""3\88U"3"3UwU"\11"Uw\88\88fUUDDDD333"DD33D3DUUUU\88\88\99ª\88wwww3"33""""\11\11\11\11\11\11\11\11\11\11"3\11"""""""""""""\11\11\11\11""""3""""""""""\11\11\11\11"\11\11""D"\11\11"\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11"D3333DUfwU"33""3DD3333DDDD3D3"""333""""3"3""""3DD3333"3333333"""""3UD"3UD""""""33DUwwD3""3"""333"""""\11\113D\88»w333DUUUD333333333"""3""333"""""""""""3"\11\11\11\11\11\11\11\11\11"\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""""3""\11\11\11\11\11\11\11"\11\11\11\11\11\11""\11"\11\11""""3D3"33DDfU"\11"""""""""""333fD\0"\11"""""""\11\11\11\11""U\99D"333ffD3"""Ufw\88\88wfUUDUUDDDDD3DDUDDUUUf\88\99\88\88fffUUD3"""""\11\11\11\11\11\11\11\11\11\11\11\11"33""3""\11""""""""3"\113"\11""""\11"3"""""\11\11""333\11\11\11""\11"\11"\11\11"\11\11\11\11\11\11\11\11\11\11"33DwwUD"33D333DDD33DDDD3""""""3333""33"3"""""33"3""3"3333"3""""\11"\11\11"""333"""""3DDf\99U3"""""""33""""\11\11""3U\88ªfDDDD3D3"""""3""""""""""3"""""""""3"""""\11\11\11"\11\11\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""""D3"\11\11\11\11\11\11"\11"\11\11\11\11\11\11\11\11\11\11""""\11"33333DU\993\11\11"\11\11\11\11""""""""D3wf\0\11\11"""""\11\11\11\11\11""U\99D33""fw3U3\11\11""DDUUw\88fU3UUDDDD33DUfUDfDf\88\88wffwfwUD3""""\11\11\11\11\11\0\11\11\11\0\11\11\11"""""""""\11\11"3"\11"""""3"3U3\11""\11"""3""\11\11\113D3""\11\11\11\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11"3UwwD"333"33D33D3D3DUD33"""3333333""D"3"""""""""3"333"33"""""""""""""333"""""333DfUUD3"""33333"""""""3DUwwUD"33DD33""""33333333""""""3"""\11"\11\11"""""""\11\11\11\11""UU\11\11\11\11\11\11"\11\11\11\11\11\11\11\11"33""""\11\11"\11\11\11\11\11"\11""\11\11\11\11\11\11\11\11""""""\11""3333U\88D"""\11\11\11""\11\11"""""3"Uw\883\11\11\11\11\11\11""\11\11\11""UªUDU3"DfD"\11""""""\11"3DUfffDDUfUUDDUUf"UffwwwwwwwfD3"3"\11\11\11\11\11\11\11\0\11\11\11\0\11\11""\11"3"""""""""3D"""3""3D3U\11"3""3333"""3U3"\11"\11"\11\11"\11\11\11""""\11\11\11\11\11\11\11\11\11""DfwU333333333333D3DDD""""3"""33""3""DD"""33""33""33"""33"""""""""""3""333""""33"3DfUD33"3DD"""""333""33DfwwDDD33D33333333UUDUUU333"3333""\11\11\11\11"""3"""""\11\11""Dwf""\11\11\11\11\11\11"\11\11"""333"""\11\11""\11"\11\11\11\11\113DD"\11"\11\11""3\11\11"""\11""""DDD\88U333\11\11\11\11\11\11\11"""""333U\99\993\11\11\11\11\11\11\11\11\11\11\11"fªwUU33DfU"\11"""\11\11"""3""3fwwwDUUUDDUffffUfwwfwfUUDD3""\11\11"""\11\11\11\0\11\11\11\0\0""\11\11"3"\11\11"""\11"""3"""3DDUUDDD""3""3"3""3DD"\11\11\11""\11"""""\11\11\11\11""\11\11\11\11\11"""Dww3333333333333333DUD""""33""""""33""D3""""""333"33"33"""3"""\11"""\11""""""""""""3333DU3"UDDU333""33333D33DDUfffUf"3DDDDDDDDDUffUwUUDDDU3D3"""""""333"""""""""DD"""\11""\11\11""""33""3\11"\11\11\11\11""\11\11\11\11""\11\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"3DUfU3D3"\11\11\11\11\11""""\11""33U\99ªf\0\11\11\11\11\11"\11\11\11\11\11w\88wwfDfDfU"\11\11\11"""\11""""""\11DUUfDUUDUUfwff\88fwfDD3DDDD3""\11\11"""\11\0\11\11\11\11\11\0\11\11""""3""\11"""""\11""3\113DDD33DD33""3\11""""3D33""\11""""\11"\11"\11\11\11\11\11\11"""\11\11"""3UwU3333"3333333333DDDD"""""""""""33333""""""""""3"\113"33"33""""""""""""33"3"""""33D33DUfUw\88\88DD3"""3333DDDD3DDUUfUUDDUUUDUUfDUUfwwUUfDUUDD"D3""D3333""3""3"""""""""""""3"\11\11\11\11"\11\11\113"\113"\11""\11\11\11\11\11""\11"""""\11\11\11\11\11\11\11\11\11\11\11\11""33DUf333""""\11\11\11\11\11\11\11\11"3"3U\99w\11"\11\11\11\11\11\11\11\11\11"wfDwwwf3Df""\11\11\11"""\11"""""\11\11"3ffUUUUff\88wwUDwU33"3DDD3""""3"\11\11\11\11\11\11\11\11\11\11\11""""3""""33"""333""33"""""DUD""D""""3D"\11\11"""\11""\11""\11""\11\11\11\11\11\11\11"""""Dff\1133""3"333333333DDUD""""33""""333""""""""""3""""""3"""3""""""\11\11\11"""33333""""D33333DDDUUfwU""3333DD3333"33DD3DUUUUUfffwwfwDfUwwfU3"3fffDUUD3DDD3U333"333"33"\11"""""\11\11"\11\11\11\11\11\11""\11"\11\11"""""\11"\11\11"""""""""\11\11\11""\11\11""\11\11\11"""33UfU"""""3\11"\11\11\11\11"""""33\88\99"\11"\11\11\11\11\11\11\11\113fD"DDUw\88UUU"\11""\11""""3"""\11"\11"UUffDUDUwfffUUD"D333D33""""""\11\11\11\11\11\11\11\11\11\11\11""3"D3"""""3""3"\113"3"\11""\11\11333U3"D""3D3\11\11""""""""""\11\11\11\11\11\11\11\11\11"\11"""3UU3"""""3"33333"""3DDD3"3""""3""""""""""3"""3""""3333""""""""\11""\11\11\11\11\11"333D33"3DDD33"""33DDDDU3"3DD33333"""33DUUD3DfffUUf\88\88UUw3DUffD\11\11\11UwwfUUUfUUDDDfUDDDD33DU3\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11"""3""""\113""3"""\11"""\11\11\11\11\11\11""""""""33DUw"""""""\11"\11\11\11\11"\11""""3\88f\11\11\11\11\11\11\11\11\11\113\99D3DD""3Uff""""\11\11\11"\11\11\11""""""3DffUfwfffUffDD"33"3D33"""""\11\11\0\11\0\11\11\11\11\11\11\11""""333\11""""""""""3""\11\11"\11\11"""\11"D3D"3D"\11\11\11""\11\11\11\11""\11\11\11\11\11\11\11\11\11"\11\11"""fU3\11"3"""""""33"3"3"3DD3\11""""3"\11"""""""""""""""""33333""""""3""""\11\11\11\11""""DDD33D333""""3U"""""3D""3D33333""\11\11"3DUUD3DUfwfUwwfU3UDDUffD\11""wwwUUUfwwDDD3DUDDDDDDD""\11\11\11\11\11\11\11\11\11\11\11\11\11""""3\11\11""D"""""""""""""""""""\11\11\11"3"\11"""3"3Ufw"""""""\11\11"\11\11\11"""""3DD\88D""\11\11\11\11\11\11\113\88DUfD"\11\113\99\883"3""D\11\11"\11"""\11\11"\11\11\113fwUUwUUU3UU3""D"3333""\11\11\11\11\0\11\11\11\11\11\11\11"\11""""""D3""333""\11\11"3"3"\11\11""\11\11"D""""33D3\11""\11"\11"""\11\11""\11\11\11\11\11"\11"\11""""3fD"\11"""""""""3""33333U3\11"""\11"3""""""""""""""""""3D3""3"3""\11\11\11\11""""\11"\11\11\11\11\11"""3DDDD3""3D3DD"\11\11"""3"33"33"3""""""3DDD3"DUUfwwwUDD"3DDUfU""""3Uffww\88\88\88fDDUUDDUDUD"\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""D""""3""3""""""""""""""""\11\11\11""\11\11\11"""""DU\88D"""3"""\11\11\11\11\11\11\11"\11\11"3UD\99""\11\11\11\11\11\11\0DwD3D3\11"\03wwD333"3\11\11\11""""\11\11\11"\11\11\11DffUUU"3D3""""33"33""""\11\11\0\0\11\11\11\11\11""\11\11""""\11"DfD33D3"""""3""""\11\11"3"\11"fD3DDUD"3"""\11\11"33""\11"\11\11""""\11\11""""3UU\11\11""\11\11"""\11"""3"33333U3\11"\11\11""3"""""""""""""333333D3333D33""\11\11""\11\11\11\11"\11\11\11\11\11"""""3DDD333D33""\11\11"""""""""33\113""\11\11"""33DDDUfw\88ªfD3"""\11\11""33"\11\11\11"\11"ww\88\99ª\99wDDUUUUUfD"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""3""""3"""""""""\11""""3""\11\11\11\11\11\11\11\11""""3""3D\88D""""UU"\11""\11\11\11\11\11\11\11""DUUf\11\11\11\11\11\11\11"f\8833U3""\11"U33""3D""\11""\11\11\11\11\11\11\11\11\11"DwfffD""""""""33"""3"\11\11\11\11\11\11\11\11\11\11\11"""""""""3UUw3"""3"3"""""""\11\11"3"\11"Dfw\88D"\11\11\11""\11\11\11\11\11"33\11\11\11\11\11\11"""""""3Dw"\11\11"\11\11\11""""3U""""3333U3\11\11\11""\11""""""""""3D333333"3""333333""\11\11"""""\11\11"\11\0\11\11\11"\11"""""DfDD333"3\11\11"""""""""3"\11""""\11"""3DD3DUUU\88wU""""\11\11\11\11\11\11""\11\11"\11"""f\88\88ª\99\88ffwfUUfD"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""3"3D3333""3"""""3"D3"""\11\11"\11\11\11\11\113"\11"""3"U\88f""\11"\11\11"\11\11\11\11"\11\11"\11\11""33ff""\11\11\11\11\113\99ª3"D"\11\11""U3"""""D"\11\11\11\11\11\11\11\11\11\11\11""UwUUwU"\11\11\11"3""33\11""3"\11\11\11\11\11"\11\11\11\11\11\113""\11""""\11"3UD\113DD3""""\11\11\113"\11"""3UwffD\11\11\11\11\11\11\11\11\11""\11""""\11\11\11\11""\11"""""3Uf\11\11\11"\11\11\11""""3"\11""""33DD3""""""""""\11"\11"""3"""33""""3"3333""3"""""\11\11"\11\11\11""""\11"\11\11"""""3333333"\11\11\11\11333"D3""""\11\11""""""3DD3UfUDfw"DD"""\11"DDDD""\11\11"""3DUUw\88fwffwwf"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""""33D3D33D3"333""33""D""""\11"\11\11\11\11\11\11\11"\11""""DwD"""\11\11"\11\11\11\11\11\11\11\11\11\11\11\11""DUff\11"\11\11\11\11fªwDDD\11"""\11DD""\11\11\11"""\113"\11\11\11"\11\11\11"\113fwwwU\11\11\11\11\11\11"""3\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11""""""""""33D3DU33""\11\11\11"33"""3DDUD"\0\0\0\11\11\11\11\11\11\11""\11"\11\11\11\11"\11\11\11\11\11\11""""3DUD\11\11\11\11\11\11"""""""""""33DU3"""\11\11""3"3""\11\11""3""""""3""\11"3333""3"\11""""\11\11\11\11\11\11""""\11\11"\11""33"""""D3"\11\11"\11\11"DDDUU3""\11"\11\11"""""DDDUfwfwfwU"D""""D\88f3DU3\11"\11\11""D33f\88wU3"\11"3"\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11"""3DU3DD33"3D3333333""33"3"""\11\11\11"\11\11\11""""3DU3\113""\11"\11\11\11\11\11\11\11\11\11\11\11"""3UU\88DUD33DwªU3D3\11"""""3"""\11"\11"\11"3""\11\11\11"\11""\11\11Uwwwf""\11\11\11\11\11"\11\11\11\11\11""\11\113\0\11\11\11\11\11\11\0\11\11\11""""""""""D3"D""3""""\11""""DDD""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11"3DfD"\11\11\11""\11"3""\11"""3""""DU"\11""\11\11\11""D""""""3"""\11"""3""""D3333"D""""""\11\11\11\11\11\11"""""\11\11\11\11""""3"\11"3"""\11\11\11"\113UUDD"""\11\11\11\11\11\11"3Dw\88\88\99\99\99wUwwwD"D3"3UfDD"\113D"\11"3"\11\11"fwwf3"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11""""DD333"3D333""""3"3333333""""\11\11\11\11\11\11""""3ff""\11"""\11\11\11\11\11\11"\11\11\11"\11""""3w\88U33UU\99\99DD3\11\11\11""""""3"""\11\11\11""\11\11""""""""\113ww\88U\11DU"\11\11"\11"\11\11\11\11\11\11"\11"\11\11\11\11\11\11\11\11\11\11\11""""\11"""""33\11"3""""\11""""33D"\11\11\11\11""\11""""\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11"""3DUD\11\11\11\11\11"\11"33"\11\11\11"""3"3"3D\11"""\11\11"""3D"""""3"""""""D""""3""33333"""\11\11\11\11\11\11\11\11\11"\11\11"\11\11\11"\11"""""\11""3"""\11\11"""DUU33D""\11\11""""3UªwU"UffUUwww""3UUU3"""""3U\11""""""DwfUD""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11""""DDD33"3333"""333333333"""""\11\11\11\11\11\11"\11"""DUUU"""\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11""33ªDDffU\88\99D33\11\11""\11""""""\11"""\11"\11\11\11\11"""33""\11"Uww3"w\88U\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""""""""""\11"3"3"""333D3\11\0\11\11\11\11""""\11"\11"\11"\11\11\0\0\11\11\11\11\11\11\11\11"\11""33DUU\11\0\11\11\11"\11\1133"""""""""33333"\11\11\11\11\11\11""""D33\11"3"""3""\11"\11""""3""333"3""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""3"\11\11\11""""""\11\11\11\11"""3Uf3D"\11\11\11""33Dw\88w3"DUDDUf\99f""U\88f"\11\11\11"\11\11UD"3""""3UfUD3""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""333DD3""3D3""3333"33"333"""3""\11\11\11\11\11""\11"3UU3D3\11\11"\11\11\11\11\11\11\11\11"\11\11\0\11\11"DDUffU3DDDf»D3""\11\11\11\11""""""\11"\11""""\11\11\11""3333""\113U33\11D\99w"\11\11\11\11"\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\113"33""""""3""\11"""""33DUD\11\0\0\11\11\11\11\11\11""\11""""""\11\11\11\0\11\0\0\11\11\11\11\11"\11"3Uf3"\11\11\11\11\11\11\113333"""\11""""""3DD"\11""""\11""""333""3"""""""3"\11""\1133""33""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11"\11\11\11\11\11"""""""\11\11""""DD\11"\11\11\11""33Dfw3"33DwDUUUU3"3\88w"\11"\11""""U3""\11\11"3UfUD""""""\11\11\11\11\11\11\11\11\11\11\11\11\11"\11""""3333""D33"33""33"""3"33""3"3"3"\11\11"\11\11"""""DD3333\11\11\11\11\11\11\11\11\0\11\11\11"33"DUDDD\883"333DªU"\11\11\11\11""\11"\113""""""""\11\11"""3DD""""""D33"3\88\883\11"\11\11\11\11\11""\11\11\0\0\11\11""\11\11\11\11\11\11""33D3"""""""3"\11""33DDDD"\11\0\11\11\11\11\11\11\11\11"""""""""\11\11\11\0\0\0\11\11\11\11\11\11\11"3UfD\11\11\11\11\11\11\11\11"33\11"""""""""""3D3"""\11\11\11\11\11""3333\11""""""\11"33"\11""""""3"""""""""33\11\11\11\11\11\11\11\11\11\11"""\11\11\11"\11\11\11\11\11\11\11\11"33"""""""\11"\11""""""DUf\88f""3""DD3""\11"DfwD""\11\11\11""33"\11\11\11""UwU33""\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11"3"3"""3DDD"""""3333333"3"""3333"""\11\11\11\11\11""""3Uf""333"\11\11\11\11\11\11\11\11""3UfUD3"33ww""3"3\99U\11\11\11\11\11\11\11\11"\11"""""""""""""""DfU3"3""3"\113w\88\88D"""\11\11\11\11\11\11\11\11\11\0\0\11\0\11\11\11\11\11\11\11\11""3D3\11""""""3""3"3DDUU3"\11\0\0\11\11\0\11\11\11\11"""33""""""\11\11\0\0\0\11\11\11\11\11"DfD3\11\11\11\11\11\11\11\11"33"\11""\11"\11"""""33D"\11\11""\11""\11""33"""""""""""""""""""3""""""3"""\11""\11\11\0\11"\11\11\11\11\11\11\11\11\11\11\11\03\11\11\11\11\11\11\11\11""D""""D"""""""\11\11"DUww\883"""3"""\11\11""f\99U3""""\11""""\11\11\11\11\11"Dw\883""\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11""""33"3DUfD3""33"3333333"""3"3""""\11\11\11\11\11\11"\11\11""UU3"""""3\11\11"\11\11"3DDDDDD33""3w\99""3"3\88U\0\11\11\11\11\11\11""\11"""""""""""""3"DUUU3""""""UUfU"\11""\113"\11\11\11\11\11\11\0\0\11\11"\11\11\11\11\11\11\11\11"3UD"""""3"3D"333DUU3\11"\11\11\11\0\0\11\0\11\11"""3DD33"""""\11\11\11\11\11\11\11\11\11"3fU\11\11\11\11\11\11\11\11\11D3\11"\11"\11\11\11\11"\11"""""D3\11\11\11"\11"""\11\11""""""""""""3""\11"""""3""""3"3"""\11\11\11\11\11\113D"\11\11\11\11\11\11\0\11\11\11\11\11""\11\11\11\11\11\11\11"3333"D\11"\11\11""\11\11"3DUDf\99w""""333""\11"3D333"""\11""3"\11\11\11\11\11"Df\88U""\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11"""""3333DDDD3"3"3"3D33333""33D33"3""\11\11"""\11\11\11""Df33"\11\11\113wwDU3D33D33D""""333\993"33Dff\0\11\11""\11\11"""\11"D""33"""""""3DD""""""3Ufw\88f\11\11""""Df"\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11"3UwU"3"""""3"3"Dff3\11\11\11\0\11\0\0\0\11\0\11\11"""333"333""3"""\11\11\11\0\0\11\113f"\11\11\11"\11\11"\11"D"\11"\11"\11\11\11\11\11"""3"33\11\11\11\11""""\11\11""""""""""""3"""""\11""""""3"3"""""""\11\11\11"3fD\11\11\11\11\11\11\11\11\11\11"\11\11""\11\0\11\11\11\11\11"33D33"""\11""\11"3"3DDwwwD"""\11""3""""""33"""""\11"3"\11\11\11""33wU""\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"""33DD33DD""33""33333333"3"""33333"""\11"\11\11\11""DU3"\11\11""\11"33"D33D333""3"""33Df"3DDUf\0\11D\11""\11\11\11\11\11\11"""\11"""\11"""3"33"3""33UfwfDU\11""""""fD\11\0\11\11\11\11\11\11\11\11\11""""""\11""DUD3U3"3Uwf\88UUwwU3"\11\11\0\11\0\11\11\11\0\11\11\11""3333"33DD33"\11\11\11\0\11\0\11\113D\11\11\11\11\11\11\11"333"\11\11\11\11\11\11\11\11"""333UUD""\11\11"""\11\11""""""""""\11"""\11""""\11""""""3"3""33""""\11\11"3D3\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"3D333"""""33""333U\88U3\11\11"\11""\11"""""\11"3""3"""\1133"\11\11\11\11""UU3"\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11"\11"33""DDDDDD3"""""3""3DD33"3""3D3333"""\11""\11\11\11"DU"\11\11\11\11""""3"""33D33"""""\113D3Df33DDU\11\0"3"\11\11\11\11\11\11"""\11"\11"D3"""33333"""33U33D"\11\113"\11\11\11"3D\0\11\0\11\11\11\11\0\11\11"\1133""""""DDDDUfDUfw\88\99\88wDDDD3\11\0\11\11\11\11\0\11\0\0\0\11\11\11""""33"3UU3"\11\11\11\0\0\0\11\1133\11\11\11\11\11"\113D3"\11\11\11\11\11\11\11\11\11\11"""33DD""\11\11\11"""""""""""""\11\11"\11""\11""""""""\11\11"3"33""3""""""""3""\11\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"3D3"33""""3""333DwwD""\11\11""\11\11""""\11"3333"""""""\11\11"\11\11"3U3""\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""33""D3"333D""""""""333"""3"D3DD333"""\11"""\11""33\11"""""""""""3333""""\11\11""333"Uª"33D\0\11\11D\11\11\11\11\11\11\11""""""33DD33"33"""3"3""""""""""\11\11""\11\11\11\11\11\11\11"\11\11\11\11\11""33""""3D333DUUDfw\99\88Dff""33"\11\11\11\11\11\11\11\11\11\11\11\11\11\11"333333D3""\11\11\11\0\11\11\11"D"\11\11\11\11""DU3"\11"\11"\11\11\11\11\11\11""""33D33""\11\11""""""""""""\11""""""""""""""\113"3"3""""3"""""""\11"33"""""\11\11\11\11\11\11\11""\11\11\11\11\11\11\11""3DD3"3""333""333DU\88U3\11"\11\11\11\11\11\11\11\11"\11\11"3U33""""\11\11"""\11\11"3UD3""\11\11\11\11\11\11\11\11\11\11\11\11\11""""333333333"3DD""""""""D333DDD3DDDD33""""""""33D"\11"""\11"\11""""""D3"3""\11"""""DD33»\88"3D\11\11\1133\11\11\11\11\11\11"3"""33DDD3"333"""""""""""""\11\11""""""\11\11\11\11\11\11\11""\11\11\11""3D3""""333DDUfffwf3"DD33333\11\0\11\11\11\11"\11\11\11\11\0\11\11\11"3""33333D3""\11"""3D"\0\11\11"DDD3""""\11\11\11\11\11\11\11\11"""3"33D3"\11\11"3""""""""""""""""\11"""\113"""3"3"\1133"""""""\11\11\11\11\11\11\11""3""3""\11\11\11\11\11\11\11"""\11\11\11\11\11""33DD33"""33"""3DDUwf3"\11\11\11\11\11\11\11"""\11\11\11"3D"33""\11\11"""\11\11\11\11UU3""\11\11\11\11\11\11"\11\11\11""""""""""33D33333DD""""""33333DDDDD333""""""""""\11"3D"\11\11"\11""""""\11\11"""""""3D""""3""3\88ªDDf\11\11\0\11"\11\11""\11"\11"""""3"DD3""3"""""""""333"""\11""33\11\11\11\11\11\11\11\11\11\11""\11"""""""""""3DDDDUUwf3"""""33""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11333333""""""""333D\11\11"D33""""""\11\11\11\11"\11\11\11\11\11""333DDD3\11\11\11""""""33""""\11"\11\11""\11\11\11\11"3"\1133"""""""3"""\11\11\11\11\11\11\11"\11\11"3\11\11\11"""""\11\11\11\11\11\11\11\0\11\11"\11\11"33UD3""3333""3DDUf\88f"\11\11\11\11\11\11\11\11"\11\11\11\11\11"3D33"\11\11\11""\11\11\11\11"DDD""\11\11\11\11\11\11"\11\11\11\11\11""""D333"33DD33""DD"""""333DDD3D3DD33""""3"3"""""3D\11\11\11"\11""\11\11\11\11\11"\11""\11"\11""3U"""D33"w\99\883w"\0\11\11\11\11\11"""""""""\11""3""""""""""""333""3"\11\11\11"\11\11\11\11\11\11\11\11\11\11\113"3"\11\11""""3"D""3DD3DDUff""""\11"""3\11\11\11\11\0\11\11\11\11\11\11\11\11\0\11\11""333"""""""""""3DD"DD3"\11\11"33""\11\11\11"\11\11"\11\11\11"\11""33DDD"\11"""\11"\11"3"""""""""D""""\11""""33"""""\11""""\11"\11\11\11\11\11\11\11"\11\11"\11\11\11""\11\11""\11\11\11\11\11\11\11\11\11\11"\11"D3DDD333333333DDfwwf3""\11\11\11\11\11\11\11\11\11\11\11\11\11"DD3"""\11\11\11\11\11\11"\113UD"""\11\11\11\11""\11\11"""""""""3""""""""\11"333""""3"3DUUDD3DDDDD3""3"""33333D"\11\11\11\11"\11\11\11\11\11\11"""""\11\11"\11\1133"3D3U\88fwffU\11\11\11\11\11\11\11\11"\11"\11\11\11"3\11""333"""""""""""3"""33"\11\11\11\11\11"\11\0\11"\11\11""""3D"\11\11"333"DD33UD3DUfU3\11"""""3"""\11\11\11"""\11\11\11\11\11\11\11\11\11""\11"""""""""""""3DffDD\11\11""""""\11"\11""\11\11\11\11\11\11\11\11"33"DDDD\11\11"""\11""\11\11""""\11\11\11""3"""""3"""""""3""""\11\11\11\11""\11\11\11\11\11"\11"\11"\11\11\11""\11"\11\11\11\11\11\11\0\11\11\11\11\11\11""DDD33333"333DDDDw\99f""""\11\11\11\11\11\11\11\11\11\11\11\11\1133D""\11\11\11\11\11\11\11"""3D""\11\11\11\11\11""\11\11\11\11""""""3"""""\11"""\11\11"""3""""""DUD3""3D33D333"33""3333D"\11"\11\11\11\11\11\11"""\11\11"\11\11"\11"""D"3DDUf\88\88"D\88f\0\11""\11\11\11\11"\113""""33"3"""""3"33""""""""""""\11\11\11\11\11\11\11\11\11"""""""3U"\11"""333"D3DU33DUfD"\11"\11"""""\11"\11""\11""\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11"\11"""3Dw\88D"3"""""3""""\11"""\11\11\11\11\113"333DDDD\11\11""\11"\11""\11""""\11\11\11""\11"""""""""""\11""33""""\11\11\11"\11"\11\11\11\11\11"33"\11\11\11""""\11\11\11"\11\11\11\11\11\11""""DDD3333333"3DDDDf\993\11"\11\11\11\11\11\11\11\11\0\0\11\11\11\11\11"33D"\11\11\11\11\11\11\11""""D""\11\11\11\11DD"\11\11\11"""""""""""""\11\11\11\11\11\11\11""""3""""DU3"""3333333""3333D3DD""\11\11\11\11\11\11\11\11\11\11\11\11"\11"""""3"DD3UDDf\88fDDww33""\11\11\11\11\11\11\0\11"3""333""""""""\11"""\11"""""""\11"\11\11\11\11\11\11\11\11\11\11""""33DD\11"33"3""3"UUD3Dff333"\11"""""3"\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11"3"\11\11\11"\11\11"""DD\88\883"""""""3"""""3"""""\11"\1133"33DDU3\11""\11\11\11""\11""\11"""\11"\11"""3"""""3\11\11\11"33"3"""\11\11\11"\11"\11\11\11\11\11\11\11\11"""\11""\11"\11\11\11\11\11\0\11\11\11"\11"""33DDD333""333DDDD\88f\11""\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11"333"\11\11\11\11\11\11\11"""33""\11\11\11\1133"\11\11\11"""""""""""""\11\11\11\11\11\11\11"""""3333"3""33""3333D333D3"333"""\11"\11\11"\11\11\11\11\11\11\11\11\11\11""""3fDDDDUUw\88fw\99\88"DD""\11"33"3333"3333"\11""\11"""""""""""""\11\11\11\11\11\11\11"\11\11\11\11\11""""""3"DUDD"333DfD""DUwfD33""""\11"""3"""\11\11\11\11\11""\11\11\11\11\11\11\11\11"""3\11\11\11\11"\11\11\11""3f\88\883"""""""""""""\11"\11\11"\11\11\11""""3DDDDD""\11\11\11"""""""\11""\11""""""""\11"3""""3"""""""\11"\11\11\11\11\11\11\11\11\11\11\11"\11""""\1133\11\11\11\11\11\0\11\11\11\11\11\11"""3DDD33""""333DUUff3""""\11\11\11\11\11\11\11\11\0\11\11\11\11\11"3D"\11\11\11\11\11\11\11\11\11\11"3""\11\11\11\11"\11\11\11\11\11""""""""""""""\11"""""""""3D33""""""""333333333DD"33""\11"\11\11\11\11\11\11\11\11\11"\11\11\11\11\11""""D\99U3DDUfwf\99\88ªf333"""""3"""3DD"D3""""D3"""""""\11""""""\11\11\11\11\11\11\11\11\11\11\11\11\11"\113""""DfUU3""3D3f33fwUD"""""\11\11\113"\113""\11\11\11\11\11\0"3"\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"\11\11""Dw\88\99UD""""\11"3""""""\11\11\11\11\11\11"D3"3"333U3""\11\11\11"""\11""""\11"\11""\11""\11""\11\11"3"""""""3"""""\11\11\11\11\11\11\11\11\11\11\11\11\11\113""D"\11\11\11\11\11\11\11\11\11\11"\11"""3U3DDD3""""33DDUUffU3""""""\11""\11\11\11\11\11\11\11\11\11"3D"\11\11\11\11\11\11\11"\11"D"\11\11\11\11\11\11\11\11\11\11\11\11"""""""""""""""""""""""""33"3""33333"333D3333D"3333"\11\11\11\11\11\11\11\11\11\11""\11\11\11""333fªU33DDf\99fw\99\99D33"""\11"""33"""33D"""\11"3D"""""""""""""\11\11\11\11\11\0\11\11\11\11\11\11\11\11"""3""D3fUwU333UDDDDw\99f3""3"""\11\11"\11"D"3"\11\11\11\11\11\11U""\11\11\11\0\11\11\11\11\11\11"\11\11\11\11""\11\11"DwUwU""\11\11\11\11""""""""\11\11\11"D"\11""""3""3DDUf"""\11\11\11""\11""""\11\11"\11""""""\11"3""""""""3"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0""3\11\11\11\11\11\11\11\11\11\11\11\11\11""333D33DD3""""33DDUUffUD"\11"3"""\11""\11\11\11"\11\11\0\11\11""""\11\11\11\11\11\11\11"""D"\11\11\11\11\11\11\11\11\11\11\11\11""""""3""3""""""\11\11"\11"""""33"""""333"333D33DD3DD3"3"\11\11\11\11\11\11\11\11\11\11"\11\11"""3""3f»wUUUUf\99UU\99\88U333"\11\11"""""333DDD""3"""""\11"\11"\11\11"\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3D"""""f\88fUUDfD"DU\88\99wUDD3"""\11D3"3D3"D\11\11\11\11\11\11\1133"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\113DUD3ff3"""\11\11\11""""\11""\11"\11\11\11"\11\11\11\11"3""3UDUD3"\11"\11\11"\11\11\11\11""\11\11\11"""""\11\11""""\11"""""""""""\11"""\11\11""\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11""3""""3D33""""33DDfffff"""33""\11\11"\11\11\11"3\11\11\11\11\11"3UU3\11\11\11\11\11"\11\11D3\11\11\11\11\11\11\11""\11"\11\11""3333333"""""3"""\11\1133"333"""3""333"D3D333D3333"""\11\11\11"\11\11\11\11\11\11""\11\11"\113"""\88ÌfDUff\88wff\99wD33"\11\11""""""""DDUD3"DD3""""\11"""\11\11"""\11\11\11\11\11\11\11\11\11"\11\11"\11\11\11"""3D""""UfUU33UDUfª\88wU3DDD3""\11\11D3"3D3DU"""\11\11\11\11"""\11\11\11\11\11\11\0\11\11\11\11\11\11""\11Uf3""DwUD""\11\11\11\11\11""""3""\11\11\11\11\11\11\11\11"\11\11""3DDUU\11\11\11\11\11\11\11\11\11\11\11\11\11"""""""\11\11\11""""""""""""""\11\11\11""""""\11\11\11\11\11\11\11\11\11""\11"""\11"""\11""""3"3D3333DD3"""3333U\88ww\883""333""""\11"""\11\11\11\11"\11\11"33\88f"\11\11""\11\113D"\11\11\11\11\11\11\11\11\11"\11"\113D3"3333""""""""\11\11""3""3"333""3""333333333""""33""\11\11"\11\11\11\11\11"""\11\11\11\11\11\11"U\99ªUUUUUw\99Uwª\883D3"\11""""""""D3DwU"3""""""\11"""""""\11\11\11\11\11\11\1133\11\11\11\11\11"""\11\11""3DD"""3UD"""fffwfUUfwD3333""""3D333DU3"\11\11\11\11\11"\11\11\11\11\0\0\11\11\11\11\11\11\11"\11\11"3U3\11""3DfwU""\11\11\11\11"\11"""""\11\11\11\11\11\11\11""""""3"DfwD\11\11\11\11\11\11\11\11\11"\11\11\11""""""\11\11"""""""""""""3""""\11\11""""\11\11\11\0\11\11\11\11\11""\11""""""\11""""""3"""""33D33"333DDffUwwU3""3D""""\11\11"3""\11\11""\11\11\11"Dfw"\11\11\11\11"3U""\11\11\11\0\11\11\11\11"\11\11""333D3D3"""""33"\11\11"""3""""3""333""333""3333"33D33"\11"\11\11""\11\11\11"""\11\11\11\11\113\99»\88DDUUUfwU\99\99f"33"""3"3D33"3DUf\99wD"""""""""\11""""\11\11\11\11\11\11\11""\11\11\11"\11\11""""""3DU""3333"333fwfUfDDUUD333""3"333DDDD"\11"\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11""DfU"\11\11\11""3wf3""\11\11\11\11"""""\11\11\11\11\11\11\11\11\11\11"""UfwfUf\88D"\11\11\11\11\11\11\11\11"""\11\11"""\11"""""""\11\11"""\11\11"""""""\113D3"\11\11\11\11\11\11\11\11\11""\11\11\11""\11\11\11\11\11"\11"\11"""""""DDD33DDUDUfU3DwD"""333"""""\11\11\11\11"\11\11\11"\11\11\11"3U3\11\11\11\11""fU"\11\11\11\11\11\11"\11""\11""333"33"""""DUU3"""""3"""""""3D3""333""333333"3"3"\11\11\11\11""\11\11\11"""\11\11\11\11\11\99fDDDUfUff»\88""3D3"""""3D333DUf\99f\88\88f"3"""\11\11\11\11""\11\11\11\11\11\11\11\11""\11\11\11""""""""""""""DD3""3Uf\88fUUUUUUUDD3333"\11"3""3D33""""\11\11"\11\11\0\11\0\11\11\11\11\11"\11"\11"3fw3\11\11\11\11\11"3Uw"""\11\11\11\11\11""""\11"\11\11\11\11\11\11\11\11"""UwffwwwwD\11\11\11\11\11\11\11"\11\11\11\11\11\11""\11"""""""\11""\11\11""\11"""3""""""\11\11\11\11\11\11\11\0\11\11\11"\11"""\11\11"\11\11\11\11""\11"""""""3DD3DDUfUfwf33fw\113""""""3""\11\11\11\11\11"\11"""\11\11\11\11"""\11\11""""U"\11\11\11\11\11\11\11\11"""333"""""33""""DD33D"3333""""3""""""""3333"3333""3D3\11"\11\11"\11\11\11\11\11\11\11\11\11"\11\113ªwUDDUUUfw\88»f"""3""""\11\11"DD33DUUw\99f\99ª»\99U3\11"""""\11"\11\11\11\11"\11"3""\11""\11\11""\11""""""333""3fwª\88wwfwU3DDDUD3""D33U\99\99wf""D3"33\11\11"\11\11\11\11\11\11\11\11\11\11"""""U\99\883\11\11\11\11\11""3fD""\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\113"f\88wfw\88wfD"\11\11"\11\11\11\11\11\11\11"\11\11"""""\11"""""\11\11\11\11""\11""33""\11"""\11\11\11"\11\0\11\11\11\11\11"\11"""\11\11"""""\11"""""""""33DUUUDfUUfffDUw3"""""333""\11\11\11\11\11"3\11\11\11\11\11\11\11\11\11""""""33D\11\11\11\11\11\11\11\11""3"33""""""""333""""3D33"33"""3"""""""3333"""3""333D"""""""\11\11\11\11\11\11\11\11\11\11\03\99wDDDUUUfwª\88D\11"3""\11""""""DDDUf\88fªª\99̪\99\99»\9933""\11\0\11"\11\11"\11\0\0\11\11""""""""""""D""3""DfwfUfw33fUD3"DDU3Dw\88ªª\99\99wUfD\0"UU3\113"\11\11\11""\11\11\11\11\11\11"""""U\88fD"\11\11\11\11\11\11\11"Df"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""3U\88ff\88\99ww3\11\11\11\11\11\11\11\11"\11\11\11\11\11\11""\11\11\11\11"3""\11\11\11\11\11"\11"""""""\11""\11\11\11"\11\0\11\11\11\11\11\11""""\11"\11\11""""""3""""""3"DUUfUUwUDDfwwwU\11"""""33""\11"\11\11\11\11\11"\11\0"""\11\11\11""""\11"33U3\11\11\11\11\11\11\11\11""""3"\11"""""3"33""333333333"""""""\11"3D3"""3"3333D3\11""\11"3"""\11\11\11\11\11\11\11\11\11\11\11w\99UDDDUDf\99ª\993\11\11\11""\11\11\11\11\11\11"\113DDUfw\88\88ª\88ÝÌ»»\99ªª\993"\11D\88ÝÌ»\99ªª\99\88f3D""""""\11""DU33Ufw\99wU33ffU3DD333"3UD3\88»ªwfwfUf\88\88w\88w"\11""\11"\0""\11\11\11\11\11\11""""Dww3"\11\11\11\11\0\11\11\11"3UfD"\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11""33f\88ww\88fU"""\11\11\11\11\11\11\11\11\11\11""\11\11\11\11"\11\11"""\11\11\11\11\11""""3\11"""\11\11"""\11""\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11"""""33"""""""3DUDffwwfUDDw\88fUD"""\11\11""""\11\11\11"\11"\11\11\11\11\11""\0\0\11\11"3""""33U\11\11\11\11\11\11\11\11\11"""""\11"\11333333"""""""33333""""""3DD33"""3""3333"3\11"""""""""\11"""""\11\11\11"\99ª33DUDD\88»Ì\88\11\11\11\11"\11""\11\11\11\11""33DUUf\88Ì\99UU\88ª\99\99\88\99ªª3UªÝîÝ»»»»ªªª\99w"""\11\11"fffUD33U\88\99wU33UwfUwfUDD3333U3ww\99wfUfUffw\99\99wD\11\11\11\11\11Df"\11\11\11\11\11"""3UwU"\0"\11\11\11\11\11\11\0\11\11"3Uw3\11\11\11\11\11\11\11\11\11\11\0\11\11\11"\11\11""""3"UfwfD3\11"\11\11\11\11\11\11\11\11\11\11"""\11\11\11\11"\11\11""\11\11\11\11"D333""\11\11"""""""""""\11\11\11\11\11"\11\11\11\11\11\11"\11"\11""""3""""""""3DDDUUU\88\88fU3UwDDfD"""\11\11\11""3"\11"\11\11\11\11\11\11\11""\11\0\11\11""33"\11""3D\11\11\11\11\11\11\11\11\11\11\11"""""3D3""""3""3""333"3""""""33DDD""""333333"""3""""""\11""\11"3"\11\11\11\0\88333DDUªÝªU\0\11\11""""""\11\11\11\11""333DfÌîÝ»\88Uwªª»ªÌîÝîÿÌ\88Uffwfff\88ªffUU\88UD\88\99\88U3"3DwUf3DDDDfww\88\88wD33333Dfw\88fUUUDDfffwUfUD3DDfw\883\11\11\11\113"3fUD""\11\11""\11\11\11\11\11\11\11""3DU"\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11"""""3DUDU3""\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11"\11\11\11"\11\11\11""3333""\11""\11"""""\11\11""\11\11\11\11\11\11"""\11\11"""\11"\11"""""3""""""3DUDDfDDfwD"U\88fDff33"\11\11\11"\11"""\11\11\11\11\11\11\11\11"\11\11\11\11\11""3""\11""3U"\11\11\11\11\11\11\11\11"\11\11\11\11"""""""33""""3""""""33""""3333""""""33D3""""3"""""""\11""\11\11\11\11\11\11\0fªf3333Dwª\99D\11\0\11\11\11"3"""\11""\11\11""""3fÝÝÌ»ÝÌ»ÌÝîÿÿîÝÌ\88wDD33UUUffw\88\99»ª»ÌÌÝÝÌ\99U\11Dwf"3D33D33U\88»»\99\88fDDDf\99ªfffUfUDDDfffUUUUUfwDUwwDfU3"DUfD\1133"3"\11\11\11\11\11\11\11\11\11"""3"\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11""""DDDU33""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11"\11\11\11\11"""""\11"""""\11"\11\11\11\11""\11\11\11\11\11\11""\11""\11\11""""\11\11""""3"""333UUUDDU3DUUDDDDDUU\11\11"\11""\11\11""\11\11\11\11\11\11\11\11"\11\11\11\11\11\11""3"\11\11\11"3\11\11\11\11\11\11\11\11\11\11\11\11\11\11"3"""""D3""""3""""""""""""""33""33"DD3""""""""""""""\11\11\11\11\11\11\11\11\113w\883""33Uª»f\0\11\11\11\11\11\11""\11"33"""""""3fÝÝÌÌÌÌÝÝ̪ªª\88wUDUD3"33D3DUD3D\88ª»Ì»\99\99\99\99ª»»ªD\11UD3D3UU\88\99wwfffª\99ª\88\88w\88UUfUDDD3DUDUD3D3D3"3"Uffww\88\99\99\99f3f\88UUU3\11\11\11\11\11\11\11\11\11"\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\113"333D333\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11"\11\11\11\11""\11"\11\11\11""\11"\11"""\11\11"\11\11\11\11\11\11\11"""""\11\11""\11\11\11\11"""""3D3"3DDDDUDUUDDDDD33DDf3""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"\11\11\11\11"""\11\11"33\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3"""3"3"""3""""33""""""""""""""33D3"33""3""""""""""""\11\11\11\11\0"w\99U33""3wª\993\0\11""\11\11\11""\11\11\11""3"\11"""DDÝÝ»»ªª»ª\88UUfD3""3DD3"333U3"UD3fwwwwfww\88\88\99\99\99ª\88\99\88w\99\88wwD"""3"3U3333DwUUUUD33333DD"3"""""""3"3UUf\99\88\88wf\88»ªfU""""\11"\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\113DUDUU3"""\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"\11\11\11\11\11""\11\11\11\11""""\11"""\11"\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11"""\11"""""333"33DDDDDUfUDDDDfUDDUf3"3""\11""\11\11\11\11\11\11\11\11\11\11\113""\11\11\0\11\11"""\11"D"\11\11\11\11\11\11\11\0\11\11\11\11\11"""\11"""3""""""3""""D3"""""""3""""3D3""3""\11\11"""3"""""3""""\11\11\11\0\88D333"Uªª3\11\11"""""\11\11\11\11"""33"""""3U\99ݪ»»ªªª\99wfwD3""333333"3"3UfUwUUfUDD3DDUDD3DDUDDDD3""\11"""""3"3DDDUUUDDD3"""33""3"\11""""33""33"DDUUUDUfwwwfUfffU\0\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11"3D3Uw3"3\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"\11\11\11\11\11""""""""\11\11""""\11\11\11\11\11\11"\11\11\0\11"\11\11\11\11\11\11\11"3\11"3"33DD3D3DDUUUDDDD333fU"\11\11"""\11\11\11\11\11\11""\11\11\11"3""\11\11\11\11"\11\11\11"3U3\11"\11\11\11\0\11\11\11\11\11\11"""\11"""333""""""\11"333""\11"""""3U""33D3"33\11""""""""3"""D3D3"\11\11\11\11f»U333"D\88»U\11\11""\11""\11\11\11\11\11"""33""3""33f»ªªªª\99\99\88\88w3""333""3D3"\113DUDUUUUUD""3333D3"""""3"""""""\11\11"""3333DUfU3D3"""""33""\11""\11""33"""""""3DD33333DUDDUUwwf33\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3DDDDD"\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11"\11\11\11\11"""\11\11\11\11"\11\11""\11"33""""""\11\11\11\11\11\11\11\11"""\11\11\11\11"\11\11\11\11\11""\11\11"""3333DD33DDDUUDUDD"33Uw"\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11\11"\11"\11""DD\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11"""3"3"33""""33""""""""3333"""""""3""333"""3"""""D3"\11"\113fª»3""""f\99w"\11\11\11\11\11\11\11\11\11\11\11""\11"3""""3333U\99»\88\99wwfUDD"""3""3""33""""D3D3DDD3""\11""""""""\11""""""""\11\11\11\11""""33""Uf33"""""""""""\11\11\11"""3""\11"\11"""""3333333"3DUDDDfwf\11\11\11\11\0\11\11\0\11\11\11\11\11\11\11\0\11\11"\11""DDDDD""\11""\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""\11\11\11\0\11"\11\11\11"\11\1133333""\11"\11\11\11\11\11\11\11\11"""""\11\11"\11\11\11\11\11\11\11\11\11\11333"333"33DUUUUDDD333DD"\11"\11\11""\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""33\11"\11\11\11\11\0\11\11\11\11\11\11\11\11""""D""""""D"""""3D"""33DUD333D3"333"33"""""""""\11\11\11\11""\11Dª»U3"3"3\99w"\11""\11\11\11""\11\11"\11\11"\11"""""\11""333wÝ\88\88w""3"D3""333""D33"\11\11""\11"3DD33""\11\11\11"""\11\11\11\11\11"\11"""3"\11\11\11"\11"""""33"D3""""""""""""\11\11\11""""""""""D""""\1133"3\11"33DDDDD3UD\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3UDffUf3""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\113\11\11\11\11\11""\11\11\11\11\11333"33""\11"\11\11\11\11"\11""\11\113"\11\11\11\11\11\11\11\11"\11\11\11\11\11""""""33333DDU3DDUD3DD"\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11""\11\11"\11\11\11\11\11\11"\11""""3D\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""D""33"33333"""""""3DD33"""""""3"3D""\1133""""""""\113"\11fªf3"3""w\993\11"""\11\11\11"\11"\11\11\11\11"""33""\113""333ª\88Df3"""3D33DU333DD"\11"\11\11"\11\11\11"D33""\11"3\11\11\11\11\11\11\11\11\11\11""""\11\11\11\11\11\11\11\11""3"333"""""3"""""\11\11"\11\11\11"\11""\11\11\11"""D"\11\11"\11""\03D\11"33UDD3U\88"\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11"3333DUf3""\11\11"\11\11"\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\0\11\11\11"\11""\11\11\11"""\11\11""33"333"\11"\11\11\11\11\11""""""\11\11\11\11\11\11\11\11""\11\11\11\11\11""""""""33"33UD3DUDD333"\11""\11\11\11\11"\11\11"\11\11\11\11"\11\11\11\11\11\11\0\0\11\11"""""3"3\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11"""""""333333"""""\11""""3D3""3"""33"""""""33"""33"3"3\113\88\99D"3"\11U\99w""3""""""\11""\11\11\11""\11\11""""""""3ff\883DD3"""3D333""3"3"\11\11\11\11\11\11""\11"""""\11\11""\11\0\11\11\11\11\11\11"""\11\11\11\11\11\11\11\11\113\11""""""3"""""""""""\11"\11\11""\11"""\11"""33"3\11\11"\11\11\11\11"3\11""3333Dw\99""D"\11\11\11\11\11\11\11\11\11\11\11\11\11\11"33"3UU33""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11"\11\11"\11"""""\11""33333""""""\11\11\11""""""""\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11"""33""""3D3DDDD333DD"\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11""\11\11"""D3\11\11\11\0\11\0\11\11\11\11\11\11\11\11"""""""""3D3"""3""""""""3""""""""""3D"""""3"""""3""3"f»\993""\11"\88\88D"""""""""\11\11\11\11"33\11"\11\11\11""\11\11""3\99ª\88UU3"3"33"\11"D3"3"""\11\11\11""\11\11\11\11"\11D\11"\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"\11\11\11\11\11\11\11\11""""""""33""""""""""\11""\11\11"\11\11\11\11\11""""""\11\11\11"""\11\11\11\11\11\11""33"3f\88f\11\113\11\11\11\11\11\11\11""\11"\11\11"""""DffD3"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""\11\11"""D333"""\11\11"""\11"""""\11\11""\11\11\11\11\11"\11\11\11\11\11\11\11"\11""""33""33DDUD3D333"D3\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\0"3"\11\11\11\11\11\11\11""\11\11\11""Dw\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11""""""3D"""\11"D""33"""""""""3"3"333DUD3""33"\11"3"""""3w»f\11"\11"f\99U""""""""3"\11\11\11\11\11"3\11"\11\11\11\11""3""3ª»ªf3""\11\11""""""3"""3"\11\11""\11\11\11\11\11"\11"\11\11\11\11\11\11\11\11\11\11\11"\11\11\11"\11\11\11\11\11\11\11\11\11\11\11""""""333""""""3"""\11"""""\11\11\11\11\11"\11\11"3""""""\11\11\11\11\11\11\11\11"33"3DU\88f3"\11\11\0\11\11\03U"""\11"\11""""Dw\88D""""""\11\11\11\11\11\11\11\11\0"\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11"\11""\11\11\11"3DD333""""\11""\11"33"3\11"3""\11\11\11\11""\11\11\11\11\11\11"\11""""333333DUfUDDD3"333\11\11""\11\11\11\11\11\11\0\11\11\11\11\11\113"\11\11\11\11\11\11\11\11\11\11\11\11\11"3DD\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""3"3"""""33"""""""""""""33D33DD3"\11"""""""""""\113fª\993\11\11"w\88U33D3"\11"""""\11\11\11\11\11\11"\11\11\11\11\11\11""\11"3DªÝ\99f3"\11\11\11\11\11"""""3""""""\11\11\11\11\11\11\11\11\11"\11\11\11\11"\11\11"\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"""UfU33"""""""""\11\11""\11\11"\11\11\11\11\11\11\11"\11\11""3\11\11\11\11\11\11\0\11\11""""3"3DffwDUUD3\11\0\11\88w"""\11"""""3Dw\88D"""""3"\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3UUD3D"3""\11\11"\11\11"""3""""\11\11\11\11\11\11"\11\11\11\11\11\11"""""33333DUUffUDDf3"DD3\11\11\11"\11\11\11\11"\11\11\11\11"\11\0\0"3"\11\11\11\11\11\11\11\11\11\11""""DD3\0\11\11\11\11\11\11\11\11\11\11\11\11""""33""33""33""""""""""\113"""DD33""""\11""""""""\11\11\11\11w»w3\11\11\11f\88f3""3D3\11\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""\11"D\99Ì»3""\11\11\11\11\11\11"""""3"\11"\11""\11\11\11"\11\11\11\11\11\11\11\11\11\11\11"33"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"3"DfUUD3""""""""\11\11\11\11\11"\11\11\11\11\11"\11\11\11\11"\11\11"\11\11\11\11\11\11\0\11\11\11"\11\11"3""DDUUfUffwwU\88\99w""""""""33UwD"33"""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11"\11\11\113DD3fUD3U""\11\11\11\11\11\11"\11"3"""3"\11\11\11\11\11\11\11\11"\11"""333333DDDDDUfwfU33D"DUD\11\11\11\11""\11\11"\11\0\11\11"\11\0\11\11"33\11\11\11\11\11\11"\11\11""33DDD\11\11\11\11\11\11\11\11\11\11\11""\11""""3333"""3"""""""""""""""333DD3""\11\11"""3""33"\11\11UªªD\11\11"U\99f3""""\11"""\11""\11\11""\11\11\11\11\11\11\11\11\11\11""3"""\88»»w\11"\11\11\11\11\11\11"\11"""""""\11"\11\11\11\11\11\11\11""\11"\11\11\113UUU""\11"\11\11\11\0\11"\11\11\11\11\11\11\11\11\11\11\11"UDUUUUUD3"\11"""""\11"\11\11\11"\11\11"\11\113"\113\11\11\11""\11\11\11\11\0\11\11\11""\11\11\11\11\11"\11"3DUD33DU\88\99ª\99\99\88UD""""""3DwUDD"""""\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11"\11"\11\11"D3DUD33D3"\11"\11\11\11\11\11""3"\11\11"3""""\11\11\11"""""""3333DDDDDUUUUwfD3DD3UD\11"\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11""""\11"""\11""\11\11""3DDDD\11\11\11\11\11\11\11\11\11\11\11""\11""""""3""""""""""\11"""\11"""333333""\11\11\11"\11""3"""333\99ªf\11\03w\99w3""""\11\11\11"""""""""\11\11\11\11\11\11\11"\11\11\11\11"""3U\99ªw3""\11\11\11\11\11\11\11\11""3""\11\11\11"\11\11\11\11\11\11""\11\11\11\11\113DD""\11\11\11\11\11\0\11\11\11\11\11"\11\11\11\11\11\11\11\11"w\88fUUDDUD3"\11\11\11""\11\11\11\11\11\11\11\11"\11"\11\11\11\11\11\11\11""\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11""3D3DDDUww\88\99ª\99\88UDUUD3"D33f"3""""""\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11""""\113DUUDUD333"3\11\11"\11\11"""3"\11""3D""\11\11\11\11"\11""""3"333DDUUDUDUUfwU3DU"UD"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3333"\11"\11""33"\11""\11\11\11\11\11\11\11\11\11\11""""""33"""""""""\11"\11"""33333""""\11\11\11"\11""""""""3wªw"\11\11\883"""\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"D3Dwª\883"\11""\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11"\11"""3333"\11\11\11\11\11\11\11\0\11"\11"\11\11\11\11\11\11\11""""wwUUDD3DD3"\11\11"""\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11""3"""\11\0\11\11\11\11""\11\11\11\11\11\11"""333DDUfffw\88\88fDUfUDUwfUD3""D3""""\11\11"\11"\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11"\11\11""\11"DDUD3D333333"\11\11\11\11\11""D"\11"""""""\11\11\11"\11"""3""3DDDDDUDfUDUUwf33UD3U3\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"3D33"\11\11\11\11\11\11\1133""\11\11\11\11\11\11\0\11\11\11\11\11\11""""""33"3""""\11\11"""3"3"3"""""\11\11\11\11\11\11\11\11""""33Dwªf"\113\88»f"""\11\11\11\11\11\11""\11"\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11"\11"D\88ª\88"""33\11\11\11\11\11\11\11\11\11\11\0\11\11"\11\11\11\11\11\11\11"""\11"UD3"\11\11\11\11\11\11\11\11\11\113"\11"\11"\11\11\11\11\11"\11"UwDUU3DDD3""\11"""\11\11\11\11\11\11""""""\11\11""\11""33"3\11""\11\11\11\11""""\11\11\11\11\11"""33DDUUUDUD3333DDDUUf\88U\11\113"""""\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"33DDD3333"3333"\11\11\11\11\11"3D"\11\11"""\11\11\11\11""\11"""333333DDDDUUDDUfwwUDDDUDD3\11\11\11\11\11\11\11\11""\11\11\11\11\11\11\11\11\11\11"\11"""3""\11\11\11\11\11""\11\11"3\11""\11\11\11\11\11\11\11\11\11\11\11"""""""3"3""""""""3""3D"33"\11\11\11\11\11\11\11\11\11\11\11\11"""3Dww3\0"w»w"\11"3"\11\11\11\11"\11"\11\11\11\11\11\11\11\11"\11"\11\11\11\11\11\11\11\11""\11"3\99»3\11"""3"\11"\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11""3DDD33\11\11\11\11\0\11\0\0\11\11\11"3"\11\11\11\11\11\11\11\11\11"3UU3DfD33D33"\11"""\11\11\11\11\11\11\11\11""""\11"\11"\11\11\11"""\11\11\11\11\11\11\11\11"""""\11\11\11\11\11""3DDUDUUDDDDDDDDUUfUDfD\11\11\113"\11"\11\11\11\11"\11"\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11""\11"UfUD33""3"""33""\11\11\11""3D"\11\11"""\11"\11\11"""""""33333DDDUUUD3Dw\99wUUDUD33D\11\11\11\11\11"\11"""\11\11"\11\11\11\11\11\11\11\11"\11"\11"""\11\11\11\11\11"""\11\11"3"""\11\11\0\11\11\11\11\11\11\11""33""33""""""""3"33"""\11"""""\11\11\11"\11"\11"\11"""3DDU\99"\11\88"\11\11"3"\11\11\11\11\11D"\11\11""\11\11\11\11"""""\11"\11\11\11\11\11\11\11"DªÝU""3"33""\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11"3DD3""\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11"\11\11\11DUfU33UD33"33"\11"""\11\11\11"\11\11\11\11""""\11""3\11\11\11"\11\11"\11""\11\11\11\11\11\11"""\11\11\11\11\11\11""33DDDDDDDDDDUUUUfUUwD"\11""\11\11"""\11"""\11\11\11\11\11"\11\11\11\11\0\11\11\11""\11"\11\11"\11DwfUUfU"D"""3D""\11\11\11""DD\11\11\11\11\11\11\11\11\11\11\11""""""33333DDUDUDUDUfUUwfDUD3DU""\11"""\11\11"\11\11\11"\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""\11\11\11"3"\11\11\11\11\11\11\11\11\11\11\11\11\11""""3"""3""""33"33"""\11"3"\11\11\11\11"\11\11"\11\11\11"""3DDfw"U\99\993\11\11"""\11\11\11\11\11"""""\11""\11"\11\11"""\11"""\11\11\11\11\11\0"wÝÌD""""3""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11UUD3"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"""\113UUU33D3""""3"""""""\11"\11\11\11\11"\113""\11\11\11\11"\11\11\11"\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11""""3DDDD3DDD33DUDUfUfw3\11\11"\11\11\11""\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11""\11\11\11\11fwUUD3DfD3DD"33""\11""DD\11\11\11"\11\11""\11""""33"3"3333DDDDUUfUUUUffwUUD33DD\11"\11""\11"""""""\11""""\11\11\11\11"""\11\11\11\11\11\11""\11\11\11\11\11\11"3\11"\11\11\11\11\11\11\11\11""\11"\11"""""""""""33""33"\11""3\11\11\11"33\11\11\11\11\11\11"""33Dw\99\99D\11\11\11\11\11\11"\11\11\11\11\11""\11"""""""\11\11\11\11""""""\11\11\11\0"ªÌ»D""""""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""DD3""\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""""3UUUD3DD3"""""""""""\11\113\11\11\11\11"33DDD3\11\11\0\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\0\0\11\11\11""""""33333DD33DDDDUUfD"""\11""""\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11fwwfUDD""33"DD33""""DD\11\11\11\11"\11""""\11""33333333333DDDDfUDUUUfffDD333D3"\11"\11\11\11"""\11"\11"\11"""\11\11\11\11\11""\11"\11\11\11\11\11\11\11\11\11\11\11\11\11"3\11\11\11\11\11\0\11\11\11\11\11""\11"\11""3""""3333"333"\11\11""\11\11\11"D3\11"""""""""Dwª\99̪U"\11\11"\11"\11\11\11\0\11\11\11\11""""""""\11\11"\11\11\11""\11\11\11\11\11\11\0"\99Ý»D\11"3"""""""\11\11\11\0\11\11\11\11"\11\11\11\11\11\11"3"""\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\03"3"3ffUf\88UD3DD3D3"3"""33"\11"\11\11""\11\11\11\11"3"\11"3"\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11"\11\11"3"333D333DUUUfUf"\11"""\11"\11\11\11\11""\11\11\11\11\11\11\11\0\11\11\11\0\11\11\11\11\11\11"\11\11"\11\11w\88wfUUU33""""\113DUDD333"\11\11\11\11""""""""33"3333333D33DDD33DDUUfffDD""D"\11\11"\11\11\11\11""""""\11\11"""""\11"\11""""\11\11\11\11\11\11\11\11\11\0\11\11\11"3\11\11\11\11\0\11"\11\11\11"""\11\11"""\11""""33""""""""""3"\11"3"""""""""""D\99ÌÌÝw3""""\11\11\11\11\11\11\11\11\11\11"\11\11"3"""\11\11\11\11\11\11\11\11\11\11\11\11\0\0\113ªîª""""""3""3"\11\11\11\11\11\11\11\11\11\11""\113"3""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11"\11\11"f\88wD3UffUwfU333"33"33D333""\11\11\11\11\11"\11\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11""33333D33"DUUUUDD"""\11""""""\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"w\88ffDUDD3"""""""\11"3DD3"""""""\11""""""""""""333DD3DD"U3333DUUUfD3"3"\11"\11\11\11\11\11\11\11"\11"\11\11"""""""""\11""\11\11\11\11\11\11\11\11\11\11\0\11\11\11""D\11\11\11\11\11\11\11\11\11\11"\11\11""\11""""3D33""""\11\11"""\11\11\11\11""\11""3"\11"3333UªÝÝ\99D"""""\11\11\11\11""\11\11\11\11""\11""""\11\11""\11\11\11\11\11\11\11\11\11\0\11D\99Ìݪ\11"""""33"""\11\11\11\11\11\11\11\11"\11""\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11""\11w\88\88ww\88wwfUffD333"""3333D3"""\11\11\11\11\11""\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11""3"33D333DDfUDwDD""""""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11"\11\11\11\11\113wwfUUDD33""""""""3"""\11\11\11""3"""""""""""3"3333333DDDD"3"33DDUwwU3333"\11\11\11""\11"""""""\113""""""""""""\11\11\11\11\11\11\11\11\11\0\11\11\11\11"3\11\11\11\11\11\11\11\11\11\11\11"""""""3D333""\11\11\11""""\113"\11\11\11"""\11\11\11"3333wÝÝ»f"""""""""\11\11\11\11\11\11\11\11\11\11\11""\11\11"""""\11\11\11\11\11\11\11\0"wªÌ̪3"\11"33""3"\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11f\99ww\88\88\88wffUDDD3""3"3"3DDD3""\11\11\11\11\11\11""\11\11""\11\11\11\0\11\11\11""\11\11\11\11\0\0\0\11\11\11\11\11\11\11\11\11\0\0\0\11\11\11\11\11\11\11\11"3333D333DUfDw\88U""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11"\11\11\11\113wffUUDD33333""""""3"""\11"3"""""""""3""""333333DDDDDDD3D"33DDfww"33D\11\11\11\11\11\11\11\11"""\11""""""3"\11""""""""\11\11\11\11\11\11\11\11\0\11\11\11\11\11""\11\11\11\11\11\11""\11\11\11\11""333"""""""\11\11""""""\11\11\11""\11""\11"""""33wÌ»\99U""""3"""\11""\11\11""\11\11\11\11\11""\11"\11"\11""""\11\11\11\11\11\11"ªÌ»»\993"""33""D3"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\113w\99\88\88\88\88\88\88wfUD"3"""""33DUfDD""\11\11\11\11\11\11\11\11""\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11\11"\11"\11\11"\11\11\0\0\11\0\11\0\0\0\11\11\11\11\11""33333DDDfDU\88DD3\11\11"\11\11\11\11"\11\11"\11\11\11\11\11\11\11\11\11\11\11\11"""\11\11\11\11\11\11"\88wfUDDDD33""""3"3"""""""\11\11\11\11""33"""""33"3"333DDDD33D3U3333DUDUDUDf"\11\11\11"\11\11\11\11"\11""3\11""""\11\11"""""""\11\11"\11\11\11\11"""\11\11\11\0\11\11""\11\11\11\11\11\11\11\11\11\11\11""""3""\11"""""""""""""\11"""""""33""333\99ÌwD"""""33"""""\11\11\11\11\11\11\11\11\11\11"""\11\11\11""3"\11\11\11\11\11\11\0fÌ»\88UU3"33""3DD33"\11\11\11\11\11\11\11\11"""\11\11\11\11\0\11\11\11\11\11\11\11""\11\11"""\11\11\11\11\11U\88w\88\88\99\88\88\88fUD33"""\11""333D3fU3"\11\11\11\11\11\11\11"""\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\0\0\0\0\0\0\0\11\11\0\0\11\11\11\11""3333D3DUfwff33\11"""\11"""\11\11"3\11\11\11"""\11\11\11\11\11\11\11"\11\11\11\0\11\11D\88fwUDD33"333"""""""\11""""\11"\11""""33DD33D333""3333D3DD33333"33UDUUUDfD\11\11\11\11\11""""\11"\11\11\11\11"\11\11\11"3""""""\11\113U"\11\11"""\11\11\11\11\11\11"""""\11\11\11\11\11\11\11""333""""""\11\11"\11\11""\11"\11""""""""3""3"D3U»»3""""""3""""""\11\11\11\11\11\11\11\11\11\11"\11""\11\11"""\11\11"\11"\11\11Dw\99\99fUfU"33UD3DD"\11\11\11\11\11\11\11\11\11\11"""""\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11"\11\11Uww\88»ªª\99ffUD3""\11\11\1133""333UU3"\11\11\11\11\11\11\11\11\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\0\0\11\11\11\0\0\11\11\0\0\11\11\11""""3333D3Dwwwf3""""\11""3""\11\11"\11"""""""\11\11\11\11\11""\11\03Uf\88wfDD33""33""""""""""""""\11""""""""3"3DD3D3""333333D33"33"33DUUUUUUf\11\11\11\11\11\11"""\11\11\11\11\11\11\11\11\11\11\11""""3U"\11\11"\11\11\11\11"3"""\11\11\11\11\11"33"""""""""""""""333"""\11""\11\11"""""""""3""""""3DU̪3\11""""33""""""\11\11\11\11"""""\11""""""\11\11"\11\11"\11\11"D\88»\99w\88fwD33"DDD3""\11\11\11\11"\11\11\11\11\11\11""""\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\113www\99»ª\88fUUU3""""""3""3333DD""\11\11\11\11""\11\11\11"\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\0\0\0\0\0\11\0\0\11\11\11\11\11\11\11\11\11""3333DDDUUw\99f"""\11\11\11\1133"\11\11\11\11"33"\11""""\11\113D"\0\113\88\99wfUfD3DD333""""""3"""""""""\11"\11"""""333333333333333333"3"333DDDDUwDfD\11\11""""""\11\11\11\11"\11\11\11\11""\11""\11"D"\11\11"\11\11\11\113""\11\11\11\11\11\11\11"\11\11333""""""""33333""""\11""""\11\11"""""333"\11""""""Uª»\88""3""33""""""\11\11\11""""""""""""""\11\11\11\11\11\11\113f\99ݪUDU3"""33DfD""\11\11\11\11\11\11"\11\11\11"""\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11"\11\11\11\11\11\11\11"""D\88\99ª\99\88wfUD3""""""""""3"333""\11\11\11"""\11\11\11\11"\11"3"\11\11"\11"\11\11\11\11\11\0\0\11\11\11\11\11\11\0\0\0\0\0\0\11\0\0\0\11\0\11\0\11\11\11\11""DD3DDDUDUf\99\99U""\11\11\11\113D3"\11\11\11"""""""3"""Uwfff\88ª\99\88fDUfUD3D3""""33"""3"""""""\11\11""""\11"""3D333DD333333333D3333DDDDDUfw\88f"""""""""\11"\11"\11"\11\11"""\11"\11"3"\11\11\11\11\11\11\11"\11\0\11\11\11""\11\11\11\11\11\113D"""""""""""3""""""""\11\11\11""""""33""\11"""33D\99ÌÌD\11"""""""""""""""""""""\11"\11"""\11"\11\11\11\11\11\11\11UÌÌݪ3D"\11"""3DUD"\11"\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11""""\11\11\11\11\11\11""3\11D\88\99\99\88wUUD3333""3"""""33D"\11\11"\11\11"3"""\11\11"3""3"\11"\11""\11\11\11\11\11\11\11\11\11\11\11\11\0\0\0\11\11\0\11\11\11\0\11\0\0\11\11\11\11"""D33DUDDUDUfU3"""\11"\11"D3"""\11"""""""3Dwwww\88\99\99\99w\88\88wfUU3D333""""33"""""""""""\11""\11""\11"""333DDD3333333333DUDD333DDDUfw\99ªf"\11\11\11"\11\11"""\11\11\11\11\11\11""""\11""D3\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11"""3D33"33"""""3"""""""""\11\11"\11"""3"""""""""3fÌÝ»3"""33""3""3""""""""33""""\11"\11""\11\11\11\11\11"fÌÌ\99\99ª3"\11\11\11""3333\11\11\11\11\11"\0\11\11\11\11\11\11\11\11\11"\11"\11\11\11\11\11"\11\11\11\11\11\11\11""\11\11\11\11\0\11"3"\11\11\88\88\88wffUDD333333D3""3DD3D3""\11\11"\11\11\11""\11\11"3"""\11""\11\11\11\0\0\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11"\11\11\0\11\11\11\11\11\11\11""""333DUUUDfw\88"""""\11\11"3""3""""33""3Ufww\88\99ª\88\99\99\88wwwffDD3"3"33333"""""\11""""\11"\11\11\11\11""""""33""3333333DDD3DDDU3""3DDfUUfw\99\88wD3""\11"\11"""\11\11\11"""333"""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3"3"""""\11"""""""""""\11""""""""\11""\11\11\11DfwÝÝ\88"3"""""333"""""3"""33"3"""\113"\11\11\11\11\11\113w»Ý»\99\88\99D"D\11\11"""D""\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\0\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11"w\88w\88wfUDDDDD33DDDDDDUUDDD""\11\11"\11\11\11\11""\11""""""3""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"\11\11\0\11\11\11\11\11\11\11\11\11"""3DDDDUUff\88w3""\11\11\11"33"""\11""""""3UwDf\88\99\99\99\99\99\99\88wfUUUD33333333""""""""""\11\11\11"\11\11"""""""333"""D33"33333DDDU""""DDUUfw\88wfwwwU\11"\11\11""""""3DD3"3""3"""\11\11\11\11\11\11\11\11\11\11\0\0\0\11\11\11\11\11\11\11\11\11\11\11\11"D3""3""3"""""""\11"""\11""3""""\11""""3\88Ì»ªªw3"33"33""""3"""33"3"""""""3DD\11\11\11\11\11D\88Ìî»\88w\99wD3D""""3D3""\11\11\11\11\11\11\11\11"\11""\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11"\11\11\11\11\11\11""\11\113\88\99wfw\88fUUfDD333DDDDDD3DUD"""\11"\11\11"\11""\11"\11""""D3""\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11333DDUUUU\88\88w3""\11\11\11"33D3""""\11"""3ffff\88\88\88\99\88\88\88wwffUDDD33333D3""""""""""\11\11\11"""3"\11""""33""\11"\11"333333"3U33""""3D3DffffwwwwwU\11"""""""""UU3""""""""\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11D33""3"""""""3"""""""""\11\11\11"""\11"D\99Ý̪\88U""33"3333""3D""D""3"3DDU33UfUDUwf\99ÌÌ»\88fDf\99fDDU"\11""333"\11\11\11\0\11\11\11\11\11\11"\11"""\11\11\11\11\11""\11\11\11\11\11\11\0\11"\11""\11\11""\11""\11\11"U\88\88\88wff\88\88wwUDDDUUDDD33D3DD333"""\11\11\11\11D"\11\11"3D3"\11""\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11"\11\11\11\11\11\11\0\11\0\11\11\11\11\11\11\11"33D3UU3Uw\99\88f"""\11\11"33DUD"""\11\11""Df\88\99Uw\88wwwwwwffUUUUDDD333""""""""""""\11\11""\11"""""""""""3\11\11"\113""33"333""""3"333DUfffffUffU"\11\11"""""""DD33"""""""\11\11\11\11\0\0\11\11\0\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11"""""""""""""3"33"\11""\11\11\11\11"33U\99Ìî\88333"""""33"3"""""3"333"f\99wDUffff\88\88\99ÌÌ»»ª\88Uff\99wfDD""""3D3"\11\11\11\11\11\11\11\11"\11\11\11\11"""\11\11\11\11\11""\11\11\11\11"\11\11\11\11""\11\11\113"3"\11\11"Uw\88wwwUffwwUDUUUUUU3DDDUDD3333333\11\113U3\11\11\11""U3\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\0\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11"3DUDfUfDf\88U3\11"\11"""33DUU""\11"Uw\88\99w\88\99\88wwfwffwffUUDDDDD33D3"""""""""""\11""\11\11\11""""""\11""""3\11\11""""333"3""""3"""33UUUUUwf3Uwf3"\11\11"""""""3333"3""""\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0"33"""""""""33"""33"\11\11"DffªÝîîf\11""""""""3333"""""33333fw\88fUUDUUUUf\88ªª\88\99ªª\88\88»\88\88wU3"\11\11""""\11\11\11\11\11\11\11\11\11\11\11\11\11\113"\113\11\11\11""""\11\11\11\11\11\11\11"\11\11"\11"""\11\11\11\11Uw\88ww\88D""3fwfffUfUDDDDUUUD33333"""D3"3\11\11\11""""""\11\11\11\11\11\11\11\11"\11"\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\0\0\11\11\11\11"""3UDUfD3UD\11""\11\11\11""33DDD""Df\88\88\88w\88\88\99\88\88wfffUUUUDDD3DD3333""""""""""3"\11""""3"""""""""""""""""""33"""""33"333DDUUfDDDDDUD""""""3333""""3333""""\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\0"""3"3"""D33"\11"3UU3DUwff»îÝÝw\11""333""333333"""""""\11"wwwUfUD333UUww»wª»»ÌÌÌ\99\88wfU\11\11\11\11"3"\11\11\11\11\11\11\11"\11\11\11\11""""\11""\11\11\11\11\11"\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11"UwwUUD""\113fwfwfUffUUDDDD3D3""D3""33""\11\11\11"3"\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11""3DUUDfw33\11\11\1133""""""33"\11Dwwww\88\99\99\88wwwfUDDDDDD3D33f3333333""""""""\11\11\11\11""3"\11""""333333D3"""""33D3""""""""3DDUfUDDD3DfD"""D3"3"333""33333D3"""\11\0\0\11\11\11\0\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0DU"33333333"\11\11\11""3DUUªÝîîÝ»f"""3D33333333333"3""3Dfw\88wfD333333DUw»»ÌÌÌîÌ\99w\88fD3"""33\11\11\11\11\11\11\11\11"\11\11\11\11\11\11"""""\11\11\11\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\113fwD3""33"UwffffwwfUfUD33DD"3DDDD""\11"""\11"3""\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\0\0\0\11\11\11\11\11\11\11\11\11\11\11\0\11\11\0\0\11\11\11"3333D33w\11""\11\11\11"3""\11"\11\11\11\11\11"Dw\88ww\88w\88\88fwUUDDDDD33"3DfD333D33""""""""\11\11""\11"""""3"333"33333D33"3"""""\11\11"""""33DDUUDDU3D3fUD""3333""""""33"3"33""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11"\11\11\11"\11fD3""3"3""""\11\11\11\11\11"3ÌÝÝÝÝÝ»\883""DD3"3"33"3""""\11DfUw\99ffUD"3333333D\99ÌÌÌÌÝÌ\99\88\88f3"\11\11\11"3"\11\11\11\11\0\11\11\11\11"\11\11\11\11"\11\11""\11\11"""""""\11\11""\11\11\11\11\0\11\11\11\11"\11\11\11\11UwUD3"\113UffffffwfUUUD33DU33"UD3"\11\11\11"3"""D"""\11\11\11"\11\11"\11\11\11""\11\11\11\11\11\0\11\11\11\11"\11\11\11\11\11\11\0\11\11"\11\11\11\11"3333DD33D\11"3\11\11"\11""\11D"\11\11\11Dw\88\88ª\99\99ª\99wwwwfUDDDDD33"3DDDDUDD333"""""""\11""\11""\11"""3"3"""33""""""""""""""\11""\11"33DDDDUUUDDD33UfU""3U""""33"3333""""""\11\0\11\11\0\11\11\0\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""UU33""\11""\11\11"\11\11"Dff»ÿÝÝÌÌ\99w\99wDDw33""""3"w"3Ufww\88wDUUUD"3333"3"D\88»ÌÌÝÝÌ\99»\993""\11\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11"\11\11""""\11\11\11"""\11""\11"\11\11\11\11\11\0\11\11\11\11"\11\11""\11UffUD"3UffffUffUUffU3DDUDDDUD3\11\11\11\11"""333"""\11\11\11\11\11"\11\11"\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11""333DUf"\11\11"\11\11\11\11\11\11\11\11"""3f\99ªªªªªª\99wfUwUDDDDDD3"D33"333D3333""""""""\11\11"3\11\1133""""""""""3""""""""333""""""33333UUDUUDDD33DDD""33"3""D3"""""\11""\11""\11\0\11\0\0\0\11\0\0\0\11\0\0\11\11\11"\11\11\11"\11\11\11\11\11\11\11\11\11""\11\11"Uf"""\11"3fUfwª»ÝÌîÿÿÝÌÌ»UUUwUDf33\11Uf\88w"fw\88wfUUD3UDUU3"D333333U»»ÌÝÌ̪\99\88D\11""\11\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""\11\11"\11"""3"""""\11\11\11\11\11\11\11\11\11\11\11""3U3fUD"3UUUffUUUUfUDDDUUDD333D"\11\11\11"""""33"\11"\11\11\11\11\11"\11"\11\11\11"""\11\11\11\0\11\11\11"\11\11\11\11\11\11\11"""""\11\11\11""3333DU"""3""\11\11"\11\11\11\11"f\88\99\99\99\88\88\88\99\99\99wfUUUDDDDD33333333333333""""""\11\11\11\11""3"\11"D"\11"""""""""""""""""""""3"""""333DUUUDUDDDDD33DU3""D333333"""\11""\11""""\11\11\11\11\11\0\0\11\0\0\11\11\0\11\11\11\11\11"\11"""\11\11\11\11""\11\11\11\11\11\11\88wDw\88ª»»»ÝîîîîÿÝ\99w\99ª\88\88UUUffw\88f\88w\88wwUfUUDUD3""DDDD3D3"""33Dw»ÌÌ̪»\88w3\11\11\11\11\11\11\11"\11""\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11"""""3"\11\11\11\11\11\11\11\11\11\11\11\11"3DD\11UUDDD3UfDUD"UUUUUUfD333DD""\11\11\11""3"""3""""""\11"""\11\11\11\11\11\11\11\11\11\0\11\11\11\11"\11\11"\11\11"\11""\11"\11\11\11\11\11\11"3DDU\8833\113"\11"\11\11\11\11\11\11Dww\88wUfwwwf\99\88UUUfDDDD3""333"""33"3"""""""""\11\11\11""\11\11""""""""""""""""""""""""333"\11""33"DUUDDDUUDD3DDD3DfU"UU""""""""""\11""\11"\11\11\11\11\11\11\0\0\0\11\11\11\11\11\11\11\11\11\11\11""""""""""\11\11\11\11\0\0Dw\99»»ÌîÝîÌÝÌÌÝîÿ»wffUffwf3UfUUf\88\99fffUUUDD333"""33DD3D33""333\88»Ì»»\99ªwU"\0\11\11\11\11\11\11\11"""""\11\11\11"3""""\11\11\11\11"""\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\0\0"UDD"UUDfD3"33""\11\11UfUUUD3"3D3D"\11""""33""""""""""""""""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3""\11\11"\11\11\11\11""D3DUUf3"""\11\11\11\11\11\11\11\11DwwfDUD3DfffwUUUUUD333""333""""3""""""""""\11\11\11"""\11"\11""""""""""""""""333""""D33"""3333DUDUDD3UUUDDDU333D3"\1133\11""\11\11\11""\11\11"\11\11"\11\11\11\11"\11\11\0\11\11\11\11"""\11\11"\11""\11\11"\11"\113"\11\11\11\11\11\11\0wwwÌ»Ý\99ÌÌÝ»îîîݪffUUDDfw"fffDDUfU3DUDD3D3""""""3"DD3DD""""3fª»»ª\88ªf3"\0\11\11\11\11\11\11\11""D3""\11"DD"""""\11\11\11\11\11\11\11\11\11\11"\11"\11\11\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11UfD"3Ufff"3"\11\11\11\0\0"UfUUD""3D33"\11\11""333"""""""""""""""""\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11""\11"3""""\11\11"\11"33DUf3"\113\11""\11\11\11\11\11DfwfUD33UffUDDDUUUD333""33"""""""""""3"""\11\11\11""""\11"""""\11\11\11""""""""""333""33D3""""""3DDDDDDDUUUfUUUUD"D"3"\11\11\11"\11\11\11\11""""""\11""""\11"""\11\11\11""\11\11\11\11\11\11\11\11\11"\11\11""\11"""\11\11"3"\11\0Dwf\99\99»Ì»ÝÝîÝݪ\99wfUDDD33Ufw\88UDDDfD333DD3"""""""""3U333D3""""3\99»»\99\88\88f"\11\0\11\11\11\11"\11\11"\11"DD""\11DU""\11"""\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11"\11\11\0\11\11\11"\11\11\11\11\0DfUDDDDfw33""\11\11\11\11\11Ufwwf""DU""""\11""33333""""""33"""33"3"\11\11\11\11\11"\0\11\11\11"\11\11\11"\11"\11"""""""\11"\11\11"""DUfD""""3""\11""\113U\88wfffw\99\99wUDDDDUUD33"""3"3"""\11\11"""""""""\11\11\11""""""""""""""""33"""3"3333"333""""""3333DUDUDDUUUUUUfD3UD"\11\11\11"\11\11\11"\11\113""\11""\11\11"3""3"\11"\11\11\11\0\11\11\11\11\11\0\11""3"""\11"""\11\11""\11"DU\99ªÝîÌÝîÝîÌ\99ff\88fD3333DD3Dfw\88fUDUD3333"""""\11"3"\11"\11DU"3D3"""\11"D\99ª\99\88\88w"\11\11\11\11\11\11\11\11\11\11\11\11"3U3\113D""\11\11"""\11\11\11\11\11\11\11\11\11"\11\11\11\0\11\11\11\11\11\11\0\0\11\11\11\11\11\11\11\113fUUfD3DUwwD\11\11\11\0\11"DUwwwU"3DD"\11""3"D33333""\11"333333333""\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"""\113"""""3"\11\11\11"""UwU\113"3"D"3"333Df\88w\99\99ªª\99\88wUUUDDD333""33""""""""""3"\11"""\11\11\11"\11""""""""""""33"33""3"""3D333"""""""3"33DDUUUUUDUUffwwUwU\11\11\11\11\11"\11\11\11\11\11\11"\11\11\11\11\11\11\11"""D"\11"\11\11\11\11\11\11\11\11\11\11\11\113UD"\11\11\11"D"\11\11"""DfUUwª»»ÿݪ\88UD33D3"""""3DUUD\99\88fUUU3DD"""\11"""""\11\11"DDw333""\11\11\11\113U\99wfU\99U\11\0\11\11\11\11\11\11\11\11\11\11\1133DDDU3"\11\11\11"""\11\11\11\11\11"\11\11"\11\0\11\11\11\11\11"\11\11\11\11\0\11\11\11\11\0\11"3fUf3UD33Dwf\11\11\11\11\11"UD3DUU33U3"""D3D3DD333"""\1133D333333"3"\11"\11\11\11\11\11\11\11\11\11\11\11\11""""""""""3"""""""3UwDDD333"\11\11\11\11\11"Dfww\88ªª»ª\99fUDD33333"33"""""""""""""""""\11\11\11\11\11""3"""333""""""33""33333D"3"""""""""3333DDDUUUUUUffw\88\88\99D""\11\11\11\11\11\11\11"\11\11""\11\11\11\11\11\11"333DD\11\0\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11"\11""""""""DD3"w»ÝÝÌ»fD3""""""""\11\11""3DDD\88fwffDDD33"\11""""\0"DwwwwwwD"DUDD333wwwfwU"\11\0\11\11\11\11\11\11\11\11\11\11""3DfU3"\11\11""\11"\11\11\11\11\11"\11\11\11\11\11\0\0\11\11\11\11\11""\11\11\11\0\11\11\11\113DffDDD3""3Uw"\11\11""333""3333UD33DDUDDff3"333"""3DUD33333""""\11\11\11\11\11\11"\11\11"""""""D"""""33"3"\11\11\11"DUff\88D333\11\11\11\11\11"fww\88w\88ª»Ì\88D33333333"33"""""\11\11"\11"""\11"3""""\11\11""DU3"33DD3"""\113333""3""3DD3""""33"""""333DDUffUUUUfUf\99\99\88\11"""\11\11\11\11\11\11"\11"\11\11\11\11\11"\11\11"33""\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""33D""D»ÝÝÌ\993""\11\11\11\11\11\11\11"\11\11\11\11\11\1133"fwUUUUD333""""3"3fwffUUUDDwwUDDUw\88ffffwfD\11\0\0\0\11"3\11\0\11\11\11\11"3DD333"\11""""""\11\11\11\11\11\11\11\11\11\11\11\0\0\11\11\11"\11\11\11\11\11\11\11\11\11\113wUwUDD"""Dw3\0\11\11\11\11\11\11""3"3"""DDDD3Uwwf3333D33""DDD3"33"3""""\11\11\11\11\11\11"""""""""3\11"""3""""3""""33fwwD""""\11\11\11\11"ffffwªª\99wD"333333"3""""""""\11\11"\11\11\11\11\11\11""""\11\11\11\11"33"33"3D3""""DD33333333D3D""""""""""""D33DUUUUUfUfw\88\88f\99U"""\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11"""""\11\0\11\11\0\11\11\11\11\0\0\11\0\0\11\11\0\11\11\11\11\11\11\11""33""U»Ý»\88U"\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""DD3DDUUDDDDDDDDDDDDDUD33DD3D3""33DwUD3\88w\11\0\0\0\11""\11\11\11\11\11\11"3D3"""""3"""""\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11""\11\11"\11\11\11\11\11\11\11\11UwwfUD3""\11DD\11\11\11\11\11\11\11\11\11\11"\11\11\11\113333DUwwffU"""33333D3"33"""""""\11\11\11\11\11\11\11"3""""""""""""33"33""\11"\113UD333"""""\11\11\11Dwfff\99\99fD"333333""""""\11\11"""\11\11"\11\11\11"\11\11\11\11\11\11\11\11""\11""""\1133D333"3333"""""33333"3""""""""33333DDDUUUUfffwfUwf"\11"\11\11\11\11"\11\11"\11"\11\11\11\11\11\11\11"\11\11\11\11"\11\0\11\11\0\0\11\0\11\11\11\11\0\0\0\11\11\11\11\11\11\11\11"""""fªÌ\99f"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""D3"33UwU33""\11"""33D33""3"""""""3DUw33fªD"\0\0\11"\11\11\11\11\11\11\11\11""3"""""3"\11"\11\11\11""\11\11\11\11\11\11\11"""\11\11\11\11\11"""\11\0""\11\11\11"UwwU3"""\11\11D"\11\11\11\11\0\11\11\11\11\11\11\11\11\11"33DUffffwDUD3"33333""D33""""""\11\11"\11\11"\11\113""\11\11""\11\11\11""""33"33""3""Uw3\1133333""\11\11\11wfDD3ffD33"3""3"""""""\11""\11\11\11"\11\11\11\11"\11\11\11\11\11\11\11\11"\11\11"""""333333D3"33""""""333"""""""333"3DDDDDDUUUUffffDw\99U\11"D""""\11\11"\11\11\11\11\11\11\11"\11"\11\11"\11\11\11"\11\11\0\0\0\0\0\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\113UU»ÌªUD"\11\11\11\11\11\11\11\11\11\0\0\11\11\11\0\0\0\0\11\11\11\11\11\11"D""D333\11"\11\11\11"3\11\11"""""""""""""\11""3Dw\88f»w"\11\0\11\11\11"\11\11\11\11\11\11"\11\11""""\11"""\11"\11\11\11""\11\11"\11"33D3"\11\11\11\11\11""\11\11\11\11"\11\11\11"ffU3"""\11\11""\11\11\11\11\0\0\0\11""""\113D"DD3""""3DUDD"3D333""D"\11"""""\11\11\11\11\11\11\11\11\11"""""""3"""""3333333"""33fD33D""""""\11"UfDDDfUD"""""""""\11\11"\11\11\11\11\11\11\11\11\11\11\11"3""\11\11\11\11\11\11"\11\11\11\11""""3U3333333""33333"33""""""""33""3DD3DD3DDUDDUfw\88f\883\11\113"""""\11\11\11\11"\11\11""\11"""\11"\11\11\11\11\11\11\11\0\11\0\0\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11"UwªÝÌ\99wD"\11"3"""\11\11\11\11\11\0\0\11\11\0\0\0\0\11\0\0\0\0\11\11\1133DD""\11\11"\11\11""\11\11\11\11"""""\11\11"\11\11"\11\11"33Dw\99»w3\11\0\0\11\11\11\11\11\0\11\11\11\11\11\11"""""""\11\11\11\11\11\11""\11\11"\11"3333"\11\11\11"3"\11""\11\11\11\11\11\11\11DfD""""\11\11\11"\11\0\11\11\11\11\11\11\11""\11\11""\11""\11\11\11"""3D3D33D33"""33\11\11"""""\11\11\11\11\11\11\11"3""""""33"""\11"33333"33"3Uwf""""\11\11"\11D"\11ffDDDwD"""""""""\11"\11"\11\11\11\11\11\11"""""3D"\11\11\11\11\11\11\11\11"\11\11\11\11""""3"3"333333333333333"""""""3"3"3DDDD3DDDUDD3UwwU\99D\11\11\11\11\11""\11\11\11\11\11\11""\11\11\11\11""""\11\11\11\11\11"\11\11\11\0\0\0\0\0\0\0\11\11""\11\11"\11\11\11\88ª»\99\99\99\88\88f3\11\113""""\11\11\11\11\0\0\0\11\11\11\11\11\0\11\0\0"\11\11\11"DDD"""\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11"""\11\11\11\11""DUUU\99w\11\0\0\11\11\11\0\11\0\0\11\11\11\11""""""""""\11\11\11"\11""\11"""""\11\11\11\11\11""33\11\11\11\11\11\11\11\11\11\11DfD"""\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11""33\11\11""3"DUU3D33"333""""""""\11\11"\11\11\11\11\11\11\113"""""\11"33"""\11"333"3D333DU\88U\11\11\11\11"\11\11"UD\88wfDUf3\11\11\11\11\11\11"\11\11\11\11\11\11\11\11""""\113""3"\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11"""""333333D3DD333333333"""""333333DD3D3333DDDDDUffUw\11\11\11\11\11\11\11""\11\11"\11\11"""\11""\1133"\11\11\11\11\11\11\11\11\11\0\0\11\11\11\11\11\11\11\11\11\11\11\11"wÌ»\88w\88wfff3"\11"""\11\11"\11\11\11\11\11\11\11\0\11\11\11\11\0\11\0\11\11\11\11\11"333""\11\11\11\11\11\11\11\11\11\11""""\11\11"\11"\11\11\11\11\11\11\11"33DU\99f\11\0\0\0\11\11\11\11\11\11\0\11\11"\11\11\11\11""\11"\11\11\11""\11"\11"""""\11\11\11\11\11\11"""\11\11\11\11\11\11\11\11\11\11\113U33"""\11\11\11\11"\11\11\11\11\11\11""\11\11\0\11\11"""3\11\11\11\11""3UfDUD3""333"3"\11\11"""\11\11\11\11\11\11\11\11\11"3"""\11\11"333"""""333DU3"DD3Df3""\11\11\11\11"U\88\99wfUff3"\11\11\11\11\11\11\11\11\11\11\11\11\11"""""33D3\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11""\11"""""""\11\11\113DUDD33"333"D3""333333UDDD33333DDDDDUUf\99"\11\11\11"\11\11\11\11\11\11\11\11\11\11"33\11"""3\11"\11\11\11\11\11\11\11\0\0\0\11\11\11\11\11\0\11\11"\11"D\88̪\88wffwUD"""\11\11""\11""3"\11\11\11\11\0\0\11\11\11\11\11\11\0\11"\11\11\11"\11""\11""\11\11\0\11\11\11\11\11\11\11""""""\11\113"\11\11\11\11\11"""33f\99"\0\0\0\11\11\11\0\11\11\11\0\11\11\11\11\11\11\11"\11\11"""\11"""\11"\11""""\11\11\11""\11"\11\11\11""\11\11\11"\11\11\11DUD"""\11\11\11\11\11\11"\11\11\11\11\11"33\11\11\11\11"""""\11\11\11\11"\11\11\11\11Uff333DDU33"\11\11"""\11""\11\11\11\11""3""\11"\11""333"""""3D3D33DD3DfU33"\11\11\11DUwwwwffw3"\11\11\11\11\11\11\11\11\11\11\11""""""3D"3"\11\11\11\11\11\0\11\11\11\11\0\11\11\11\11\11\11\11"\11"""""""""""""DUDD"33"3"33"33""3DDD3333333DDUfffUfw\99\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3"3""""\11\11\11\11\11\11\11\11\11\11\0\11\11\0\11\0\0D\99»»\99»ªwwwUfDDU3""\11"""\11\11\11""\11\11\11\11\11\0\11\11""\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11""""""""""D\11\11\11\11\11\11\11\11"DD\99D\0\0\0\0\0\11\0\0\11\11\11\11\11\11\11\11\11\11\11""\11\11""\11"3"""\11\11"3"\11\11"\11\11\11\11\11\11""""\11\11"\11\113UD3""""\11\11\11\11\11"\11""\11\11\113U\11\11\11""""\11""\11\11"\11\11\11\11"U\88UD33DUU33\11\11\11"""\11"\11\11\11\11\11"""\11\11"""\11\11"33""3333D333DDDUUfDDD\11"\113\99\88\88wfU"fD\11\11\11\11\11\11\11\11\11\11""\11"""3"3""""""\11\11\11\11\11\0\11\11\0\11\11\0\11\11\11\11""""""""""""""""3UD333"3"33"333"3UUD333333DD33UªwUfw\88f\11\11\11\11\11\11\11\11"\11\11\11\11\11""\1133"""3"\11\11\11\11\11\11\0\0\0\11\11\11\11"U\99ªwf\88wUUwUD"3DD3""\11\11\11"""""""\11\11\11\11\11\11""""\11\11""\11\11"\11\11\113\11\11\11\11\11\11\11\11\11\11""\11""""""3"""\11\11\11\11\11\11"\11\11\11"3Uw3\0\0\11\11\11\11\11\11\11\0\11\11\0\11\11\11\11\11"""\11"\11\11\113"""\11\11\11\11"""\11\11\11\11\11\11\11\11\11"\11\11\11\11"\113UUD3""""\11\11\11\11""""\11\11\11\11"U\11\11""""""\11\11\11\11\11\11\11"3"UUUDDDDUD3"\11\11"\11"3"3"\11\11\11"""""""""3"""33333D33D33DDUDD3"3"\11\11"wfUUUDD3w"\11\11\11\11\11\11"\11""""""33"3"""""3\11\11\11\11\11\0\11\11\0\0\11\0\0"\11\11\11"""""\11""33""""""3DDD333"33333333UUDD33D333D33DwUffww\99"""""\11\11\11\113D\11\11"\11"""""""\11\11\11\0\11\11\11\11\11\0\11\11\11\11"DªªfDDD3Dff3""33"333\11\11\11\11\11\11"\11"\11\11\11\11"\11\11"""""""\11\11\11\11\11\11\11\11"""\11\11\11\11\11\11\11"""3D33"33"""""\11\11\11\11\11\11\11\11\11"DwD\0\0\11\11\11\11\0\11\0\11\11\11\0\11\11\11""\11\11\11"\11"\11"""3D""""\11\11\11""""\11\11\11\11\11\11\11\11\11\11"\11\113UD""""\113"\11\11\113""\11\11\11\11\11\11\11\11\11\11"""\11\11\11\11"""\1133"3"3UD3""D333""""33"""\11\11"""""""\11""333"""333333DUDDDUUDUfD\11"UwfUUUDDD3f\11\11\11\11\11""""""""""333"""\113U3\11\11\0\11\11\11\11\11\11\11\0\11\11\11\11"""""\11\11\11"""""\11\11"""3DD333""3"33333DUDDDD3D333D333UDfw\88\99D\11\11\11\11\11\11\11\11\1133\11\11\11\11""3"\11\11\11\11\11\11\11\11\11"\11\11\11\11""3w»w33D3DwU3"3""""""3"\11\11\11\11\11\11""\11\11\11\11\11\11"""""""""\11\11"\11\11\11\11\11"""\11\11\11\11\11\11""""3"D33"""3""\11\11\11\11\11\11\11\11\11""UD\0\0\0\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11""""""\11UUf3\11"\11\11\11\11""""3f3\11\11\11\11\11\11"\11\11\1133""""\11\113\11\11\11\11""\11\0\11\11\11\11\11\11\11\11\11\11"\11"\11"\11""""3"""\11\113\11\11\11\0"U3""3ffD3""""""3"3"""""3D"3""""33333DUDw\88fUU\8833\88\88ffUUUDDDDDD\11\11\11\11""3"""""33""3"""\11"DU"\11\11\11\11\11\11\11\11\11\11\11\11""""""\11"""3""""""""""3D3"333"3D3333DUUDD3D333"3333DDUw\88\88w\11"\11\11\11\11\11\11\11\11"\11\11"33"""\11\11\11\11\11\11\11\11\11"\11"""3Dw»\99"""3DUfD""3"""""""\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11"\11""\11"3""\11\11\11\11\11"""3""3""\11\113"\11"33DD3"DD""D"\11\11\11\11\11\11\11\11"3D3\0\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11Df3\11\11\11\11\11\11\11"""\11\11\11\11\11"\11"""\11\11\11"D""\11""\11\11\11\11\11\11\113\11\11\11\11\11\11\11\11\11\11\11\11"\11"\11\11""""""3""\11\11\11\11\11\11\11\11"3"Dw\99\99wD33""""3"""3""""DD""""""""D3D33Dww\88w\88Df\88fUUfUUDUDD3DU\11"""3"333"""3"3D""3""DD3"\11\11\11\11\11\11\11\11"\11"3""\11\11""""\11\11""""""""""3"3D333"DD33D3DDUUUD333D33D33"UDUff\99U\11\11\11\11\11\11\11\11\11\113""""3"\11""""\11\11\11\11\11"\11\11\11\11"Dªª3\11""DUUU3"33""333\11""\11\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11""""\11\11""""3""""3""\11\11""3"3"3333DD333D3\11\11\11\11\11\11\11""""\11\0\0\0\11\11\0\11\11\11\11\11""\11\11\11\11\11\11\11\11"""""\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11"\11""""3\11\11"33""""\11\11\11\11\11\11\11D3\11\11\11\11\11\11\11\11\11\11\11\11""\11""\11"""""3"""\11\11\11\11\11\11\113w\99ª\88ª\99\99w3""3""""""3""""33""""3"""DD3DDUDD\99ªª\99\99U3DUUDUUDD33ff""""333""""3"3""333fff""\11\11\11\11\11\0\11\11\11\0""""\11""""""\11"""\11""""""\1133"UDD3333DDDD3DUUUUD3DDD3""""UUUU\88f\11\11\11\11\11\11\11\11\11\11\113D"""""\11\11\11\11\11\11\11\11\11\11""""\11\88ªU"""3fUDDD333""3U3""\11\11\11\11"3"\11"\11\11\11\11\11\11\11\11\11\11\11\11\11""""\11\11\11"""""""D33"""""33"33333D33"3""\11\11\11\11\11\11""33\0\0\11\11\0\11\11\11\11""\11"""\11\11\11\11\11\11"""""""\11\11\11\11"\11\0\11\11\11\11""\11\113"\11"""3"\11\11\11\11\11U3"""""\11\11\11\11\11\11"""\11""\11\11\11\11\11\11""\11\11\11"""\11"""3DDf3"3""33Uw\99\99\99\88w\88\99\88\88U3"""33D"""33"""3"""""""3DDDDDDfUD\99ª\88UDUUUDfUDD"3\88\99U3"""3D"""3"""""3333D33""\11\11"\11\11\11\11\11\11\11\11"\11\11\0\11"""""""""\11"""""""D"\11"D33333DDDUfwfUUffDUD3""3"3DwUwf""\11\11\11\11\11\11\11\11\11"\11""""""\11"\11\11\11\11\11""""3DUªª3"""DfDUUD3""""""""""\11\11"""\11\11\11\11\11\11\11\11"\11""\11\11\11"""""""""""""3DDD33"""""""""3""33"""\11\11\11\11\11\11""""D"\0\11\11\11\0\11\11"\11"\11\11\11\11"\11\11\11\11\11\11\11\11"""""""\11\11\0\0\0\11\11\11"\11\11\11"\11\11"\11""""\11\11\11\11\113U""""""\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11"\11\11"\11\11"""""3333f\88wffUf\88\99\88fDDUUfffw\88D33""""3333""""333""3"3333DDD3Dfff3f\88UUUfwwfU3Ufªª\99fD3D3U3""3"""3"3D33"""3"""\11"\11\0\11\11\11\11\11\11\11\11\11\11\11\11""""\11\113\11"\11\11"""""\11\11""3333DDUDf\88\99\88fUUfwfUD""""DDUfUw""""\11\11\11\11\11\11\11\11\11\11""3"""\11\11\11\11"\11""33"D\99»\883"DUfUDDD3"3"""""""\11\11\11\11\11""\11\11\11\11\11\11\11""""""\11"""""""3""""33DDUDDUUD333"3""""""33""\11\11\11\11\11\11\11\11""33\0\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""\11\11\11\11\11\11\11\11\11\11""\11\11"3"""""\11\11\11\11\11\1133""""3"\11"\11"\11\0\11\11\0\11"\11""\11\11\11""\11\11\11""""""3DUU\88ª»ª»»ª\88f3"\11"3UD33DUD"3333""33"3"""3333"""33333D"DUUff\11UwfffwwfDDU\88\99\99wwwf3DDDD"""""3"3333"""33"\11"\11\11\11\11\11\11\11\11\0\11\11\11"\11\11""""\11\11""\11\11"""""\11\11\11\11""3"33UUDf\88\88wfUDUwwfUD3""3DUffww""""\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11""DU3\11\11\88D33wfUD""""""D3"3""\11\11\11\11\11""""\11"""""""""""\11\11"333333"""33DUUUU3DDUDDD3"3"3""""""3\11\11\11\11\11\11\11\11\11"3"\0\0\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11\11\11\11""\11\11""""3333"\11\11"\11\11\11\11DD""3"3U""\11""\11\11\11\11\11""\11\11\11\11\11\11\11\11\11\11"""""33DDUw\88»»ª\99UD""\11""""D3""33"3"33""333"3""3333333333333DDDUUf3"U\99\88\88wwwffwwwwfffwwUDDUU""""3"""33"3333""""\11\11\11\11\11\11\0\0\11\11\11\11\11\11""""""\11"\11\11\11"\11"""\11\11\11"""DDD\11Df\88\88fUUUDwwwwfUD3"3DDUw\88f3""\11\11\11\11\11\0\11\11\11"\11\11\11\11""""\113"D3""\11D\99ªUDDUwU33"3"""\11"3"3"""\11\11\11"\11\11\11""\11"""""""""3"\11""""3DDDD3DDDDD"33\11\11\11""3""333D3""3""\11\11\11\11\11\11\11\11"""3\0\11\11\11\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\113\11\11""""33\11""DUUUD33\11\11\11\11\11\11\113DD""""3U33"\11\11\11\11\11""\11"\11\11\11\11\11\11\11\11\11"3DDDDDDUUDww\99ª\88D3"""\11""\11"D""3""3333"""33333""""3333""""""3DDDUU"\11"\11\99ª\88\99fUUfwfUffDUwwwwff"""3333"""3D3""3""""\11\11\11\11\11\11\11\11\11"\11\11\11\11""""\11\11\11\11\11\11"\11\11\11\11\11\11\11"""3UD3"U\88wUfUUf\88w\88wffUDDDDDf\99ª\88"""\11\11\11\11\11\11\0\11\11\11\11\11\11""3"\11"3""""3fªªf3DfUUD3"""""\11\11\11""3"\11\11\11\11\11\11\11\11\11"\11\11""""""""\11\11\11"""""""""3""3333"""\11\11\11"""""333"""33"""""\11\11\11"\11\11\1133\11\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11"\11\11\11\11\11""\113"""3"\11\11"3DfUD3""\11\11"\11\113DDD3"""UUDD""\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\1133Dfww\88wfUfUUfUD3""\11"\11"""\113D"3"""333DD333333""""33D3333"""""33DU"\11"\11\11f\99\88wfffffDUU3DUUw\99\99\88D333333""""3D333"""""\11\11\11\0\11"\11"\11"\11\11\11\11"""\11\11\11""\11\11"\11\11\11\11\11\11\11\11""333fU3"Dwf\88\88\88wfffwfUUDDUU\88ª\99U"""\11\11\11\11\0\0\11\11\11\11\11\11"\11"""UU\11"DU\99ª\99fDU\88fD3D""\11""\11\11\11\113"\11"""\11\11""\11\11"""\11\11\11"""""""\11\11"3"3"""\11"""""333""\11\11\11\11\11\11""""""""3""""\11\113""\11\11"\11"\113\11\11\11\11\11\11"""""""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11""\113D3\11\11\11\11\11"3"\11\11"\11\11\11\11\11\11333D3""3D""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"3DU3UfwfUfUD3D3""\11\11"""\11"\11\11\113D3"3"33DD33333D"""""3DDD3""3""""3DU33"\11\11\113\99\99w\99\88fUUDD3DDUUw\99\99\99w33""""""333DD""""3""\11\11\11\11""\11"\11\11\11\11\113\11\11\11\11""\11""\11"3\11\11\11"\11\11"""3fwU\11"\11"33w\88wffffffUffUUfw\88\883"""\11\11\11\11\11\11\11\11\11""""\11\11\11D\99ªÌ»ªª\88fUDf\88DDD3"33""""""33"""""3""\11"""\11"\11"\11\11"""""""""3""\11"""""""333""\11\11\11\11\11\11"""""3""""""\11\11""3"\11\11"""3"3\0\11\11\11""""""3""\11""\11"\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11""3"\11\11\11\11\11\11\11\11""\11D33\11\11\11\11"3D3"""\11\11"""\11"\11\11\11\11\11\11"\11\0\11\11\11\11""\11\11\1133DD33UDD3"""33\11\11\11"\11"""""\11\11\11D333"DDDD33DDD""""33DDDD33"""\11"DDUD3\11\113"D\88fffUDDDD3DDUfffw\88\88f3U"""""333333"""3""\11\11\11\11\11"\11"\11""\11\11\11\11\11""""\11\11D"\11\11\11\11\11"\11\11\11\113ffD"\113\11"3"U\88fwwwfUffUwUDwwfww\11"\11"\11\11\11\0\11\11\11\11""\11\11\03f\99\99\88wfffUUfwfU3333"""3"""""3""""""""3""""\11""""\11"\11"33"""33D33"""""""""""3"\11\11\11\11""\11"""3""""\11\11"\11""\11"\11"""33DD\0\11\11"3\11\11""3D"\11\11""""\11\11\11\11\11\11\11\11\11\11\11\11""3"""""\11"\11"\11\11\11\11\11"""\1133\11\0\11\11\11\113DD3""\11\11""""\11\11\11"""""\11\11\11\11\11\11"\11\11\11\11\11\11\1133"33"\11\11\11\1133\11\11\11"\11"\11\11\11"\11\11\113DDDDDUDUDDUUD33"3DUDUUDD3"\11\11\11\113UUU3\113UDfDUfUD33333DDfffff\99\99DU""""3"3D3D"""""3"""\11\11\11\11\11"3\11""33\11\11\1133\11\11"3D""\11\11\11"\11\11"Uwf3"\11\11\11""3""fwfwwwfUUUffUfwfw\993"""\11\11\11\0\11\11D"""\11\0"\99»\88wwfw\88\88\88wwfD333"3""""""""\11"""""""""3"3""\11""\11"\11""""3""""DDD""""""\11"\11"""3""\11\11\11\11\11\11"""3"3"""""""""\11""""3DD3\11\11\11\11"""\11\11"3\11\11\11""\11\11\11\11\11"\11"\11\11\11\11\0\11""3""""\11\11\11\11\11\11\11\11"\11\11"3"\11\11\11\11\11\11\11\11"D33""""""""""333"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11"\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11""DD3\11"UD33UUUDD3DUf3UfUDD3"\11"\11""3UD3"\88\88ffUUfUD333DDUffwwww\99\88\88wD3""""333D""3"""3"\11\11\11\11"\11Uf3Dff"\11"""3"""""3"\11"""\11Dw\88D""\11\11""3D3D3UwwfUwffffwfwffU\99D""""\11"\11\11\11\113\11\11"UªªwU3DfwfUDDDD3""3""""\11""""""""""""""""\11\11"3""\11\11\11\11\11\11""33""33D33"""""""\11"3"""\11\11\11\11\11\11\11"""""3DD"\11"""\11\11""""33DDD\11\11\11\11\11\11\11\11\11"\11\11\11""\11\11"\11\11\11""\11\11\11\11\11\11\11\11"""\11\11"""\11"""\11""\11"3"\11\11"\11\11\11\11\11\11\11""33"3D""\11"3"33D"\11\11""\11\11\11\11"\11\11\11\11\11"\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11"\11\11"D3"\0UUffDDD3"\11DwfffUD"""""3DD3"ª\88wfffUUUUD3DUDUUwfww\88\88ffU""3""""3"""33"3"""""\11\11DwwfUf""\11"\11"""\11""""""\11"3wf3"3""""""D"UD""wwfDwwww\88wwwff\88\88"""3""\11\11\11\11"\11\11f\99ªfD333DDUDD3333""33"""\11"""\11\11""3"""""""\11\11\11\11""""\11\11\11\11\11""3"\11""3D333""333"\11\11"3"""\11\11\11\11\11\11""\11"33"D3"""""""""3DDDUwD""\11\113333Df"3""\11\11\11\11\11\11""\11\11"\11\11""\11\11\11\11""""""""\11"3""""""\11\11\11"\11\11\11\11\11\11"333"3"\11\11"""\11"\11\11\11\11"""\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11""\11UDUUDU3\11"\11UfUffUD""\113""D\88f\88ªªwfUUUUUUUDUUUfwfww\88\88w\88ffU33"\11""""33""3"""""3Dff33U"""""\11\11\11\11\11\11"""""3UUU3\11""""""3"D333""3Uwww\88w\88wffffUU\88D3"""""\11\11\11\11\113\88ªwD3"""333D3333""333"3"\11"\11""\11\11""""""""\11\11\11\11\11\11""""\11\11"\11""3"""""""""3"""3"\11\11""3"\11\11\11"""""""""33"33"3""\11"\11"3DDfwwffD3\11DUUff\88\88DU3\11\11"\11\11""\11\11""\11\11\11\11\11\11\11\11\11"""""""\113fU""""""\11\11\11\11\11\11\11\11\11\11"3""\11""""""\11"""3""\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\0\11\11\11\11\11\11\0\11"\11\11\0\11\11\11\11\11\11\11\11\11""3DDD3DU"\11\11"w\88\88\88wwU333"3U\99\99f\88\99ªwfUUUffD3DDUDUfwwwffwwUw\88\88wU3"""""\11""3"33"DUUU3\1133\11"""\11"\11\11\11\11"3"33Uf333"""\11\11\11\11"\113"33"""DUUw\88wwffwffUUD3"33""""\11"""\88»\88DD3"""""33333333""D3"""""\11\11\11"""""""""""\11\11\11\11"""\11\11\11\11\11"""\11\11"""\11"\11"\11\11\11\11\11\11\11""""""\11\11""""""""33"\11"D""D3"""\11"DDDw\88UfwfwDUfDw\99\99UU3D"""\11"\11\11\11\11\11"""\11""\11\11\11"""""""33ff3"""""""\11\11\11\11\0\11\11\11"""DUD3""""\11"""33"\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\0\11\0\11\0\0\0\11\11\11\11\11\11\11\11\11\11\11\0\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""DUUfffUfUDfffUDDfw\88\88w\88\88\88wfU\88\88\88\99wUwfDUUUDDDDUUfffffwUUwwwUUUU3"333"""""3fwDU3\11""\11\11"""3D"""""\113U\883\11"3""\11\11\11\11\11\11\113"\1133""3""ff\88w\88wffffDwD"""\11""\11""""\11\88UD3""""""333"""3"""3333"""\11\11\1133D3""\11""""\11\11\11\11\11"\11\11\11""""""\11"""\11"""""\11\11"\11\11\11\11\11"\11""\11""\11"\11""""33"""D"""3""""3DDUw\88UUUUUUDDUw\99\99wwUUw3"""\11\11\11\11"""""""\11\11"\11""""""33U3\11""""3"\11"\11\11\11\11\11\11\11""Df\88U3""\11"""3""333\11\11\11\11\11\11\11\11\0\11\0\11\11\0\11\11\0\0\11\0\0\0\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\113"3fUfUfUD3"""""""""3DDUUffUfwfDwwwffwwUUUUUUfUUfffUUf\88\88wUUffww3""""""""3U3\113""\11"\11\11D3Uwf"""33DUw3"""""\11\11\11\11"\11\11"3333""3333UD\88w\88fffUffw"33"\11""""""3\88DU""\11\11""\11"""3"333""33""""\11\11\11\1133"3D"""""""\11\11\0"D""""""""\11"""""\113"\11\11\11\11\11\11\11\11\11\11\11"""\11"\11\11\11""""3"33""3""""""""3DDDU\88333DDDDUUfwwfw\88wfww3""\11\11\11"\11""""""\11"""""""333DD"""3"""""\11\11"\11\11\11"""3wU\11\11\11\11\11""""33"3"\11""\11\11\11\11\11\11\11\11\0\11\11\11\0\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\113"DfUD3333"3"""""""""3DDDDDUUfUUU33UffDUfwffUfUUffwwUf\88wwfUUfw\88w\88\88\88\88\88D3\11\11"33D"\11\11\1133fwffwfUUDUD3ff"""""3\11"\11\11\113"33333"3"3D3DDw\88wfffwf\88D3"""33D"\11"wÌ\99U\11"\11"\11\11\11\11""""333"3""""""\11\11\11\11"3""3"""""""\11\11\11"DU3""\11"\11\11\11""""""""\11\11\11\11\11\11\11\11\11\11\11""\11"\11\11\11\11"""\11"33333""3""""""3D3DDU"""""3DDUUffwfw\99\88fw\883"""""""3""33""\11\11"3"33"""3DD"\11""\11""""""\11\11""3"""\11\11\11\11"\11\11\11\11""D3"\113D3\11""\11\0\11\11\11\11\0\11\0\0\0\11\11\0\11\11\0\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11"\11"U3""""3""\11""\11\11"""""333DUfUUUUD3"3f33D33wwffwUfD\11\11"Ufffwfwwfw\88\99\88\88\99\88\99\99\88wfUw\99f"3w\88\99\99wUDf\88fD3333DD""""3D""""""3"""3""3333"33DUwww\88wwww"33333D"3\88Ì»fD\11""\11"\11\11\11""3"333"""""""D\11\11\11\0"D"""3"\11"3"\11\11\11\11"D\11"3"\11\11\11"""""""\11""\11\11"\11"\11\11\11\11\11\11\11\11"""""\11"""""33333""33"""333DDDDf3""""33DDUUUUfUf\88\88\88w\993"""\11\11"""3DDD"""\11"""3333D3"""\11\11\11\11\11""""""\11"""""\11\11\11\11\11"\11\11\11""""""33U"""\11\11\11\11\11\11\11\11\0\0\0\11\11\0\11\11\11\0\0\11\11\11\11\11\11\11\11\0\11\11\11\11\11""\11"3"\11\11\11"\11"DD3"""""""\11\11\11\11\11\11\11"""""3DDUffDD33""3""3333f\88w\88fD"\11\11\11\11\11"Ufwwwfw\88\88\88w\88\99\88\88wffDDf\88ª\99ª»ª\88fU3DDwfDfUUwf"""3D"D33"""33"""3""""33333D3D\99\88\88\99w\88U"33""\113\88Ì»\88DUU"""\11\11"\11""33"33"""""""3\11\11\11\113D\11""""\11""""""\11"3\11\11""""\11\11"\11""\11\11\11\11\11\11""\113""""""""""""""""\11"""""D3""3""""33DDDDDU3""""3333DDUUfffwff\88»\99f3\11"\11""3"DDUD"""""""33"3""\11""\11\11""""""""""""\11\11\11\11\11\11\11"\11\11\11""""33"\11"3""\11\11\11\11\0\0\11\11\11\0\11\11\11\0\11\11\11\11\0\0\11\11\11\11\11\0\11\11\11\11\11\11\11""\11\113"\11\11\11\11\113D3"""33""""""\11\11\11\11\11\11\11\11"3Uw\88\88f3"3""""""33333D\99w"""\11\11\11\11\11\11"33wf\88\88\88fw\88\88\99\88wwffDfw\88\88w\99\99ffDUUUfffwUDfwD"3""3DD3""3D3D3"""""""33"333333w\88\99\88\88U3D3D33\88Ì»w33fD3\11\11\11"""""\11"33"""""""\11"\11\11\11\113D"""3"\11\11\11"\11""""\11\11\11\11\11\11"\11\11\11\11""\11\11\11\11\11\11"""3"3""""\11\11""33"""""""""3D""33"""""3D3DDDD3D3"""""3"33DDDUfw\88w\88\88\99Ì\883""33D3DD3""""""3""""""""\11""""\11"""""""""\11\11\11\11"\11\11\11\11\11\11\11\11"""33"\11""""\11\11\11\11\11"\11\0\11\11\11\0\11\11\11\11\11\11\0\11\11\11\11\11\0\11\11\11\11\0\11\11"\11"3"""\11""UU"""33""""""""\11\11\11\11\11\11\11\11\11""3\88\88\88w3""""""333"33Dwf"\11"\11\11\11\11\11""\11\11"w\88\99\99w\88\88\88\99\99\88DDUUww\99wwwDDD3DDUw\88fffDffD\11""3DUUDUUUDDf3"""3"""3"""D3333\11\99»\8833DfDfªÌª33Df3"\11\11333""""""3"""333f"\11"""\11"3333"3""""""""3"\11\11\11\11\11\11\11\11\11\11\11\11\113\11\11\11\11""""""3""\11\11\11"33333""""""""D3"""""""33DDDDDUU\11\11D3D3D"""""""3DUfww\88\88\88ªª\88"33333""3D""""""""""""""\11"""\11\11"""""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3"\11\11\113""""\11\11\11\11\11\11\11\0\11\11\11\11\11\0\0\0\0\11\11\11\11\11\11\11\11\11\0\11"\11\11""\11\11"\11"UwD"\11\11\11"33"""""""\11\11\11\11\11"\11\11\11\113U3"DwU""""""33""DfUw"\11""\11\11\11\11\11\11\11\11\11"3fwfUUDDDUf3DDw\88\88wfU""DD3"DUUfDUDDUfUUDDfwUUDDDDDDD"3""33"3""33""3"D33\99ª»\88U3"DwÌ»ffUD3"\11"\11U3\113UDD33D3\11\11""3333""\11\11\11"""3333"DD""""3D"\11\11\11\11\0\11\11\11\11\113"3"\11\11"\11"""""\11"3"\11"DD3333""""""""D3"""""""""DDDUDDD\11\11"3""33"""3U3"33DDDUwwww\99\88\883"""""3U3""""3"33"""""\11"\11"\11""""3"\11"\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3"""""\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\0\0\0\11\11\11\11\11\0\11\11\0\11\11\11\11""""\113fUDDD"""""33"""""\11\11"\11\11\11\11\11""""UU""3Uf3"33333"3333\88D""\11"\11""""\11\11\11"""3U"UU"3""UDwUw\88U"D3""3D333DDD3UDUwwU"DUDfUDD333"D3333DDDDD3333"3"D"33U\88ª\8833\88»»fUD333DD"""\11\11\11""""""DDUD""""""3"\11\11"""""\11\11""3""3"""3\11\11\11\11\11\11\11\11"""3"\11\11\11\11"\11\11\11"\11\11""""""3DD33"\11\11333"\113D"\11\11\11"""""3UDUUDU"\11"3"""3""""DD"""333DDfw\88w\88\99ww""""33"""3fw3D3""""""""""""3""""\11\11""\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11"""\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\0\11\0\11\11\11\11\11\11\11\11\11\11\11\11"\11"3Uf3"3DUD33D3""33"\11\11\11\11\11\11\11\11\11\11\11\11"DUf"\11"3fD3""333""33UwD\11\11""""\11"\11"""\11\11"333D"3"\11"Uf3"fD"33"DDUD33"33D3UUU3"333"3DDDD33"D33333"3DD33333""""3D3Dwª»»Ì»wUUD3"3Uf3"""\11\11\11\11"""""\11\11"""""3"""""33"""\11\11""""\11\11\11""33""\11\11\11""\11""""\11\11\11""\11\11\11\11\11\11\11""\11"\11\113DDD"""33""\11"D""\11\11\11""""33DUDUD3""3""""""3""\11\11""""33DDUwww\88\99wwU""33""3DDUU3"3"""""""""""""""""\11\11"\11\11\11\11\11\11\11"\11\11\11\11"""\11\11\11\0"3"\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\113wfU3""33333"""""3""\11\11"\11\11\11\11\11\11\11\11\11"3333"\11\11UD3"333"""3D\88UD\11\11\11\11\11""3""\11\11\11"\113333333333"""33D33"333""""333Uf3""333""3D3333"D3"33"3333"333""3"33333\88\99ªÝÝ\88D33333""33"""\11\11"\11""""\11\11\11D""\11\11\11\11\11"""U3\11"""\11""""\11"""\11\11"""\11\11\11""""\11"\11\11\11\11"\11\11"\11\11\11\11\11\11"\11"\11\11""3333"33"\11\11""3""\11\11""""3"DUfDfD"""3"\11""""3""""\11""""DDUfffw\88fffw3D333D333D3"""""""3""""""\11\11"33"\11\11"\11\11\11\11\11"""\11\11\11""""\11\11\0\113"\11\11\0\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11UfUD3""33"""""""3""\11\11\11"\11\11\11""\11\11""\11"""""""\11U3333333""D\88\88\113\11\11\11\11"\11\11\11\11"\11\11"""3"""33D""\11"3"DUD""""3"""""33DD""""""""3333D3"3D"DDDDD3"33""333"3D33""f»ÌÝ\99wD3D33""""\11"""""""""\11\11\11""""\11\11"""""\11\11\11\11"3""\11"""\11"\11\11\11""""\11\11\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11"333DDD333"""33"\11\11\0\11""3333UUfUU\11""D3\11"""""""""""""333DDUUU\88\88ww\88\99fD33""333UU"3""\11""""3"""\11333"""""\11\11"\11\11"3"\11\11\11"""33\11\1133""\11\11\11\11""""\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\0\11\11\11\11\11""ffD3""33""""""""""""""\11\11\11"""\11\11"\11\11""\11\11\11"""3f"3""""""3D\99D"\11\11\11"\11""\11"\11\11\11"\11\11""\11\11\11\113D"\11"3UfD3DU3""3"\11"""33UD""""""""33""""DD333DDU3"3"""333"333"3"D»Ì»\88wUDD3""""33"""\11\11\11"\11""\11""33""\11""""""\11\11"3"""""""""\11\11"""3""\11\11""\11"\11\11\11\0\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11""333D"D3"D"\11""D"\11\11\11\11\11""33DDUffU3""33""""33"3"3"3""""33DDUUUwwfUww3\11\11\1133DDfwf3DD3UfU"\11"""33"""\11\11\11\11\11\11\11"""""\11\11\11""3DD"\11"U"""\11\11\11\11\11"3"\11""""\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0DfUD3333"""""""""\11\11"\11\11\11\11\11\11""\11\11\11\11""\1133""""""UD\11""""""33ff\11\11\11\11"3"""\11""\11\11"3"""33"3UDDDUD33"DD3D3\11\11"""""33DU3"""""3"3""""D3DD33DD3"""3333""3"3"3"U»ªfUDDDD333""""\11""\11"\11""""\11""""\11\11""""""""""\11"""""""""""\11\11\11\11\11\11""\11"""\11\11\11\11\0\0\11\11\11\11\11\11\11\11\11\0\11\11\11"""333D333""""""3"\11\11\11\11\11""33DDDf\88D3""""""""D3""33"""3""""3DDDUffwwUU"""""3D333DwwwfDUD3"\11"33\11\11\11\11\11\11\11\11\11\11\11\11\11""\11"\11\11"D33D3"\1133""\11\11\11\11\11\11\11\11""33"\11\11\11"\11\11\11\11\11\11\11\11\11\11""\11"""\11ffUDD3"""\11\11\11\11\11"\11"\11\11\11\11\11\11\11\11\11\11\11"""\11"""\113D""""""w"""""""""Dw"\11\11"\11"""3"\11"3""DD3D33DD3"""""""333333""""\11"\11"3DDD\11"""""3""""""UD333D3D"3333"""""3""DDw»\883DD3DDDDD""\11\11""3""\11""\11\11""\11"\11\11\11"""""""""""""""""""""""""\11""\11\11\11"""""\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11"3"3"33"""""3"\11\11\11\11\11\11"""33DUU\99D"""3\11\113"""3"3""3"""33"3333DUUUwwff3\11\11\11"""3D""""""""\11\11\11"""\11""\11\11\11\11\0\11\11\11\11\11\11"\11\11\11\11\11\11\113\11\11\11\11\11"""D3\11\11\11\11\11\11\11"3"3""\11"""\11\11""\11\11\11\11\11\11\11\11"\11""ffD333""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11"\11\1133""33\11""""\11DU\11""""""""Df\0"""\113UDDUD"""3D"D3"3"\11\11\11""""""""3""3DD""\11"""33U\11"""""""""""\113DDD333D33"""""""33""33\99ªU33DDD3UfUU"""\11""\11""\11"\11""3\11\11\11\11""\11\11\11""""""""""""""""\11"""""""\11\11\11\11\11"""\11"\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11""\11"3"""""""3"""""\11\11\11\11\11\11\11\11"3DDUwD"""""""333""\11"33D33""D"3333DUUfDUDD\11\11\11\11"""\11"""""\11"""""""\11\11""""\11\11\11\0\0\11\11\11\11\11\11\0\11\11\11\11\11"\11\11\11\11\11\11\11\11"""\11"\11\11\11\11"""""\11"""""\11\11\11\11\11\11\11\11""\11\11\11\11UfU333"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11"\11\11\11\11\11"3"3DD3"""""\11\88D""""\11\11\11\113Uf33333D"\113UUD3""3DD""\11\11"\11\11""\11"""""""33"D"\11\11\11\11"3U3""""""""""\11"\11DD3333333"""33""33"\11"U\99\88D3"DDDDDDUDD3"\11\11\11\11\11\11"""\113"\11\11\11\11\11\11\11\11"\11\11\11"""""""\11"\11"""\11"3"""""3""\11\11"\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3\11\11\11\11"""""3DD"""\11\11"\11\0\11\11\11\11\11"3DUw3\11"""""""""3""333D33333"3"33DUUUwfUD3\11"\11\11"""\11"""""\11\11\11""""\11\11"""\11\11\0\11\11\11\11\11\11\0\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11""""33"""""""\11\11\11"""\11\11"\11\11\113wfUD33"""\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11"\11\11\11\11\11\11"\11"""3D333"""\11\88U"""\11\11\113DUUDfDDDD"\11"UUfw\88wUUD"\11\11\11"\11\11"""""""\11\11""3""D3\11\11\11\1133UD""""""\11""\11\11\11DD333DD3"""""""""3""U\99ªf"3""33DDUD3"33""\11\11\11\11\11"""3"\11\11"\11\11"\11"""""\11"""3"""""""D""3D3""""\11""\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11""""""\11\11"3"3UfwD"3\11""\11\11\11\11\11\11\11\11""3Uw\883""""""DUD"""3"""""3333"33D333DDDUU""""\11\11\11\11""\11""\11\11\11\11\11\11\11\11"\11""\11\11\11\11\11\11\11\11\11\0\0\11\11\0\11\11\0\0\11\11\11\0\11\11\11""3"\11\11\11"""""\11"3"""""""\11""\11""""""\11"""f\88UD333""\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11"""\11\11"""""3\11"3""""""\11\0wf3"""3DDD3D33D33"""U3DfD3""\11\11\11\11\11"\11"""""\11\11\11"""\11"""""3""""3DD""""""\11""\11\11\11"U333D33""""3""""33D\99ªw3"3DDD"33DD""D3"""\11\11"\11""3""\11\11""\11\11\11\11\11""""333""""""3"3"""\11"3"""\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11""""3D""3""""3333"DUfU""""\11\11\11\11\11\11"\11\113DDUDD""""""DUD"""3"333""3"333DD3D33DUDDffUD\11\11\11\11"\11\11"\11\11\11\11\11\11\11\11\11\11\11"\11"""\11\11\11\11\11\11\0\0\11\11\11\11\0\11\11\11\11\0\11\11\11""\11\11\11\11\11\11"33""""3""""""""""""""""""""DwffU33""\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11""""\11"33""""DD3"3"""\11\11\11ª\88UDD333"""""""3D3"3D3D3\11\11"\11\11\11\11\11\11"\11\11\11\11"\11"""""\11\11\11\11""""D3\11"3UD"""\11"\11\11\11"\11"DUUD3""3"""""""""Uw\99\99fU"""33"33DDD33""""""""""""""\11\11"\11\11""\11\11\11"""333"""""3D3"""\11"""""""\11"\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11""33"""3""3""""""3DDDD"\11\11\11\11\11\11\11\11"""Dw\99D\11\11"""3DD3"\11""""""33"""\11\11"33"3"33DDD3ffD3"\11\11\11\11\11"\11\11\11\11\11\11\11\11"\11\11\11\11"\11"\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\113\11\11\11\11\11\11"\11\11"\11\11""\11\11\11""3"3"""33"""""3""""""3UwD"3"33""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\113UUD3UfwwD333"\11\11\99UD3"""""D""333UD"""3""\11"3"\11\11\11\11\11"""\11\11\11\11\11\11""\11\11"\11\11\11""\11"3DUDDU3\11""\11\11\11"""DDUD3"""""""33"""3f\99\99f3"""""""3"DD3D333"""""""""""D3"""\11"\11\11\11\11\11""""""3""""333"""\11"""""""\11\11\11""\11\11\11\11\11\11\11\0\11"\11\11\11"333""3333""""""""""""\11\11\11\11"\11\11"3"3D\99ªf\11\11\11""333""""""\11"""""\11""""""""""""3DDDD3DD3\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11""\11\11\11""\11""""\11"\11\11\11"3DDDU3333""""33""""33Dff33""33"""""\11\11\11\11\11\11\11\11\11"""\11\11""\11\11\11\11\11"DUwUfwf3DUUD33UwwUD3""33""33333DU33"""\11\11"3D"\11\11\11\11\11""""\11"\11\11"\11""\11\11\11\11"\11"\11\11""33UfU""""""\11""DD3fU"\11""33""""Dfw\88wU3""""\11"""""3DDD3DD"3"""33""""DD\11"""\11\11\11\11"""""""""""""3"3"""""""""""\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11"3333"""""\11\11333"""""""\11\11\11\11\11\11"3\113DDf\99ªªD\11\11\11"3D""333""""\11""""""""\11"""""""""3D3DD"D3"\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"""\11""\11"\11\11"\11\11\11\11\11"D3UUD3"""33333""""33fwD333"3""""""""\11\11\11\11\11\11"""\11\11\11""\11\11\11\11\11"3DU\88\99fUD33333DDDUD33""""""""333333"3""\11\0"DD"\11"\11\11\11"""""""\11\11\11\11\11\11\11\11"\11\11"\11\11\11"""33DUD""""""33"DDUU"""""D""U\88\88wU3"""""\11""""""3DD33""D3""3"3""""33""\11\11\11\11\11\11\11""\11"\11""33"""""3""""""""""\11\11""\11"\11\11\11\11\11\11\11\11\11\11\11\11\11"3""""\11\11\11\11"33\11\11\11"""\11"\11\11\11\11\11\11\11\113"3Dw\99ªªf"\11\11\11"D33"33"""""""""\11\11\11\11""3"\11"""""\11"""3"DD3D3""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3""""""\11\11\11\11333"3""""3333""""333Dww33333333""\11\11""\11\11"\11\11\11""""\11\11\11\11""\11\11""3DDfwD"UU"\11\11""""33\11""""""""""33333333"\11\11"33\11\11\11\11\11\11""""333"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11""33DDD3"33""3UDDDD""3"Dw\88\88DD3""""""\11\11"\11""3DD33D""3U3"D3"\11\11\11\1133"""\11\11\11\11\11\11\11\11"\11"""""\11"""""""""""""\11""\113"\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11"""""\11\0\11\11"""""""\11\11"\11"\11\11\11\11\11\11\11\1133Dffª»wD\11\11\11\1133"3"3"""""""\11\11\11\11\11\11\11\11\11""\11\11"\11"""""33"UDDD3"\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11"""\11""\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11"33"333""\11\11Df"""\11""""333"""""33U\88w33333"33"\11\11\11\11""""""\11"""""\11\11\11\11\11"\11""333DDUDDD"\11""""\11\11\11\11\11\11"""""3"33"""3D"33"\11\113"\11\11"\11\11"\11"""""""""\11\11\11\11\11\11\11"\11"\11\11""""""""333DDD""33UUD""33"3UwwU333"""\11""\11\11\11\11""33DD33D33UU3"""\11\11\11\11"D3""\11\11\11""\11\11\11"\11"""\11"\11\11"""33"""""""""\11\11""\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\1133"\11\0\11\11\11""\11""""""\11\11\11\11\11\11\11\0\11\11\11\11"Uwf\99»ªw\11\11\11""""""""33"""\11"\11\11\11\11\11\11\11\11"""\11\11\11"\11\11\11\11\11\11"3333DD"\0\11\11\11"\11\11\11\11\11\11\11\11\11\11\11"\11\11\11""\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11"""33333""Df3\11"""333DD3"""333U\88\88UD33"3333""\11\11\11""""""""""3"\11""\11"\11\11\11""3333DUD\11\11\11\11\11""\11\11\11\11\11\11\11""""333"""3333333"\11""\11\11\11\11\11\11\11"\11\11""33""\11\11\11\11\11\11\11""\11\11\11""\11""""""33333DD""DD333DDUw\88fU""""""""""""\11\11"""DD3DDD33DD3"\11\11""\11\11"3"""\11\11\11"\11\11\11\11"\11"""""\11""""""""""""""\11\11\11\11\11\11\11"3"\11\11\11\11\11\11\11"\11\11\11\11"3\11\11\11\11\11\11\11\11""""\11\11"\11"\11\11\0\11\0\0\11\11\11\11\11"f\99\99»ª\993\11"3"D3"\11""""""\11\11\11\11\11\11\11\11\11\11\11\11"\11"\11\11\11\11\11\11\11\11""\11""3UDD\11\11\11\11"3""\11\11"\11\11""""""\11"3"3"\11"\11\11""""\11\11\11\11\11\11\11"\11""""""""\11\11""D""3DDD3D3"33D\88\99\88U33"333DD3"\11\11""""""""""""3"""\11\11\11\11""""3D3DUDD""\11\11\11\11\11\11\11\11\11\0\11\11"""""""""3"3"33"3""\11\11\11\11\11\11\11"\11"\11\11"333"\11"\11\11\11\11\11\11"\11\11\11""\11""""""33""33DU3333"33"Uww33""""""\11"\11\11"\11\11\11\11""3D333DD"33"3"""3"\11\113""""\11\11\11\11\11"\11"""""\11""\11\11\11\11\11\11""""""""\11\11\11\11\11\11""""\11\11\11\11\11\11\11"\11\11""""\11\11\11\11\0\11\11\11"""""\11"\11\11\11\11\11\11\11\11\11\11\11"3"DU\99ªª\88"\11\11"33""""""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11"\11\11"\11\11"33D"3D\11"33""""""""""""""D"""3""\11\11\11"\11\11\11""\11\11\11"\11\11\11"""\11\11\11\11\11\11\11\113333D3333UUDfª\99f33D33333"33""""""""\11""""""3\11"\11\11\11\11\11""""33DDDw3\11\0\11\11\11\11\11\11\11\11""\11\11"3"""""""33""""33D3D\11\11\11\11\11"\11\11\11\11\11\113"\11\11"""\11\11\11""\11\11\11""\11\11"33""\11""""333UDDD33"3U\99f3D3"""""\11\11\11\11"\11\11\11\11\11"DD3333D3""D3"\11""\11\11\11"\11"""\11\11\11\11\11\11\11""\11""""\11\11"\11"""""""""\11\11"\11\11\11\11\11"3"\11\11\11\11\11\11\11\11\11\11""UD333"\11\11\11\11"\11\11\11\11"\11""\11\11\11\11\11\11\11\11\11\11"3DUw\99ªª\88D\11"\11\11""""""""\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11""UDDDD"3"\11\11""\11"3""""333D""3""3"\11""""""\11\11\11\11"\11\11\11"\11"\11\11\11\0\11\11\11\11\11"D33D3""3Df\99wUDDDD3333333"""""""3""""""3""""\11\11\11"\11""""33DUUD"\11\11\11\11\0\11\11\11\11\11""\11\11"""D3"3333""3D3"\113D\11\11\11\11\11\11\11\11\11\11\11\11"""\11\11""\11\11"""""\113""""""\11""""""""3DDUf3"\11D\88w3"""3D"\11"\11\11\11""\11"\11\11\113D333333""333"\11\113\11\11\11""""\11"\11\11\11\113""\11"""""\11\11\11"\11"\11"""""""\11\11\11\113\11""3"\11\11\11\11\11\11\11\11\11""D3UDDD"""\11\11"\11\11\11"""\11""\11\11\11\11\11\11\11\11\11\1133wªÌ»ªD"DD\11\11\11""\11""""\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""3DDD"\11\11""""""33"""""3333""\11""3D33""\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11""3""3Uw3UDDD33333333""""""""33"""""\11"\11"""\11""""""33DwU33\11\11\11\11\11\11\11"\11"""D\11\11"\11"3"3""""33DU""""\11\11\11\11\11\11\11\11\11\11"\11""""\11"\11""\11\11"\11""""""\11"""""""""""33DDUD""f\88D3"""""D""\11\11\11\11\11"\11\11\11\113333333""""33"\11\11"\11\11\11""""""\11\11\11\11"\11\11\11\11\11\11\11""\11"\11\11\11\11\11\11""\11"\11"""\11\11\11"""D\11\11\11\11\11\11\11\11\11"3UUDD33"""""""\11\11\11\11""\11""\11\11\11\11\11\11\11\11\0"3f\99\88\99\99D\11\11"3D"\11\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11""3DD3\11""3""""""333""""""3"""333U3"\11""\11\11\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11"3fwDD""333D3"33""""\11""""""""\11""\11\11\11"3""\11\11""""33DwU"3"\0\11"\11\11\11\11\11\113"DD\11\11""""3""3"3""3D3D"\11\11\0\11\11\11\11\11"\11\11\11\11\11"\11"""\11\11\11\11\11"""""3\11\11""\11\11""""\11""""3DDf33ww3""""""3D""\11\11\11"\11\11\11\11\113333333"""""3""\11""\11\11\11\11\11\11""\11""\11"\11\11\11\11\11""""\11\11\11\0\11"\11\11\11\11\11\11"\11\11\11\11\11\11\11""3\11\11\0\0\11\11\11\11"33333333"""\11"""\11\11\11\11"""""\11\11\11\11\11\11\11\11\11\11""3UUf"\0\11\11\11"3U"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11"\11\11\11\11\11"""\11\11\11"""33DUD3U33"""""""""333"""""DUUD3""""\11\11\11"3""\11\11\11\11\11\11\0\0\11\11\11\11\11\11\11\11\11\11\11\11"3fU"\11\11\11"3"333DD3""\11""""""3""\11\11"\11\11\11"3\11""\11""""""DfD\11\11"3\0\11\11\11\11\11\11\11\113"33""""33"3"3"3"33DU"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11""\11\11\11"""3D33"""""\11\11\11""""\11"3"33DUDUfD""3"""3"33"""\11\11\11\11\11\11\11"""3333""""""3""""\11\11\11\11\11\11"\11"""""\11\11\11\11\11"\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3U"\11\0\11\11\11\11\113D""\11"3""3""""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""3DU3\0\11\11\11\11333Uf"\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11"""""\11\11"""""\11\11"""3333D3DD33""""""""333""""DUD333""""""""3""\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"3fD""\11\11\11\11""UD"3D"""""""33""3\11\11\11\11\11""3\11"""""3"""Uf\11\0\0\11D"\0\11"\11\11\11\11"3D333\11"33DD"""333"3333\11"\11\11\11\11\11\11\11\11\11\11\11\11""\11""""""""""D""\11\11"""\11\11"\11""""""D"3DDwf3333"""""3333""3"\11\11\11\11"3"3"D3"""3""""\11\11"\11""""""\11\11"""\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3\11\0\0\0\0\11\11""D"""\11""33"""""\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11""333D3\11\11\0\11\11\11"33DDfD"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""""\11"\11""\11\11"\11""""""3""33333"D"""33"3""wUUD3D3\11\11\11"""\11""3\11\11""""\11\11\11\11\11\11"\11\11\11\11\11\11\11"\11\11Dwf"""\11\11\11\11\11"3D3333""""""33"33"\11\11\11"""""\11""""3""ff\11\0\11\11UU"""\11\11\11\11"""""D"""3UD3333""3""3"\11""\11\11\0\11\11\11\11\11\11\11""""\11"""3"""""""\11\11"""\11"\11\11"\11"""""""33D\88f333"\11"""""3""33"3"\11\11\11"""""33""""""""\11"""\11\11""\11"\11\113""\11"\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""\11\0\11\0\11\11"""\11\11\11"""\11\11"""\11\11"\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"3333"\11\0\11\11\0\11""3333DfwD\11\11\11\11\0\0\0\11\11\11\11\11""\11\11\11\11\11""\11\11\11""\11\11\11\11""\11\11\11\11\11\11\11"\11"""D3"D33UUU33DDUwfD3DD\11\11\11""\11\11\11\11""\11""""""\11\11\11"""""""\11\11"""DwU"""\11\11\11\11\11""""33"3333"""33"33"""\11\11\11"""""""\11"3Df\0\0\11\11"3"3D\11\11\11\11"""""3U""333333"""333"""\11"\11\11\0\11\11\11\11\11\11\11"3""\11"""3"\11\11"""""\11"\11\11"""\11\11\11"""\11\11"3"3f\99D""""\11\11""""""""UD\11\11\11\11"3"""""3"\11\11\11"""""""\11\11\11"""""\11"""\11\11\11\11\11"""3"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"33"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""\11\11"""""\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""D"D"\0\11\11\11\11\11""3333DDUUwU"\11"UfD"\11\11\11\11\113\11\11\11""\11""\11""""\11\11""3"\11"\11\11\11\11""\11""3DDUDDfUf3""DDD3\11\11\11\11""""\11\11\11"\11\11\11"3"""3"""""\11""""""3"3U\88U33\11\11\11\11\11\11\11\11\11\11D"33U333"""""DD"""""""\11\11"""\11\11"DUD\11\0\11"""""\11\11"\11\11""3""\11DD"""3""33"""D33\11\11"3""\11\11\11\11\11\11\0\0"3D"\11\11""""\11\11\11\11\11""\11""""""\11\11\11\11\11\11"3""3U\88\88D"""\11"""""""""""D3"\11\1133""""33"\11""\11"""""\11\11"""3"\11\11\11""\11"""""\11"33""""\11\11\11\11"\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""\11\11\11\11"3""\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3D\11\0\11\11\11\11\11""""333DUUUDUwwwfw\88wwfUUw\88UDUD3\11\11\11\11""""\11\11\1133\11\11\11\11\11\11\11"\11\11""3"DUDUU3UDD"DUfwfDD\11"\11\11"\11\11\11\11\11""""""""""\11\11"""""333"3w\88UD3""\11\11\11\11\11\11\11\11"""D3333"3333DU"3"\11\11"\11\11\11\11\11"\11"3DDU"\11\11\11\11"""""\11"""\11"3"""DD333""""3"33""\11\11"""\11\11\11\11\11\11\11\11\11333"\11\11"3""\11\11\11\11\11""\11"\11\11"""\11"\11\11\11"""\11\11UfwUD"333""\11\11""\11""""333""DD"""""3\11\11\11\11\11\11""3"\11"""""3\11\11\11\11"3"""""""""""\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\1133"\11\11\11\11\11\11\11\11\11\11\0\0\11\0\11\11\11\11\11\11\11\11\11\11\11\11""""""\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11"3D"\0\0\11\11\11\11"3"""""333DDD33DDUU33"33333DUfwf3UwU\11\11"\11\03fU""\11\11\11\11\11\11\11\11\11""333D3DUUUUD333DUfwwU\11\11\11\11\11\11\11\11\11""""""""\11""\113"""3D3"Df\88fU33"""\11\11\11\11\11\11\11\11\11\113DU3""33DDD333"""""\11\11\11\11\11"33DD"\11\11\11\11\0\11\11"""\11\11\11\11"""33DDDU3"""""""3""""""""\11\11\11\11\0\11\11\11"33"\11\11""""\11""\11\11"\11\11\11\11\11\11\11\11\11\11\11\11""""\11\11Dwf3UD"3D3\11\11\11"\11\11""""33"3"D3"""""3"\11"\11\11\11\11"""\11"""""""\11\11\11\11""""""""""""33"""\11\11\11\11\11\11\11\11\11"\11\11"""\11\11\11\11\11\11\11\11\11\11\11\0\11\11\0\11\11""""\11\11\11\11\11""\11D3"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"3D3\0\11\11\11\11""""""\11\11""""33"3""333"""\11\11"""""DD\88\88\99\88\88fDUwª\99\99\88\11"\11\11\11\11"\11"\11"33DDDD"DUD"33333"DDDUwf3"\11\11\11\11\11"""""""\11\11\11"\11"3"33DD"UD\88fUDD3"""\11\11\11\11\11\11\11\11\11\11\11\11DD3"3DD3D"D"3""\11\11\11\11\11"\113"DU\11\11\11\0\11\11\11\11"""""""\11\11\11"""33DD""""""33"33""""\11\11\11\0\11\11\0\0\11333\11\11\11""""\11"""""""\11\11\11\11\11\11\11\11"\11""3DDDffD33U3333""\11""""""33""UDD3""3""33"\11\11\11\11\11""""3""3"""\11\11""3"\11"""\11"""""3"""""\11"\11\11\11\11\11"\11\11\11""\11\11\11\11\11\11\11\11\11\11\0\0\11\11\11\11\11\11""3"\11\11\11\11""""33\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""3\11\11\0\11\11\11"\11"\11\11\11\11\11\11\11"""""""""\11"\11""\11\11\11"\11\11""DUDfUUw\88wDwww\88UDDUfffw\88\88U3""3333UD""\11\11\11"""33DUUf3\11\11"\11"Uwf"""""""""\1133""DD3ffU\99fD3"33"""\11\11\11\11\11\11\11\11\11\0"UDD3DU3U33D33"\11\11\11\11\11\11\11"\11DU"\11\11\11\11\11\11\11\11"33"""3"\11\11"33"D33""3"""""3""""""\11\11\11\11\11\11\11\11"3"\11\11"""""""""3D"""\11"\11\11"3D"\11"""3UfwfD3""U333""\11\11""\11""""""3UD3"""""3D3""\11""""333"""""""""""""""""""""""3"33""\11\11\11\11\11"\11\11"\11\11"\11\11\11"\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11"3"\11\11\11"33333"\11\11\11\11\0\11\0\11\11\11\11\11\11\11"\11\11\11""3\11\11\11\11\11\11""\11"\11\11\11\11\11\11\11\11\11"""\11\11\11\11\11"""""\11\11\11\11\1133Dff3333"\11DffUDDfUDf\88UD3DUUfU3D3fU\11\11\11\11\11\11\11""3DDU3UU"\11\11"Uff3\11\11"33"""""D3"UfUUwU\88\99UD333"""\11\11\11\11\11\11\11\11\11\11\11"333DU33UD33D"\11\11""\11\11\11\11\113U\11\11\11\0\11\0\11\11\11"""""""3"\11\11"3333333""""""""33"""\11\11\11\11\11\11\11""\11\11\11"""\11""""""3D""33\11\11"3D33""3DfUDDUD3""DDDD3"\11\11\11\11"\11"""3"3D3""""33DD33"""3"3DD3""\11\11""\11\11"""3"""""""3""""DU3""\11\11\0\11\11"\11\11""\11""\11"3"\11\11\11\0\11\11\11\11\11\11\11\11\11"3D"\11\11""333D"\11\0\0\11\11\11\11\11\11\11\11\11\11\11"""\11\11""3\11\11\11\11\11\11""""\11\11\11\11\11\11\11\11\11"""\11"\11\11\11""\11\11\11\11\11\11\11""DDUw3"33"""ffUU33D333U3""\11"3DUw\99»ª\88D"\11\11\11\11\11\11"3DD3"U3\11\11\11Dw3D33fD"333"\113f\88w\99\88\88UUD\88\88U33"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11""\11\0DUUDD3""""\11\11\11\11\11"3\11\11\11\11\11\11\11\11\11\11"""""3"\11\11\11\11"DD3333"""3""333"33\11\11\11\11\11\11\11"3"\11\11\11"""\11""\11"""3D"""""3DD3"33DDDUfUD3U33"DUDUDD""\11\11"\11"""""3D33333"DDD3""""3"DDDD3""""""""3333"""""3"33"3U3""""33""""\11""\11\11"\11"3"\11\11\11\11\11\11\11\11\11\11\11\11\11"3D""3"3"3D3"\11\11""\11\11\11\11\11\11\11\11\11"""""""3U3\11\11""""""\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\113\11\11\11\11""DDUf""3D33""fUU3"333"33\11\11\11\11\11\11\113Uw\99\88\99\99\88U"\11\11\11""33DDDfD333UDDDfwU33D3D3\11ffw\88\88\99\88\88wff\88U""\11\11"\11\11\11""\11\11\11\11\11\11\11"""\11\11\11\11\113fUD"33""\11\11\11\11\11"D3\11\11\11\11\11\11\11\11\11\11"\11\11""""\11\11\11\11"D3DDDD"""3""3333"\11\11\11\11"\11\11U33"\11"""""\11\11""""3U"3"33DD3"3""33DUUD3"D33DDU"DU33"\11\11\11\11\11""""3D3333333DD33"3"33DUUD3"333"3"""3D"""3"""D"3"""""""""""""\11\11\11\11""\11\11\11\11\11"""""\0\11\11\11"\11"""DD"""3""3DD""\11\11""\11\11\11\11\11\11\11"""""""""UD\11\11"3"""""\11\11\11"\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11D3\11""""DUUU3\1133UU"\113fD333333"D\11\11\11\11\11\11\11"3Dfww\99wwwwU"\11\113"3DDDUffUU3UUffDUDUf3UffDDUUUfUUDDDUf3"\113\11\11\11""\11\11"\11\11\11\11\11\11\11\11\11"\11\11\113fU3333""\11"\11\11"D"\11\11\11\0\11\11\11\11\11""\11\11\11\11"""\11\11\11\1133DUUU3"""""""""\11\11\11\11\11\11\11"U33"3"""\11\11"""""""D3"33DD3""3""33DDDD"""33D3UD3DfDDD""\11"\11"\11"UD"33333D33D3DD""3DDUD3333D"D3""33""3D3""""3""3\11"""""\11\11\11\11\11\11\11"\11\11\11\11"\11\11\11""\11\11\0\11\11\11"""""3D\11"3"""33D33"\11\11\11""\11\11\11\11"\11"""333""3DUDUfDDUfDDDDD3"\11\11"""33""""""\11\113f"""3"DwUf""3UfD3\113UD333333"D"\11\11\11\11\11\11\11"3DUf\88ffffww\88wU"33DDUUff\99\99\99wU333UUffDDUDDDUDD333333DDD3DD"\11\11"\11\11\11"\11\11\11\11\11\11\11\11""\11\0"DfDD33""\11""\11"D3\11\11\11\0\11\11\11\11\11""\11\11\11\11\11"3"\11\11\11"3DUD3D3"""""""\11\11\11\11\11"\11\11\113D\11"3""""\11"""\11"3"3333DD3"""""33DDD3D3""""""3DDU"DDD3\11"\11\11\11"3UU333333"33Df3D33UDDD33""33"3D"3"""""3D3""""\11"""\11""\11""\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11"\11\11\11\11\11"""""3D\11"3""""33D33""\11"\11\11""\113"""33333"33Dwww\88\88\99f3UD33"D"D3333333D3DDUDDwU"""3UfUD"""3"""""DDD333333D3\11\11\11\11\11\11\11\11"3Dw\88fUfwwffff\88wD33D3"U\88UUU""3333333333DDDDD33""3"3"333""D3""\11\11\11\11\11\11\11\11\11"3DDD3"3DD333""\11\11""3D3\11"\11\11\11\11\11\11\11""\11\11\11\11\11\11"\11"\11\11"3333"3""\11\11\11"\11""\11\11\11\11\11\11\11\11\033"""\11""""""\11"""333DD3"""""3333333"""""""""333DDDD"""\11\11\113DU3"3D333"3DUUUD3UUDD33""""3DDD"3""""\11""3""""""3"\11\11""\11\11\11"\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11""\11"\11\11"""3"DD"3"\11""33"DD3""""""""""""""33DD"3""3fwwff33D3\11\0\11\11\11\11\0\11"""33""33DDDDDDDDUUUDfD\0\11"""""""UDD33DDDD"\0\11\11\11\11\11\11\11""3U\99fDUUUfffUUffwfD33ffUD"""""333333"3333D33"""""""""3"\11\11"3"\11\11\11\11"\11\11\11\11""DUDD""\11DD33""\11\11""3DU""\11\11\11\11\11\11\11\11"\11\11""\11\11\11\11\11\11\11\11""""\11\11"""""\11\11"""\11\11\11\11\11\11\11\11\11"""\11\11""\11"3"\11""333""""""\11""""""3"""DD3"""""3DD"3"3333\11\11\113D3D33fD"33DDUDUUDUDDD"""3"3333""""""""\11"""""""""\11\11\11\11\11""""\11\11\11\11\0\11\11\11\11\11\11\11\11\11\113"""\11\11"""""3U"\11""""33""DD3""""\11\11\11\11\11"""""33D33"""3U\88wf\11\11\11"""\11\11\11\11\11\11\11"\11\11"""33"333\11"\11"\11""3UDfffUD"3D"fUUDw\99fDU3\11\11\11\11\11\11\11\11\11""DU\99D3DD33333333Uf\99\99fU3"\11\11""""33333""""""33"""""""\11\11\11\11\11\11\11\11D3"\11\11\11\11\11\11\11"\11"33U"\11""3D3""\11\11""3Df"""\11\11\11\11\11\11"""\11\11""\11\11\11\11\11\11\11\11"""\11\11""""""\11"""\11\11\11\0\11\11\11""3"""\11"""\11""\11\11"333""\113"""""""333333U33"3""""D"UU"D3333UUDDDD33U"\11D33DUDUUfDDDD3""3333D"\11""3"""""""""""""\11\11\11\11\11\11\11""""\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11"3"""3U"\11\11"3""""3"33""""3"\11\11\11\11""\11"33Uf""""""Uw\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"""33333"\11""\11""""\113"3"\0\11"DD3wwww\88UUD33""\11\11\11\11\11""\11\11"Dwf"3"""""\11\11\11""3DUD33"\11\11\11\11\11\11"""""""""""""""\11"""\11\11\11\11\11\11\11\11\11\11U3""\11\11\11\11\11\11\11\1133UD""3\11"3"""\11\11"3Df""""\11"\11""""""\11"\11\11\11\0\11\11\11\11\11\11"\11\11\11\11\11""3""33\11""\11\11\11\11\11"\113D3"""""\11""""33333""""""""""DDDD3DD"3"D""""3Dffff\88\88UDUwwwDDDDD"\1133D3UUfDDDDD"\11"3333333"""3"""\11"\11"""""3\11\11\11\11\11\11\11\11""""\11\11""""\11\11\11\11\11\11\11\11\11\11\11\11\11"3"""""3"\11\11""""""""3"""""3"\11\11\11\11\11"\11\11"3U\88D"\11"""Uf3\11\11\11\11\11\11\11\1133"\11\11\11\11\11""\11""""""\11\11\11"""\11"3\11""\11\0\11\11\11\0\11"Dw\99wUU\88DD3""\11""""""\11"3Dw""""\11\11\11\11\11\11\11"""33"""\11\11\11\11\11"""""""""\11"""""\11""""\11\11\11\11\11\11\11\11\11\11""""\11""\11\11"""\11"DDD"3""3"\11"\11\11\11"DU3"""""""""""\11\11\11"\11\11\0\11\11""""\11\11\11"\11\11\11"""""""""\11\11\11""""\11"33\11""""3333333"3""""""""""D333DD3333""3"""DDDDDUwU3Uw\88ffwDUU"3DD3DfUUUDD33""""""333"3"33""\11""""\11"\11\11"3\11\11"\11\11\11\11""""\11\11"""""\11""\11\11\11\11\11\11\11"\11"33""""3\11\11\11\11\11\11"""""\11""""\11""\11\11\11\11\11\11\11""3Ufw3\11"""\113D\11\11\11\11\11\11\11"3D3\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11"\0\0\11\11\11""3DUwww\88\88wUD33333""""""3Uf"""\11\11\11\11\11\11\11\11\11\11\11""""\11\11\11\11\11""33333"""\11"""\11\11\11\11\11""\11"\11\11\0\11\11\11\11\11""""""\11\11"3""3D333"""3""3333DUfw""""3""""""\11\11"\11\11\11\11\11\11"""\11\11\11\11\11\11"""""\11""""""\11\11""""\11\11\11""\11"""333"33""33""""""""33333"DDD3""""""33DDUDDUfwf\88wwUDDfD3DDDDUffUUD3"""""""333D3"""3""""""\11\11\11\11\11\11\11""\11\11\11\11\11\11\11\11"\11\11\11"""""\11\11\11\11\11\11\11"""""""""""""\11""33D"""""\11"\11\11\11""\11\11\11\11\11\11\11\11""3fff"\11\11\11"""\11\11\11\11\11\11\11""33\11\11\11\11\11"\11\11\11\11\11\11\0\11\11\11\11\11\11\11""\11\11\0\11\11\11\11\11\11""""3fUDD333\11\113333""3333DDUf""\11\11"\11\11"\11\11\11\11\11\11\11\11"""\11\11\11\11\11""3333"\11"\11"""\11"\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11D"3"\11\11\11"3"333""33"3DUDUUD3"3f\99D""""""""""\11\11\11\11\11\11\11\11\11\11\11\11"3\11\11""""""""""""""\113"""""\11\11\1133\11"\11\11""""33333"""""333""3333DDD3"333""""33DDDD3wwwDDD3DDDD3DDDDUUffU""3\11""""3"""3"""3"""\11\11\11"""\11\11\1133\11\11"\11\11\11\11\11\11\11\11\11"""""""\11\11\11\11\11\11"33DD"\11\11"""""\11\11"33"33"\11"\11\11\11\11\11"""\11\11\11\11\11\11""3DDfUw""""3\11\11\11\11\11\11\11\11\11"""\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\113\11\11\11\11\11\11\11\11\0\113"\11\0\0\0\11\11\0\11"D3DDDDw\88\88\88f3""""\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3"3""""\11"\11\11"\11"\11\11\11\11"\11\11"\11\11\11\11\11\11\11\11D\11""""""""33"""""3DDUf3"333U\88f"""333"""""\11\11"\11\11\11\11\11\11\11"""3\11\11"\11\11""""""3"""\11\11\11""""\11\11\11\113"\11"\11\11""""""33"""""33"""""D333D333D33"""3333D3Dw\88fD3D333DDUUDDDfUUDD""""""\1133""""""""""""\11"""\11\11"\11""\11"\11""\11\11\11\11"\11\11"\11""""""\11\11\11""\1133D3""\11\11"""\11"""D"\11\11"33\11\11\11\11\11\11\11\11"\11\11\11\11\11""D33DD3Uf"""3"\11\11\11\11\11\11\11\11\11"""\11\11"\11"\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\113"\11\11\11\11\11\11\11\11\11\0\11\11\0\0\11\11\11\11\11\11\033"3""f\99\99\99\883""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3\11""3""\11""\11\11\11"\11\11\11\11\11\11\11\11\11\11"\0\11\11\11\0"3\11""\11"3"3"333D3DUD""DfDDDUfwUD\11\11"3"""""\11\11""\11\11\11\11\11\11\11\11""3"\11"""\11"\11""""3"\11"\11""\11"\11\11\0\11\11"3"""""""""33"33""""""""""DD333DU3333"""333"33U\88wU333"3D3DDDUUUfffUD""""""""3"""""\11\11""33"""""\11\11""\11\11\11\11"""""""\11""""""3""""""""\11"DD3\11\11\11\11\11\11\11\11\113"3""\11\11\11"""\11\11\0\11\11"\11\11\0\11\11\11\11"3D3DD"3Uf"""3\11\0\0\11\11\11\11\11\11"""""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""\11\11\11\11"\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11""""3U\88ª\99\88D3"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""""""\11""\11\11\11"\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11U3""""""""D3Dfw\88wUUDDDUUf\88UD3U3""3"""""""""""\11\11\11\11\11\11"""\11\11\11\11"""""""""\11\11\11\11\11\11\11\11\11\11\11\11\11""""""""""""D"""""""""3333UfDDUDD3333""3"""""3fwfD333"3333D3Df\88fUfUD""3""""3""""""\11\11""333""""\11""\11"""\1133"""""\11"""""""""""""""""""\11\11\11\11\11"\11\11""""\11\11\11\11\11\11\11\11"3\11\11\0\11\11\11\11\0\0\11\11\11""UDD33"DUD""\11\11\11\0\11\11\11\11\11\11""3"""33\11""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11"\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11""333f\99\99\99wD""""\11\11\11\11\11\0\11\11\11\11\11\11\11\11""""\11\11"""\11\11"\11\0\11D""\11\11\11\11""\11\11\11\11\11\11\11\11\11\11DU33333DfUfwUD33""\11\11""""3"33U3"""""""""\11"3"\11\11\11\11\11\11\11\11\11""\11\11\11\11\11\11""""""\11"\11""\11\11"""\11\11"UU33"""""\11"""""3""""""DDDDUD33"333D3""3"""""\11Dw\88U3"3333"33333Dw\88fUU"\11""""""""""3\11"\11\11""333"""3"\11""\11\11\11"\11""""""\11"""\11\113"\11"3""""""""\11\11\11\11""\11\11\1133""\11\11\0\11\11\11\11\11\11\113\11\11\11\11\11\0\11\0\11\11\11""D33""3DUfDDD\11\11\0\11\11\11\11\11\11\11\11""333"\11"\11\11"""\1133"\11\11\11\11\11\11"""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11""\11\11""33w\99\99ª\99U"3""\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11\11\0\11\11"\113\88w3\11\11\11""""""\11\11\11\11\11\11\11\11D3"DDDUwffD""\11\11\11""\11\11"\11"""3DU3"3\11\11"3"3"""""\11\11\11\11\11\11\11\11\11\11"""\11\11\11\11\11""""""""\11"\11""3"\11\11""3wU""\11"""""333"3"""3"3U3333333333333"""""""\11UwwD3""333333333Dfw\88U3"\11"3"""""""""\11""\11\11"333"""D3"\11\11"\11\11\11""""""\11\11"""\11""""""""""\11\11""""""""\11""""""\11\11\0\11\11\11""\11\11\11\0\11\11\11\0\0\0\11\11\11\11""3U33"33DwfDfU\0\11\11\11\11\11\11\11\11\11"""3"\11""""""\11\11D"\11\11\11\11\11\11\11""""\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11"\11\11\11\11\11"""3U\99\88wf""""\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11""3"\11"UUw\88\99ªªªª\99f3\11\11\11""""\11\11\11\0\11\11\11\113U3DUDUD33D"\11\11"\11\11"\11\11"\11\11""33U3""\11\11\11\11"""""""\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\0\11\11"""""""""\11\11"""\11\11"\11"\11"D3""33"333""""""""33333""333""""3"""""\11"\113w\88f3"""3"3333333D\88\88wf""""""""""""""""\11\11\11\11""3"""3"\11\11\11""""3"""""""""""\11\11\11"""\11""""\11"\11\11\0"\11\11"\11"3"\11""\11\11\11\11\11\11\11\11\11\11\11\0\11\0\11\0\0\0\0\11\11\11\11"3D3333DDUwwf\883\0\0\0\11\11""\11\11\11"3""""""""\11"\11""\11\11\11\11\11\11\11"""\11\11\11\0\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11"33DwU"\11"""\11\11\11\11\11\11\11\11\11\11\11\0\11"Dw\99ª\99\99\99ª»ªªªª\99\88w\99\99\88D""""\11\0\0"DDDUUDDfDDD3"""3D3\11\11\11\11\11\11\11""\11\11\11"3DU3"""""\11"""\11""\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11""\11\11"""\11""""\11\11\11\11\11\11\11\11""""""3"""33"""3"3""D33"333""""""3"""""\11DfwU"333"33D333DDUw\88\88f3\11""""""\11\11\11"""\11"\11\11\11""33"""""""""\11""""""""""""""\11\11"\11\11\11""3""""\11\11\113"\11\11\11"3\11\113"\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\0\0\11\11\11"""3D""33UfUfw\883\11\11\11\11"""\11\11\11"""""""""3""""\11\11\11\11\11\11\11\11\11\11\11\0\0\0\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""333"UD"""\11\11\11\11\11\0\11\11\11\11\11\113w\99\99\88\88\88wwwwwwwwffffw\99\99D""\11\11"DwwwffUUU3""3""""3""\11\11\11\11\11\11\11\11"\11\11\11\11"3f3""""\11"\11"\11""\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\0\0\11""\11\11"\11\11\11"3"\11\11""""3"\11""""""""""""""""DDUDUD3333"333"""""""""""""Dwf""3333DDU"3DD3UwwwfU\11"""""3""""""\11""\11\11\11"""""3"""""""""""""""""""""\11\11\11\11\11\11""3"\11\11\11\11\11\11""\11"33"""3"\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11""3D"3D33Uf\88wf3D\0\11\11\11\11\11\11\11\11"333""""""""""\11\11\11\11\11\11\11\11\11\0\0\0\0\0\11\0\11\0\11\11\11\11\11\11\0\11\11\11\11\11\11\11""\11\11\11\11\11\0\11\0\11\11"""33333D\11\11"\11\11\11\11\11\11\11\0\0\11\11f\99wffffUUUDfUfwwfffff\99w\11"3DfDDD3"33333""3""""""""\11\11\11\11\11\11\11\11"\11\11\11""DU3"\11""""3"""""\11\0\0\11\11\0\0\11\11\0\11\0\0\11\11\11\11"""\11\11"\11\11\11\11""\11""""3"""""""""""\11""""""3ffDD3"3"33333""""""""""""3Dww3333DUDDUD333DUw\88wfUD"3""""\11\1133"3"3"\11\11\11\11\11"33""""""""""""""""\11""""""\11\11\11\11\11\11\11""\11\11\11\11\11""""33""""DU3\0\11"\11\11\11\11\11\11\11\11\11"""\11\11\11\11\11\11\11\11"3D33333DUffffwD\0\11\11\11\11\11\11""""3""D3"""""\11\11\11\11\11\11\11\11\11\11\0\0\11\0\0\11\0\0\0\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11"3333"\113U\11"\11\11\11\11\11\11""33DwfUDDUUUDDDDUUUfffffw\88ªfUff3""""""3""""\11"""""\11""""\11\11\11\11\11\11\11\11\11\11\11""3DD"\11\11""3"""33"\11\0\0\0\0\11\0\0\0\0\11\11\0\11\11\11\0\11"""\11\11\11\11\11\11\11"\11"3""33""""""""""""""""""UU333"3""333UU""""""""\11\11"UwfD3333"DUUfU33DDUwwUDDUU"""\11"""\1133""3D"\11\11"\11"""33""""""""""""33\11""""\11\11\11"\11"\11\11\11\11\11\11\11\11"""\11\11\11\11\11\11\11DUUf33"\11\11\11\11\11\11\11\11""""""\11\11\11\11\11\11\11"3DDDD3"3DUfwf"\11\0\11\11\11\11\11\11\11\11"""""33\11\11"""\11\11\11\11\11"""\11\11\0\0\0\0\0\11\0\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\0\11\11\11\11\11""3D3""3wD\11\11\11\11\11\11\0"w\88\88\88\88D333D3DDD333DDDffffww\99\88DD3"""\11"""33""\11"\11\11\11\11\11\11"""\11\11\11\11\11\11\11\11"\11\0\11\11""DU3"\11\11"3\11""33\11\11\0\11\0\11\11\11\11\0\0\0\11\11\11\11\11\11\11\11""\11\11\11\11\11""""""""33""""""""""""""""""DD3"333333"3fwU"""""""""3fww"3"""3"3UfU"33DwwwfDDDUU"""""""""3"3""""\11""""333""""""""33"""\11""\11\113"\11\11\113\11\11\11"\11"""""""\11\11\11\11\11\11"DD3"""3\11\11\11\11\11""""\11\11\11\11"\11\11\11\11\11\11\11"DDDD"3"DDDwf\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11""\11\11\11"""\11""\11\11\11\11\0\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11"3D"\11\113wDw"333D""wwwwwU333333333"33DDDUfffUfwD""""""\11\11""""""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\0\11\11\11"33D""\11""\11"""""\11\11\11\11\11\11\11\0\0\0\0\11\11\11\11\11\11\11\11""\11\11\11\11"\11"33"\113333"""""""""""""""""""3D"333333"3ffU"""""""""Dw\88fD""33"33"DU3"3DwwwwDDDDUU"\11\11"""""""""3"3"""""""3""""""""""3""3""\11\11"33\11\11\11\11""""\11"""\11\11\11\11\11\11\11\11\11\11"\11\11\11\0\11\11"""""""\11\11\11\11\0\11\11""\11\11\11\11\11"3DDUD""3DDww"\11\11\11\11\11\11\11\11\11\11"\11\11\11""\11\11\11\11""3"""3""\11"""\11\11\11\11"\11\11\11\11\11\11\0\0\11\11\11"\11\11\11\11\11"""\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\113UUUffUUw\88wfffUUD"3"""3333333333DUUUUUffffD""\11\11\11\11"33""""\11\11\11\11\11\11\11"\11"\11\11\11\11\11\11\11\11\0\11\11\11"""U""""\11\11\11\11\11""\11\11\11\11\11\11\11\11\0\11\0\0\11\11\0\11\11"\11\11\11\11\11\11"""333"\1133D"\11\11"\11\11\11""""""""""""33""""333""3UUD"""""""""3w\88U"""333"3U"DU3D3UwwwU33UDD3D\11D3""\11\11"""""""\11""""""3"3""""\11"33"""""\11"""""""\11""""""3""\11\11\11\11\11\11\11"\11\11\11"\11\11\0\11\11\11"33""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"DUfDD33DDU\88"\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\0\11""3"""""""""\11"\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11""\11\11\11"""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0DU33Ufw\99\99\99wUDDDD333"""3""""33333DDDDUUUDUDDU3\11\11\11\11\1133D3DUU3"\11\11\11\11""\11\11\11\11"\11"\11\11\11\11\11\0\11\11"fU""""\11\11\11"""\11\11\11\11\11\11\11\0\0\11\11\11\11\11\11\11\11\11"\11\11\11"\1133333"""3333"3"\11"""""""\11""\11""""33"""3"33"3DD3""""3""333\88\88U"3333D333UUD3D3UwwUD"DDDD"DDDU\11""""""""""\11"333""""""""33"33"3""\11""\11\11\11\11""3""""""\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\0\11"\11"33""\11\11\11\11\11\11\11\11\11\11"\11\11\11\11"3UfUDDDDDDD3"\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11""""\11"3"""""\11\11\11\11\11\11\11\0\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11UU"3fUD\88fUfU333""33"3"""""""""""33DDDDDD3DDUUU3"\11\11\11"3"D33DDD3"\11\11\11\11""""""""\11\11\0\11\11\11"DwD"""\11\11""\11"\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11"\11"\11\11"f"\11"""\11""33DU"\11\11"""\11""\11"""""""3"""""""3"3D3""""""""333\88w3"333"3""3DUD3UfwwwU33DDDDDDDUU"\11"""""""\11\11"3""33""""""""333""""\11\11\11\11"\11\11""""3""""\11\11\11\11\11\11\11\11\11\11\11""\11"""""33"33""""\11\11\0\0\11\11\11\11\11\11\11\11\11\11\11"3UDDDDD3DUD""""""\11"\11\11\11\11\11\11\11\11\11\11""33\11"3""\11\11\11\11\11\11\11\11\11\11\0\0\0\11\0\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\03wU""DDfwUUUU3""""""""""""""\11"""3"3DDD33333DD33DUUD"3D"\11\11\11\11"""DUD"3f\88\88wUU"\0\11\11\0\11DD\11"fwU3"""\11\11\11"""\11\11\11\0\11\11\0\11\11\11\11"""""\11"\11\11\11"3U\11\11"\11\11\11"3"33UD\11""\11""""""""3"""""""""""33D33"""""""3333\88w3"""3333""333DfwwwUU3"33DUDDDDfUD"3"""""""""""""""""""""""""""\11\11\11\11\11"""\11""""""""\11\11\11\11\11\11\11"\11\11\11""\11"3""""33DD3"\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11"3D3D33D3f"\11"""""""\11\11\11\11\11\11\11\0\11\113"\11"\11""\11"\11"\11"\11\11"\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\0\0\11\11\113"\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"ffU3"UwDUUUD33\11\11"""""""\11""\11""""\11""DD333""33333"3D33DUDD3\11\11\11\11\11\11"3DU3UUfffwUUUU3\11"wUDwf3UD"\11\11\11\11\11"""\11\11\11\11\11\11\0\11\11\11\11\11""D"\11\11\11\11"3""\11""\11"3D3\11"DD""""\11\11""\11""33""""""""""""333"""""""33333\88U3"""3333"""DDww\88wUD""33DDDDDDUUUUwD3"""""""""\11"""33""""""\11"\11""3\11\11\11\11""\11\11"""\113DD\113"\11\11\11"""""\11D3"""""\11"3"3"3"\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3333333f"\11"""33""\11\11\11\11\11"\11\11"UD\11\11""""""3"\11\11"\11\11\11\11"\11\11\11\11\11\11\11\11\0\11\11\11\11\11\0\0\0"D"\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11DwwUDUfD"""\11\11\11\11\11\11\11"""3""\11\11"""""""\11"""333""""""3"""3"\11\113"33"\11\11\11\11\11\11"DD33333wDDUff\88U\88w\88\88f3\11UD\11\11\11\11\11"""\11\11\11\11\11\0\0\0\11\11\11\11\11\11\11""""\11""\11\11"\11"""3"""\1133"""""\11\11"""""""""""""""3""33333"""""3"33f\88U33"""3"33""3wwwwfD3\11""3333D33DUUUfD3""3D3""3"\11"""""""""""""\11\11\11"\11\11\11\11\11\11\11\11"\11"33""3D""\11"\11""""""""""""""""""33"3""\11\11\11\11\11\11\11\0\11\0\11\11\11\11"""""""3Uf3\11""3"3""\11\11\11\11"""\11"33"\11\11\11\11\11"""""\11\11\11"\11\113U3"\11\11"\11\11\11\11\11\11\0\0\0\0"DU3"33""""\11\11\11\11\11DUU"f\88\88wwfUD3"\11\11\11\11\11\11\11\11\11\11""""\11\11\11"""\11"3""""3"3"""""""""\11\11"\11\11\11"3""""\11\11\11\0\1133"""""3UDUUffw\99\99ªwUU"\1133\11""\11\11""\11\11\11\11\11\11\0\0\11\11\11\11\11\11\11\11"3\11\11"\11\11\11"\11\11"\11""""\11"3""3"""\11""""""""""""\11""""3"3333"""""""3Dww333"3""333""Dfw\88\88U3"\11""3333D3"DUUDDfD333DDD33"\11\11"""""""""""\11"\11\11"\11"\11\11\11\11\11\11\11""""3""\11"3"""33"""3"3""33"""""""""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11"33""\11\11""UU\11\11"33""""\11\0\11\11"""\11\11"\11\11\11\11""3D3"""\11"""\11\11\11"\11\11\11\11\11\11\0\0\11\11\11\11\0\11\0\0DUD333""\11\11\11"3UDUfUw\88\99wwUUD33"\11\11\11\11\11\11\11\11\11\11\11"""""""""""""""""""""""\11""""\11\11\11\11\11\11\11\11"\11"""\11\11\11\11\11"""\11"\11""33DDUU\88\99\99\99wDD"\11""\11\11\11\11\11\11\11\11\11\11\0\0\0\11\11\11\11\11\11\11\11\11\11""\11""\11\11\11"""\11\11""""\11"\1133\11\11\11\11""""3"\11"\11""""""""33D33"""3"""33fwU"3""33333333w\88\88\88wUD"""""3333333DDU3U3D3DDD3D33"\11\11""""""\11\11\11""\11""""\11\11\11\11\11\11\11\1133"3333"""33""D3"3""3""""33"""33""33\11\0\11\11\11\11\0\11\11\11\11\11\11\11"33D3"\11""3fDU3"DD""\11"\11\0\11\11""\11\11"\11\11\11"D"DfD3""""""\11\11\11\11\11\11\11\11\11\11\0\0\11\11\11\11\11\11\0\0"3""\11""\11\11\11\11"DffUUDf\88\88fUUDD3""\11\11\11\11\11\11\11\11\11\11"\11""""\11\11"""\11\11"\11\11"""""""""""""\11\11\11\11\11\11\11\11\11"""\11\11\11\11"\11"""\11\11\11\11""""33Uwwww\88f3D"\11"3\11\11\11\11\11\11\11\0\11\0\0\11""\11\11\11\11\11\11""\11\11\11""\11\11\11\11""""\113""33UDD\11\113\11\11"""""""""3""""""3333""""""""3Df\88D"3""3"3333"3\88w\88wU""""""33"333"333DUUU3D3DDDDU3"""\11"\11\11"\11\11\11"""""""\11\11\11\11\11\11\11\11\11"3333DD3""33333""\11""""3"""""""""3"\11"\11\11\11\11\11\11\0\11\11\11\11\11\11\11"333D"\11\11"DUfUD""3D"\11"\11\0\11\11\11"\11\11\11\11\11\113UUDwD""3"""\11\11"\11\11"\11\11\11\11\11\0\0\0\11\11""\11\11\11\11"\11\11\11\11"\11"33DDUUD33UUfUDDDD3""\11\11\11\11"\11\11\11\11\11\11"""\11\11\11\11\11"D3\11\11\11""""""""""""""\11\11\11\11\11\11\11\11\11\11\11"""\11\11\11\11\0\11\11\11\11"\11\11"""""DUfDffffUD\11\11""\11\11\11\11\11\11\11\11\0\0\11\11\11\11\11\11\11\11\11"""""\11\11"\11\11\11""""""3DUfUD3\11\11""\11"""""""""D3"""""3333"""""""""UwU""3""""3333DU\88\88wf3"""""""DDD333333DDUDDD333UDfD3"\11\11\11\11\11"\11\11\11\11"33"""\11\11\11\11\11\11\11"\11"""33""3""33333"""""333"""3""\11""""\11\11\11\0\11\11\11\11\11\11\11"\11\11\11\11"33\11""\11"\11DwfD""33"""3"\11\11\11\11\11\11\11"""\113UUDU"""3""""\11"\11""\11\11\11\11\11\11\0\11\11\11\11\11\11\11\113"\0"\11\11\11\113wUUDDD33"DUDDDDDD""\11\11\11\11\11\11\11\11\11\11\11\11"""\11\11\11\11\11\11"U3\11\11\11"""""""3""""""\11\11\11""""\11\11"3"""\11\11\11\11\11\0\0\11\11\11\11\11"""""33DUffUw\88U\11""\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11"\11\11""\11""""\11"\11\11\11"\11"3ffUfDD\11\11""3"\11""""""""\1133"""""3333"""""""""DD3""3"""3"33"U\88\88\88wU3\11""""""3D333333DDDDUD""33DUDDD3"""\11\11\11\11\11\11\11""""""""\11\11""\11\11\11"""""""""""3"33"""""""""""""""""""\11\11\11\11\11\11\11\11\11"\11"\11\11\11\1133D3"""""3ffD33"""33"3"\11\11\11"\11"""\11\11DfU3\11"""3"""""\11\11"\11\11\11\11\11\11\11\11\11\0\11\11\0\11\11\11"\113w\88fUfwwUDDDD3"""DUDDDD33""\11\11\11\11\11\11\11\11\11\11\11"""\11\11\11\11\11\11""3"\11\11\11""3""333""""\11\11\11\11\11""\11"\11\11"33""\11\11\11\11\0\11\11\0\11\11\11\11"""\11"D3UUUUwf\88"\11"\11\11\11\11\11\11\11\0\11\11\11\11\11\11\0\11\11"\11""""\11""""""""3DDUUf3"3"\113D3"\11\11"""""""""3\11"""""333D""3""""DD""""""""3""33f\99\99w\88f3"""""""DUDDD""33D33D33333DUD33D"""\11"\11\11\11\11\11\11""\11"33""""""\11"33"""""\11"""""33"""33""""""""""""\11\11\11\11\11\11\11\11\11\11\11"""\11\11\11\11"DDD3""""3D3D"3333333"\11\11\11\11\11"""3"\11"D3D""\11""""\11"3""\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\0U\99ª\99\88ffwDD3333""3DD333333""""\11\11\11\11\11\11\11\11\11\11"\11""\11""\11\11\11\11"""\11""3""3D33""\11\11\11\11"\11""""\11\11\11"\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"33ff333UU\11\11"\11\11\11\11\11\11\11\0\0\11\11\11\11\0\11\11\11\11\11\11"""""3D33333333333\11"3DDD3"""\11"""\11""""""\11\11\11"""3"""""""\113D3""""""""""""3f\99\99\99wfU"""3"""33DDDD3"3333DD33"3DD333UD33"""\11\11\11\11\11\11\11"\11""3"""""\11""3"""""""""""33"3""""""""""\11\11\11\11\11\11"""\11\11\11\11\11\11\11\11""\11\11\11\1133DD33""3Df""\11D333333"\11"\11\11""""\11""\11\11\11Uf3"D3\11""D"3""\11\11""\11\11\11\11\11\11\11\11\11\11\11\0\11"w\99\88ffD3DD333"3""D3DDD333333""\11"\11\11\11\11\11\11\11\11\11""\11""""\11\11\11\11""""""3333333""\11\11\11"""333"\11\11\11"\11\11"""\11\11\11\0\11\11\11\11\11\11\113"\11\11"""U3""3f""\11\11""\11\0\0\11\11\11\0\11\11\11\11\11\11\11\11\11\11"3"""3U3"""3"3"3"33""3UU3""\11\11"""""""""""\11"""""""""""\11"fD"""""\11""\11"""3U\88\99\99\99wfDDD3D33"33"DDDDD33333D33333D3"33UD3D3"\11\11\11\11\11\11\11\11"""3""""\11\11"\11\11\11""""""""""333"""3"""\11"\11\11\11\11\11\11\11"\11"""\11\11\11\11""\11\11\11\0\11\11\113DUD3D3"3UU3""D33"3"3""\11"\11\11""""\11""\11""DUDD3UUUUUU33333""\11"""\11\11\11\11\11\113w\88\88wUDDD3"3333"3"""3D3DD"33""""\11\11\11\11\11\11\11\11\11"\11"""""\11\11\11\11\11\11\11""3"""33"33""\11\11\11\11""""3"""\11\11""\11\11"""\113\11\11\11\11\0\11\11\11\11\11\11\11\11\11"33\11""ff\11\11"\11\11\11\0\11\11\0\11\11\0\11\11\11\0\0\11\11\11\11"3DDDD3"""""""""3DU""33DD3"\11\11"\11""\11"""""\11"\11""\11""""""""3f3"""""\11"\11\11""33w\88\99\99\88fU"""333DD"3"3DDD333""3DD3DDD33D33DUDUD"""\11\11\11\11\11\11\11\11"""""""""""\11"""""""3"33DD3"""""""\11\11\11\11""""\11""\11\11\11\11\11\11\11\11\11\11\11\0\0\11""3UUU33DDDDD""""""""""\11\11"\11\11"""\11\11\11""\11\11\11\11\11fUUfUUUDUUDD3DD3DDDD33D33DfU33DDDDD33333333"3"333D33D3"""""\11\11\11\11\11\11\11\11\11\11\11\11"\11"\11""\11"""""33""3""3"""\11"""\11"3"""\11\11\11\11\11\11\11""""\11"\11\11\11\11\11\11\11\11\11\11\11\0\11""3\11\11""DD\11""\11\11\11\11"\11\11\11\11\11\11\0\0\11\11""\11"""33"""\11\11"""""""33""3"DD3""\11\11\11""""""""""\11\11"""""\11\11"\11DD3""""""\11\11\11""""U\88\88\88wf"3"33D3D3D33""3333"""333DDUU3D33333DUDDDDD"\11"\11"\11\11\11""""""""""""\11"""""""3"3DD3""""""\11\11\11\11\11\11\11\11\11\11\11\11""\11"\11\11\11\11\11\11\11\11\0\11"33DwwD"33DfDD"""""""""\11\11\11"\11\11\11""\11\11\11\11\11\11\11""ff3DDDDDD3333D33DD3UUUDDDDDD333DD3333333D33"33333DD3333"""\11\11\11\11\11\11\11\11\0\11"""\11"\11\11"3"\11""\11\11"""333"333"""\11\11\11"3"""\11\11\11\11\11\11\11\11\11""\11\11"\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11""3DD\11""\11"""\11\11\11\11\11\11\11\0\11\11""3"\11""""""\11\11"""""\11\11\11\11\11\113"""""""\11""""""""""\11\11\11""""""\11\11\11f3"""""""""""""33w\99\88fU33333D333333"3333333"3333UUfD3D333333D333Df""\11\11\11\11\11""3D"\11"\11"\11"\11\11"\11""""""33333"""""\11""\11\11\11\11\11\11\11\11\11\11""\11"\11"\11\11\11\11\11\11\11"33"3\88f3""3"DD"\113"\11"""3""\11\11\11\11\11\11\11\11\11"\11\113UfUUffUUUD3333333D3"3"DUUUDDDDD333DUDUDUD"333333"3"333DD3"3""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""33\11\11\11\11""\11\11"""""333""""\11"333""\11\11\11""""\11\11\11"\11\11\11"\11\11\0\0\0\0\11\11\11"\11\11""\11\11"""333D"\11\11""\11\0\11\11\11\11\11\11\11"""\11\11""\11\11\11\11\11\11"""\11\11\11\11\11\11\11\11\11"3""3""""""D3""""""\11\11"\11\11\11"\11\11"\11"w3\11\11"\11\11""333""""f\88\88fDf3D333"333D33"3""333333"33UUUDDDDDD"3""""""DDD\11\11\11\11\11"\11""""\11"\11\11\11\11\11"""""""333"""3""""\11""\11\11\11\11\11\11\11\11\11\11"""\11\11\11\11\11\11\11\11""33333fU3""3UUD3\11""""\11""""\11\11\11\11DDD""DUff\88\88fDDDDDDD33"33333333DDUUDDD3333D3DUUffUD3"""33"3333D333"3""""\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11"3"\11\11\11\11\11\11\11""""""333"\11""3333""\11\11\11""\11\11"\11\11\11\11\11\0\11"\11\0\11\0\11\11\11\11""\11\11""\11"""3DD3D"\11""\11\0\0\11\11\11\11\11\11\11\11"\11\11\11\11\11\11"""\11\11"""\11\11\11\11\11\11\11\11\11"""\11""""""3D""""\11\11"\11\11"\11\11\11"\11"\113U3\11"""""""""""3Dw\99wDDDD"33D3333D3D333""3""33"3DUUDUDDD33"\11\11"\11"\11"3UU3\11\11\11\11\11\11\11\11"""""\11"""\11\11\11\11""""""""33"""\11"""\11\11\11\11\11\11\11\11\11\11"""""\11\11\11\11\11\11\11\1133333f"\113"3Df"\11"\11\11\11\11\11\11"""\11\11\11\113DDUUDUUfUDDDDDDDDD3D3DD333D3DUUUUDDD333DDDUfwfUD3""D33D33333333"3"3""""\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11""\11"\11\11"""\11""""""D33"\11\11"33D3"""\11"""\11""\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11"\11\11""\11"\11"33D3DD\11"\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11""""""""""\11\11\11\11\11\11\11""\11\11\11""3""\11\1133""""\11"\11\11""\11\11\11\11\11\11Uf"\11\11\11\11\11""""""\113f\99\99UDD3DD"D3333333D333""33"333DUDDDUUU3333"\11"""""33UU3\11\11\11\11\11\11\113D""""""\11\11\11\11\11\11""""333""""""\11""\11"\11\11\11"""\11\11\11\11""\11\11"\11\11\11\11\11""3333f3\11"33Dff3"\11"\11\11\11\11"""3"\11\11DU333DDDUDD333333DD33"3D333D3DUUDDDDDDUUUUUUDDUD"333D3DD333UUD3333333""""\11\11\11\11\11\11\11\11\11\0\11\11\11\11"""\11\11\11\11"\11"\11""""""""""""""3333"""3""""""3"\11\11\11\11"\11\0"\11\11"3\11\11\0"\11\11"\11\11""""33UU3\11\11""\11\11\11\11\11""\11\11\11\11\11\11\0\11\11""""""\11""\11\11\11\11"\11"""\11\11\11"333\11\11\11"D""D""""\11\11"\11\11\11\11\113ww\11\11\11"\11\11"""\11""D\88\99\99wDD3D3D33D3333333D""""3"3"33UDDDDUU33DDDD""""""33DDff\11\11""""33"D""""\11\11\11\11\11\11"""\11"""""""\11\11\11"""\11\11\11\11\11""\11"\11"""""""\11\11\11\11\11\11"3DDUw"\1133DUU3DDDUDU""DDUfD3333333""3DD3"""33DDD333DD3DDDDUUDDDDDDUUDD333333DDD33333DDDUUU3"333"3""""\11\11\11\11\11\11\11\11\0\11\11\11\1133"\11\11"\11"D"\11\11\11""""""""""""""333""3""3"""33"\11\11\11\11\11\11\11"3"33"\0\11\11"""""""""3DUD3\11""""\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11""""""\11"\11\11\11\11""""\11\11\0\11\11"333"\11""3\11"3"\11""\11"\11\11\11\11\11D\88f""\11\11\11\11""\11""3wªª\88UDDDD3DDDD3333""3333""""""3DD33DDDDU"3D3DD"""""333DDUf3U3"""""""""\11"\11\11\11\11\11\11"""""\11\11\11\11\11\11\11\11\11""\11"\11\11\11\11\11""\11""""\11\11\11\11\11\11\11\11\11"3DUDwf"""D3UDDwD333UUU33333"""""\11""""3D3""333DDD333D33DDDDDDDDD33D3DDD33333DDD33"33"DUUfUD""33"3"""""\11\11""\11\11\11\11\11\11\11\11D3\11\11""\11DwU""\11\11"""3"3333""""3333""3"""\11"3"""\11\11\11\11\11"\1133""""\11\11"\11\11""""""33DDU"""""\11\11\11\11\1133\11\11\11\11\11""\11\11""""""""\11\11\11\11\11\11\11\11\11\11\11\11""3333""""\11\11""\11\11\11\11\11\11\11\11\11\11Uf"""\11\11\11"""""3D\88ª\88\88UUDDDDDDDD"33333"33"3"\11""3D""DDDDD33DU3""D33"3333"3D3DUUUU\11\11\11\11"3""\11"\11\11"\11"\11""\11\11\11\11\11\11\11\11\11\11\11\11""""""\11\11\11""""""\11\11\11\11\11\0\11\11\11\11""3DDw\883""33DwfU"\11\11"""3""""""\11"""""""DD3DD3"""3DDD33DD333333D3333333D33333D"3DDD3"3"3DDUfDD3"3333"""""\11""\11\11\11\11\11\11\11\11""""""""3fU""\11\11"\11"""3"""""3"DD3"""D"\11\11\11""""""\11\11\11\11\11"\11\11\11""\11\11\11"\11\11"""\11"""DD33"3""\11\11\11\11\11\11\11\11\11\11\11\11"""""""""""""\11\11\11\11\11\11\11\11\11"\11\11"DU""3""""\11\11\11\11\11\11\11\11\11\11\11\11"DfD"""""""""""""w\99wwfUUD33"33D33"33333333""33UfUUwfUU3"333UD"33"33"3"333D3D3DDUUwwDU""""\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""\11"""\11""\11\11\11\11\11\11\11\11\11\11\11\11\11"3DUwU""""3DUw\11\11\11""""\11\11"\11\11\11\11\11"""""33DD"33""""333DDDDD3D3"33DD33333333333DD33DDD333DUDUfUfD"3333"""""""\11\11\11\11\11\11\11\11"33\11\11""\11"""3""\11"3"\11\11\11"\11""\11""3DDD3"33\11\11\11""\11"""\11\11\11\11\11\11""\11\11""\11\11\11\11\11\11"""""""DDDDU"3"\11\11\11\11\11\11\11\11\11\11\11"""\11""3"\11""""\11""\11\11"\11\11\11\11\11\11\11\11"D"\11\11"""\11\11\11\11\11\11"\11\11\11\11\11\11Dww"""""""""""""\11f\99wfffUD333333D3""3333333""UfffwfUD3""33"33DD3"33UD3D""3UDDDDDDffUww3\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11""""""""""""""\11\11\11\11\11\11\11\11\11\11"DDff3"\11\11\11333DU"\11\11\11\11\11\11\11"\11\11\11\11"""""333"33"33333DDDDDDDDD3D33DUD3""33D3DDDDD33333D"3333UUf\88f3333333D"""""\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11"3"\11\11\11\11\11""\11\11\11\11\11"3""""3D33\11""\11\11"3""3"\11\11\11\11\11"\11\11"""""\11\11\11\11\11\11"""""""DDDDD3DD""\11\11"\11\11\11\11\11\11\11""\11""3""\11\11"""\11\11\11\11""\11\11\11\11\11\11\11\11"\11""""""\11\11\11\11\11\11\11\11\11\11\11"UUD333""""""""""\11wªfffUUDDD33333"""3""33"""3UfUDDD3""""3"""""33""333DUf3""DD33UUUD33DUD\11""""\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\113""""""\11""""3"33"\11\11\11\11\11\11\11"3DDD3\11"\11"""DUU3\11\11\11\11\11\11"""""\11"""""3333333D3333DUD3D3DD3DDDDUU3"3"3DDDDDDDDD3333"""3333DD3UD3333"3D33""\11\11\11\11\11\11""\11"""\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11"""""\11"D3"3""\113""33D3\11"\11\11\0\11\11\11\11\113"""\11\11\11\11\11\11\11\11\11""""3DUDDDDD3""""\11\11\11\11\11\11\11\11\11\11"3"""\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11"""\11\11\11\11\11\11\11\11\0\11\11UD3333333""""""""3\88\99\88wwfUDDDDDD33D"33"""33D3UfU333333""""""""""3"""3DDUfD3D"333D33333D3ff"\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""D3""33D333""\11\11\11\11\11\11\11"3DD"\11\11"""33D3"\11\11\11\11\11\11\11\11"33"""3""3DDUD3"333DD3DfUDDDDDDDDDDDDfU33DU333DD3D33D3D3333333333"3333DDD33""""""\11\11"\11\11\11\11"\11""\11\11\11\11\0\11\11\11\11\11""\11\11"\11"""""\11\11"33D""""333"3D"""\11\0\11\0\11\11\11""\11"\11\11"\11\11\11\11\11\11\11\11"""3DD"33UU3""3""\11\11\11\11\0\11\11\0""""""\11\1133"\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""\11\11"\11\11\11\11\11\11\11\11\0\113UU333333333"""""3w\99\99\88wffUUUDD3DD3U"3"""333DDUUD333333"""""""""""3"D33DDf3\11"\113"3D333333D3Df\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11"\11""fU3333"""\11"\11\11\11\11\11\11\11"3UUD"\11""""UD""\11\11""\11\11\11\11""3"3"333DDDDw\88\88D3DDDDDw\88fDDDDUUUwwfUwfDUUD3333DD33DDUDUU333333D333""33DD\11"3""D3"\11\11\11\11\11\11\11\11""\11\11\0\0\11\11\11\11\11\11\11""\11\11\11\11"""""\11\11\1133"""\11"""""\11DD\11\11\11"\0\11\11\11\11""\11\11"""\11\11\11\11\11\11\11\11\11"""3333"UDU"""33"\11\11\11\11\11\11\11\11\11\11"\11""\1133""\11\11"\11\11\11\11\11\11\11"\11""\11""""""\11\11\11\11\11\11\11\0"\88fDD33333333333D3f\99ª\88wwffUUUUUDD3DDD33"""\11"DDUD333333""""""""""""""33D3DDU3""UwUD3333333D3DfwDD3"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""\11""3D33""""""""\11\11\11\11\11\11\11\1133DU3"""""ww"\11"""""\11"""33""""3DUfUU"3"fwDUUUfwD\88wUUUUf\88\99DDDwwUU3"""33333DD3DDU3D3"333333D33333UD"333UU3\11\11\11\11\11\11\11\113D"\11"\11\11\11\11\11\11\11"\11\11"\11\11\11"""""""3U3""\11"""\11\11\11\11"D"\11\11\0\0\0\11\11\11""\11\11\11\11"\11\11"\11\11\11\11\11\11\11\11"""333UfDD\11\11"""\11\11\11\11\11\11\11\11\11\11\11\11""\11"33"\11\11"\11\11\11\11\11\11\11\11\11""\11"""""\11\11\11\11\11\11\11\11\03\88ªfUDDDUDDDDDDDDU\99ª\88UfffffUDUUUDD3Df3""""""Dff3333333"3"3""""""""""""3DDDDDwfUD333333333333"3Dwwwf\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11"""""\11"""""\11"""\11\11"\11\11\11\11\11\11\0\11"33DD""""3\88w3\11"3"3"\11""""D3"""""333"3\11\11\11\11fUffwfDD\88fUDUUf\99\99w"Df3"UfD""""3DDD3333D3"33333D33D3DDDDDD"3DDU3\11\11\11\11\11\11\11"33\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""D3DD3"\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11"\11\11\11"\11\11\11\11\11\11\11\11\11""3DDfDD3\11\11\11"\11\11\11\11\11""""\11\11"""""D33\11\11"D\11\11\11\11\11\11"""""\11\11"""\11\11\11\11\11\11\11\0\0Uªª\99wwwwwwUfUUUUfwªª\88""fUUUU33DUUUDDUDD3"""3DfU333""3"3""""""""""""""""3UD3""33"3"333333333333DDfff\88D\0\11\11\11\11\11\11\11\11\11\11\11\11\11""""""\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11"\11\0\11\113DD3333f\99\99""333"""33"33D3"3"\11"""\11\11\11\11\11\11\113fDUU"\11w\88fDUUff\99\88\99f\88U"3UfD""3fU3D""D33UU333333D333333U3""DDDD3"\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""3D"3"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\0\11\11\11""""3DD3D3\11\11"\11\11\11\11\11\11""3\11\11"\11\11\11"DD3D"\113\11\11\11\11\11"""""""""\11\11\11\0\11\11\11\11\0\0\0Uªª\99ªªª\99w\88fwwfww\99ª»ªU\11\11UUDUDDDDDDUUUUDD33""3UUD"""""""3"""""""""""""""33D33"33"3"3333333"33D3DDUUUfUfwD\0\11\11\11\11\11\11\11\11\11\11""\11""""\11"""\11"\11\11\11\11"\11\11"""\11\11"\0\11\11"DU"\11Df»»wU33333"3D3""33D33""\11"""\11\11"\11"\11\11\113"fD3UwfUUUfw\99\99\88fwf"\11DfU3"wfD33D3fD33DD3333"3333333DD"33DUD""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11""""D"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11"\11\11\11\11\11\11""""DDDD33D"\11"\11\11\11\11\11\11\11\11""""\11\11\11\113fUD""3""\11\11""""3"""3D\11\11\11\11\11\11\11\11\0\0\11\88fw\99ªÌ»ª\99\99\99\99ªª»ªª\99U\11\1133DU3DDD3DDDUUf3D3333DU3""""""""""""""""\11""""""33D3333333"3333333"33333DDUUfUffUww"\11\11\11"\11\11\11\11\11"""""""\11\11\11\11\11\11\11\11""""""""""\11\0\11"3DU""\99ÌÌ»\8833DDD33333D33D3333""""\11"\11\11\11\11\11\11"3UUfUDDDD33"DwwD33\11\11"DDD"DUD"33UDDU3"3""""\11"33333""3333D3"\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\0\11\11\11\11\11\11\11\11\11\11\11"3"3""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11"\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""3D3DU333""\11\11\0\11\0\11\0\11""3""\11\11\11"3DUD""3""\11\11\11\11""\11""333\11\11\11"\11\11\11\0\113\88»\99"Df\88ª»»»»»»\99fUw\88f"\11\11D333DD333DDDDDUDDD333DD""3""""""""""""""""""""""3D3"3"""3"""33333""3"333333DDUUUUfUwwDffU3\11\11\11\11\11\11""\11\11\11"\11\11\11\11""""3"""33"3\11\0\11""ffDU\99wª»wDDDUUDDD3333DD333DD"""\11\11\11\0"\11"3DDDD3D3D33333ww\11"\11\11\11"3Df3"3333DD3D""33"""""3DD33333333333"""\11""\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""\11"3"3""\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""33D"D"""3\11\11\11\11\11\0\11\0\11\11"33""\11\11\11"""3D"D3D"""""""\11""\11\11\11\11\11\11\11\11\11\03\88ª\99ªªwDU\88ª»»»ªªU"""3f\11"\113UD3DDDDUUUUUUfDUfD333DD33"""""\11\11""33"""""""""""33333"333""""33333"""3333333DDUUUfUUUfwfww"\11\11\11\11"\11\11\11\11\11""\11\11"""""""""\11"\113"\0\0\11"\88Ì\88wfDwªÌ\88UUDDDUDDD3DDD3D3D33U3"\11\113DD"""\1133DDDD3""33fwwwD""""3Uw33333333DD"""3"""""""3D333"3333""""\11\11\11\11\11\11\11"""\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11"33"""\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11"\11\11\11\11\11\11\11\0\11\11\11\11\11"\11\11"""\11\11\11\11""""Dw"\11\11\11\11\11\11\11\0\0\11\11\11\11\11\11""""\11\11\11"\11DUD333"3D3""\11""3\11\11\11\11\11\11\11\11\11\0D\99ªªª\99wDUUf\88\99\99\88UDDU"3U""\11"UUDUUDffwffwwffffU33DDD33"""""\11"""""""""""""""""3333"""""""3""33""""3"3333333DDDUDDUD33Dff"\11\11\11\11""\11\11\11""\11"""\11"\11"\11\11"\11\11\11\113\11\11\11U\88ÌÌ»\88DDwªªwUwUffDDUUUUDUDDDDD3D"\11""\11\11""\11"""""333""3"3f\88\88U3"""""UwD333333DDD3"3D3"""""3D"333D3""""""\11\11\11\11\11\11\11\11\11\11"\11"\11\11\11\11\11\11\11\11""\11\11"\11"DD33"""\11\11\11\11\11\11\11\11\11""\11\11\11""""\11\11\11"""\11\11\11\11\0\11\11\11\11\11\11\11\11\113\11\11""3D33DUUw3\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""\11\11\11"33""3"\11"""\11\11\11\11\11\11\11\11\11""\11\11\11\11\11U»»»ªw3Df3DDUD3"\1133"D3D3\11\11"UUDDUDUfffw\88wwwffD3DD333""""""""\11""""""""""""""33"""""""3""33333""3"3"333333333DDDD3333DDfU\11\11\11\11"\11\11\11""\11"""\11"3""""\11\11""3"\11\11fªªªÌ\99DD3UUfwffww\88fDDDUDDUfwwfwUUD\11"""3"\11"""3""33""""3DU\99w3333"""DUfD33""333D3333""""333333""""""\11\11\11\11\11\11\11"\11\11\11"""\11"""""\11\11\11\11\11\11"""""DD3D3"""""""\11\11\11\11""\11\11"""""\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11"""3DDDDDUw3\11\11\0\11\11\11\11\11"\11\11\11\11\11\11"""\11"""""""""""\11\11\11\11\11\11\11\11\11\11"""\11\11\0\11"f»»ªw3\11Dww"D333"""\11"D33DD\11\11UUU"\11\11DUUffw\88wwwffUUUD"33""\11"""""""""""""""""""D33"""""""33"333D""3""""33"3333"33333333333UwD\11\11\11\11"\11\11""\11\11"\11"""""\11\11\11""DD"\11D»»\99\99»f3D3""\11\11"\11\11"Df\88f3UD3U3\11\0\11D3D""""""""""""""""""33DU\88ªfD33"""333D3DUD33333""""\11""3""3D3"""""\11""\11""\11"""\11\11\11""""""\11\11\11\11"\11\11\11""""3DUU3D333"""""""\11""""\11"""""\11\11"\11\11\11\11\113""\11\0\11\11\11\11\11\11\11"\11\11""33DUUUww"\11\11\0\11\11\11\11""\11\11\0\11\11\11\11""""""""""3"""\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11D\99\99ªª\99D\0\0Dfww3"3"""3"""""3DD""DD\11\11\11""DD33f\88wwwfUfUUDD3""\11"\11""""""""""""""""3D33"""""""""""""3"""""""""""""""""""""""3DDDfwf"""\11\11\11""\11"\11\11""""""\11\11""DD3"fª\99w\88\88\88D3"333"""""D33DfDffD"\11\11\11\11\11\11\11\11""""""3""""""""333UDDDUf33D33"3"DfUfD333"3""\11""""""3333""""""""""\11"""""\11"3333"D333333"""""""DDUU3333333"""""""""\11\11"""\11"\11\11"\11\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11"""33Dfff"\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11""""""""33""\11\11\11"\11\11\11"""\11\11\11\11\11\11"\88»Ì\99\88w3\0\11""3UU"""""""\11\11\11""3U3\11\113\11\11\11"""""\11DwwwwfffffDD3"""""\11""""""""""""""3D3"""""""""""""""3"""""""""""""""""""""""33333Uwf3"\11\11\11\11"""\11"\11\11"\11""\11""3DD3Uw\88ffwfDD"3"333""3""333""\11"\11\11\0\11\11\11\11\11\11"""""""33"\11\11""\11\11"333D3D33DD"D33UfU\88\99fDD33"33"""""""""33""""""""""""""""""D333"\11"3"3333"""""""3UffD"\11""3D3""""""""\11"""3"""""\11\11\11\11\0\11\113"\11\11\11\11\11\11\11\11\11\11\11"""33Dff3"\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11D333"333"""\11""\11"""""""""\11\11\11U»Ì»3\113\11\0\0\11"33D"""3D3"\11\11"""33D"""\11"""""3""DwwwwwfUwwDD3""""""""""""""""""""3D33""""""\11\11"""""3"""3""\11"""""""\11"\11"\11"\11""""3333DD\88D\11\11\11\11\11\11"""\11\11"\11"\11\11\11"3DDUUUfwUfffD333333""333333333"\11\11\11\11\11\11\11\11\11"3""\11"""""""\11\11"\11"""""DD3"""33"33D33DDw3D""""3"33333""""""""""""333"33"3""3"""\11""""""33"3"""\11"3DUwf"\11""""3333""""""""""""""""\11\11\11\11\11\11\1133"\11\11\11\11\11\11\11\11\11\11""""3DfU33\11\11\11\11\11\11\11""\11\11\11\11\11"\11\11"3UD33DD3""""""\11"""""\11""\11\11\113\88»»\88"\11\11\11\11\11\11\11"3"\11""U3"\11\11""333DD3"""""33"""3fUwwfwwwwUD33""""""""""""""""\11"""DD333""""""""""""3"333""""\11"""\11\11\11\11\11"""""""""""333\88\99D\11\11\11\11\11"""""\11"\11"""3DUUUwwUUUfffU33333D3333D333""3"""\11"\11\11"\11\11""D""""""""""\11"\11\11"""""DU""""3""""\11"DDUf"""""3333DD3333"""""333"3"3DUUUDDD33""""\11""""333""""""3Ufff""""""3"333333""""""""""""\11\11\11"\11\11\11\113"\11\11\11\11"\11\11\11\11""""""3fD""\11\11\11\11\11\11"""\11\11\11\11\11"\11"3"3DDDD3D3"3"""""""\11\11\11"\11\11\11\11Uª»U3\11\11\11\11\11\11\11\11"\11"\11\11\11""\11\11"\11"3333UU3"""""33"3UUUDwfwwwwfDD33"""""\11""""""""""\11"3DD3D"3""""""""33"""3"3"""""\11""""\11\11\11"""\11"""""""""3D\99\88"\11\11\11\11\11"""\11\11\11\11""3333DUwwfUUff3UD33333D33D3D3""""""\11\11\0\11\11""\11\11\11\11\11\11""3333""""\11"""""""\11\11"""33\11"""""DUUw3D3"33DD3DD333""33""3"\11"3"UwU33""""3D"""""""""333"3"33DffU""""33"3333333333"""""""""\11\11\0\11\11\11\11\11""\11\11\11\11\11\11\11\11\11"""\11""DU"333""""""""\11\11\11\11\11\11\113333DDUDUU3""33"""\11\11\11\11""\11\11\113\99\88f"\11\11\11\11\11\11\11\0\11\11"""\11\11\11\11\11""""3"333Df3"3"33"3UfDD333DfwwffD3"""""""""3"""""""\113DDD3333"""""""3"33333""""3"""\11\11\11\11\11\11\11"\11\11"\11""\11"""""3UU\99\88\11\11\11\11\11\11\11\11\11\11\11"""3""3DDDffUUffUD"333D33D333333"""""\11\11\11\11\11\11\11\11\11"\11\11"""""33D3""\11""\11"""""\11"""""""""""33DUUD3333333333333"333333""33U\88w3"\11"""""33"""\11\11""""""333DDffU"""""33"333"333333""""""33"\11\11\11\11\11\11\11"3"\11\11\11\11\11\11\11\11\11"\11\11"33D""3D3""333"\11\11\11\11\11\11\11\11""33""3UUD"\11"""""\11\11\11\11\11\11\11\11\11"U»\99"""\11""\11\11\11\11\11"""\11\0\0\0\11\11\11\11"""33DDDwU"33333UUDDD33DD"DwwDD3"""""""""3"3"""\11\113DDDD3"3""""""\11"""""3UD""33"""""\11\11\11\11\11\11\11\11\11"\11"\11"""\11\11\113DUU\99\88"\11\11\11\11""\11\11\11\11\113"""33DUfUUUUUUUU33DDD3D3333""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""3"33"\11\11\11\11""""""\11\11\11"""""""33""33UfD3DDDDDD333DDDD3D333D33UUffD"\11\11\11""""3DD""""""\11\11"3333DUfU33"33"""""33333333"""""""33""\11\11\11\11\11\11\11"""\11\11\11\11\11\11\11\11\11\11""333"""33""3"""\11\11\11\11\11\11\11\11""""""3Uw3\11\11\11\11""\11\11\11\11\11\11\11\11\11D\88\99\99Df3"\11\11\11"\11\11""3""\11\0\0\0\0\0\11\11\11"""3DUDff33333UUD3DD3DUD"3DfU33""""""""3""""""\11DUU333""""""""""""""""DD3"""""3"\11"\11"\11\11\11\11\11\11"\11\11"\11""""""DDUffU\11\11\11\11""\11\11\11\11"\11\11\113333DUfUUUUDDDDD3DD3DD333"""\11\11\11\11\11\0\11"\11\11""\11\11\11\11\11\11"\11\11""""\11\11\11"""""\11\11"\11\11\11""""""3333333DDUUDUD33333DU333"UfDDDDD3D3\11\11\11"\11\11\11""""3""""\11\11\11"DD33DDw\99D"D333"33"33333333"""333""333""\11\11\11\11""\11\11\11\11\11\11\11\11\11\0\11\11\11\11""3D3""""33""""\11\11\11\11\11"\11\11\11\11\11""3"Dw3\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11U\99\99D\0UU3\11\11\11"\11\11\1133D"\11\0\11\0\0\0\0\11\11"""3DUDDfD33DDfU33DDDfU3"33UD3""""""""3"""3""""DDD""3"""""""""""\11"3"""33D""""""\11\11\11\11\11\11\11\11\11\11\11"""""""3"333DffU"\0\11\11\11\11\11"\11\11\11""\11""333DUfUUDDD3DDDDDUD33"3""""\11\11"\11\11\11""\11"\11"\11\11\11\11\11""\11\11"\11\11\11"\11\11"""\11\11\11\11""\11"\11"\11"""33""33333wwUDD333"33""""33333"3D333"""\11\11"""""""""\11\11\11""3D33DUwU""Df33333"""333333333"""""33"3""""\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11"3DUD""""33"""\11\11\11\11\11\11""\11\11\11\11\11"333UD\11\11\11\11\11\11\11\11\11\11\11\11\11"U\88\99w\11\11\11DU""\11\11""""33""\11\11\0\11\11\0\11\11"""3DUfDfU33DUfD333DDf3""3"DU"""""3333333"""""3UD3"""3"""""\11\11""\11"""3"""\113D""""""\11\11\11""\11"\11"\11"""""""""3"3DDUDffD\11\11\11\11\11\11\11\11\11\113""3DDDUUfUUU3"DDD3DDUD3333""\11\11\11\11""\11\11"""\11\11\11"\11\11\11""""\11"\11\11\11\11\11""""\11"\11"""\11\11\11"""""33333"3D\88»wUDD333""""""""""""33"DDD3"\11\11\11"""""""3\11\11""""333UwU3""3UfD333"3""333333333333"3"33""""""\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11"\11"DU3\11"""""""\11\11\11\11\11\11""\11\11\11\11\11\11"33DD3\11\11\11\11""\11\11\11\11\11\11"wªªw"\11\11\113D"\11""""3D33"\11"\11\11\11\11\11\11"""3DUffwD3DfUDDDDDfww"""""DU3"""333""33"3"""3D33"""""""""\11\11"\11"\11\11"33""""\113"\11\11"""\11\11\11"\11\11\11\11""""""""""DD333DDDUfww\0\11\11\11\11\11\11"""""33UffUffUUU"DD333D3DDD3""""""33"DD"""\11"\11""\11\11\11""\11""""\11\11\11\11\11\11\11\11\11""\11"\11\11\11\11\11"\11\113"33333D33DwUDDDD33""3"""""3""333DD33""""""""""3"""""""""DwD"""3D33"""3"33D""333"33333"""D3"3"""\11\11\11\11"\11\11\0\11\11\11\11\11\11\11\11"\11"3U\11\113""""""\11\11\0\11\11\11""\11\11\11\11\11\11\11"33"U3\11"\11\11\11\11\11\11\11\11\11""fªª3\11\11\11\113D"\11""3"UD3"\11\11\11\11\11\11\11\11""3DDU\88\88\99\88wfUUUUffUf\88U"""3UfU33"""33"33"""""\11D3""""""""\11"\11\11"\11"""\11"3333"""\11""\11\11"""""""\11\11\11\11\11"""3""3333DD333DUfDfw\11\11\11\11\11\11"D""""3DUUUUUUU333DD"3DUDD3""""""\11\11\11\11\1133""""\11\11\11\11\11\11\11"""""""\11\11\11"\11\11\11\11\11"\11\11\11\11\11\11\11\11\11""""D333""""\11"DDUUU3"\11"\11"""""""""333D3"""""\11""""3"""""33"\113U"""""3ffD33D3D3DD3333"3333333"3333""\11""\11\11\11\11"\11\11\11\11\11\11\11\11"""""D""3""3""\11\11\11\11\11\11\11""\11\11\11\11\11\11\11\11"3333""\11\11""""\11\11\11""f\88w3\11""\11\11UD""""3UU3"""\11\11"\11\11"""3DUw\88ww\88ª\88\88wwwfUfwf"\11""3wwDD3"""33"""3"""""D3"""""""\11\11\11\11"\11\11""""""33"3"""\11\11""\11\11"""""\11\11\11\11\11\11""3D3""33DDDD33UUfUff"""""\113""""3D33DDUfUD333"3UUUD3"33333""\11\11""\11"""3""\11\11\11\11\11\11"""""""""""""""\11""\11\11\11\11\11\11\11""\11""3D33"""""""""3D"""\11\11\11"3"""\11"""3D3D3\11""\11\11""\11"33""""""""33D""""""33\88fD3333DD33333"3D"33D3333"""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""3""""\11""3"\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\113"\11"""\11"""\11\11\11""3wwD""""""3f3\11\11\11\11DUD3"""""""33DDUfwwfff\88ª\99wUUUUwwD""""3fwfDD""3333333""""3U3"\11""\11\11\11\11"""""\11\11\11""""DDD333"\11\11\11\11\11\11\11""""\11""\11"\11\11""3333333DDDDDDDDUU\88w\11""\11\11"\11"""""DD3DUUD33"3D3DUUD333D3""""""""\11""""3""\11\11"\11""""\11\11""""""""""""""\11"""""""""33DD"""""""\11"""33""""""""""\11\11""3DDDD3""\11""""\11"3""""""""""""""3333""33"DD3UUfUD33333"333D3D33D""""\11\11\11\11\11\11\11\11\11\11\11\11"\11""D3D3"\11\11""""""\11"""\11"\11\11\11\11\11\11\11\11\11\11\11"\11\11\11"""""\11\11\11\11"UªU\11"""""\11\11fD"\11\11"UUD33""""33DUUfwUUfwUU\88ªfUDDDDww3"""""fwfDD333333333""3"DU333"\11\11\11\11""\11"\11\11"\11\11""""""DD33"\11\11\11\0""\11""\113"\11"\11""\11"""""33"3D3DD3D3DDDf\88D\11\11\11\11\11\113"\11"3"D33DUUD3333"DUUDD3"33""""""\11"\11\11""""""\11\11\11\11""33"""""""3"""""3"""""""""33DDD33"3"""""\11"\11""""""""""""""""33DD333"\11\11"""\11""""""333""""\11"""\11\11"33""33D3""33DDDDD33333"333"3333""\11\11\11\11\11\11\11\11\11\11\11\11\11"""33DfU3""""""\11"""\11\11\11\11\11\11"\11\11\11\11\11\11\11\11"\11""""\11\11"\11\11"U\99»D\11"""""""DU3\11\113UUD3333""33DDfw\88fDDfww\88wD3DfDDfU"33"""DwwUDD333333333""3DD33"""\11""\11\11\11\11"\11\11\11"""""\11"\11\1133\11\11"\11\11\11"3\11\11"\11\11\11"""""""""""3"""333D3D333Dfwf3\11\11\11\11\11""\11"3"333DDD333""DU3DD333"""""\11\11\11\11\11\11""""""""\11\11"3333"3"""33""""""""""""\11\11"333UDDD3""\11""\11\11\11\11\11""\11"""""""""""3D3"33"3""\11\11""""""3\11"DD3"""""\11"""""""3DUU3"""""333DDDD3""3333""3333""\11\11\11"""""\11\11\11\11\11"\11"3Dfff"""\11""""3"\11\11\11\11\11\11\11"\11\11\11\11\11\11\11"""""""\11\11\11\0D\88»\883\11""""""""wD""DUDUD3D33D33DDUffwff\88\99wfDDDD3DUUD\11""3"""fwwfDDDD33333"""DUD""3"\11\11""\11\11"\11""\11""""\11""\11\11\11"\11\11\11\11"\11\11\11\113\11"\11\11"""""""""""""3333D"3"3333DUUUf3\11"\11\11\11\11\11"""33D3333""""33DD3333""""\11"\11""""3D""""""\11""3333""3""DD33"3""""""""""""33"3UD3"""""\11\11\11""""""""\11""""""333""333"3""\11""""""\11"""D33"""\11\11""\11\11"""""3D3"""""3"D3DDDD"3""3""D3D3"""\11\11\11\11"""""\11\11\11\11""""3UDDU3"\11"33"""\11\11\11\11\11\11\11"\11\11\11\11\11\11"""""3"\11\11\11\11\11UÝ»w"\11"""""""\11UU""UD3DD3333DDDDUDDf\99ª\99wUUDDDDDD33Uw""""333DffwfUUUD3333"""fD"""""\11\11"\11\11\11"\11\11\11\11"\11\11"\11\11""""""\11\11\11\11"\11\11\113"\11""\11\11\11"""""""""3333"D33333"""DDDUU\11\11\11\11\11""""3fD"33"""""3"3DUDDD333DU3""""33""\11""""\11\11""3D333""3"""33""3"""\11""\11\11\11""""""3fD3""\11"\11"\11""""""""""\11""""""""""""33D3""\11\11\11"""""3"""""""\11"\11\11\11\11"""\11""3""""""333333UD33"333D33"""""\11\11\11\11"""\11""\11\11\11"""3DDDDD3""333"\11\11"\11\11\11\11""\11\11\11\11\11""""3"""""\11\11"\99ÝÌw"\11"""""""\11\11w33fD""""3DD3DUUUDf\88\99fD33DDDD333DDUU33"3""\11DDfUUUUUDD33"""Dw3""\11"\11\11"\11\11\11\11\11\11\11\11\11\11\11\11"\11\11"""""""""\11\11"\11\11\11D"\11""\11\11\11"""""""""3""""D"33"""3333UUf"\11\11\11""""3D33"33""""""33D3DD3"33"\11""""\11\11"\11"""\11"\11"""33"333""""""33"3""""\11"\11\11\11\11\11""""""UD3"\11\11\11"""""""""""""""33""\11"3""""333D3""\11""""""""""""\11""""""""""\11""""""""3333333D3"3"333D3333""""\11\11\11"\11\11\11"""""""DDUUDUU3""3"\11""""\11\11\11\11"\11\0\11\0\11"""""33"""\11\11U»ÝÝ»D\11""""""""\11"wUwf3""""3DDDDUUf\88wU3""333333"3UU333333333"UDffUDUDDD33"3Uf3""""\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11""""""\11"3\11\11\11\11"\11\113"\11\11\11\11\11""""""""""""""""""""""""""3DUwf333"333DD333"""3"3""33DDD3""""""\11"""""\11""3"\11\11"""3D33DD3"""""""""""""\11""\11\11\11\11""""""3DD3"""\11""""3""3""""\11"3UD"\11"D"""""3""33"3"\11"""""""33"\11\11""""""""""""\11\11"\11""3333333DD333"D3D3"33333"""\11"""\11\11""""""D3DDDDU333"\11"\11\11\11\11\11\11\11\11"\11\0\11\11\11\11"""""3"""""wÌÝÝ»\99wD""""""""\11UD\88wD33"""3DDDDU\88\88D3"""""\11""""DU""33333333D3UUffUUDDDD33DfD3""""""""\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""\11\11"\11\11\11\11""\11\113\11\11\11""\11""""""""""""""\11""3""""""3""33U\88\88\88\99\99w3Uf333""""""33DDDDD33"""""""3""""3DDD"\11\11\11""3DDff3"""""""""""\11"\11\11"\11\11\11\11\11""\11"""UU33"""3"""""""""""""33\11\11"33\11"""""""3D33"\11\11"""\11\11\11"""\11\11\11\11\11\11\11\11\11"\11""""""""""""""333DD3""3DD3D33333"""""""""\11\11"""3""""DD3fU\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11"""\11"""""DfÌÝ»ª\99\99\99U3"""""""3UffU3""""""3DfwwU"""""\11\11\11\11\11"3UU\11\11"3333DDDD3DfUwfUU3333UUU33"""3"3"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11""\0\11\11\11""\11\113"\11\11""\11\11\11"""""""3"""""3"""""3"33"333Uw\99»ªwffD3"3"""""3"3DDDD33"""\11\11"""""""\11DUU3\11\11\11\11\11""3333"""""""""""\11\11\11\11\11"""\11\11""\11""3"UfUD"\11"33""""""\11\11\11\11""""\11"\11"""""\11\11""3"3D3D"\11""""\11\11\11\11\11""\11\11\11"\11""\11\11"""""\11"\11"""D3""333D3"3DDD3333D3"33"\11""""""""\1133"""""33"U3\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""""3"D3\88Ì̪\99\99\88\88wfU"""""""DffD3"""""3ww\88fD"\11""""""\11\11\11"DUD"\11"""D33DD3D3fffwwwU"3UwfD"3"""3"33""\11"\11\11\11\11\11\11\11\11\11\11""""""\11\11\11\11\11\11\11"3""\11\11""""\11\11\11\11\11""""""""""""""3"""3""33333DUf\88\88\99wwU"33"""""33"D333"3""""\11"""\11""""D3"\11\11\11"""3""""""3"3""""""""""\11\11"""""""""3"33DDD\11\11\11""3""""\11\11"\11\11"""""\11""\11\11""\11"3""""DDD3\11\11"\11"\11"\11"""""\11\11\11\11""""\11\11\11"\11""\11"3"3U333"3D3"333333333D33""""""""""3"\11"\11\11\11"""D3DU""""\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11""""""33DDwÌ»\88w\99\99ªwUwU"""3"33wwD33333"D\88U"\11"""""""""""""UUD3"\11""3DDDDU33UffwfUUwUwfD33"D""""33""\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""\11\11\11\11\11\11\11"\11""\11\11\11"""\11\11\11\11""""""3"""""""3"\11"""3"333DDDUUUU\88ª\99D"33""""3"333DD33D3""""""\11"""33"\11"""""3"""""3"33333""""""\11""33D"""333333333D3""""""3""""\11\11\11\11"\11\11""""\11\11\11\11\11\11""""""33333\11\11\11\11\11\11\11"\11"""\11"\11\11\11"\11\11"\11"""\11"""D33D3"33"3D"333DUU3"""33""""\11\11""""33""""""""33DU3"""\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11"""""333Dwª\99\88\99\99\99ª\99\99\99U"333333ffDDDD3Uf\99w""\11\11""""\11""""""3fUDD3""""3DUDUUD3wfwwUUffUDD333333"33"""""\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11\11\11\11"3"3""\11\11\11"""""\11\11\11"""""""""\11\11"3"""""333333333333DUww"3"""""""3DDD333""3"""""\11"""""\11"""""""""""""3"""3"""333DUwwfw\88wwUDDDUUUDDDDD3""3"""D3"3\11""\11\11"""33\11"\11"\11\11"""""""333D"""\11\11\11""""\11"""\11"\11\11\11"""\11"3""""""DDD3""""3D3""DD33UDD333"3"33"\11"3DD3""""""""""3Uf"3""\11\11\11\11\11\11\11\11\11\11""\11\11\11\11""""33Df\88\99\88\99\99ª\99ªª\99\99\88D333333f\88UDUfU\99\99UU\11"""""""""""""3UDDDDDD"""3333DUUUUwfwwU33"3D333333333""""""\11\11\11"\11\11\11\11\11\11\11\11\11""\11\11\11\11\11\11\11"D3"""\11\11\11\11\11""""\11\11"""""""""\11"\11""""""""""3333""33DDUU3333"""""33"3"""""3"""""\11"\11"""\11"3"""""3"""""""""3"3333DDUUUfffwUwwwfUDD3333DDDDD"""""D3\11"3""3\11""3"\11"""\11\11\11"\11""""3DD3""""\11\11"""\11"3""\11\11\11"\11\11"\11""\11"""""DD"\11"3"""U3"3UUUUwfUfUD33D"""3DUUD""""""\11\11\11""333DUD"\11\11\11\11\11\11"\11\11\11\11""\11\11"""""33DUÌ\88\88\99\99\99\99\99\88ªª\88fD"333DDwwfU\88ªªU"\11"""""""\11""""""3wfD3DDDD333"333UUUUUUDD3"""DUD33D3333333"""""""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\113""""""""\11\11\11\11\11\11""\11"""""\11"\11\11"3333"""""33""""3"33UUD3333""""""""""""\11""""""""""""\11"3""\11"""""""""3D33""333"3333DDUUUUUUfwU3DUDDUfDUUD""\11\11""3\11\11\11\11\11\113""""\11\11"3\11\11\11""""333DDD33""""""""""""""\11\11\11\11\11\11\11\11""""""DU3""3""\11UD"3DDUUUDDDDDUffUUUUUU3""""""\11\11\11"""""333D"\11"\11\11\11\11\11\11\11\11\11"\11\11\11"\11\11"""3Df\88fw\88w\99\99\88\88ªªª\99UU33DD33wf\88ª\99w3\11\11\11"""""\11""""\11\11"U\88wfwfD3UUDDDDUUDfUDDfwUD3"3DUD""3333333""""""""""\11"\11\11\11\11"""\11""\11\11\11""""3""""\11"""""""\11"""\11\11"""3""\11\11"3D3"""\11"""""""3333UUU333""""\11\11"\11""\11\11\11\11\11""""""""""\11""333"33D33"3DUffUD333"""""""333DDUUUDDDD33DD3UD3DD"\11\11\11\11\11\11\11\11""\11\11\11\11""\11\11"\11"""\11\11\11""33DDUDD333""""""3"""""\11\11\11\11\11\11\11\11\11"""""3D"""3""\11UwDDD3DDD3DDDDDUDDDDU33""""""\11\11\11"""""""333D3\11\11\11\11\11\11""\11\11\11""""\11\11\11"33Dw\99ffww\88\99\99\88\99\99ª»ªwD33333f\99»\99D333"\11\11""""\11\11"""\11\11"w\88U33DfwfDUDUDDUUUUUUffUD3"33D33"33D333""""""""3""\11\11\11\11\11\11"\11"\11"\11\11\11""""\11"""3"""""\11""""""""""""""""\11"\113D"""""3"""""33DDD3D"333"""\11\11\11\11\11\11\11\11"\11\11\11"3"""""""""""33UDDDD333Dffwf3D""""""\11""""""333DDD""3"""\11\11\11"""\11\11\11\11\11\11\11"\11\11\11"""3"\11\11"""""""\11""""3DDDDDD333"""""""""3""\11\11\11"\11\11\11"\11"""""D3"3"3"\11fffU3333DUU3D3DD3DDDD""""""""\11"\11""""""""3333D3"\11\11\11\11\11\11\11\11""\11\11\11\11""333\88\99Ufff\88\88\88\88\88\88\99\88\88wfU333DUªÌ\8833333""\11""""""""""3\99f""3DDUUf\88UDDDDUUUDDwwwUU33"333D33333333333""""""""\11\11\11\11\11\11\11\11"\11\11\11""""\11"\11"3"""""""""""33"3"""""""\11"\11\11DD""""""""""3DDD3"D"""3""\11\11\11\11\11\11\11"""""\11""""\11"""""""33"""3DD333DUU33UD3""""""3""""""3333"""""3"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""\11\11"\11"""""""""""33DDDDUD333""""""""3"""\11\11\11\11\11\11\11"""""333"3""Dwwww333333333333DDDD3""""""""""""\11\11"""""""33DDD"\11\11\11\11\11\11\11""\11\11\11""""3D\88wDUfffw\88\88\88\88\88\88\88fwwD33f\99Ì»f33D33""\11\11""""\11""""U\99f"333DUUUDf\88w3DDUwww\88\88\88fUDDDD33333"333"""""""""3""""""\11\11\11\11\11\11"""""\11""\11\11""""3"""""""""""""\11\11"""\11\11"""\11"D3"""3"3"33DDDUfD3""""\11\11\11"\11\11\11\11"""\11\11\11"\11"\11"\11\11\11\11""3""""""3U333DfDUD3""""""""\11"""""""""""""3DD33\11\11\11"\11\11\11\11\11\11\11\11"\11"\11"""""\11\11""""3D"\11"\11\11""33DDDDDDUDDD3333D3D"3333\11"\11"\11"\11""""3""""33fwwUUf"3D3333DDDDDUDD333"""""\11"3""""""""""3"33333D33\11"\11\11"\11\11"\11""""3fwD3UffUUfwwwwwwfUUw3D\99»ªfDDDD333""""""""""""DwD"3333DUUUDUf\99\88\88wwffUU\88wfD33DD333DD3D33"""""""""3"""\11\11\11\11\11\11"\11\11"""\11\11\11\11"""""""33""\11\11"""""""\11""""\11\11\11\11\11""33""""333333DDDDUU3""""\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11"3""""""3UUDD3DUUU3""""\11\11\11""""3"""333""""33"33"\11\11\113\11\11\11\11\11\11""\11\11\11\11\11\11"\11\11""D3D33"\11\11"\11\113"33DDDDUUUUUfffw\88wffUDDU3\11\11\11\11"\11"""""""""""UfwfUfD3"33333DUUUU3DUUD""3""""""33333""33DDUDDD333D3\11"\11\11""\11"""333wU33DDUUUUfwwwwfw\88\88ffU»\99fUDUDDD33"""""""""""33D"""""33DUDDDUffw\88UDDDUfwfDD3333333DD3333"""""""333"""""\11\11\11\11\11\11\11""\11\11\11\11\11\11"""333D"3\11"\11""""""""\11"\11\11"\11\11\11\11\11"3"""\11"3""333333UDDD\11\11\11\11""\11\0\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\113U3""""DDUU33UD3"\1133""\11\11""\11""""333333"""3""""3"\11\11""\0\11\11\11\11"""\11\11"\11""""""333""\11\11\11\11\11"3""33333DDUUUffwfwwUUfwUDD""\11\11\11\11""""""""""3"ffwUfUfDD3"333UUU33DDDD"33333333DUDDD3DDDDDDDDD3""""\11"\11\11\11\11""""3"D\88D"33DDDUUUfwwwfU\88ª»wf\99UDDDDDDD333""\11"""""""3D3""""""33DDUDUUUfw\88fDUUffwfUDD333"3DD3333""""""3333""""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""3D3"33""\11"""""\11"""\11\11\11"\11\11\11\11"\11\11\11\11"""3""3D333D33"\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"33D3""DDDDD3DD""D3D"""""""""""""""3DD"3333"""3\11\1133\11\11\11\11\11\11"\11"3"\11\11""\11\11"""""\11\11"\11"\11"D"333"DUD3DUUwwwwU\88ffwfwfUUD3\11"\11\11"""""3""""""UUwUDwUDDDDDDUD3D3DDDfD33"3DDUUUUUD3333DDDDDD333Df3\11""\11\11\11""""33w\883"DDD3DDDUDUUUffU\88»Ìª\99DDUUDDDDD33""""3""3""UD"\11\11\11\11""33DDD3DUUDDfwUDUffffUUUD"D3DDDDDD3"3"""3333333""""\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11""""3"D33"\11\11"""""""\11\11\11\11"\11\11\11\11"\11\11\11\11\11\11"33"33D3D3DU3\11\11\11"\11\11\0\11\11\0\11\11\11\11\11\11\11\11"""\11\11\11\11\11\11"DUU3"3D33DDD"3DUUD""33"""\11\11""""""333D""""33"""""3"\11\11\11\11\11\11\11\11"""\11""\11\11\11"""\11\11\11""\11\11"3""""""D333DUwwfUUfDDUwwwwfUU3""""\11"33""""3""3f\88f3UwfUUfwwfUUUUDUUUD"33"D3D3DD3""33"DDD3DU333DU3\11""\11\11""33333ww33DDDD3DDDDDDUUUfUwÌ̪UUUUUUUDDD33"""""33"3U3\11"\11\11\11\11\11"3DDDU3DDDDUUwDDDUw\88ffUDD333D3DDDD33"33DDD333333"""\11\11\11\11\11\11\11\11\11\11\11\11"\11"\11""""D"D3"""\11\11\11\11"""\11""\11\11\11"\11\11"\11\11\11\11\11\11"""3""333333Uw"\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""""\11\11\11\11\11\11\11DwwU"3D3DUD33"Uw3D33""\11\11\11"\11"""\11"""""""3""""3"3""\11\11\11\11\11\11\11"\11\11"\11\11\11\11\11\11\11\11\11"""\11\11""\11\11""\11"""""""""3UfUUDDUUUUUUwwffffD\11"\11"""333"""333D\88\88UDwfffff\88wUDD3"3DD33"""333D"""""333DU3333DD333U3"""\11\11\11"33DDf3"33DDDD3DDDDDUUDUw\99»\99fUUUUUUUUUDD33""""""3UU"\11\11\11\11\11\11\11"""33UUDD33UUUfUDDU\88fffUDD33DDUDD3DD3D3DDDD333"""""\11\11\11\11\11\11\11\11\11\0\11\11"""33""333D3"""\11\11\11"""""""\11"\11"\11"\11\11\11\11\11\11\11\11"""""33"DDUUf3\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""\11\11\11\11\11\11"""3UUfwDDD3"3UDDDD3""""""\11\11\11"""\11\11\11\11\11\11"""3""333"\11\11\11\11\11\11\11""""\11\11\11\11"\11\11\11""""""\11"\11\11"\11""""""""""3DUUUUDUfffUfw\88wfwfDU""33"""""33333"Uwf3DwUw\88wwfffD"""""""3"""D"3U3"""333DUD33333333DD3\11"\11\11\11"33"f\88D"3DDDDUDDDDDUUUDwª\99wUDDUUUUUUUUUDDD3"""""UU3""\11\11\11\11\11\11"""3DDDD3D3DDUUU\99wDw\88fDDD3333D3DD3DD3DD3DDD3333""""\11"\11\11\11\11\11\11\11\11\11\11""""""3DD3D3"\11""\11""\11"""""\11"""""\11\11\11\11\11\11\11\11\11\11\11""""33"UUfU""\11\11"\11\0\11\11\11\11\11\11\11\11\11\11"""3"\11\11\11\11\11\11\11"""DDDfwDDD3DUDD3D33"""""\11"3D3"\11\11\11\11\11\11\11\11\11"""""""\11\11\11\11\11\11""""\11\11\11\11""\11\11"""\11"""""""\11\11"""""\11\11"""DDUUDDDUUUUUDDffwwUDDUDD3"""""3333Dw\88\88UUUwww\88\88wf3""""""""""3"""3DD3333333"3DD33333D3U3\11\11\11""3333\88\993"DDDDDDDDDDDUUUwª\88U3DUUUUUUfUUUUDDD333"33wf"3""\11\11\11\11\11""""3DDDDD3D3UUUfDf\88wwwDDD"33DDDD33DDUDDDDD3333""""\11\11\11\11\11\11\11\11\11\11\11\11"\11""""3"3"""""""\11"""\11\11""""\11"""\11\11\11\11\11\11\11\11\11\11""""""33DDD33U3"\11\11\11\11\11\11\11\11\11\0\11\11\11\11"""3"\11\11\11\11\11\11\11"""""3UwU33DDD33Uf33""""3\11"""\11"\11\11\11""\11\11\11"""\11\11\11"3"\11\11\11\11\11"""\11\11\11\11\11"3"\11"""\113"""\11\11\11\11\11"""""\11\11\11""3DDD""33333D333Uwww\88fDDf3"""3333D33fwwfUDDw\88\99\99f3""""""33""""""""3""33"33333"D3333D3UU"\11\11\11\11"33"3\88\99"333DDDD33DDUUUU\88\99U""3DUUUUffUUUUUDDD33"3UwU"""""\11\11""""""3DDDDDD33DDUUD3fwUwwUD333DUDD33DDUUDDDDD333""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\1133DD3""3""\11""""""\11""33"\11\11"\11\11\11\11\11\11\11\11\11"\11"""""33DD3D"3""\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""D3"\11\11\11\11\11\11\11"3""33UD33DUD33fwD3"3D33"""""\11\11\11\11""\11"\11"\11"\11"\11\11"""3\11\11\11"\11""\11\11\11\11"33\11"\11""D3""\11\11\11\11"""""""\11"""3UD3"""""""""3"Dffwffwwww3"""33"3DDf\99ª\88wffUUfwU3"3"""""333"3""3"""""333333"3DD3"3UfUU"\11\11"""33"D\99\9933D3DDDD33DDDUf\88\99f333"DDUUUUUUUUUUDDDD3"DfD3"3""""""\11"""""333DD3333DDDUDU\88wUwf33333DDD3D3DUUDDDDDD33"""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""33""""\11\11\11\11""\11\11\11"\11\11"3"\11\11\11\11\11\11\11\11\11\11\11\11\11"""""333UU33"3"\11\11\11\11\11\11\11\11\11\11\0\11\11\11""""D3\11\11\11\11\11\11\11\11"""""3333DDD3UDUU33D3D\11"""D"\11\11"\11"3"\11\11\11\11\11\11"3D"\11""""\11""\11\11\11""\11\11\11""""""33"""\11"\11\11\11"""""""\11\113D33"\11\11\11"\11""""33DffUUUf\99\88wU"""3"DD3w\99ªª\99wwD""""DD3"""""""D"3"""33""3D3333333D3UfwwfUwU3\11"D""3"w»\8833D3DDD3DDDDUfwªªD3333"DDDUUUUUUUUDDDD33Dw33333"3""""""""""333D3333DDDDUf\88wfDwU3""3U"3333DDDUDDD3333""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11""\11\11"\11"\11\11"\11\11\11\11"\11"""""\11\11\11\11\11\11\11\11\11\11\11""""""33333""3""\11\11\11\11\11\11\11""\11\11\11""""3""\11\11""\11\11\11\11""""""33DDDD3DDD""333"\11"\11\11""""333\11\11\11\11\11\11""""3"\11\11"""""3"33\11\11""""""\11""3""""\11"""\11""3""""""D3""\11\11\11\11"""""""3DUfUUfwfw\99\99f"33333Uw\88w\88fUDw"""333333""""""D"3""\113"""33"3""33UfffDD"3UDD333D""D\99ªw333DDDDD3DDDUUf»Ìf"3333DDDDUUUUUUUUUUDDDff3"33""3"""""""\11""""333D33DDDUUfw\88fUwfUUUDDD3""3DUDDD3D3D""3""""\11\11\11\11\11\11\11\11\0\11\11\0\11\11\11\11\11\11\11\11""\11\11\11"\11\11\11\11\11\11\11\11"""""\11"\11\11\11"\11\11\11"""""""""3"3DD""3""\11\11\11\11\11\11\11\11\11""\11"\11"\11\11"\11""""\11\11\11\11\11"""""""3DDD33DUf33""3"\11"\1133"""33""""\11\11\11\11"""\11\11\11\11\11""\11"3""""""""3""""""333""""""\11""""""3"3"""\11\11\11\11""""""""3DUUUUfwfU\99\99\883333Dfw3DUfUDfU"333"3"333D333333"""33""33333D3DUU333DUDf3333UD"3f\99\99f3333DDDDDDDDfUU\99wUU33333DDDDUUUUUUUUUUDUwU""""""3"33"""""""""""3333DDUUDUwfUfUwwUUUUD3D"3DUUDD33D33"""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11"\11"\11\11\11\11\11\11\11""\11\11\11""""""\11\11\11""""""""""33DD""3""""\11\11\11\11\11\11"\11\11\11\11\11\11\11\11"\11"""\11\11\11\11""\11\11"\11\11"""33333DUfDD33"""""33"""33""3""\11\11\11""""\11\11\11\11\11\11\11\11\11"""3\11"""""""""33""""\11"\11"\11""\11"\11""3""""\11\11\11"33\11\11"""""3DUffUUfw\88\99\99\99f333wf33UUUDD33333"""3UD3D3D3"D3"""33"3D33DDDUU33DfwfDUD333DUUf\99\88\88\88D33D3DDDDDDDUUUww33U33333DDDDUUUUUUUUUUf\88D33""3"""333"""\11\11\11\11\11\11"""333DUfwUfD"\11UUfUDUUU3"D"UfUDD33333"3""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11"""\11\11"\11\11\11"\11\11"""\11"""\11"3""3"""""""""""""3DU3""""\11"\11\11\11\11\11\11\11\11"\11\11"\11\11\11\11\11""""\11\11\11\11""\11\11"\11\11"""3DUD33DDUDUDD3D"3"\11\11""""333""\11""\11"\11\11\11\11"\11\11\11\11\11\11""3"""3""""""""333"\11""\11\11\11"\11\11"\11\11\11"333""\11""""\11"\11\11""33DfUfUUUUUf\88\99\88\88DUwfUwwUUD333"""33333DD"33333D"""""3DD333333fDDfwU3DU3D3Dfwfw\99\88\88\99U33D3DDDDDDDUDfwfU3"UDD33DDDDDUUUUUUUUf\88\88D333""D""333"""\11\11\11\11\11\11""""3UDUffUfw3""\11UfUUDUD33DUfUDD333D3""""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""\11""\11\11"3""""\11"""\11""\11\11""""""""""3""33"DU3"D3""3"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""\11""\11\11\11\11\11\11"""3UDD3DDUffwf33"DD3\11\11\11"""3D3""\11\11\11\11\11\11\11\11""\11\11\11\11\11\11""3"\113U333D"333333""3"\11\11"3"\11\11\11\11\11"3"3"""\11\11"\11"\11\11""""33DUUfUUUfffw\99\88\99wUUDDU\99fD333""""3"333"33"3D3""""""33DD333333ffwU333UU3UUwwU\88\88ª\99ªf333D33DDDDDfUfªD3D33DUDDDDDDDDUUUUUUDwªwDD3333"33"333"""\11\11\11\11""\11""3DfUUUfwf3\11\11\03UDUfDD3DDDUUUD3"3333""""""\11""\11\11\11\11\11\11\11\11\11\11\11\11"3""\11"""""\11""""""""""\11\11\11\11\11\11\11""3""""""""33"33Dfw\88fD3DD\11\11\11\11\11\11\11\11\11\11\11\11"\11"\11\11"""\11\11\11\11\11\11\11\11\11\11\11\11""3DUD3DUDwfUffD33"3"\11\11"""""3""\11\11\113\11"\11\11""""\11\11\11\11"3"""DUD""DU""D3D""""""""3D\11\11""""3""""""\11\11\11\11\11\11"""""333UUUfUUw\99\99\99\99\99\99wDDDwwwwU3""3D3U3"3333333333"""""33DDD3333DwUfU33"UfUUffwUfw\99wwfD33D3DDDDDDfUU\88ª333333UfDDD33DDDDUUUU\99ªUDDDD33""D"""33"\11\11\11\11\11\11\11\11""3DDfUUUfU"\11\11\11\11DUDfD3DDDDUUUUD33333"33"""\11"\11\11\11\11\11"\11\11\11\11\11\11\11"3"""""""\11""""\11"\11\11""""\11"\11\11\11\11""3"""""""""3DDUUw\88wUUfw\88f\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11\11\11\11"\11\11\11\11"33DD33DDUDDD33333"\11"\11\11"""""3""\11""\11\11\11\11""3"\11\0\11\113""""3DDU"3U3"33333DDD3""\11\11\11\11"""""""\11""""\11\11\11\11\11\11""""33"3DDUwff\99ª\99w\88\88wU3DffUUUfUUwUDD33D3333333333"""3"DDDD33DDUUUfD"3"3fUfwwwww\99\88U"""3DD3DDDDDUUU3w\99w333D33"DÌUffDDUUUDDw\99\883DDDD333""3"""33"\11\11\11\11\11"\11""333UfUUfU"\0\11\11\11"fUUD3""DDDDDDDD33333"3""""""""""\11\11"3"\11\11"33""""""""""3\11\11\11\11\11\11""\11\11""\11\11\11"""333"""""333fwwwwUDUDUfwwU"\11\11\11\11\11\11\0\11\11\11"""\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11"3"3DD333UDDDDD"333\11\11""""""\11"""""\11\11""""""\11\0\0\11\11\11""""""DD33UD33DDU3DDU""\11\11"\11"\11""""""\113"\11\11\11"\11"\11"""""""333DUffw\99\88fDDfU33DUfUffU\88f33333333DUD333""3"""3"DDDUUDDDD3UD""33"UUUffwww\88w3"3333DDDDDDDDUUU3\88\883""3333"3\99fwDDDUUUUª\99UDDDDDDDD333"3"3"""\11\11\11""\11""333DUffww"\0\11\11"3DwfU"3DD3DDD"3D333333"3"""""\11\11\11""""""""3""""""""""""3"\11\11\11\11\11\11\11"""3\11\11\11\11\11"""3""""333"DfwwfD3DDUUDDUfD\11\11\11\11\11\0\11\11""\11""\11\11\11\11\11\11\11\11"""\11\11\11\11\11"""DDDDUUDUDDD33"""""\11\11\11\11"\11\11\11\11"\11""""\11""\11\11\11\11\11\11\11"3"""33DD"DU""UDDUUUDD3"\11""\1133"""3"""3""""""\11""""""3"333Ufwwªªf3DDDUUUffUDDDUDw3D3333""3D333333""""3DUffwffUUfU3"""3D3UDDfwwwww"333333333DUDUUUUUfw3""3333"3"fªUDDUUDf»\8833DDDDDDDD3333"""3"""""3"""3DDDDUwwf3""33""UUDD\11DUDD"3DDDDD33333"""""\11""""\11\11""\11"""""""""3"""3"\113\11\11"\11\11\11\11"\11"\11"\11\11"\11""33"33""3333UUfD33UDDDUUff\88"\0\11\11\0\11"\11\11""3\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11"\11"3D333DUUDD333D""""""\11"\11\11\11\11"\11"\11\11\113"\11""\11\11\11\11\11\11\11""3"\1133333DD""3DDDUUff3""""\11\11""""3"""3""""\11\11\11\11\11"\11""""3D3Uf\88\88ª\99wDDDDUUUwwUD3DDDUwD3D333333DD3333"3""3DUwf3D33D"\11\11""3333DUDUwwwff""333DD33DDDUffUUffU\11\11"""3"""""D\99\88DDDwª»f33DDDDDDDDD33"""""333""33""33D33DwfD"""\11"""UDUU33UDDD"33DDD333"33""""\11"""\11\11\11"""""""""""""\11\11""""3"\11\11\11\11\11\11"\11\11\11\11\11\11"\11"333333"33D333UUD"3DUUUUfw\88w"\11\11\11\11\11\11\11\11""DfUDD\11"\11\11\11\11\11\11\11\11""""""DD33DUDDD3333"\11""""""\11\11\11\11\11""\11"""3\11""""\11\0\11\11\11""\11""3"3"3D3"3"DD3DDUfU""""\11"""""3DD"D3""\11"\11\11\11\11\11\11""D3DDDUww\99ª\88fDDDDUffUUUDD3DUUwwUfwD3"333DUfD3"3333DUUfDUU33"""33"333DDDUUffww"33"3333DDDDDUfDUfU3\11"\11"""33"""""\99ªw\88ªÌwD3DDDDDDDDDDD33"""33D333DD3333DDDU\99f"\11"\11\11\11\11\11"fUwf3DDDD33D3DDDDDDD3""""""3""\11"""""""""3"\113\11\11\11"""\113\11\11\11\11\11\11\11"\11\11\11\11""\11\11"333"3"""33333DUfD33DUfUfw\88\99D\11\11\11\11\11\11\11\11\11"3DfUD3""\11\11\11\11\11""\11\11\11"""3"33DDDD3333D3"""3"3"\11\11\11\11\11\11\11"\11""3""""""\11\11\11\11""\11"33""""33""33UD33DU3333""""""3DUU3D33"\11\11\11\11\11"\11"""3DUDDDffw\99\8833UDDffffDDDDDDUUffwfffDDD"DDD3D3"33DDUfwU3Df3""""3""3"333DUDUwwwU"33333DDDDDDDfD"Uf\11""\11""3""""3""D̪»ÌªU333D3DDDDDDDD3D3333""33DDDDDDDDUUf\88wU""\11\11\11\11\11\11\11DffUD33D""DDDDD3DDDDD3""""""""""3"""""""""\11\11\11\11"""\03""\11\11\11\11\11\11""""\11\11\11\113"""\11""""33333DDUD33DUUfUw\88w3\11\11\11\11\11\11\11\11\11\11"33"""\11"3"\11"\11""\11\11\11\11"""""33"33"33"DD"""3""""\11\11\11\11\11\11\11"\11\11\11\11"""""\11\11\11\11"""\1133""""3"""D3UUD3DD"""""""""""DUf"3D33"\11"\11\11\11"\11"""3DDDDUff\88wD3DUUUffUDUDDUUDDDDwfUUUD33DD333333DDUUfUfDDDUD"\11"""""""3"DfUDUUD3"3""3DDDDDDDDDfDDU\11\11\11\11""""""3""DU\88\99\99wfDDDDD33DDDDDDDD3D333""333DDDDDUUDUUDf"D"\11\11\11\11\11\11\11\11DUDDUDD333333333DD3DUD""""""""""""""3"\11\11\11\11\11"""""""\11\11\11"""""\11\11"\11\11\11\11""""\11\11\11""333333DD3U333DUfwww\88""\11"\11\11\11\11\11\11\11""3"""""""\11\11\11\11\11\11\11\11\11\11"""""3""33""DDUD""D33""3\11\11\11\11""""\11""""""\11"\11\11\11\11"3"""""""3D"""3UUD"DU"\11"""3"D3333UUUUD3"""\11\11"""""\11"33UDDDUf\88w33DUDUfwDDUUDDDD3D33wUDDfD"3DD3D333DUUUD3wwUDDD3\11""D3""3D33ffD""\11""""3DfUUUDDDDUUwf3\11\11\11\11\11""""""33f\99\99wDDD3DDDDD33DDDDDD3D3D33"""333DUDDfUUD33"33"\11\11\11\11\11\11\11\113D33DUD33333333""DDDDD""""""""""""3D3"\11\11\11\11"3"\11\11""""""\11""""""\11\11"\11"""""""\11"""3""33D3333333Uwwwwfff""\11\11\11\11\11\11\11\11""3D""""33\11"\11\11\11\11\11\11\11\11""333"""3"3DDDU""DU33"3"\11""""""\11"""\11\11"D""\11\11\11""\11"""""""""""3DUDDD"""""""""U3D3333"DD\11\11\11""""""""D33DDUDUw\88\88333DDDUfDDDUUD333"DUwU3DUf333DDDUDDDDDUD3fwDD3"""""3D33DD"3UwD"""""""33UUUDDDDDDfwf\11\11"\11\11""""""""Uw\88\99\99\99U33DDDDD3D33DDUDD333D""""3333UDDUUff3"\1133U"\11\11\11\11\11\11\0"D"33UUDD"3D3333333UUDD"""""""""""3UD"\11"\11"""\11"""""\11\11"\11"""""\11\11""\11\11"""\11"\11\11"\11\11"3333DD33U33DDfwwwfDDU\11"\11\11\11\11\11\11\11\11"3""""""3"""\11\11\11\11\11\11"\11"""3""3U33D3"33"DDDDfU"""""""""""""""U3""\11""""\11\11"""""""""333D3DDDU3"""""3UD3"D3DUD""""""""3""DD33DDUUU\99\88D"3DDDUfD3D33D33"3"UfU33DUfUDUUffDDUUUfffUD33D3""333"33DUUUUfD\11""""""33DDDDD3DDUwwD\11\11"\11\11"\11""""""w\99fww\99\88fDDfwD33D3DDDDDDD3333"""3333DD33UUfU3"33DD\0\11\11"\11\11"3D\11\11\11DUDDD3D333"333"UUDD"3"333"""3"UU3"\11\11""""""\11"""\11"\11"""""\11\11""\11\11""""\11\11\11\11\11\11\11"3333DD3D3333UfwffDDfD"""""\11\11\11\11""3""""""""\11\11\11\11\11\11\11\11\11\11"""3333333""33"DD3Dfff33""33""3"""3333"""\11\11\11"""3"\11""3"""""3"33DD\88\88D3""3DD333DD3D"\11\11""""3U33"33"33DUUU\88\993"33DDUUD333D33333DD\88wD3DDDfUUUUfUUfUUUD3"3"3""""""\11"DDUfwwfU3""""""""DDDDD333DDww3\11"\11\11\11\11\11"""""3w\99\88\88\99\99\99\99\88\88\99fD3DD3DDDDDDDD3333"""3333D333DUD33"33D3\11\11\11\11\11"3D"\11"3DDDDDD"333333333UUU3"""""3"3\11DU3"\11""3""""""""\11"""\11"\11""\11\11\11\11\11""""\11\11\11\11\11\11\11""3333DD333"33UfUUD33f""33D3\11\11\11"""""""""33\11\11\11\11\11\11\11\11\11"""""3"3333"3333Uf3DDDDD333"3""""""""""""\11\11\11\11\11\11\11\11""\11"33"""33"33U3D333"""UD3D3U3"33"\11\11""\11\11"3D3\11"""3DUDw\99\88U"333DDUD3D333333"3D\88UD3U33UfUfff\99w\88U33333""""\11"""\11"3UUUU\88ffUD""""""333UDDDDDD3Dff""\11\11\11"\11\11\11""""Dw\88\99\99\88fUDD\88\88fw3DDDDDDDDDD333333""33DDDDDDDU""3""DD3\11"""\11\11\11"\11\11"UfUDD3D3"""3333D33DUU3"""3333""U33""33"""\11\11"3"""\11""""""""\11"""3""\11\11\11\11\11\11\11\11"33"UDD"""333DDDDD33UD3D333"\11\11\11""""""""33\11\11\11\11\11\11\11\11\11\11\11""""33D333DDD3UU3DUDD3333D"33"""""""""\11\11\11"\11\11""\11\11\11""""3"""3"33DD33U3\11"3DD"3UU3333"\11""""3U33""3333DUf\99ª\993""3333DUD3333""3"33fUD33"DDUUUfffwfU"33"3"""\11"""\11""\113ffffwwD"\11\11\11"""333D333333DDfU\11"\11\11\11"\11\11"""\11"3ww\88wfUDDDw\99D3Uf3D3DDUDDDD33""""""33DDDDDUU3""3UD3\11\0\11""\11"""\11\11"3UUUD333"""3"33333D3U3"333333\11\11"3"333"""""\11""\11""\11\11"""\11\11\11\11\11\11"3"3"""\11\11\11\11\11"\11""3D333"333333DDD333f"3D33"\11\11\11""""""""""3\11\11\11\11\11\11\11\11\11\11"3"""33333D3DUDDDUD333D333333"\11"""""\11"\11\11\11\11\11\11\11\11\11\11\11\11""\11"""""""3"33Uf""""D33333UUD3"""\11\11"3""""3333DDD\88\99\99\99fUfD"3"3D3""""""3"3D33333DD3UUDf\88\88wwfDDD333"""3D"\11""""UUUfUD3\11"\11\11""""333"3333DDDUU\11\11\11""""\11""\11\113DfwfUUDUUDDfwUUUwUDDDDDDDDD33""""""3DDDDUUU""33U"\11\11\11\11\11\11\11\11"3\11\11333UUD33""\11""""3D333DUUUDD"""""\11"3""""""""""\11""\11""""3""\11\11\11\11\11""""""""\11\11\11\11\11\11\11""3""D3"333333D3333Uw33""""\11\11\113""3""3""3"\11\11\11\11\11"\11\11\11\11\11""""""3333333DUUD3"3DD"""33"""""\11"\11\11"\11\11"\11\11\11\11\11\11""""""3"""""D333wwf""""3"33"33333""\11\1133""""3333DDD\88\99\88\99\88fww3"""33""""""33"3DD333333DUUUfw\88\88fDDD3"3"""333"D3"33UUUfD3""\11\11\11\11""3""3"33DDDUD"3""\11"""\11\11\11"3DffUD"""""3333DDUUfwUDDUDD3D33"""""33DDUDDU3\11"33U\11\11\11"\11\11\11\11\11"\11"\11DUUDDD"""""""""3DD3333Uffw33"\11\11""3"""\11""""""\11""\11\11\11"""\11\11"\11\11\11\11""""""""""""\11\11""""3"D3"33333D3333Dw\883"""\11""\11"33"3\11""""33"\11\11\11"\11\11\11\11\11"\11""""""3D3"D33UUD"""3333333""""""\11\11"\11\11\11\11\11"\11\11\11\11"""""\11"""3U3D33fUfwD"""3"""""3"""\11"\11\11"3"""""3"333Dw\88\88\88wffwf"\11\11"""""""""""3D33333333DUDUUUfw\88f"3333""3DD""3""DfUUff"""\11\11""""""333"33DUfU3"333""""""""DwfD"""""3""333333DUwU3DD33333""""""333DU3""\11""3U3\11\11\11\11\11\11\11\11\11"\11"DUDDD3"""3\11""3DD333333"333DffUDD3D33""""\113""\11"\11\11\11"\11"\11\11""\11\11\11""""3""""""""\11\11""""33"""3D33333"33Uwf""""\11"3"33D33""3""""""\11\11\11\11\11\11\11"\11\11\11\11"""""3""33DDD3"3333333D3"""\11\11\11\11\11\11"\11""\11\11\11\11\11\11""""\11"""\11"D333"3fff3"3UU3"""3""\11\11\11\11""\11"\11""3"33333Df\99\99\88ffwwUD"\11\11""""""""""3333"333333DUDUUUw\88w\99D33D333D3"""""3DDDU33"\11\11\113""""3D33""3DUffD"""333333""3UUfD""""""""3333333DDwD3D3333333"""""333DD"\11""3"DD\11\11\11\11\11\11\11"\11\11\11\11"DUD333333""""33DD""3333333"33DffD"33\11""\11""""\11\11\11\11\11\11\11"""\11\11"""""""33""""""""""""333""3DD33D3"""D\88U""""\11""3"333"3333"""""\11\11\11\11\11\11\11\11\11\11\11\11\11"""33"3DUUDDU3DUD3D333"""""\11\11"\11\11""""\11\11"3"""3"""""""33""D""3UU"3DfwD\11""3"""\11\11\11"\11\11\11\11"""333333UU\88ª\99\99www\88f"""""""""""""333D333333333DUUfffUDfDDUDDDDD"""""3D3UU3""\11"\11"3\11"""D333333UUf3333DD333"333fU3""""""""""""33"33DDfD3333DD3333""3333DD\11"""33DD\11\11\11\11\11\11"\11\11\11\11\11\03DD"33"D3"3"3""3UD"333"33"333D3UfD"3""\11\11""""\11\11\11\11""""3"\11\11"""""3"""3"3"\11\11""\11"""33333333D3333"D3fU3"""\1133""""3D3333""""\11""\11\11\11\11\11\11\11\11\11\11""""3333DDDD3DUUUU3""""\11\11"\11"\11"\11\11\11""""\113""33""""""""333"3D3""3DD3UUwf3""3"\113"\11\11\11\11\11\11""""33333DUUwªªª\88\88\88fU3""""""""""3D3"3DD3333333DDDUUUUDDDffDDDDD33""""3DDUU333"\11"""""""""3D333DDDUDD3D3"3D3"3DffD3"333333""""3""333DUU33333333""333D3333"""3D3UD\11\11\11\11\11\11\11\11\0\0\11\11\11\11DDDD3"\11"33""""3UU3"333D"3333DDDDffD"\11\11\11"""\11\11"""\11\11"\11"""""""""""""""""""""\11\11""3D3333333DD3333DUU"""""D3""""3UU33""""""\11\11\11\11\11\11\11\11\11\11""\11"""""33DD33DUDDUUD"3"""""""""\11\11\11"""\11""3D"""\1133"\11""3""333333"3DDDUwfUD""\11\11"""\11\11\11\11\11\11""""3333DUUU\88\99\99\88wfUD3""""\11"""""3D333DD3333333D3DDUDDDDD3ff3DD333"""""DDDDDD3"\11"""""""3"""333UU3333DDD3DDD3"Dff"D333D3DD3"""33"3333DfDD33333"3333333"3\11""3333DD\11\0\11\11\11\11\11\11"\11\11\11\11\03D3D3"\11\11\11\11""""\113fUDD3333333""3DDUUfU"""""\11\113ffU"\11"""""""""""""""""""""33"\11\113"33"3333D333DDDD33"""""33"3""3UUD333""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11""33D3D33DfDDD333"3""""""\11\11\11\11\11"\11""""33""\11\113"\11"D"""3"3333333DUDw\88U333""\11\11\11\11"3"\11\11""""333DDUwfw\99w\88fUfD"""\11\11"3"""""D3"3f33333333DDD3D3333UU3fU3UUD""""""3UDD""3"\11""""""\1133333"UUDD"""3D33UD33D3UU"3333333DD"""""""""3DUUD33333333333333""""33""3f\11\11\11\11\11\11\11\11\11"\11\11\11\1133\11""\11\11\11\11\11""\11""""3DDU3333"33D333DDDDUDD3""fwwU3D"\11""""\11"""""""\11"""""3""""\11""""3""33DD33DDf3\113D""""""""3333DUD333"""""\11\11\11\11\11\11\11\11\11\11\11\11\11"\11""33333333UUUDD333"\11""""\11\11""\11\11"\11\11\11\11"\1133"\11"\11"\11""""3""333"33ffUfffwU""""\11\11\11\11\1133\11\11"""33"3DUUf\99\88ªwwwUD3""""\11""\11"""""DDUfUUD"333D333DD3"33DDUDfffDUD""""33DDD""""""""""""""3"DUUU3""3""3333DDDDDwU3""33""33D"""""""3"33DDDDD3333333DD3DD"\11"D33333U"\11\11\11\11\11""""\11\11\11\11"3\11\11"\11\11\11\11\11\11"""""""3"DD3"""""333333DDDfwwDUffUD3333""""\11"""""""""\11"""3""""""\11\11""""333D33D3""\11\11\11\11\11""""""333DDDUUD33"""""\11\11\11\11\11\11\11\11\11\11\11\11"""""""333333DUfU3333"3""\11\11\11\11\11\11\11\11\11\11""\11\11\11333\11\11\11"\11\11"""""""33""333UwffU3\11\11"\11"\11\11""\11\11\11"""3333DDUfw3wfD333"""\11\11\11\11"\11"U3\11"DUfDUwD3""3D3333D333333DUfww3DDD"33DU333"\11"\11\11\11"\11""3"""""DDDD3"""""3333""3UwfU""""3"33333"""""""3"33DfUDDD3333"DDDD3"""DD33"3f3\11\11\11\11\11\11"""""\11"""\11\11\11"\11\11\11\11\11\11"""""""3"D3D"\11""""""3333DDUf\88wfDDDDDD3D3"""\11\11\11\11\11""""\11"""""\11\11\11"\11\11\11""""333DDD3\11\11"\11"""\11""""""""33UfUUD3"3"""""\11\11\11\11\11\11\11\11\11\11\11\11\11"""33"3D33333UUUD3"""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3""""\11"""""""""""33"33UfwwwDD33"\11\11\11""\11\11""""""3DUDffD\88\88UD33""\11\11""\11""D33\113DUUUUU"33333"333"3333333DDwffU333333D33"\11"\11\11\11\11\11"\11"D"3"333UD3D3"33"3""3""3ffUD""""""""3D33"""""""33DUwUUUDD3333D3DD3"333"""3DU"\11\11\11\11\11\11\11\11"\11"""""""\11""\11\11\11\11\11"""3"""""""D3\11\11"""\11"""3"33DUfwUU33D3DD3""\11\11\11\11\11""""""""3\11\11"\11\11\11\11\11\11\11\11""\11"33DDD3""""""\11\11\11"""""3""3DD333"""""""""\11\11\11\11\11\11\11\11\11\11\11\11\11"3"""33"33333UUfDDD"\11\11""\11\11\11\11\11\11"\11""\11\11\11\1133""""""""""""""""""3DD3DDDf3"DwU3\11\11\11\11\11"""""""3DUUUDw\88wDD3""\11\11"\11\11"3D33D33UDDDDD"33"3""3"3333333333DUDDUU3"333333"\11\11\11\11\11\11\11\11"""3"333"DUDDDD""3D33D"3UUUU33"""33"333"""""""""333UUDUUfD3DD333UD3"333""33DU"\11\11\11\11\11\11\11\11\11\11\11\11\11"3""""\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\1133\11\11"\11\11\11\11"""""3DwwUDDD33333333\11\11\11\11\11\11\11"""\11\11\11""""\11\11\11\11\11\11\11""3""""33D3""""""""\11""""""33DD33""""""333"""\11\11\11\11\11\11"\11\11\11\11\11""""""3333"3"DUUUDD""\11\11\11\11\11\11\11\11""\11"\11\11\11\11\11"""\11""\11""""""""""""3D"33D3333"3"3"\11\11\113"""""""3DDUfff\99ªw3"3"""\11\11\11"33D33D"DD3D333""3333"3"""33333333DDDDDUU3DD33333"\11\11\11\11\11\11\11"""333""33DDD3UD33U33UUDUDDD3"3""3""""""""""""""""33DDDUUfDDD33"DDD333""333DfD"\11\11\11\11\11\11\11\11\11\11\11\11"""""\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11"""""3DDUUD333"3333333"\11\11\11\11\11"\11\11"\11\11\11\11"""\11\11\11\11\11\11\11"""\113"3""33D3"""\11\11"333""33D3333""""""""33"""\11\11\11\11\11\11\11\11\11\11\11""\11""DD"33"3""3UfD33\11"\11\11\11\11\11\11\11\11""""\11\11\11\11"""\11"3"\11\11"\11"""""""33UD""3UD3D""D3\11\11\11\11"33\11"3""3DDUfww\88\99wU"3""""\11"D3333D3"3D"3D3""""333"3""""33333DDD333DDUwfUDD333\11\11\11\11\11\11\11\11\11""""3"33"DDD3D333UU3UDDDDD3333""""33""33"""""3""3333DDUDDffUDDDD"D3""""3333UU3\11\11\11\11""\11\11\11\11\11\11""33""\11\11\11\11"\11\11\11\11""\11""\11\11\11"\11\11\11\11\11""\11""33UUfDDUUDD333"3333Df3\11\11\11""\11""""""\11\11""\11\11\11\11""""\11"33333DD"DDD3""\11"DD33333"""3"33"3"""""""""\11\11\11\11\11\11\11\11\11\11"""\11"33D3"""""3UDD33"""\11\11\11\11\11\11\11"""\11\11\11\11\11"""\11\11"\11"\11\11""""3"3D33"""""3Uf333"""\11\11""""""""3DDUUffw\88\88ªf""""""""D"3""333"3333""""33"""""""333"33DD3""333Uw\88\88\99f333""\11\11\11\11\11"33"\11""333D3DDUD333DUUDDD333"33"333"33"3"""""""D33"3D33DDDDUUUUDD3DDD""""""33UD3D\11\11\11\11\11\11\11\11\11\11"""D33""\11\11\11\11"\11\11\11\11""\11\11\11"\11""\11\11\11"""\11\11\11"33DfUUfUDDD3""""DDDUD"\11\11"\11"333"3""""3"""333"\11""333333DD3333"""DDD33D33"""333333"3"""3""""\11\11\11\11\11\11\11\11\11\11"\11\11\11\11"3D3"""""33DD3D3""\11\11\11"\11\11"""\11\11"\11\11\11""\11\11\11\11\11\11""""""3U\88f3"""333DD"D3"""""333"""3DDUUDUffww\88ª\883""""""3""3D"""3"3333""33"D3"""33""""3"3DD3"33"33Uwwfw\99UD"""\11\11\11"""33"\11""3"3D3UffDDDfDDDD3"3"3333"33"33""""""33""33D3DDDDDUDUUUUDDDDUD""""3"3DUf"3"\11\11\11\11\11\0\11\11\11"""3""3\113\11\11\11\11"\11\11\11\11"\11\11""\113\11\11\11\11\11\11\11\11"""""3fUUUDDDDD""""33D"3f""""33DD3"""\11"33"""333""""333"""D3D3D33UDD3""33"D33333"""""""""33""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"3"""""333D333D""\11\11\11"\11"""""\11\11"3"\11\11\11\11\11\11\11""""""33UDD3""3DDUUUfD""""3DDU33"DDDUUDUfwUw\88ªªwD3"\1133"""33""""3"3333333"33""3""""D333D33"""""""Dffffwww3""""\11\11\11"\11\11""""33D333UUDUUUUD3D33"""3333"3"33"3"""3"3"3333DDDUDDUUDUUDDDDUfD""""\11"3DDw33"""\11\11\11\11\11\11\11""33""D"3f\11\11\11"\11""\11"\11"\11\11\0""\11\11\11\11\11\11\11"\11""\11DwffDUDDDDD"333"3"D\88\88D"33"""33""""\11\11\11\11""33\11""""33"3"333333DDD33333DDD333""""\11""""""3"33""""\11\11\11\11"\11\11\11\11\11\11\11\11\11""3""""3DU3"3"""""\11\11"""""3""3"\11\11\11\11\11\11"\11\11"3"33333"3333D3DUUU33""\11"3DffD"3DDDDDDUUUwfU\88»\88U3"""3"""333""3"\11""3""3"DD""""""""33DD333"""3"""3DUUfw\88wf3333\11""\11\11\11\11""""33DDDDD33wfDD333"""3"3333333DD3"\11"333"33DUDDUD3UUDUUDDDUDUUD3""""""3Dw3"U""\11\11\11\11\11\11\11"\11"33"D33DD\11\11\11"\11"\11\11\11\11\11\11\11\11"\11\11\11\11\11\11"\11\11""3UD"3DD33"3"3""""DUwfUfU33""\11""\11\11""\11\11\11\11\11\113"\11""\11"""33"3""3"3D33D3D333"33""""""""\11\11"""3"""D3"\11"\11\11\11"\11\11\11"\11\11\11\11\11\11""""""""DU""""""""\11""""""""""\11\11\11\11\11"\11\11\11"3333""""DD333D3333""\11"""""ffD"3DDD3DDUfUDUw\88ª\88f""""D3"""3""D3"""""""3D333"""""""""3DD""""""""""DDDDfwwww3"33\11"\11\11\11\11""""3DDDDDUUDUfU3333""3D"333DD3DD3D3D333333333DfD3DDDDDfDDDDUDD33"""""""3Df\1133"""\11\11\11"""\11\11"3"3D"DU"\11"33\11\11"\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\113wUD"\11"3D3""3""3DwwUU3"3UD\11"""""\11\11\11\11\11\11\11\11\11\11""\11\11\11\11"""""""33"3333333D333D3""""""""\11""\11""""""3""\11\113\11\11"\11\11\11\11\11\11\11\11\11\11\11""""""""33""3"""\11\11\11"3"""\11"\11\11"\11\11\11"\11"""""3"D"""3DD333D333D33\11\11\11\11"\113Uw33DDDDDDUfwfDU\88ªªUU""33""""3"Dwf""""""3DDD3"""""""3"""D""\11\11"""""""3DDUUDw\88w\883"3"""\11"""33DDD3DD3DUU33"D"33333333"""D3""""3D3"33333D33D3DD3DDUDDUDDUD3""333""3"""Uf\11""\113"""3""\11\11"33D3"DU3\11\0\11"33DDD\11\0\11\11"""\11\11\11\11""\11"ff"""""""33"3UUw\88w3"\11""3DU\11""""\11\11\11\11\11\11\11\11""\11\11"\11\11""""""3"33""33333"3DD3"3"3"""""""\11\11"\11""""33""""""""\11\11\11\11\11\11\11\11"\11\11\11\11\11"\11"""""3D3""""""\11""3""""""\11\11\11"33"3"""""DD"""3U3DD3DD3""D"\11\11\11\11\11"DDUUDDDDDDDUUfffwªÌ»f"3DD"\11"\11"3wªw3""\11"33333"""""""""\11333"\113D"""""""DD3DDDDfwwfDD""\11\11"""333D"33"D3UU33""3U3"""""""""""""""333""333333333D33DDDDUDUDDD"33333""3"\11\11\11UD""""33"""3""3D3DD""U3"\11"""\11\11\11\11\11\11\11\11""""\11\11""""D\88U3""""\11\11\11\11DwwwU"\11"\11""""33U3""\11"""\11\11\11\11\11\11\11\11""""\11""\11\11"""33"333"""333""""""3""""""""\11"""""3"""""""""\11"\11\11\11\11\11\11\11\11\11\11"\11"""3""""DD"""""""3""""""3"\11\11\11"\11\11"3"""33"3"3"DD3D33DDD""3"\11"\11\11\11"""33DDUDDDDDDUff\88\88\88\88""33\11"""\11wwwD3"\11"33"""""""""""\11"33"\11\11"""\11\11""333D3333DUff\88wf3\11\11\11\11""3""3"D333D3DD""33"3"""""""\11\11""\11"""""3"33"33D3DU33DDD3UUDUDDD"3D33"3"33"\11\11\11"w3"\11""33"\11"D"""3333"UU3\11\11""\11\11\11\11\0\11\11\11\11""33""""3wwD""""""\11\11"\11\113D"33"""""""333D\11"\11"\11\11\11\11\11\11\11"""""\11\11\11\11\11"\11\11"3"33333""""33D3"""""""""""\11""""""3"""3"3"""""\11\11\11\11\11\11\11\11\11\11\11\11""\11""\11"""DD"33"""""""33\11\11\11\11\11\11\11"\11"""3D333"33"ff33DD3D3"DU"""\11\11"\11""3333DD33D3DUf\88ªwUw\88ªw3"\11\11""""\88ª\88\99"\11"""""33"""""""""3"""\11\11"D"""""333333"3DUUUfwf3"\11\11\11\11"33""3DDDD333D3"UD3D3""33"\11""""\11""""""3"3"DDD3""U3"33DDfUDDD33DD33"3"""""\11\11"Uf\11\11\11"33"\11""\11\11"333"\11Df33\0\11"\11\11\11\11\0\11"\11"""""""""DwD"\11"""\11\11\11""\11\11\11"3""3""""""""33""\11\11\11\11\11\11\11"""""\11""\11"""""""""""3"3U"""33333"3"3""""""\11""""""33"""3"""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""""D3333333""\11"""\11"\11\11""""""""D333333"3UD"333DU3"DDU3"\11""""""3"33D33UUUfUDDUUfwª\99""\11"""\99ªªªwwU\11""""\11"3""\11\11"""""D""\11\11"\113D""""333D""""3DDUUUfD"3"""""D333"33DDDDDD33U3UwU""33"""\11\11\11"\11""""""""3333333"""3UDUUDD3333"333DD""333""3wU"""3""\11""\11\11""33333UU3"\11\11""\11"\11""\11\11""""""3DU33"""\11\11""\11\11\11\11\11"\11"""33"""""\11\11"33\11\11\11\11\11\11""\11\11\11"""""""""""""""""3""""""""3333"""3"""\11"""""""333"""""""""\11\11\11\11\11\11\11\11\11\11\11\11\11"""""""33D3333"3D3""D3""\11\11"""3"""3DDDDDD3""3fD"333DUU3"DUf3"\11"""""3"""33Uw\88fUD3"DDUD\88ªD"\11""U\88\99U3UUU\11""\11"""\11"\11\11\11""""3""\11\11\11\11\11"""""333333"\11"""3DDDffD3UU3""\1133DD"3D33333"DDDU33U"33"""""""\11""""\11""3333DDDUD3D33DDDDDD3D""3"33U3"333"\1133\88""3"""\11"""DDDUDUU3ffU3"\11"\11\11"\11"3"\11""""\11\11UfD3""3"\11"""\11\11\11"\11"\11\11\11"33"\1133"\11\11\11""3"\11\11\11\11"\11\11\11\11""""""""""""\11"""333"""33""33""33"""\11""\11"\11"33""333"""\11""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3""\11"DD33"333333"\11\11""""33D33333333D3"""3U333333UUDD3333""""33"3333DfwfwUD3""U3DUU»f\11Uf3\88w3"3fDUD\11\11\11\11""\11\11"\11\11\11"\11""\11""\11\11"\11\11"""33D"33""\11\11\11""33DDffU3D3""""3UDDD3"3"""3333"33DD33""""""\11""""""""33333D3DD"3DDDDDUDDD3333"33"3"333"\11"3wf\11""""""""3DD33"""fUUUD\11\11\11\11\11\11"UD""""\11\11UwD""""""""""\11"""""\11\11""3D"""33""\11"""3\11\11\11""\11\11\11""""""""""""\11\11""""""""""3"""3"""3D"3"""""""3D3""3"""\11\11"\11\11\11""\11\11\11\11\11\11\11\11\11\11"\11\11""""""\11"DD3"""333"""\11"""3"3UD"""3333DDD333U3"333"DUDD\88fD"U333DUDDUUfUUDDDDD3""3D33D\88»\99\99»\88f3\11""DUDDD""\11""\11"""\11"\11"""\11\11"""""\11"""33""33\11""\11\11\11""3DDUUfDD333""3D333D333\11""D33"U3"3DDDUU3"""\11"""""3333"3333DU333"33DUUD333DD""333DD33""""Uª\11\11"3333333""333"DUffU3U\11\11\11\11\11\11""\11\11\11\113DfU"\11""33"3""""""""3"\11"""""\11""3"""\11\11\11"D""""\11\11\11\11""\11\11""""""""\11"""""""""""3"3"""""3D"""""""33D3"""""""""\11\11\11""""\11\11\11\0\11\11\11\11""\11""3""\11\113DD3""3333"\11"""""33"fwU""3333DD333"UU"""3"Uffww\99\99\99wwUfUUUffD3333DDD33"3D3"33Dw»»ÝÌf"""""DU"UD""\11"""""""\11"3\11\11\11\11\11\113"\11"""33"3D""\11""\11\11\113"3DUUDfU3"\11\11"D3""""""\11"3"333"D333DDDUwww3""\11""""D3""3D3"3DD33D333333D33DDfU333DDUDD3""3D\883\113DD333"3"333DDDUfUfUD3\11"\11\11\11\11\0\0\0"UUD3"\11\11""33333333"""""33"\11"""\11\11"33"\11\11\11\11"33""\11\11\11"\11""\11""\11\11"""\11"\11\11"3"""""""""3"3"33DU3D3\113""""""""""""""""""\11"""""\11\11\11\11\11\11\11""\11"""""""3DD3"33"""""""""""""3w"""33D33333"3Uf3""3UwwUUfUfwfUDDfDDDUD33333DD3DD333333DDfÌÝU""3"""3DD3w"""""""""""3"\11\11\11\11\11\11\11\11""""""""3"\11\11"""\11\11\11""33DDw\88w""3"333"""""\11""33""3""DD""3DDD3D3""\11\11""""""3""333DD333""333333UUU\88\99U333DDD3\11"3DUf3DDD3""333"33D3"fDUUUU3""\11\11\0\11"DUfD"\11\11\11\11\11\11\11"\11"""""""""""""""33"\11\11"33"\11\11\11\11""D3"\11\11"""""""""""""\11\11"3"\11"3"""""""3""""333333D3"33""33"""""3""""""""DD3""\11\11\11\11\11\11\11"3"""""\11"DD3333"""3"""""""""""UD3""33"333"33UD""D\88wUUUUDUUUD"UwD""""3D33"3""""""3D"333U»Ýª"D3"3"3D3UwDUff""""""33"\11\11\11\11\11\11\11\11"\11\11""\11""3""\11\11"\11\11\11\11\11\11"3UUf\88\88D"\113D3""""""\11\11\11\11""""""33333D33333"""\11\11"\11""""""""3D3DD33""""3""3w\88wªfDDDDD33"""DDªD333D3"""3"""33\11DfDDDDUD"\11\11""DU3\11\11\11\11\11\11"""\11\11\11"\11\11\11""3""""""\11""3D"\11"33"\11\11\11\11\11"3D"\11\11"""""""""\11\11"\11\11"""""""3"""""""3""""D3D3"DU3"""3""""""3"""""33DUUDD3""\11\11\11\11\11\11\113D""""""3D3"""\11""""3DDD"""""""3"""3333333""D3"3ffUUUUDD3D33DDD3"3""""3""3"""""""""3333\88ÝîU3D3""3f3U\88U3DfD33""3U3""\11\11\11\11\11\11\11\11\11""33""""\11""\11"\11\11"\11""33UDfffUDDUD33"""""\11\11"""33D333"3"""33"3"33""""\11""""""""3DUDD333"3D333Dwª»w3DUD"33\11"3D3ªw\11"33\11\11"""3""""\11\11wDDD33D""\11U3\11\0\0\11\11\0\11\11\0"""\11\11\11\11\11\11\11\11\11"3\11""""""\11""3"""""\11\11\11\11\11"3U33""""33""""\11\11\113\11"\11""""3""""""""""""""33"3333""333""""3333333DfwwfDDD3""\11\11\11\11\11\11\1133"""""3"""""\11\11""\11"UDD""3"""3333"33"333"3DD3DDwU3DD33333D""3D""3"""33""""""""""""333D\88Ýݪ\11"DD333UU\88"3DUU33""Df"\11"\11\11\11\11\11\11\11\11\11\11"""\11"""\11\11""""\11\11\11\11""3DUUfffwww\88U33""""\11\11\113""333333DU"3UD3D"""3"""""""\11""""""3D3333"Uw333"f»\99\99f33DD"""""DDwª\0"3"\11\11"3"""3"\11\11\11\11fD33DD3"\11wD\0\11\11\11\11\0\11\11\033"\11"\11\11\11\11\11\11\11"""""""""""\11\11""""\11\11\11\11\11\11"3DU""\11""""3"""\11\11\11"""""3"""333""3"\11\11"""3"3D33D33333D3"""33DDDDUU\88\88\88f3\11""UD"\11\11\11\11\11""\11""3DDDD""""""""\11""""""33""333"""""333D33Dw\99\99\88wDDD3333DD3""33"""""""3""\11""""3""""33Df\99ÌÝ»»U"3"DDD3\883""DDU3\11"Uf"\11\11\11\11\11\11\11\11\11""\11"3"""""\11\11\11\11\11"D\113"\11\11"DDUfUUUfwwwf"3"\11\11"\11"""""DDDDDDD333DDD""3"""""""""\11"""""3D33"""\113333""fwDDU3"""\11"""DUfª\11\11""\11\11""333"""\11"\11DUDDDDD3Df"\0\11\11\11\11\11\11\11\11\1133"""\11\11\11\11\11\11"\11\11\11"\11""""\0\11""3"\11\11\11\11\0\11\11\11"3D3"""3""333""\11\11\11""""""""""""33"""""""""""3"3D33D33""333UUUf\88\99\99f3"\11\11"3\11"3""\11\11\11"""3""3DfD3""\11\113D""""""""3"33"3"""33"33""33\11D\99\99wUDDDD3D3fD"""3""""""""""\11\11\11\11"""""""3U\88»Ì̪»ª»U"33UD"3w""3DfD33fD\11\11\11\11\11\11\11\11\11\11\11"\11""""3""\11\11\11\11\11\11\11"33""""UUUfUUUfffwfDD""\11\11\11"\11""3DDDUD3D3333DD3333"""""\11""33""""333333"""""""33333"""\11\11\11\11"Df\88\99"\11\11"\11""333\11\11\11\11"\11\11"UDDUfU3DD\11\11\11\11\11\11\11\0\11\11\11"\11\11\11"\11\11\11\11\11\11\11"""\11"\11""\11\11\0\0\11""\11\11\11\11\11\11\11\11\11"3U3""33"333""\11\11\11"""""""""""""D3"""3"33U3"33"3D33D3D3DD33Uf\88»Ì\883\11""\11""\11"""""""\11""""""D3DD3D"333""""""3D"""""333333"333D3""3wwDD3DD3DD33D3""""3""""\11""\11""\11\11"\11"""""33ªÌÌ»\99ª»ªD"333DD\11w"""DUf3D3U"\11\11\11\11\11\11\11\11\11"""""""""\11\11\11\11""\11\11D"DDD"3DDDUDDDDUUUwUD3""\11\11"\11\11"333"3DD33D333DDDD"""\11"33""3"\11"\11\11"33333""""""""""DD""D"\11\11""3DwªD\0\11\11\11""\11\11\11\11\11\11\11"\11\11\11\113UUffUU3\11\11\11\11\0\11\11\0\11\11\11"""\11\11\11\11\11\11\11\11\11""""\11\11\11""\11\11\11\11""""\11\11\11\11\11\11\11""3U3333D"333""""\11"""""""""3"""333""3333U33"""3DDDDDDUDfw\99\99Ì\99U"\11\11""""\11"\11"""""\11\11"""3DDDDDDU3"3D3"""\11"""""""""""33"33333DD"3fwUDD"3D33"3"DDD3"""3""\11\11\11\11\11\11"\11\11\11\11\11\11"""3Dfªªªª\99ª»f\1133"33""f""3DfUD""3""\11\11\11\11\11\11\11\11""""3""\11\11"\11\11\11"3\11""3D"3"33DDDDDDUffffDD\11"\11\11"\11\11""""""""""3333333DDD333UD33DU""\11"\11""33"""""\11\11\11"D3""\113DD""\11"3Dwª\88\0\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11"DUU\88fwUU"\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11""""""\11"\11\11\11\11\11\11""""\11\11\11\11\11"""DUD3"33"""333D"""""""""333"""33""333D3D3"33"3DUffw\88\99»Ì»\88D\11\0\0\11\11\11\11""""""""""""\11"""DfUDD33D3""""""\1133""333""""3D""333333"w\99wDD333333"3"D3"D3"""""\11\11\11\11\11\11\11\11\11\11"\11\11\11"33DUf\88\99\99\99D"\883\11"3"3""DD3"DUwD"\11"\11\11\11\11""\11\11\11"""""3"""\11\11\11\11\11"D"\11""3""3"33DDDDDDD3DUwU""""\11\11\11"""""""""""333333DDDDDD33D3D"""\11\11"""""3""""\11\11\11"3U"DDDff3""""3f\99»"\11\11\11\11"\11\11\11\11\11\11\0\0\11"ffD\1133\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11"33"\11\11\11\11\11\11\11\11\11""D"\11\11\11\11\11\11\11\11""\11""\11\11\11""""3UU3333333333DD33"3333"33"33"3D3D3Dfw\99wfUUDDfw\99\99ª»\99ffD3\11\0\0\0"\11\11\11\11""""""""3"""""""DwfU33D33"""""""""3""3"""""3D3D333"33D\99wUDDD33"333"""3""3D3""\11""\11\11\11\11\11\11\11"\11""""3DUUffw\99fD\11\11U\883"33"""U"33Dw3""\11\11\11\11\11\11\11\11\11\11"""33"""\11"\11\11\11\11\11"\11""\11\11\11"\11"""3333D333DDUfU"""""\11"""""\11"\11"3"""33"333fUU33"""""D"\11\11"\11"""3"\11\11\11\11\11\11\11\11""""UD"3"33"3Uf\99U\0\11\11\0"\11\11\11\11\11\11\0D\88UD3\11\11\113\11\11\0\11\11\0\11\11"""""\11\11\11\11"3D3"\11\11\11\11\11\11"\11\11""D\11"\11\11"\11\11\11\11""\11""\11\113"333DwDD333DUDDDDfD333D333DUDDUUD3DUwffD3\99\99»ª\99\99\88wwD\0"""\11\11\11\11\0\11\11\11\11\11\11\11""""""""33"""""\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0
\ No newline at end of file
diff --git a/gtk/parent b/gtk/parent
new file mode 100644 (file)
index 0000000..94fee61
--- /dev/null
@@ -0,0 +1,10 @@
+    gdk_window_show (widget->window);
+    gdk_window_clear_area (widget->window,
+                          widget->allocation.x,
+                          widget->allocation.y,
+                          widget->allocation.width,
+                          widget->allocation.height);
+    gdk_window_hide (widget->window);
+      if (GTK_WIDGET_VISIBLE (widget->parent))
+         if (GTK_WIDGET_REALIZED (widget->parent) &&
+         if (GTK_WIDGET_MAPPED (widget->parent) &&
diff --git a/gtk/runelisp b/gtk/runelisp
new file mode 100644 (file)
index 0000000..115080c
--- /dev/null
@@ -0,0 +1,6 @@
+#! /bin/sh
+if test $# -lt 1; then
+  echo >&2 "usage: $0 file.el"
+  exit 1
+fi
+exec emacs --no-init-file --no-site-file --batch --load $*
diff --git a/gtk/simple.c b/gtk/simple.c
new file mode 100644 (file)
index 0000000..4789377
--- /dev/null
@@ -0,0 +1,39 @@
+#include <gtk/gtk.h>
+#include <gdk/gdkprivate.h>
+
+
+void
+hello ()
+{
+  g_print ("hello world\n");
+}
+
+int
+main (int argc, char *argv[])
+{
+  GtkWidget *window;
+  GtkWidget *button;
+
+  gdk_progclass = g_strdup ("XTerm");
+  gtk_init (&argc, &argv);
+
+  window = gtk_widget_new (gtk_window_get_type (),
+                          "GtkObject::user_data", NULL,
+                          "GtkWindow::type", GTK_WINDOW_TOPLEVEL,
+                          "GtkWindow::title", "hello world",
+                          "GtkWindow::allow_grow", FALSE,
+                          "GtkWindow::allow_shrink", FALSE,
+                          "GtkContainer::border_width", 10,
+                          NULL);
+  button = gtk_widget_new (gtk_button_get_type (),
+                          "GtkButton::label", "hello world",
+                          "GtkObject::signal::clicked", hello, NULL,
+                          "GtkWidget::parent", window,
+                          "GtkWidget::visible", TRUE,
+                          NULL);
+  gtk_widget_show (window);
+
+  gtk_main ();
+
+  return 0;
+}
diff --git a/gtk/test.xpm b/gtk/test.xpm
new file mode 100644 (file)
index 0000000..9b0d2ef
--- /dev/null
@@ -0,0 +1,92 @@
+/* XPM */
+static char *openfile[] = {
+/* width height num_colors chars_per_pixel */
+"    20    19       66            2",
+/* colors */
+".. c None",
+".# c #000000",
+".a c #dfdfdf",
+".b c #7f7f7f",
+".c c #006f6f",
+".d c #00efef",
+".e c #009f9f",
+".f c #004040",
+".g c #00bfbf",
+".h c #ff0000",
+".i c #ffffff",
+".j c #7f0000",
+".k c #007070",
+".l c #00ffff",
+".m c #00a0a0",
+".n c #004f4f",
+".o c #00cfcf",
+".p c #8f8f8f",
+".q c #6f6f6f",
+".r c #a0a0a0",
+".s c #7f7f00",
+".t c #007f7f",
+".u c #5f5f5f",
+".v c #707070",
+".w c #00f0f0",
+".x c #009090",
+".y c #ffff00",
+".z c #0000ff",
+".A c #00afaf",
+".B c #00d0d0",
+".C c #00dfdf",
+".D c #005f5f",
+".E c #00b0b0",
+".F c #001010",
+".G c #00c0c0",
+".H c #000f0f",
+".I c #00007f",
+".J c #005050",
+".K c #002f2f",
+".L c #dfcfcf",
+".M c #dfd0d0",
+".N c #006060",
+".O c #00e0e0",
+".P c #00ff00",
+".Q c #002020",
+".R c #dfc0c0",
+".S c #008080",
+".T c #001f1f",
+".U c #003f3f",
+".V c #007f00",
+".W c #00000f",
+".X c #000010",
+".Y c #00001f",
+".Z c #000020",
+".0 c #00002f",
+".1 c #000030",
+".2 c #00003f",
+".3 c #000040",
+".4 c #00004f",
+".5 c #000050",
+".6 c #00005f",
+".7 c #000060",
+".8 c #00006f",
+".9 c #000070",
+"#. c #7f7f80",
+"## c #9f9f9f",
+/* pixels */
+"........................................",
+"........................................",
+"........................................",
+".......................#.#.#............",
+".....................#.......#...#......",
+"...............................#.#......",
+".......#.#.#.................#.#.#......",
+".....#.y.i.y.#.#.#.#.#.#.#..............",
+".....#.i.y.i.y.i.y.i.y.i.#..............",
+".....#.y.i.y.i.y.i.y.i.y.#..............",
+".....#.i.y.i.y.#.#.#.#.#.#.#.#.#.#.#....",
+".....#.y.i.y.#.s.s.s.s.s.s.s.s.s.#......",
+".....#.i.y.#.s.s.s.s.s.s.s.s.s.#........",
+".....#.y.#.s.s.s.s.s.s.s.s.s.#..........",
+".....#.#.s.s.s.s.s.s.s.s.s.#............",
+".....#.#.#.#.#.#.#.#.#.#.#..............",
+"........................................",
+"........................................",
+"........................................"
+};
diff --git a/gtk/testgtk.c b/gtk/testgtk.c
new file mode 100644 (file)
index 0000000..b1d698a
--- /dev/null
@@ -0,0 +1,3110 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include "gtk.h"
+#include "../gdk/gdk.h"
+#include "../gdk/gdkx.h"
+
+
+void
+destroy_window (GtkWidget  *widget,
+               GtkWidget **window)
+{
+  *window = NULL;
+}
+
+void
+button_window (GtkWidget *widget,
+              GtkWidget *button)
+{
+  if (!GTK_WIDGET_VISIBLE (button))
+    gtk_widget_show (button);
+  else
+    gtk_widget_hide (button);
+}
+
+void
+create_buttons ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *box1;
+  GtkWidget *box2;
+  GtkWidget *table;
+  GtkWidget *button[10];
+  GtkWidget *separator;
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "buttons");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+      box1 = gtk_vbox_new (FALSE, 0);
+      gtk_container_add (GTK_CONTAINER (window), box1);
+      gtk_widget_show (box1);
+
+
+      table = gtk_table_new (3, 3, FALSE);
+      gtk_table_set_row_spacings (GTK_TABLE (table), 5);
+      gtk_table_set_col_spacings (GTK_TABLE (table), 5);
+      gtk_container_border_width (GTK_CONTAINER (table), 10);
+      gtk_box_pack_start (GTK_BOX (box1), table, TRUE, TRUE, 0);
+      gtk_widget_show (table);
+
+
+      button[0] = gtk_button_new_with_label ("button1");
+      button[1] = gtk_button_new_with_label ("button2");
+      button[2] = gtk_button_new_with_label ("button3");
+      button[3] = gtk_button_new_with_label ("button4");
+      button[4] = gtk_button_new_with_label ("button5");
+      button[5] = gtk_button_new_with_label ("button6");
+      button[6] = gtk_button_new_with_label ("button7");
+      button[7] = gtk_button_new_with_label ("button8");
+      button[8] = gtk_button_new_with_label ("button9");
+
+      gtk_signal_connect (GTK_OBJECT (button[0]), "clicked",
+                         (GtkSignalFunc) button_window,
+                         button[1]);
+
+      gtk_table_attach (GTK_TABLE (table), button[0], 0, 1, 0, 1,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+      gtk_widget_show (button[0]);
+
+      gtk_signal_connect (GTK_OBJECT (button[1]), "clicked",
+                         (GtkSignalFunc) button_window,
+                         button[2]);
+
+      gtk_table_attach (GTK_TABLE (table), button[1], 1, 2, 1, 2,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+      gtk_widget_show (button[1]);
+
+      gtk_signal_connect (GTK_OBJECT (button[2]), "clicked",
+                         (GtkSignalFunc) button_window,
+                         button[3]);
+      gtk_table_attach (GTK_TABLE (table), button[2], 2, 3, 2, 3,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+      gtk_widget_show (button[2]);
+
+      gtk_signal_connect (GTK_OBJECT (button[3]), "clicked",
+                         (GtkSignalFunc) button_window,
+                         button[4]);
+      gtk_table_attach (GTK_TABLE (table), button[3], 0, 1, 2, 3,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+      gtk_widget_show (button[3]);
+
+      gtk_signal_connect (GTK_OBJECT (button[4]), "clicked",
+                         (GtkSignalFunc) button_window,
+                         button[5]);
+      gtk_table_attach (GTK_TABLE (table), button[4], 2, 3, 0, 1,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+      gtk_widget_show (button[4]);
+
+      gtk_signal_connect (GTK_OBJECT (button[5]), "clicked",
+                         (GtkSignalFunc) button_window,
+                         button[6]);
+      gtk_table_attach (GTK_TABLE (table), button[5], 1, 2, 2, 3,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+      gtk_widget_show (button[5]);
+
+      gtk_signal_connect (GTK_OBJECT (button[6]), "clicked",
+                         (GtkSignalFunc) button_window,
+                         button[7]);
+      gtk_table_attach (GTK_TABLE (table), button[6], 1, 2, 0, 1,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+      gtk_widget_show (button[6]);
+
+      gtk_signal_connect (GTK_OBJECT (button[7]), "clicked",
+                         (GtkSignalFunc) button_window,
+                         button[8]);
+      gtk_table_attach (GTK_TABLE (table), button[7], 2, 3, 1, 2,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+      gtk_widget_show (button[7]);
+
+      gtk_signal_connect (GTK_OBJECT (button[8]), "clicked",
+                         (GtkSignalFunc) button_window,
+                         button[0]);
+      gtk_table_attach (GTK_TABLE (table), button[8], 0, 1, 1, 2,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+      gtk_widget_show (button[8]);
+
+
+      separator = gtk_hseparator_new ();
+      gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
+      gtk_widget_show (separator);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button[9] = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button[9]), "clicked",
+                                (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+      gtk_box_pack_start (GTK_BOX (box2), button[9], TRUE, TRUE, 0);
+      GTK_WIDGET_SET_FLAGS (button[9], GTK_CAN_DEFAULT);
+      gtk_widget_grab_default (button[9]);
+      gtk_widget_show (button[9]);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+void
+create_toggle_buttons ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *box1;
+  GtkWidget *box2;
+  GtkWidget *button;
+  GtkWidget *separator;
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "toggle buttons");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+
+      box1 = gtk_vbox_new (FALSE, 0);
+      gtk_container_add (GTK_CONTAINER (window), box1);
+      gtk_widget_show (box1);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_toggle_button_new_with_label ("button1");
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+      button = gtk_toggle_button_new_with_label ("button2");
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+      button = gtk_toggle_button_new_with_label ("button3");
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+
+      separator = gtk_hseparator_new ();
+      gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
+      gtk_widget_show (separator);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+void
+create_check_buttons ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *box1;
+  GtkWidget *box2;
+  GtkWidget *button;
+  GtkWidget *separator;
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "check buttons");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+
+      box1 = gtk_vbox_new (FALSE, 0);
+      gtk_container_add (GTK_CONTAINER (window), box1);
+      gtk_widget_show (box1);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_check_button_new_with_label ("button1");
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+      button = gtk_check_button_new_with_label ("button2");
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+      button = gtk_check_button_new_with_label ("button3");
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+
+      separator = gtk_hseparator_new ();
+      gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
+      gtk_widget_show (separator);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+void
+create_radio_buttons ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *box1;
+  GtkWidget *box2;
+  GtkWidget *button;
+  GtkWidget *separator;
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "radio buttons");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+
+      box1 = gtk_vbox_new (FALSE, 0);
+      gtk_container_add (GTK_CONTAINER (window), box1);
+      gtk_widget_show (box1);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_radio_button_new_with_label (NULL, "button1");
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+      button = gtk_radio_button_new_with_label (
+                gtk_radio_button_group (GTK_RADIO_BUTTON (button)),
+                "button2");
+      gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (button), TRUE);
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+      button = gtk_radio_button_new_with_label (
+                 gtk_radio_button_group (GTK_RADIO_BUTTON (button)),
+                "button3");
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+
+      separator = gtk_hseparator_new ();
+      gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
+      gtk_widget_show (separator);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+void
+bbox_widget_destroy (GtkWidget* widget, GtkWidget* todestroy)
+{
+}
+
+void
+create_bbox_window (gint  horizontal,
+                   char* title, 
+                   gint  pos, 
+                   gint  spacing,
+                   gint  child_w, 
+                   gint  child_h, 
+                   gint  layout)
+{
+  GtkWidget* window;
+  GtkWidget* box1;
+  GtkWidget* bbox;
+  GtkWidget* button;
+       
+  /* create a new window */
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_title (GTK_WINDOW (window), title);
+
+  gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                     (GtkSignalFunc) bbox_widget_destroy, window);
+  gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                     (GtkSignalFunc) bbox_widget_destroy, window);
+  
+  if (horizontal)
+  {
+    gtk_widget_set_usize (window, 550, 60);
+    gtk_widget_set_uposition (window, 150, pos);
+    box1 = gtk_vbox_new (FALSE, 0);
+  }
+  else
+  {
+    gtk_widget_set_usize (window, 150, 400);
+    gtk_widget_set_uposition (window, pos, 200);
+    box1 = gtk_vbox_new (FALSE, 0);
+  }
+  
+  gtk_container_add (GTK_CONTAINER (window), box1);
+  gtk_widget_show (box1);
+  
+  if (horizontal)
+    bbox = gtk_hbutton_box_new();
+  else
+    bbox = gtk_vbutton_box_new();
+  gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), layout);
+  gtk_button_box_set_spacing (GTK_BUTTON_BOX (bbox), spacing);
+  gtk_button_box_set_child_size (GTK_BUTTON_BOX (bbox), child_w, child_h);
+  gtk_widget_show (bbox);
+  
+  gtk_container_border_width (GTK_CONTAINER(box1), 25);
+  gtk_box_pack_start (GTK_BOX (box1), bbox, TRUE, TRUE, 0);
+  
+  button = gtk_button_new_with_label ("OK");
+  gtk_container_add (GTK_CONTAINER(bbox), button);
+
+  gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                     (GtkSignalFunc) bbox_widget_destroy, window);
+
+  gtk_widget_show (button);
+  
+  button = gtk_button_new_with_label ("Cancel");
+  gtk_container_add (GTK_CONTAINER(bbox), button);
+  gtk_widget_show (button);
+  
+  button = gtk_button_new_with_label ("Help");
+  gtk_container_add (GTK_CONTAINER(bbox), button);
+  gtk_widget_show (button);
+  
+  gtk_widget_show (window);
+}
+
+void
+test_hbbox ()
+{
+  create_bbox_window (TRUE, "Spread", 50, 40, 85, 28, GTK_BUTTONBOX_SPREAD);
+  create_bbox_window (TRUE, "Edge", 200, 40, 85, 25, GTK_BUTTONBOX_EDGE);
+  create_bbox_window (TRUE, "Start", 350, 40, 85, 25, GTK_BUTTONBOX_START);
+  create_bbox_window (TRUE, "End", 500, 15, 30, 25, GTK_BUTTONBOX_END);
+}
+
+void
+test_vbbox ()
+{
+  create_bbox_window (FALSE, "Spread", 50, 40, 85, 25, GTK_BUTTONBOX_SPREAD);
+  create_bbox_window (FALSE, "Edge", 250, 40, 85, 28, GTK_BUTTONBOX_EDGE);
+  create_bbox_window (FALSE, "Start", 450, 40, 85, 25, GTK_BUTTONBOX_START);
+  create_bbox_window (FALSE, "End", 650, 15, 30, 25, GTK_BUTTONBOX_END);
+} 
+
+void
+create_button_box ()
+{
+  static GtkWidget* window = NULL;
+  GtkWidget* bbox;
+  GtkWidget* button;
+       
+  if (!window)
+  {
+    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+    gtk_window_set_title (GTK_WINDOW (window),
+                         "Button Box Test");
+    
+    gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                       (GtkSignalFunc) destroy_window, &window);
+    gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                       (GtkSignalFunc) destroy_window, &window);
+    
+    gtk_container_border_width (GTK_CONTAINER (window), 20);
+    
+    /* 
+     *these 15 lines are a nice and easy example for GtkHButtonBox 
+     */
+    bbox = gtk_hbutton_box_new ();
+    gtk_container_add (GTK_CONTAINER (window), bbox);
+    gtk_widget_show (bbox);
+    
+    button = gtk_button_new_with_label ("Horizontal");
+    gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                       (GtkSignalFunc) test_hbbox, 0);
+    gtk_container_add (GTK_CONTAINER (bbox), button);
+    gtk_widget_show (button);
+    
+    button = gtk_button_new_with_label ("Vertical");
+    gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                       (GtkSignalFunc) test_vbbox, 0);
+    gtk_container_add (GTK_CONTAINER (bbox), button);
+    gtk_widget_show (button);
+  }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+
+void
+reparent_label (GtkWidget *widget,
+               GtkWidget *new_parent)
+{
+  GtkWidget *label;
+
+  label = gtk_object_get_user_data (GTK_OBJECT (widget));
+
+  gtk_widget_reparent (label, new_parent);
+}
+
+void
+create_reparent ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *box1;
+  GtkWidget *box2;
+  GtkWidget *box3;
+  GtkWidget *frame;
+  GtkWidget *button;
+  GtkWidget *label;
+  GtkWidget *separator;
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "buttons");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+
+      box1 = gtk_vbox_new (FALSE, 0);
+      gtk_container_add (GTK_CONTAINER (window), box1);
+      gtk_widget_show (box1);
+
+
+      box2 = gtk_hbox_new (FALSE, 5);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      label = gtk_label_new ("Hello World");
+
+      frame = gtk_frame_new ("Frame 1");
+      gtk_box_pack_start (GTK_BOX (box2), frame, TRUE, TRUE, 0);
+      gtk_widget_show (frame);
+
+      box3 = gtk_vbox_new (FALSE, 5);
+      gtk_container_border_width (GTK_CONTAINER (box3), 5);
+      gtk_container_add (GTK_CONTAINER (frame), box3);
+      gtk_widget_show (box3);
+
+      button = gtk_button_new_with_label ("switch");
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         (GtkSignalFunc) reparent_label,
+                         box3);
+      gtk_object_set_user_data (GTK_OBJECT (button), label);
+      gtk_box_pack_start (GTK_BOX (box3), button, FALSE, TRUE, 0);
+      gtk_widget_show (button);
+
+      gtk_box_pack_start (GTK_BOX (box3), label, FALSE, TRUE, 0);
+      gtk_widget_show (label);
+
+
+      frame = gtk_frame_new ("Frame 2");
+      gtk_box_pack_start (GTK_BOX (box2), frame, TRUE, TRUE, 0);
+      gtk_widget_show (frame);
+
+      box3 = gtk_vbox_new (FALSE, 5);
+      gtk_container_border_width (GTK_CONTAINER (box3), 5);
+      gtk_container_add (GTK_CONTAINER (frame), box3);
+      gtk_widget_show (box3);
+
+      button = gtk_button_new_with_label ("switch");
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         (GtkSignalFunc) reparent_label,
+                         box3);
+      gtk_object_set_user_data (GTK_OBJECT (button), label);
+      gtk_box_pack_start (GTK_BOX (box3), button, FALSE, TRUE, 0);
+      gtk_widget_show (button);
+
+
+      separator = gtk_hseparator_new ();
+      gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
+      gtk_widget_show (separator);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+void
+create_pixmap ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *box1;
+  GtkWidget *box2;
+  GtkWidget *box3;
+  GtkWidget *button;
+  GtkWidget *label;
+  GtkWidget *separator;
+  GtkWidget *pixmapwid;
+  GdkPixmap *pixmap;
+  GdkBitmap *mask;
+  GtkStyle *style;
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                          (GtkSignalFunc) destroy_window,
+                          &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                          (GtkSignalFunc) destroy_window,
+                          &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "pixmap");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+      gtk_widget_realize(window);
+
+      box1 = gtk_vbox_new (FALSE, 0);
+      gtk_container_add (GTK_CONTAINER (window), box1);
+      gtk_widget_show (box1);
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
+      gtk_widget_show (box2);
+
+      button = gtk_button_new ();
+      gtk_box_pack_start (GTK_BOX (box2), button, FALSE, FALSE, 0);
+      gtk_widget_show (button);
+
+      style=gtk_widget_get_style(button);
+
+      pixmap = gdk_pixmap_create_from_xpm (window->window, &mask, 
+                                          &style->bg[GTK_STATE_NORMAL],
+                                          "test.xpm");
+      pixmapwid = gtk_pixmap_new (pixmap, mask);
+
+      label = gtk_label_new ("Pixmap\ntest");
+      box3 = gtk_hbox_new (FALSE, 0);
+      gtk_container_border_width (GTK_CONTAINER (box3), 2);
+      gtk_container_add (GTK_CONTAINER (box3), pixmapwid);
+      gtk_container_add (GTK_CONTAINER (box3), label);
+      gtk_container_add (GTK_CONTAINER (button), box3);
+      gtk_widget_show (pixmapwid);
+      gtk_widget_show (label);
+      gtk_widget_show (box3);
+
+      separator = gtk_hseparator_new ();
+      gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
+      gtk_widget_show (separator);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                 (GtkSignalFunc) gtk_widget_destroy,
+                                 GTK_OBJECT (window));
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+void
+create_tooltips ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *box1;
+  GtkWidget *box2;
+  GtkWidget *button;
+  GtkWidget *separator;
+  GtkTooltips *tooltips;
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                          (GtkSignalFunc) destroy_window,
+                          &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                          (GtkSignalFunc) destroy_window,
+                          &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "tooltips");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+      tooltips=gtk_tooltips_new();
+
+      box1 = gtk_vbox_new (FALSE, 0);
+      gtk_container_add (GTK_CONTAINER (window), box1);
+      gtk_widget_show (box1);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_toggle_button_new_with_label ("button1");
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+      gtk_tooltips_set_tips(tooltips,button,"This is button 1");
+
+      button = gtk_toggle_button_new_with_label ("button2");
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+      gtk_tooltips_set_tips(tooltips,button,"This is button 2");
+
+      button = gtk_toggle_button_new_with_label ("button3");
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+      gtk_tooltips_set_tips (tooltips, button, "This is button 3. This is also a really long tooltip which probably won't fit on a single line and will therefore need to be wrapped. Hopefully the wrapping will work correctly.");
+
+      separator = gtk_hseparator_new ();
+      gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
+      gtk_widget_show (separator);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                 (GtkSignalFunc) gtk_widget_destroy,
+                                 GTK_OBJECT (window));
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+
+      gtk_tooltips_set_tips (tooltips, button, "Push this button to close window");
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+GtkWidget*
+create_menu (int depth)
+{
+  GtkWidget *menu;
+  GtkWidget *submenu;
+  GtkWidget *menuitem;
+  GSList *group;
+  char buf[32];
+  int i, j;
+
+  if (depth < 1)
+    return NULL;
+
+  menu = gtk_menu_new ();
+  submenu = NULL;
+  group = NULL;
+
+  for (i = 0, j = 1; i < 5; i++, j++)
+    {
+      sprintf (buf, "item %2d - %d", depth, j);
+      menuitem = gtk_radio_menu_item_new_with_label (group, buf);
+      group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem));
+      gtk_menu_append (GTK_MENU (menu), menuitem);
+      gtk_widget_show (menuitem);
+
+      if (depth > 0)
+       {
+         if (!submenu)
+           submenu = create_menu (depth - 1);
+         gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
+       }
+    }
+
+  return menu;
+}
+
+void
+create_menus ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *box1;
+  GtkWidget *box2;
+  GtkWidget *button;
+  GtkWidget *menu;
+  GtkWidget *menubar;
+  GtkWidget *menuitem;
+  GtkWidget *optionmenu;
+  GtkWidget *separator;
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "menus");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+
+      box1 = gtk_vbox_new (FALSE, 0);
+      gtk_container_add (GTK_CONTAINER (window), box1);
+      gtk_widget_show (box1);
+
+
+      menubar = gtk_menu_bar_new ();
+      gtk_box_pack_start (GTK_BOX (box1), menubar, FALSE, TRUE, 0);
+      gtk_widget_show (menubar);
+
+      menu = create_menu (2);
+
+      menuitem = gtk_menu_item_new_with_label ("test\nline2");
+      gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
+      gtk_menu_bar_append (GTK_MENU_BAR (menubar), menuitem);
+      gtk_widget_show (menuitem);
+
+      menuitem = gtk_menu_item_new_with_label ("foo");
+      gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
+      gtk_menu_bar_append (GTK_MENU_BAR (menubar), menuitem);
+      gtk_widget_show (menuitem);
+
+      menuitem = gtk_menu_item_new_with_label ("bar");
+      gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
+      gtk_menu_item_right_justify (GTK_MENU_ITEM (menuitem));
+      gtk_menu_bar_append (GTK_MENU_BAR (menubar), menuitem);
+      gtk_widget_show (menuitem);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      optionmenu = gtk_option_menu_new ();
+      gtk_option_menu_set_menu (GTK_OPTION_MENU (optionmenu), create_menu (1));
+      gtk_option_menu_set_history (GTK_OPTION_MENU (optionmenu), 4);
+      gtk_box_pack_start (GTK_BOX (box2), optionmenu, TRUE, TRUE, 0);
+      gtk_widget_show (optionmenu);
+
+
+      separator = gtk_hseparator_new ();
+      gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
+      gtk_widget_show (separator);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+void
+create_scrolled_windows ()
+{
+  static GtkWidget *window;
+  GtkWidget *scrolled_window;
+  GtkWidget *table;
+  GtkWidget *button;
+  char buffer[32];
+  int i, j;
+
+  if (!window)
+    {
+      window = gtk_dialog_new ();
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "dialog");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+
+      scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+      gtk_container_border_width (GTK_CONTAINER (scrolled_window), 10);
+      gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
+                                     GTK_POLICY_AUTOMATIC,
+                                     GTK_POLICY_AUTOMATIC);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
+                         scrolled_window, TRUE, TRUE, 0);
+      gtk_widget_show (scrolled_window);
+
+      table = gtk_table_new (20, 20, FALSE);
+      gtk_table_set_row_spacings (GTK_TABLE (table), 10);
+      gtk_table_set_col_spacings (GTK_TABLE (table), 10);
+      gtk_container_add (GTK_CONTAINER (scrolled_window), table);
+      gtk_widget_show (table);
+
+      for (i = 0; i < 20; i++)
+       for (j = 0; j < 20; j++)
+         {
+           sprintf (buffer, "button (%d,%d)\n", i, j);
+           button = gtk_toggle_button_new_with_label (buffer);
+           gtk_table_attach_defaults (GTK_TABLE (table), button,
+                                      i, i+1, j, j+1);
+           gtk_widget_show (button);
+         }
+
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
+                         button, TRUE, TRUE, 0);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+void
+create_entry ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *box1;
+  GtkWidget *box2;
+  GtkWidget *entry;
+  GtkWidget *button;
+  GtkWidget *separator;
+
+  /*  if (!window) */
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "entry");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+
+      box1 = gtk_vbox_new (FALSE, 0);
+      gtk_container_add (GTK_CONTAINER (window), box1);
+      gtk_widget_show (box1);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      entry = gtk_entry_new ();
+      /* gtk_widget_set_usize (entry, 0, 25); */
+      gtk_entry_set_text (GTK_ENTRY (entry), "hello world");
+      gtk_box_pack_start (GTK_BOX (box2), entry, TRUE, TRUE, 0);
+      gtk_widget_show (entry);
+
+
+      separator = gtk_hseparator_new ();
+      gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
+      gtk_widget_show (separator);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  /*  else
+    gtk_widget_destroy (window); */
+}
+
+void
+list_add (GtkWidget *widget,
+         GtkWidget *list)
+{
+  static int i = 1;
+  gchar buffer[64];
+  GtkWidget *list_item;
+
+  sprintf (buffer, "added item %d", i++);
+  list_item = gtk_list_item_new_with_label (buffer);
+  gtk_widget_show (list_item);
+  gtk_container_add (GTK_CONTAINER (list), list_item);
+}
+
+void
+list_remove (GtkWidget *widget,
+            GtkWidget *list)
+{
+  GList *tmp_list;
+  GList *clear_list;
+
+  tmp_list = GTK_LIST (list)->selection;
+  clear_list = NULL;
+
+  while (tmp_list)
+    {
+      clear_list = g_list_prepend (clear_list, tmp_list->data);
+      tmp_list = tmp_list->next;
+    }
+
+  clear_list = g_list_reverse (clear_list);
+
+  gtk_list_remove_items (GTK_LIST (list), clear_list);
+
+  tmp_list = clear_list;
+
+  while (tmp_list)
+    {
+      gtk_widget_destroy (GTK_WIDGET (tmp_list->data));
+      tmp_list = tmp_list->next;
+    }
+
+  g_list_free (clear_list);
+}
+
+void
+create_list ()
+{
+  static GtkWidget *window = NULL;
+  static char *list_items[] =
+  {
+    "hello",
+    "world",
+    "blah",
+    "foo",
+    "bar",
+    "argh",
+    "spencer",
+    "is a",
+    "wussy",
+    "programmer",
+  };
+  static int nlist_items = sizeof (list_items) / sizeof (list_items[0]);
+
+  GtkWidget *box1;
+  GtkWidget *box2;
+  GtkWidget *scrolled_win;
+  GtkWidget *list;
+  GtkWidget *list_item;
+  GtkWidget *button;
+  GtkWidget *separator;
+  int i;
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "list");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+
+      box1 = gtk_vbox_new (FALSE, 0);
+      gtk_container_add (GTK_CONTAINER (window), box1);
+      gtk_widget_show (box1);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      scrolled_win = gtk_scrolled_window_new (NULL, NULL);
+      gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
+                                     GTK_POLICY_AUTOMATIC, 
+                                     GTK_POLICY_AUTOMATIC);
+      gtk_box_pack_start (GTK_BOX (box2), scrolled_win, TRUE, TRUE, 0);
+      gtk_widget_show (scrolled_win);
+
+      list = gtk_list_new ();
+      gtk_list_set_selection_mode (GTK_LIST (list), GTK_SELECTION_MULTIPLE);
+      gtk_list_set_selection_mode (GTK_LIST (list), GTK_SELECTION_BROWSE);
+      gtk_container_add (GTK_CONTAINER (scrolled_win), list);
+      gtk_widget_show (list);
+
+      for (i = 0; i < nlist_items; i++)
+       {
+         list_item = gtk_list_item_new_with_label (list_items[i]);
+         gtk_container_add (GTK_CONTAINER (list), list_item);
+         gtk_widget_show (list_item);
+       }
+
+      button = gtk_button_new_with_label ("add");
+      GTK_WIDGET_UNSET_FLAGS (button, GTK_CAN_FOCUS);
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         (GtkSignalFunc) list_add,
+                         list);
+      gtk_box_pack_start (GTK_BOX (box2), button, FALSE, TRUE, 0);
+      gtk_widget_show (button);
+
+      button = gtk_button_new_with_label ("remove");
+      GTK_WIDGET_UNSET_FLAGS (button, GTK_CAN_FOCUS);
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         (GtkSignalFunc) list_remove,
+                         list);
+      gtk_box_pack_start (GTK_BOX (box2), button, FALSE, TRUE, 0);
+      gtk_widget_show (button);
+
+
+      separator = gtk_hseparator_new ();
+      gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
+      gtk_widget_show (separator);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+void
+color_selection_ok (GtkWidget               *w,
+                    GtkColorSelectionDialog *cs)
+{
+  GtkColorSelection *colorsel;
+  gdouble color[4];
+
+  colorsel=GTK_COLOR_SELECTION(cs->colorsel);
+
+  gtk_color_selection_get_color(colorsel,color);
+  gtk_color_selection_set_color(colorsel,color);
+}
+
+void
+color_selection_changed (GtkWidget *w,
+                         GtkColorSelectionDialog *cs)
+{
+  GtkColorSelection *colorsel;
+  gdouble color[4];
+
+  colorsel=GTK_COLOR_SELECTION(cs->colorsel);
+  gtk_color_selection_get_color(colorsel,color);
+}
+
+void
+create_color_selection ()
+{
+  static GtkWidget *window = NULL;
+
+  if (!window)
+    {
+      gtk_preview_set_install_cmap (TRUE);
+      gtk_widget_push_visual (gtk_preview_get_visual ());
+      gtk_widget_push_colormap (gtk_preview_get_cmap ());
+
+      window = gtk_color_selection_dialog_new ("color selection dialog");
+
+      gtk_color_selection_set_opacity (
+        GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (window)->colorsel),
+       TRUE);
+
+      gtk_color_selection_set_update_policy(
+        GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (window)->colorsel),
+       GTK_UPDATE_CONTINUOUS);
+
+      gtk_window_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                          (GtkSignalFunc) destroy_window,
+                          &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                          (GtkSignalFunc) destroy_window,
+                          &window);
+
+      gtk_signal_connect (
+       GTK_OBJECT (GTK_COLOR_SELECTION_DIALOG (window)->colorsel),
+       "color_changed",
+       (GtkSignalFunc) color_selection_changed,
+       window);
+
+      gtk_signal_connect (
+       GTK_OBJECT (GTK_COLOR_SELECTION_DIALOG (window)->ok_button),
+       "clicked",
+       (GtkSignalFunc) color_selection_ok,
+       window);
+
+      gtk_signal_connect_object (
+        GTK_OBJECT (GTK_COLOR_SELECTION_DIALOG (window)->cancel_button),
+       "clicked",
+       (GtkSignalFunc) gtk_widget_destroy,
+       GTK_OBJECT (window));
+
+      gtk_widget_pop_colormap ();
+      gtk_widget_pop_visual ();
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+
+void
+file_selection_ok (GtkWidget        *w,
+                  GtkFileSelection *fs)
+{
+  g_print ("%s\n", gtk_file_selection_get_filename (GTK_FILE_SELECTION (fs)));
+}
+
+void
+create_file_selection ()
+{
+  static GtkWidget *window = NULL;
+
+  if (!window)
+    {
+      window = gtk_file_selection_new ("file selection dialog");
+      gtk_window_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (window)->ok_button),
+                         "clicked", (GtkSignalFunc) file_selection_ok,
+                         window);
+      gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION (window)->cancel_button),
+                                "clicked", (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+
+/*
+ * GtkDialog
+ */
+static GtkWidget *dialog_window = NULL;
+
+void
+label_toggle (GtkWidget  *widget,
+             GtkWidget **label)
+{
+  if (!(*label))
+    {
+      *label = gtk_label_new ("Dialog Test");
+      gtk_misc_set_padding (GTK_MISC (*label), 10, 10);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->vbox), 
+                         *label, TRUE, TRUE, 0);
+      gtk_widget_show (*label);
+    }
+  else
+    {
+      gtk_widget_destroy (*label);
+      *label = NULL;
+    }
+}
+
+void
+create_dialog ()
+{
+  static GtkWidget *label;
+  GtkWidget *button;
+
+  if (!dialog_window)
+    {
+      dialog_window = gtk_dialog_new ();
+
+      gtk_signal_connect (GTK_OBJECT (dialog_window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &dialog_window);
+      gtk_signal_connect (GTK_OBJECT (dialog_window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &dialog_window);
+
+      gtk_window_set_title (GTK_WINDOW (dialog_window), "dialog");
+      gtk_container_border_width (GTK_CONTAINER (dialog_window), 0);
+
+      button = gtk_button_new_with_label ("OK");
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->action_area), 
+                         button, TRUE, TRUE, 0);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+
+      button = gtk_button_new_with_label ("Toggle");
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         (GtkSignalFunc) label_toggle,
+                         &label);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->action_area),
+                         button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+      label = NULL;
+    }
+
+  if (!GTK_WIDGET_VISIBLE (dialog_window))
+    gtk_widget_show (dialog_window);
+  else
+    gtk_widget_destroy (dialog_window);
+}
+
+
+/*
+ * GtkRange
+ */
+void
+create_range_controls ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *box1;
+  GtkWidget *box2;
+  GtkWidget *button;
+  GtkWidget *scrollbar;
+  GtkWidget *scale;
+  GtkWidget *separator;
+  GtkObject *adjustment;
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "range controls");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+
+      box1 = gtk_vbox_new (FALSE, 0);
+      gtk_container_add (GTK_CONTAINER (window), box1);
+      gtk_widget_show (box1);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      adjustment = gtk_adjustment_new (0.0, 0.0, 101.0, 0.1, 1.0, 1.0);
+
+      scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment));
+      gtk_widget_set_usize (GTK_WIDGET (scale), 150, 30);
+      gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
+      gtk_scale_set_digits (GTK_SCALE (scale), 1);
+      gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
+      gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0);
+      gtk_widget_show (scale);
+
+      scrollbar = gtk_hscrollbar_new (GTK_ADJUSTMENT (adjustment));
+      gtk_range_set_update_policy (GTK_RANGE (scrollbar), 
+                                  GTK_UPDATE_CONTINUOUS);
+      gtk_box_pack_start (GTK_BOX (box2), scrollbar, TRUE, TRUE, 0);
+      gtk_widget_show (scrollbar);
+
+
+      separator = gtk_hseparator_new ();
+      gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
+      gtk_widget_show (separator);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+
+/*
+ * GtkRulers
+ */
+void
+create_rulers ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *table;
+  GtkWidget *ruler;
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "rulers");
+      gtk_widget_set_usize (window, 300, 300);
+      gtk_widget_set_events (window, 
+                            GDK_POINTER_MOTION_MASK 
+                            | GDK_POINTER_MOTION_HINT_MASK);
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+      table = gtk_table_new (2, 2, FALSE);
+      gtk_container_add (GTK_CONTAINER (window), table);
+      gtk_widget_show (table);
+
+      ruler = gtk_hruler_new ();
+      gtk_ruler_set_range (GTK_RULER (ruler), 5, 15, 0, 20);
+
+      gtk_signal_connect_object (
+        GTK_OBJECT (window), 
+       "motion_notify_event",
+       (GtkSignalFunc) 
+          GTK_WIDGET_CLASS (GTK_OBJECT (ruler)->klass)->motion_notify_event,
+       GTK_OBJECT (ruler));
+
+      gtk_table_attach (GTK_TABLE (table), ruler, 1, 2, 0, 1,
+                       GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
+      gtk_widget_show (ruler);
+
+
+      ruler = gtk_vruler_new ();
+      gtk_ruler_set_range (GTK_RULER (ruler), 5, 15, 0, 20);
+
+      gtk_signal_connect_object (
+        GTK_OBJECT (window), 
+       "motion_notify_event",
+       (GtkSignalFunc) 
+          GTK_WIDGET_CLASS (GTK_OBJECT (ruler)->klass)->motion_notify_event,
+       GTK_OBJECT (ruler));
+
+      gtk_table_attach (GTK_TABLE (table), ruler, 0, 1, 1, 2,
+                       GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+      gtk_widget_show (ruler);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+
+/*
+ * GtkText
+ */
+void
+create_text ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *box1;
+  GtkWidget *box2;
+  GtkWidget *button;
+  GtkWidget *separator;
+  GtkWidget *table;
+  GtkWidget *hscrollbar;
+  GtkWidget *vscrollbar;
+  GtkWidget *text;
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+      gtk_widget_set_name (window, "text window");
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "test");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+
+      box1 = gtk_vbox_new (FALSE, 0);
+      gtk_container_add (GTK_CONTAINER (window), box1);
+      gtk_widget_show (box1);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      table = gtk_table_new (2, 2, FALSE);
+      gtk_table_set_row_spacing (GTK_TABLE (table), 0, 2);
+      gtk_table_set_col_spacing (GTK_TABLE (table), 0, 2);
+      gtk_box_pack_start (GTK_BOX (box2), table, TRUE, TRUE, 0);
+      gtk_widget_show (table);
+
+      text = gtk_text_new (NULL, NULL);
+      gtk_table_attach_defaults (GTK_TABLE (table), text, 0, 1, 0, 1);
+      gtk_widget_show (text);
+
+      hscrollbar = gtk_hscrollbar_new (GTK_TEXT (text)->hadj);
+      gtk_table_attach (GTK_TABLE (table), hscrollbar, 0, 1, 1, 2,
+                       GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
+      gtk_widget_show (hscrollbar);
+
+      vscrollbar = gtk_vscrollbar_new (GTK_TEXT (text)->vadj);
+      gtk_table_attach (GTK_TABLE (table), vscrollbar, 1, 2, 0, 1,
+                       GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+      gtk_widget_show (vscrollbar);
+
+      gtk_text_freeze (GTK_TEXT (text));
+
+      gtk_widget_realize (text);
+
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "spencer blah blah blah\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "kimball\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "is\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "a\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "wuss.\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "but\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL,
+                      "josephine\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "(his\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "girlfriend\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "is\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "not).\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "why?\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "because\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "spencer\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "puked\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "last\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "night\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "but\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "josephine\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "did\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "not", -1);
+
+      gtk_text_thaw (GTK_TEXT (text));
+
+      separator = gtk_hseparator_new ();
+      gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
+      gtk_widget_show (separator);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+
+/*
+ * GtkNotebook
+ */
+void
+rotate_notebook (GtkButton   *button,
+                GtkNotebook *notebook)
+{
+  gtk_notebook_set_tab_pos (notebook, (notebook->tab_pos + 1) % 4);
+}
+
+void
+create_notebook ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *box1;
+  GtkWidget *box2;
+  GtkWidget *button;
+  GtkWidget *separator;
+  GtkWidget *notebook;
+  GtkWidget *frame;
+  GtkWidget *label;
+  char buffer[32];
+  int i;
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "notebook");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+
+      box1 = gtk_vbox_new (FALSE, 0);
+      gtk_container_add (GTK_CONTAINER (window), box1);
+      gtk_widget_show (box1);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      notebook = gtk_notebook_new ();
+      gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP);
+      gtk_box_pack_start (GTK_BOX (box2), notebook, TRUE, TRUE, 0);
+      gtk_widget_show (notebook);
+
+
+      for (i = 0; i < 5; i++)
+       {
+         sprintf (buffer, "Page %d", i+1);
+
+         frame = gtk_frame_new (buffer);
+         gtk_container_border_width (GTK_CONTAINER (frame), 10);
+         gtk_widget_set_usize (frame, 200, 150);
+         gtk_widget_show (frame);
+
+         label = gtk_label_new (buffer);
+         gtk_container_add (GTK_CONTAINER (frame), label);
+         gtk_widget_show (label);
+
+         label = gtk_label_new (buffer);
+         gtk_notebook_append_page (GTK_NOTEBOOK (notebook), frame, label);
+       }
+
+
+      separator = gtk_hseparator_new ();
+      gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
+      gtk_widget_show (separator);
+
+
+      box2 = gtk_hbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+
+      button = gtk_button_new_with_label ("next");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_notebook_next_page,
+                                GTK_OBJECT (notebook));
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+      button = gtk_button_new_with_label ("prev");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_notebook_prev_page,
+                                GTK_OBJECT (notebook));
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+      button = gtk_button_new_with_label ("rotate");
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         (GtkSignalFunc) rotate_notebook,
+                         notebook);
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+
+/*
+ * GtkPanes
+ */
+void
+create_panes ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *frame;
+  GtkWidget *hpaned;
+  GtkWidget *vpaned;
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "Panes");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+      vpaned = gtk_vpaned_new ();
+      gtk_container_add (GTK_CONTAINER (window), vpaned);
+      gtk_container_border_width (GTK_CONTAINER(vpaned), 5);
+      gtk_widget_show (vpaned);
+
+      hpaned = gtk_hpaned_new ();
+      gtk_paned_add1 (GTK_PANED (vpaned), hpaned);
+
+      frame = gtk_frame_new (NULL);
+      gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
+      gtk_widget_set_usize (frame, 60, 60);
+      gtk_paned_add1 (GTK_PANED (hpaned), frame);
+      gtk_widget_show (frame);
+
+      frame = gtk_frame_new (NULL);
+      gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
+      gtk_widget_set_usize (frame, 80, 60);
+      gtk_paned_add2 (GTK_PANED (hpaned), frame);
+      gtk_widget_show (frame);
+
+      gtk_widget_show (hpaned);
+
+      frame = gtk_frame_new (NULL);
+      gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
+      gtk_widget_set_usize (frame, 60, 80);
+      gtk_paned_add2 (GTK_PANED (vpaned), frame);
+      gtk_widget_show (frame);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+
+/*
+ * Drag -N- Drop
+ */
+void
+dnd_drop (GtkWidget *button, GdkEvent *event)
+{
+  g_print ("Got drop of type |%s| with data of:\n%s\n",
+          event->dropdataavailable.data_type,
+          event->dropdataavailable.data);
+  g_free (event->dropdataavailable.data);
+  g_free (event->dropdataavailable.data_type);
+}
+
+void
+dnd_drag_request (GtkWidget *button, GdkEvent *event)
+{
+  g_print ("Button |%s| got drag request %d\n",
+          gtk_widget_get_name (button), event->type);
+
+  gtk_widget_dnd_data_set (button, event, "Hello world!!!", 
+                          strlen("Hello world!!!") + 1);
+}
+
+void
+create_dnd ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *box1;
+  GtkWidget *box2;
+  GtkWidget *box3;
+  GtkWidget *entry;
+  GtkWidget *frame;
+  GtkWidget *button;
+  GtkWidget *separator;
+  char *foo = "testing";
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "Drag -N- Drop");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+      box1 = gtk_vbox_new (FALSE, 0);
+      gtk_container_add (GTK_CONTAINER (window), box1);
+      gtk_widget_show (box1);
+
+      box2 = gtk_hbox_new (FALSE, 5);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
+      gtk_widget_show (box2);
+
+      frame = gtk_frame_new ("Drag");
+      gtk_box_pack_start (GTK_BOX (box2), frame, TRUE, TRUE, 0);
+      gtk_widget_show (frame);
+
+      box3 = gtk_vbox_new (FALSE, 5);
+      gtk_container_border_width (GTK_CONTAINER (box3), 5);
+      gtk_container_add (GTK_CONTAINER (frame), box3);
+      gtk_widget_show (box3);
+
+      /*
+       * FROM Button
+       */
+      button = gtk_button_new_with_label ("From");
+      gtk_box_pack_start (GTK_BOX (box3), button, FALSE, TRUE, 0);
+      gtk_widget_show (button);
+
+      /*
+       * currently, the widget has to be realized to
+       * set dnd on it, this needs to change
+       */
+      gtk_widget_realize (button);
+      gtk_signal_connect (GTK_OBJECT (button), 
+                         "drag_request_event",
+                         (GtkSignalFunc) dnd_drag_request,
+                         button);
+      
+      gtk_widget_dnd_drag_set (button, TRUE, &foo, 1);
+
+
+      frame = gtk_frame_new ("Drop");
+      gtk_box_pack_start (GTK_BOX (box2), frame, TRUE, TRUE, 0);
+      gtk_widget_show (frame);
+
+      box3 = gtk_vbox_new (FALSE, 5);
+      gtk_container_border_width (GTK_CONTAINER (box3), 5);
+      gtk_container_add (GTK_CONTAINER (frame), box3);
+      gtk_widget_show (box3);
+
+
+      /*
+       * TO Button
+       */
+      button = gtk_button_new_with_label ("To");
+      gtk_box_pack_start (GTK_BOX (box3), button, FALSE, TRUE, 0);
+      gtk_widget_show (button);
+
+      gtk_widget_realize (button);
+      gtk_signal_connect (GTK_OBJECT (button), 
+                         "drop_data_available_event",
+                         (GtkSignalFunc) dnd_drop,
+                         button);
+
+      gtk_widget_dnd_drop_set (button, TRUE, &foo, 1, FALSE);
+
+
+      separator = gtk_hseparator_new ();
+      gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
+      gtk_widget_show (separator);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_button_new_with_label ("close");
+
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+/*
+ * Shaped Windows
+ */
+static GdkWindow *root_win = NULL;
+static GtkWidget *modeller = NULL;
+static GtkWidget *sheets = NULL;
+static GtkWidget *rings = NULL;
+
+typedef struct _cursoroffset {gint x,y;} CursorOffset;
+
+static void
+shape_pressed (GtkWidget *widget)
+{
+  CursorOffset *p;
+
+  p = gtk_object_get_user_data (GTK_OBJECT(widget));
+  gtk_widget_get_pointer (widget, &(p->x), &(p->y));
+
+  gtk_grab_add (widget);
+  gdk_pointer_grab (widget->window, TRUE,
+                   GDK_BUTTON_RELEASE_MASK |
+                   GDK_BUTTON_MOTION_MASK,
+                   NULL, NULL, 0);
+}
+
+
+static void
+shape_released (GtkWidget *widget)
+{
+  gtk_grab_remove (widget);
+  gdk_pointer_ungrab (0);
+}
+
+static void
+shape_motion (GtkWidget      *widget, 
+             GdkEventMotion *event)
+{
+  gint xp, yp;
+  CursorOffset * p;
+  GdkModifierType mask;
+
+  p = gtk_object_get_user_data (GTK_OBJECT (widget));
+
+  gdk_window_get_pointer (root_win, &xp, &yp, &mask);
+  gtk_widget_set_uposition (widget, xp  - p->x, yp  - p->y);
+}
+
+GtkWidget *
+shape_create_icon (char     *xpm_file,
+                  gint      x,
+                  gint      y,
+                  gint      px,
+                  gint      py,
+                  gint      window_type)
+{
+  GtkWidget *window;
+  GtkWidget *pixmap;
+  GtkWidget *fixed;
+  CursorOffset* icon_pos;
+  GdkGC* gc;
+  GdkBitmap *gdk_pixmap_mask;
+  GdkPixmap *gdk_pixmap;
+  GtkStyle *style;
+
+  style = gtk_widget_get_default_style ();
+  gc = style->black_gc;        
+
+  /*
+   * GDK_WINDOW_TOPLEVEL works also, giving you a title border
+   */
+  window = gtk_window_new (window_type);
+  
+  fixed = gtk_fixed_new ();
+  gtk_widget_set_usize (fixed, 100,100);
+  gtk_container_add (GTK_CONTAINER (window), fixed);
+  gtk_widget_show (fixed);
+  
+  gdk_pixmap = gdk_pixmap_create_from_xpm (window->window, &gdk_pixmap_mask, 
+                                          &style->bg[GTK_STATE_NORMAL],
+                                          xpm_file);
+
+  pixmap = gtk_pixmap_new (gdk_pixmap, gdk_pixmap_mask);
+  gtk_fixed_put (GTK_FIXED (fixed), pixmap, px,py);
+  gtk_widget_show (pixmap);
+  
+  gtk_widget_shape_combine_mask (window, gdk_pixmap_mask, px,py);
+
+  gtk_widget_set_events (window, 
+                        gtk_widget_get_events (window) |
+                        GDK_BUTTON_MOTION_MASK |
+                        GDK_BUTTON_PRESS_MASK);
+
+  gtk_signal_connect (GTK_OBJECT (window), "button_press_event",
+                     GTK_SIGNAL_FUNC (shape_pressed),NULL);
+  gtk_signal_connect (GTK_OBJECT (window), "button_release_event",
+                     GTK_SIGNAL_FUNC (shape_released),NULL);
+  gtk_signal_connect (GTK_OBJECT (window), "motion_notify_event",
+                     GTK_SIGNAL_FUNC (shape_motion),NULL);
+
+  icon_pos = g_new (CursorOffset, 1);
+  gtk_object_set_user_data(GTK_OBJECT(window), icon_pos);
+
+  gtk_widget_set_uposition (window, x, y);
+  gtk_widget_show (window);
+
+  return window;
+}
+
+void 
+create_shapes ()
+{
+  root_win = gdk_window_foreign_new (GDK_ROOT_WINDOW ());
+
+  if (!modeller)
+    {
+      modeller = shape_create_icon ("Modeller.xpm",
+                                   440, 140, 0,0, GTK_WINDOW_POPUP);
+
+      gtk_signal_connect (GTK_OBJECT (modeller), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &modeller);
+      gtk_signal_connect (GTK_OBJECT (modeller), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &modeller);
+    }
+  else
+    gtk_widget_destroy (modeller);
+
+  if (!sheets)
+    {
+      sheets = shape_create_icon ("FilesQueue.xpm",
+                                 580, 170, 0,0, GTK_WINDOW_POPUP);
+
+      gtk_signal_connect (GTK_OBJECT (sheets), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &sheets);
+      gtk_signal_connect (GTK_OBJECT (sheets), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &sheets);
+
+    }
+  else
+    gtk_widget_destroy (sheets);
+
+  if (!rings)
+    {
+      rings = shape_create_icon ("3DRings.xpm",
+                                460, 270, 25,25, GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (rings), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &rings);
+      gtk_signal_connect (GTK_OBJECT (rings), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &rings);
+    }
+  else
+    gtk_widget_destroy (rings);
+}
+
+
+/*
+ * Progress Bar
+ */
+static int progress_timer = 0;
+
+gint
+progress_timeout (gpointer data)
+{
+  gfloat new_val;
+
+  new_val = GTK_PROGRESS_BAR (data)->percentage;
+  if (new_val >= 1.0)
+    new_val = 0.0;
+  new_val += 0.02;
+
+  gtk_progress_bar_update (GTK_PROGRESS_BAR (data), new_val);
+
+  return TRUE;
+}
+
+void
+destroy_progress (GtkWidget  *widget,
+                 GtkWidget **window)
+{
+  destroy_window (widget, window);
+  gtk_timeout_remove (progress_timer);
+  progress_timer = 0;
+}
+
+void
+create_progress_bar ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *button;
+  GtkWidget *vbox;
+  GtkWidget *pbar;
+  GtkWidget *label;
+
+  if (!window)
+    {
+      window = gtk_dialog_new ();
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_progress,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_progress,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "dialog");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+
+      vbox = gtk_vbox_new (FALSE, 5);
+      gtk_container_border_width (GTK_CONTAINER (vbox), 10);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
+                         vbox, TRUE, TRUE, 0);
+      gtk_widget_show (vbox);
+
+      label = gtk_label_new ("progress...");
+      gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+      gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0);
+      gtk_widget_show (label);
+
+      pbar = gtk_progress_bar_new ();
+      gtk_widget_set_usize (pbar, 200, 20);
+      gtk_box_pack_start (GTK_BOX (vbox), pbar, TRUE, TRUE, 0);
+      gtk_widget_show (pbar);
+
+      progress_timer = gtk_timeout_add (100, progress_timeout, pbar);
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
+                         button, TRUE, TRUE, 0);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+
+/*
+ * Color Preview
+ */
+static int color_idle = 0;
+
+gint
+color_idle_func (GtkWidget *preview)
+{
+  static int count = 1;
+  guchar buf[768];
+  int i, j, k;
+
+  for (i = 0; i < 256; i++)
+    {
+      for (j = 0, k = 0; j < 256; j++)
+       {
+         buf[k+0] = i + count;
+         buf[k+1] = 0;
+         buf[k+2] = j + count;
+         k += 3;
+       }
+
+      gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
+    }
+
+  count += 1;
+
+  gtk_widget_draw (preview, NULL);
+
+  return TRUE;
+}
+
+void
+color_preview_destroy (GtkWidget  *widget,
+                      GtkWidget **window)
+{
+  gtk_idle_remove (color_idle);
+  color_idle = 0;
+
+  destroy_window (widget, window);
+}
+
+void
+create_color_preview ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *preview;
+  guchar buf[768];
+  int i, j, k;
+
+  if (!window)
+    {
+      gtk_widget_push_visual (gtk_preview_get_visual ());
+      gtk_widget_push_colormap (gtk_preview_get_cmap ());
+
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) color_preview_destroy,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) color_preview_destroy,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "test");
+      gtk_container_border_width (GTK_CONTAINER (window), 10);
+
+      preview = gtk_preview_new (GTK_PREVIEW_COLOR);
+      gtk_preview_size (GTK_PREVIEW (preview), 256, 256);
+      gtk_container_add (GTK_CONTAINER (window), preview);
+      gtk_widget_show (preview);
+
+      for (i = 0; i < 256; i++)
+       {
+         for (j = 0, k = 0; j < 256; j++)
+           {
+             buf[k+0] = i;
+             buf[k+1] = 0;
+             buf[k+2] = j;
+             k += 3;
+           }
+
+         gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
+       }
+
+      color_idle = gtk_idle_add ((GtkFunction) color_idle_func, preview);
+
+      gtk_widget_pop_colormap ();
+      gtk_widget_pop_visual ();
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+
+/*
+ * Gray Preview
+ */
+static int gray_idle = 0;
+
+gint
+gray_idle_func (GtkWidget *preview)
+{
+  static int count = 1;
+  guchar buf[256];
+  int i, j;
+
+  for (i = 0; i < 256; i++)
+    {
+      for (j = 0; j < 256; j++)
+       buf[j] = i + j + count;
+
+      gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
+    }
+
+  count += 1;
+
+  gtk_widget_draw (preview, NULL);
+
+  return TRUE;
+}
+
+void
+gray_preview_destroy (GtkWidget  *widget,
+                     GtkWidget **window)
+{
+  gtk_idle_remove (gray_idle);
+  gray_idle = 0;
+
+  destroy_window (widget, window);
+}
+
+void
+create_gray_preview ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *preview;
+  guchar buf[256];
+  int i, j;
+
+  if (!window)
+    {
+      gtk_widget_push_visual (gtk_preview_get_visual ());
+      gtk_widget_push_colormap (gtk_preview_get_cmap ());
+
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) gray_preview_destroy,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) gray_preview_destroy,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "test");
+      gtk_container_border_width (GTK_CONTAINER (window), 10);
+
+      preview = gtk_preview_new (GTK_PREVIEW_GRAYSCALE);
+      gtk_preview_size (GTK_PREVIEW (preview), 256, 256);
+      gtk_container_add (GTK_CONTAINER (window), preview);
+      gtk_widget_show (preview);
+
+      for (i = 0; i < 256; i++)
+       {
+         for (j = 0; j < 256; j++)
+           buf[j] = i + j;
+
+         gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
+       }
+
+      gray_idle = gtk_idle_add ((GtkFunction) gray_idle_func, preview);
+
+      gtk_widget_pop_colormap ();
+      gtk_widget_pop_visual ();
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+
+/*
+ * Selection Test
+ */
+void
+selection_test_received (GtkWidget *list, GtkSelectionData *data)
+{
+  GdkAtom *atoms;
+  GtkWidget *list_item;
+  GList *item_list;
+  int i, l;
+
+  if (data->length < 0)
+    {
+      g_print ("Selection retrieval failed\n");
+      return;
+    }
+  if (data->type != GDK_SELECTION_TYPE_ATOM)
+    {
+      g_print ("Selection \"TARGETS\" was not returned as atoms!\n");
+      return;
+    }
+
+  /* Clear out any current list items */
+
+  gtk_list_clear_items (GTK_LIST(list), 0, -1);
+
+  /* Add new items to list */
+
+  atoms = (GdkAtom *)data->data;
+
+  item_list = NULL;
+  l = data->length / sizeof (GdkAtom);
+  for (i = 0; i < l; i++)
+    {
+      char *name;
+      name = gdk_atom_name (atoms[i]);
+      if (name != NULL)
+       {
+         list_item = gtk_list_item_new_with_label (name);
+         g_free (name);
+       }
+      else
+       list_item = gtk_list_item_new_with_label ("(bad atom)");
+
+      gtk_widget_show (list_item);
+      item_list = g_list_append (item_list, list_item);
+    }
+
+  gtk_list_append_items (GTK_LIST (list), item_list);
+
+  return;
+}
+
+void
+selection_test_get_targets (GtkWidget *widget, GtkWidget *list)
+{
+  static GdkAtom targets_atom = GDK_NONE;
+
+  if (targets_atom == GDK_NONE)
+    targets_atom = gdk_atom_intern ("TARGETS", FALSE);
+
+  gtk_selection_convert (list, GDK_SELECTION_PRIMARY, targets_atom,
+                        GDK_CURRENT_TIME);
+}
+
+void
+create_selection_test ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *button;
+  GtkWidget *vbox;
+  GtkWidget *scrolled_win;
+  GtkWidget *list;
+  GtkWidget *label;
+
+  if (!window)
+    {
+      window = gtk_dialog_new ();
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "Selection Test");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+      /* Create the list */
+
+      vbox = gtk_vbox_new (FALSE, 5);
+      gtk_container_border_width (GTK_CONTAINER (vbox), 10);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), vbox,
+                         TRUE, TRUE, 0);
+      gtk_widget_show (vbox);
+
+      label = gtk_label_new ("Gets available targets for current selection");
+      gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+      gtk_widget_show (label);
+
+      scrolled_win = gtk_scrolled_window_new (NULL, NULL);
+      gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
+                                     GTK_POLICY_AUTOMATIC, 
+                                     GTK_POLICY_AUTOMATIC);
+      gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
+      gtk_widget_set_usize (scrolled_win, 100, 200);
+      gtk_widget_show (scrolled_win);
+
+      list = gtk_list_new ();
+      gtk_container_add (GTK_CONTAINER (scrolled_win), list);
+
+      gtk_signal_connect (GTK_OBJECT(list), "selection_received",
+                         GTK_SIGNAL_FUNC (selection_test_received), NULL);
+      gtk_widget_show (list);
+
+      /* .. And create some buttons */
+      button = gtk_button_new_with_label ("Get Targets");
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
+                         button, TRUE, TRUE, 0);
+
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         GTK_SIGNAL_FUNC (selection_test_get_targets), list);
+      gtk_widget_show (button);
+
+      button = gtk_button_new_with_label ("Quit");
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
+                         button, TRUE, TRUE, 0);
+
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                GTK_SIGNAL_FUNC (gtk_widget_destroy),
+                                GTK_OBJECT (window));
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+
+/*
+ * Gamma Curve
+ */
+void
+create_gamma_curve ()
+{
+  static GtkWidget *window = NULL, *curve;
+  static int count = 0;
+  gfloat vec[256];
+  gint max;
+  gint i;
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+      gtk_window_set_title (GTK_WINDOW (window), "test");
+      gtk_container_border_width (GTK_CONTAINER (window), 10);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      curve = gtk_gamma_curve_new ();
+      gtk_container_add (GTK_CONTAINER (window), curve);
+      gtk_widget_show (curve);
+    }
+
+  max = 127 + (count % 2)*128;
+  gtk_curve_set_range (GTK_CURVE (GTK_GAMMA_CURVE (curve)->curve),
+                      0, max, 0, max);
+  for (i = 0; i < max; ++i)
+    vec[i] = (127 / sqrt (max)) * sqrt (i);
+  gtk_curve_set_vector (GTK_CURVE (GTK_GAMMA_CURVE (curve)->curve),
+                       max, vec);
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else if (count % 4 == 3)
+    {
+      gtk_widget_destroy (window);
+      window = NULL;
+    }
+
+  ++count;
+}
+
+
+/*
+ * Timeout Test
+ */
+static int timer = 0;
+
+void
+timeout_test (GtkWidget *label)
+{
+  static int count = 0;
+  static char buffer[32];
+
+  sprintf (buffer, "count: %d", ++count);
+  gtk_label_set (GTK_LABEL (label), buffer);
+}
+
+void
+start_timeout_test (GtkWidget *widget,
+                   GtkWidget *label)
+{
+  if (!timer)
+    {
+      timer = gtk_timeout_add (100, (GtkFunction) timeout_test, label);
+    }
+}
+
+void
+stop_timeout_test (GtkWidget *widget,
+                  gpointer   data)
+{
+  if (timer)
+    {
+      gtk_timeout_remove (timer);
+      timer = 0;
+    }
+}
+
+void
+destroy_timeout_test (GtkWidget  *widget,
+                     GtkWidget **window)
+{
+  destroy_window (widget, window);
+  stop_timeout_test (NULL, NULL);
+}
+
+void
+create_timeout_test ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *button;
+  GtkWidget *label;
+
+  if (!window)
+    {
+      window = gtk_dialog_new ();
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_timeout_test,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_timeout_test,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "Timeout Test");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+      label = gtk_label_new ("count: 0");
+      gtk_misc_set_padding (GTK_MISC (label), 10, 10);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
+                         label, TRUE, TRUE, 0);
+      gtk_widget_show (label);
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
+                         button, TRUE, TRUE, 0);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+
+      button = gtk_button_new_with_label ("start");
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         (GtkSignalFunc) start_timeout_test,
+                         label);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
+                         button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+      button = gtk_button_new_with_label ("stop");
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         (GtkSignalFunc) stop_timeout_test,
+                         NULL);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
+                         button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+
+/*
+ * Idle Test
+ */
+static int idle = 0;
+
+gint
+idle_test (GtkWidget *label)
+{
+  static int count = 0;
+  static char buffer[32];
+
+  sprintf (buffer, "count: %d", ++count);
+  gtk_label_set (GTK_LABEL (label), buffer);
+
+  return TRUE;
+}
+
+void
+start_idle_test (GtkWidget *widget,
+                GtkWidget *label)
+{
+  if (!idle)
+    {
+      idle = gtk_idle_add ((GtkFunction) idle_test, label);
+    }
+}
+
+void
+stop_idle_test (GtkWidget *widget,
+               gpointer   data)
+{
+  if (idle)
+    {
+      gtk_idle_remove (idle);
+      idle = 0;
+    }
+}
+
+void
+destroy_idle_test (GtkWidget  *widget,
+                  GtkWidget **window)
+{
+  destroy_window (widget, window);
+  stop_idle_test (NULL, NULL);
+}
+
+void
+create_idle_test ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *button;
+  GtkWidget *label;
+
+  if (!window)
+    {
+      window = gtk_dialog_new ();
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_idle_test,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_idle_test,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "Idle Test");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+      label = gtk_label_new ("count: 0");
+      gtk_misc_set_padding (GTK_MISC (label), 10, 10);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
+                         label, TRUE, TRUE, 0);
+      gtk_widget_show (label);
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
+                         button, TRUE, TRUE, 0);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+
+      button = gtk_button_new_with_label ("start");
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         (GtkSignalFunc) start_idle_test,
+                         label);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
+                         button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+      button = gtk_button_new_with_label ("stop");
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         (GtkSignalFunc) stop_idle_test,
+                         NULL);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
+                         button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+void
+test_destroy (GtkWidget  *widget,
+             GtkWidget **window)
+{
+  destroy_window (widget, window);
+  gtk_main_quit ();
+}
+
+/*
+ * Basic Test
+ */
+void
+create_test ()
+{
+  static GtkWidget *window = NULL;
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) test_destroy,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) test_destroy,
+                         &window);
+
+
+      gtk_window_set_title (GTK_WINDOW (window), "test");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    {
+      gtk_widget_show (window);
+
+      g_print ("create_test: start\n");
+      gtk_main ();
+      g_print ("create_test: done\n");
+    }
+  else
+    gtk_widget_destroy (window);
+}
+
+
+/*
+ * Main Window and Exit
+ */
+void
+do_exit ()
+{
+  gtk_exit (0);
+}
+
+void
+create_main_window ()
+{
+  struct {
+    char *label;
+    void (*func) ();
+  } buttons[] =
+    {
+      { "buttons", create_buttons },
+      { "toggle buttons", create_toggle_buttons },
+      { "check buttons", create_check_buttons },
+      { "radio buttons", create_radio_buttons },
+      { "button box", create_button_box },
+      { "reparent", create_reparent },
+      { "pixmap", create_pixmap },
+      { "tooltips", create_tooltips },
+      { "menus", create_menus },
+      { "scrolled windows", create_scrolled_windows },
+      { "drawing areas", NULL },
+      { "entry", create_entry },
+      { "list", create_list },
+      { "color selection", create_color_selection },
+      { "file selection", create_file_selection },
+      { "dialog", create_dialog },
+      { "miscellaneous", NULL },
+      { "range controls", create_range_controls },
+      { "rulers", create_rulers },
+      { "text", create_text },
+      { "notebook", create_notebook },
+      { "panes", create_panes },
+      { "shapes", create_shapes },
+      { "dnd", create_dnd },
+      { "progress bar", create_progress_bar },
+      { "preview color", create_color_preview },
+      { "preview gray", create_gray_preview },
+      { "gamma curve", create_gamma_curve },
+      { "test selection", create_selection_test },
+      { "test timeout", create_timeout_test },
+      { "test idle", create_idle_test },
+      { "test", create_test },
+    };
+  int nbuttons = sizeof (buttons) / sizeof (buttons[0]);
+  GtkWidget *window;
+  GtkWidget *box1;
+  GtkWidget *box2;
+  GtkWidget *scrolled_window;
+  GtkWidget *button;
+  GtkWidget *separator;
+  int i;
+
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_widget_set_name (window, "main window");
+  gtk_widget_set_usize (window, 200, 400);
+  gtk_widget_set_uposition (window, 20, 20);
+
+  gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                     (GtkSignalFunc) gtk_exit,
+                     NULL);
+  gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                     (GtkSignalFunc) gtk_exit,
+                     NULL);
+
+  box1 = gtk_vbox_new (FALSE, 0);
+  gtk_container_add (GTK_CONTAINER (window), box1);
+  gtk_widget_show (box1);
+
+  scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+  gtk_container_border_width (GTK_CONTAINER (scrolled_window), 10);
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
+                                 GTK_POLICY_AUTOMATIC, 
+                                  GTK_POLICY_AUTOMATIC);
+  gtk_box_pack_start (GTK_BOX (box1), scrolled_window, TRUE, TRUE, 0);
+  gtk_widget_show (scrolled_window);
+
+  box2 = gtk_vbox_new (FALSE, 0);
+  gtk_container_border_width (GTK_CONTAINER (box2), 10);
+  gtk_container_add (GTK_CONTAINER (scrolled_window), box2);
+  gtk_widget_show (box2);
+
+  for (i = 0; i < nbuttons; i++)
+    {
+      button = gtk_button_new_with_label (buttons[i].label);
+      if (buttons[i].func)
+        gtk_signal_connect (GTK_OBJECT (button), 
+                           "clicked", 
+                           (GtkSignalFunc) 
+                           buttons[i].func, NULL);
+      else
+        gtk_widget_set_sensitive (button, FALSE);
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+    }
+
+  separator = gtk_hseparator_new ();
+  gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
+  gtk_widget_show (separator);
+
+  box2 = gtk_vbox_new (FALSE, 10);
+  gtk_container_border_width (GTK_CONTAINER (box2), 10);
+  gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
+  gtk_widget_show (box2);
+
+  button = gtk_button_new_with_label ("close");
+  gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                     (GtkSignalFunc) do_exit, NULL);
+  gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+  GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+  gtk_widget_grab_default (button);
+  gtk_widget_show (button);
+
+  gtk_widget_show (window);
+}
+
+int
+main (int argc, char *argv[])
+{
+  gtk_set_locale ();
+
+  gtk_init (&argc, &argv);
+  gtk_rc_parse ("testgtkrc");
+
+  create_main_window ();
+
+  gtk_main ();
+
+  return 0;
+}
diff --git a/gtk/testgtkrc b/gtk/testgtkrc
new file mode 100644 (file)
index 0000000..e909e31
--- /dev/null
@@ -0,0 +1,69 @@
+# pixmap_path "<dir 1>:<dir 2>:<dir 3>:..."
+#
+# style <name> [= <name>]
+# {
+#   <option>
+# }
+#
+# widget <widget_set> style <style_name>
+# widget_class <widget_class_set> style <style_name>
+
+pixmap_path "."
+
+style "window"
+{
+#  bg_pixmap[NORMAL] = "warning.xpm"
+}
+
+style "scale"
+{
+  fg[NORMAL] = { 1.0, 0, 0 }
+  bg_pixmap[NORMAL] = "<parent>"
+}
+
+style "button"
+{
+  fg[PRELIGHT] = { 1.0, 1.0, 1.0 }
+  bg[PRELIGHT] = { 0, 0, 0.75 }
+}
+
+style "main_button" = "button"
+{
+  font = "-adobe-helvetica-medium-r-normal--*-100-*-*-*-*-*-*"
+  bg[PRELIGHT] = { 0.75, 0, 0 }
+}
+
+style "toggle_button" = "button"
+{
+  fg[NORMAL] = { 1.0, 0, 0 }
+  fg[ACTIVE] = { 1.0, 0, 0 }
+  bg_pixmap[NORMAL] = "<parent>"
+}
+
+style "text"
+{
+  bg_pixmap[NORMAL] = "marble.xpm"
+  fg[NORMAL] = { 1.0, 1.0, 1.0 }
+}
+
+style "ruler"
+{
+  font = "-adobe-helvetica-medium-r-normal--*-80-*-*-*-*-*-*"
+}
+
+style "curve"
+{
+  fg[NORMAL] = { 58000, 0, 0 }                 # red
+}
+
+widget_class "GtkWindow" style "window"
+widget_class "GtkDialog" style "window"
+widget_class "GtkFileSelection" style "window"
+widget_class "*Gtk*Scale" style "scale"
+widget_class "*GtkCheckButton*" style "toggle_button"
+widget_class "*GtkRadioButton*" style "toggle_button"
+widget_class "*GtkButton*" style "button"
+widget_class "*Ruler" style "ruler"
+widget_class "*GtkText" style "text"
+widget "main window.*GtkButton*" style "main_button"
+widget "*GtkCurve" style "curve"
diff --git a/gtk/testinput.c b/gtk/testinput.c
new file mode 100644 (file)
index 0000000..1c6dae0
--- /dev/null
@@ -0,0 +1,379 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "gtk.h"
+
+/* Backing pixmap for drawing area */
+
+static GdkPixmap *pixmap = NULL;
+
+/* Information about cursor */
+
+static gint need_cursor = FALSE;
+static gint cursor_proximity = TRUE;
+static gdouble cursor_x;
+static gdouble cursor_y;
+
+/* Unique ID of current device */
+static guint32 current_device = GDK_CORE_POINTER;
+
+/* Check to see if we need to draw a cursor for current device */
+static void
+check_cursor ()
+{
+  GList *tmp_list;
+
+  /* gdk_input_list_devices returns an internal list, so we shouldn't
+     free it afterwards */
+  tmp_list = gdk_input_list_devices();
+
+  while (tmp_list)
+    {
+      GdkDeviceInfo *info = (GdkDeviceInfo *)tmp_list->data;
+
+      if (info->deviceid == current_device)
+       {
+         need_cursor = !info->has_cursor;
+         break;
+       }
+
+      tmp_list = tmp_list->next;
+    }
+}
+
+/* Erase the old cursor, and/or draw a new one, if necessary */
+static void
+update_cursor (GtkWidget *widget,  gdouble x, gdouble y)
+{
+  static gint cursor_present = 0;
+  gint state = need_cursor && cursor_proximity;
+
+  if (pixmap != NULL)
+    {
+      if (cursor_present && (cursor_present != state ||
+                            x != cursor_x || y != cursor_y))
+       {
+         gdk_draw_pixmap(widget->window,
+                         widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+                         pixmap,
+                         cursor_x - 5, cursor_y - 5,
+                         cursor_x - 5, cursor_y - 5,
+                         10, 10);
+       }
+
+      cursor_present = state;
+      cursor_x = x;
+      cursor_y = y;
+
+      if (cursor_present)
+       {
+         gdk_draw_rectangle (widget->window,
+                             widget->style->black_gc,
+                             TRUE,
+                             cursor_x - 5, cursor_y -5,
+                             10, 10);
+       }
+    }
+}
+
+/* Create a new backing pixmap of the appropriate size */
+static gint
+configure_event (GtkWidget *widget, GdkEventConfigure *event)
+{
+  if (pixmap)
+    {
+      gdk_pixmap_destroy(pixmap);
+    }
+  pixmap = gdk_pixmap_new(widget->window,
+                         widget->allocation.width,
+                         widget->allocation.height,
+                         -1);
+  gdk_draw_rectangle (pixmap,
+                     widget->style->white_gc,
+                     TRUE,
+                     0, 0,
+                     widget->allocation.width,
+                     widget->allocation.height);
+
+  return TRUE;
+}
+
+/* Refill the screen from the backing pixmap */
+static gint
+expose_event (GtkWidget *widget, GdkEventExpose *event)
+{
+  gdk_draw_pixmap(widget->window,
+                 widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+                 pixmap,
+                 event->area.x, event->area.y,
+                 event->area.x, event->area.y,
+                 event->area.width, event->area.height);
+
+  return FALSE;
+}
+
+/* Draw a rectangle on the screen, size depending on pressure,
+   and color on the type of device */
+static void
+draw_brush (GtkWidget *widget, GdkInputSource source,
+           gdouble x, gdouble y, gdouble pressure)
+{
+  GdkGC *gc;
+  GdkRectangle update_rect;
+
+  switch (source)
+    {
+    case GDK_SOURCE_MOUSE:
+      gc = widget->style->dark_gc[GTK_WIDGET_STATE (widget)];
+      break;
+    case GDK_SOURCE_PEN:
+      gc = widget->style->black_gc;
+      break;
+    case GDK_SOURCE_ERASER:
+      gc = widget->style->white_gc;
+      break;
+    default:
+      gc = widget->style->light_gc[GTK_WIDGET_STATE (widget)];
+    }
+
+  update_rect.x = x - 10 * pressure;
+  update_rect.y = y - 10 * pressure;
+  update_rect.width = 20 * pressure;
+  update_rect.height = 20 * pressure;
+  gdk_draw_rectangle (pixmap, gc, TRUE,
+                     update_rect.x, update_rect.y,
+                     update_rect.width, update_rect.height);
+  gtk_widget_draw (widget, &update_rect);
+}
+
+static guint32 motion_time;
+
+static gint
+button_press_event (GtkWidget *widget, GdkEventButton *event)
+{
+  if (event->deviceid != current_device)
+    {
+      current_device = event->deviceid;
+      check_cursor ();
+    }
+
+  cursor_proximity = TRUE;
+
+  if (event->button == 1 && pixmap != NULL)
+    {
+      draw_brush (widget, event->source, event->x, event->y,
+                 event->pressure);
+      motion_time = event->time;
+    }
+
+  update_cursor (widget, event->x, event->y);
+
+  return TRUE;
+}
+
+static gint
+motion_notify_event (GtkWidget *widget, GdkEventMotion *event)
+{
+  GdkTimeCoord *coords;
+  int nevents;
+  int i;
+
+  if (event->deviceid != current_device)
+    {
+      current_device = event->deviceid;
+      check_cursor ();
+    }
+
+  cursor_proximity = TRUE;
+
+  if (event->state & GDK_BUTTON1_MASK && pixmap != NULL)
+    {
+      coords = gdk_input_motion_events (event->window, event->deviceid,
+                                       motion_time, event->time,
+                                       &nevents);
+      motion_time = event->time;
+      if (coords)
+       {
+         for (i=0; i<nevents; i++)
+           draw_brush (widget,  event->source, coords[i].x, coords[i].y,
+                       coords[i].pressure);
+         g_free (coords);
+       }
+      else
+       {
+         if (event->is_hint)
+           gdk_input_window_get_pointer (event->window, event->deviceid,
+                                         NULL, NULL, NULL, NULL, NULL, NULL);
+         draw_brush (widget,  event->source, event->x, event->y,
+                     event->pressure);
+       }
+    }
+  else
+    {
+      gdk_input_window_get_pointer (event->window, event->deviceid,
+                                   &event->x, &event->y,
+                                   NULL, NULL, NULL, NULL);
+    }
+
+  update_cursor (widget, event->x, event->y);
+
+  return TRUE;
+}
+
+/* We track the next two events to know when we need to draw a
+   cursor */
+
+static gint
+proximity_out_event (GtkWidget *widget, GdkEventProximity *event)
+{
+  cursor_proximity = FALSE;
+  update_cursor (widget, cursor_x, cursor_y);
+  return TRUE;
+}
+
+static gint
+leave_notify_event (GtkWidget *widget, GdkEventCrossing *event)
+{
+  cursor_proximity = FALSE;
+  update_cursor (widget, cursor_x, cursor_y);
+  return TRUE;
+}
+
+void
+input_dialog_destroy (GtkWidget *w, gpointer data)
+{
+  *((GtkWidget **)data) = NULL;
+}
+
+void
+create_input_dialog ()
+{
+  static GtkWidget *inputd = NULL;
+
+  if (!inputd)
+    {
+      inputd = gtk_input_dialog_new();
+
+      gtk_signal_connect (GTK_OBJECT(inputd), "destroy",
+                         (GtkSignalFunc)input_dialog_destroy, &inputd);
+      gtk_signal_connect_object (GTK_OBJECT(GTK_INPUT_DIALOG(inputd)->close_button),
+                         "clicked",
+                         (GtkSignalFunc)gtk_widget_hide,
+                         GTK_OBJECT(inputd));
+      gtk_widget_hide ( GTK_INPUT_DIALOG(inputd)->save_button);
+
+      gtk_signal_connect (GTK_OBJECT(inputd), "enable_device",
+                         (GtkSignalFunc)check_cursor, NULL);
+      gtk_widget_show (inputd);
+    }
+  else
+    {
+      if (!GTK_WIDGET_MAPPED(inputd))
+       gtk_widget_show(inputd);
+      else
+       gdk_window_raise(inputd->window);
+    }
+}
+
+void
+quit ()
+{
+  gtk_exit (0);
+}
+
+int
+main (int argc, char *argv[])
+{
+  GtkWidget *window;
+  GtkWidget *drawing_area;
+  GtkWidget *vbox;
+
+  GtkWidget *button;
+
+  gtk_init (&argc, &argv);
+
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_widget_set_name (window, "Test Input");
+
+  vbox = gtk_vbox_new (FALSE, 0);
+  gtk_container_add (GTK_CONTAINER (window), vbox);
+  gtk_widget_show (vbox);
+
+  gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                     GTK_SIGNAL_FUNC (quit), NULL);
+
+  /* Create the drawing area */
+
+  drawing_area = gtk_drawing_area_new ();
+  gtk_drawing_area_size (GTK_DRAWING_AREA (drawing_area), 200, 200);
+  gtk_box_pack_start (GTK_BOX (vbox), drawing_area, TRUE, TRUE, 0);
+
+  gtk_widget_show (drawing_area);
+
+  /* Signals used to handle backing pixmap */
+
+  gtk_signal_connect (GTK_OBJECT (drawing_area), "expose_event",
+                     (GtkSignalFunc) expose_event, NULL);
+  gtk_signal_connect (GTK_OBJECT(drawing_area),"configure_event",
+                     (GtkSignalFunc) configure_event, NULL);
+
+  /* Event signals */
+
+  gtk_signal_connect (GTK_OBJECT (drawing_area), "motion_notify_event",
+                     (GtkSignalFunc) motion_notify_event, NULL);
+  gtk_signal_connect (GTK_OBJECT (drawing_area), "button_press_event",
+                     (GtkSignalFunc) button_press_event, NULL);
+
+  gtk_signal_connect (GTK_OBJECT (drawing_area), "leave_notify_event",
+                     (GtkSignalFunc) leave_notify_event, NULL);
+  gtk_signal_connect (GTK_OBJECT (drawing_area), "proximity_out_event",
+                     (GtkSignalFunc) proximity_out_event, NULL);
+
+  gtk_widget_set_events (drawing_area, GDK_EXPOSURE_MASK
+                        | GDK_LEAVE_NOTIFY_MASK
+                        | GDK_BUTTON_PRESS_MASK
+                        | GDK_POINTER_MOTION_MASK
+                        | GDK_POINTER_MOTION_HINT_MASK
+                        | GDK_PROXIMITY_OUT_MASK);
+
+  /* The following call enables tracking and processing of extension
+     events for the drawing area */
+  gtk_widget_set_extension_events (drawing_area, GDK_EXTENSION_EVENTS_ALL);
+
+  /* .. And create some buttons */
+  button = gtk_button_new_with_label ("Input Dialog");
+  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+
+  gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                     GTK_SIGNAL_FUNC (create_input_dialog), NULL);
+  gtk_widget_show (button);
+
+  button = gtk_button_new_with_label ("Quit");
+  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+
+  gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                            GTK_SIGNAL_FUNC (gtk_widget_destroy),
+                            GTK_OBJECT (window));
+  gtk_widget_show (button);
+
+  gtk_widget_show (window);
+
+  gtk_main ();
+
+  return 0;
+}
diff --git a/gtk/testselection.c b/gtk/testselection.c
new file mode 100644 (file)
index 0000000..3377cc6
--- /dev/null
@@ -0,0 +1,466 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "gtk.h"
+
+typedef enum {
+  SEL_TYPE_NONE,
+  APPLE_PICT,
+  ATOM,
+  ATOM_PAIR,
+  BITMAP,
+  C_STRING,
+  COLORMAP,
+  COMPOUND_TEXT,
+  DRAWABLE,
+  INTEGER,
+  PIXEL,
+  PIXMAP,
+  SPAN,
+  STRING,
+  TEXT,
+  WINDOW,
+  LAST_SEL_TYPE,
+} SelType;
+
+GdkAtom seltypes[LAST_SEL_TYPE];
+
+typedef struct _Target {
+  gchar *target_name;
+  SelType type;
+  GdkAtom target;
+  gint format;
+  GtkSelectionFunction *handler;
+} Target;
+
+/* The following is a list of all the selection targets defined
+   in the ICCCM */
+
+static Target targets[] = {
+  { "ADOBE_PORTABLE_DOCUMENT_FORMAT",      STRING,        0, 8,  NULL },
+  { "APPLE_PICT",                          APPLE_PICT,    0, 8,  NULL },
+  { "BACKGROUND",                          PIXEL,         0, 32, NULL },
+  { "BITMAP",                              BITMAP,        0, 32, NULL },
+  { "CHARACTER_POSITION",                   SPAN,         0, 32, NULL },
+  { "CLASS",                               TEXT,          0, 8,  NULL },
+  { "CLIENT_WINDOW",                       WINDOW,        0, 32, NULL },
+  { "COLORMAP",                            COLORMAP,      0, 32, NULL },
+  { "COLUMN_NUMBER",                       SPAN,          0, 32, NULL },
+  { "COMPOUND_TEXT",                       COMPOUND_TEXT, 0, 8,  NULL },
+  /*  { "DELETE", "NULL", 0, ?, NULL }, */
+  { "DRAWABLE",                            DRAWABLE,      0, 32, NULL },
+  { "ENCAPSULATED_POSTSCRIPT",                     STRING,        0, 8,  NULL },
+  { "ENCAPSULATED_POSTSCRIPT_INTERCHANGE",  STRING,       0, 8,  NULL },
+  { "FILE_NAME",                           TEXT,          0, 8,  NULL },
+  { "FOREGROUND",                          PIXEL,         0, 32, NULL },
+  { "HOST_NAME",                           TEXT,          0, 8,  NULL },
+  /*  { "INSERT_PROPERTY", "NULL", 0, ? NULL }, */
+  /*  { "INSERT_SELECTION", "NULL", 0, ? NULL }, */
+  { "LENGTH",                              INTEGER,       0, 32, NULL },
+  { "LINE_NUMBER",                         SPAN,          0, 32, NULL },
+  { "LIST_LENGTH",                         INTEGER,       0, 32, NULL },
+  { "MODULE",                              TEXT,          0, 8,  NULL },
+  /*  { "MULTIPLE", "ATOM_PAIR", 0, 32, NULL }, */
+  { "NAME",                                TEXT,          0, 8,  NULL },
+  { "ODIF",                                TEXT,          0, 8,  NULL },
+  { "OWNER_OS",                            TEXT,          0, 8,  NULL },
+  { "PIXMAP",                              PIXMAP,        0, 32, NULL },
+  { "POSTSCRIPT",                          STRING,        0, 8,  NULL },
+  { "PROCEDURE",                           TEXT,          0, 8,  NULL },
+  { "PROCESS",                             INTEGER,       0, 32, NULL },
+  { "STRING",                              STRING,        0, 8,  NULL },
+  { "TARGETS",                                     ATOM,          0, 32, NULL },
+  { "TASK",                                INTEGER,       0, 32, NULL },
+  { "TEXT",                                TEXT,          0, 8 , NULL },
+  { "TIMESTAMP",                           INTEGER,       0, 32, NULL },
+  { "USER",                                TEXT,          0, 8,  NULL },
+};
+
+static int num_targets = sizeof(targets)/sizeof(Target);
+
+static int have_selection = FALSE;
+
+GtkWidget *selection_text;
+GtkWidget *selection_button;
+GString *selection_string = NULL;
+
+static void
+init_atoms ()
+{
+  int i;
+
+  seltypes[SEL_TYPE_NONE] = GDK_NONE;
+  seltypes[APPLE_PICT] = gdk_atom_intern ("APPLE_PICT",FALSE);
+  seltypes[ATOM]       = gdk_atom_intern ("ATOM",FALSE);
+  seltypes[ATOM_PAIR]  = gdk_atom_intern ("ATOM_PAIR",FALSE);
+  seltypes[BITMAP]     = gdk_atom_intern ("BITMAP",FALSE);
+  seltypes[C_STRING]   = gdk_atom_intern ("C_STRING",FALSE);
+  seltypes[COLORMAP]   = gdk_atom_intern ("COLORMAP",FALSE);
+  seltypes[COMPOUND_TEXT] = gdk_atom_intern ("COMPOUND_TEXT",FALSE);
+  seltypes[DRAWABLE]   = gdk_atom_intern ("DRAWABLE",FALSE);
+  seltypes[INTEGER]    = gdk_atom_intern ("INTEGER",FALSE);
+  seltypes[PIXEL]      = gdk_atom_intern ("PIXEL",FALSE);
+  seltypes[PIXMAP]     = gdk_atom_intern ("PIXMAP",FALSE);
+  seltypes[SPAN]       = gdk_atom_intern ("SPAN",FALSE);
+  seltypes[STRING]     = gdk_atom_intern ("STRING",FALSE);
+  seltypes[TEXT]       = gdk_atom_intern ("TEXT",FALSE);
+  seltypes[WINDOW]     = gdk_atom_intern ("WINDOW",FALSE);
+
+  for (i=0; i<num_targets; i++)
+    targets[i].target = gdk_atom_intern (targets[i].target_name, FALSE);
+}
+
+void
+selection_toggled (GtkWidget *widget)
+{
+  if (GTK_TOGGLE_BUTTON(widget)->active)
+    {
+      have_selection = gtk_selection_owner_set (widget,
+                                               GDK_SELECTION_PRIMARY,
+                                               GDK_CURRENT_TIME);
+      if (!have_selection)
+       gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON(widget), FALSE);
+    }
+  else
+    {
+      if (have_selection)
+       {
+         if (gdk_selection_owner_get (GDK_SELECTION_PRIMARY) == widget->window)
+           gtk_selection_owner_set (NULL, GDK_SELECTION_PRIMARY,
+                                    GDK_CURRENT_TIME);
+         have_selection = FALSE;
+       }
+    }
+}
+
+void
+selection_handle (GtkWidget *widget, 
+                 GtkSelectionData *selection_data, gpointer data)
+{
+  guchar *buffer;
+  gint len;
+
+  if (!selection_string)
+    {
+      buffer = NULL;
+      len = 0;
+    }      
+  else
+    {
+      buffer = selection_string->str;
+      len = selection_string->len;
+    }
+  
+  gtk_selection_data_set (selection_data,
+                         selection_data->target == seltypes[COMPOUND_TEXT] ?
+                                 seltypes[COMPOUND_TEXT] : seltypes[STRING],
+                         8, buffer, len);
+}
+
+gint
+selection_clear (GtkWidget *widget, GdkEventSelection *event)
+{
+  have_selection = FALSE;
+  gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON(widget), FALSE);
+
+  return TRUE;
+}
+
+gchar *
+stringify_atom (guchar *data, gint *position)
+{
+  gchar *str = gdk_atom_name (*(GdkAtom *)(data+*position));
+  *position += sizeof(GdkAtom);
+    
+  return str;
+}
+
+gchar *
+stringify_text (guchar *data, gint *position)
+{
+  gchar *str = g_strdup ((gchar *)(data+*position));
+  *position += strlen (str) + 1;
+    
+  return str;
+}
+
+gchar *
+stringify_xid (guchar *data, gint *position)
+{
+  gchar buffer[20];
+  gchar *str;
+
+  sprintf(buffer,"0x%x",*(guint32 *)(data+*position));
+  str = g_strdup (buffer);
+
+  *position += sizeof(guint32);
+    
+  return str;
+}
+
+gchar *
+stringify_integer (guchar *data, gint *position)
+{
+  gchar buffer[20];
+  gchar *str;
+
+  sprintf(buffer,"%d",*(int *)(data+*position));
+  str = g_strdup (buffer);
+
+  *position += sizeof(int);
+    
+  return str;
+}
+
+gchar *
+stringify_span (guchar *data, gint *position)
+{
+  gchar buffer[42];
+  gchar *str;
+
+  sprintf(buffer,"%d - %d",((int *)(data+*position))[0],
+         ((int *)(data+*position))[1]);
+  str = g_strdup (buffer);
+
+  *position += 2*sizeof(int);
+    
+  return str;
+}
+
+void
+selection_received (GtkWidget *widget, GtkSelectionData *data)
+{
+  int position;
+  int i;
+  SelType seltype;
+  char *str;
+  
+  if (data->length < 0)
+    {
+      g_print("Error retrieving selection\n");
+      return;
+    }
+
+  seltype = SEL_TYPE_NONE;
+  for (i=0; i<LAST_SEL_TYPE; i++)
+    {
+      if (seltypes[i] == data->type)
+       {
+         seltype = i;
+         break;
+       }
+    }
+
+  if (seltype == SEL_TYPE_NONE)
+    {
+      char *name = gdk_atom_name (data->type);
+      g_print("Don't know how to handle type: %s (%ld)\n",
+             name?name:"<unknown>",
+             data->type);
+      return;
+    }
+
+  if (selection_string != NULL)
+    g_string_free (selection_string, TRUE);
+
+  selection_string = g_string_new (NULL);
+
+  gtk_text_freeze (GTK_TEXT (selection_text));
+  gtk_text_set_point (GTK_TEXT (selection_text), 0);
+  gtk_text_foreward_delete (GTK_TEXT (selection_text), 
+                           gtk_text_get_length (GTK_TEXT (selection_text)));
+
+  position = 0;
+  while (position < data->length)
+    {
+      switch (seltype)
+       {
+       case ATOM:
+         str = stringify_atom (data->data, &position);
+         break;
+       case COMPOUND_TEXT:
+       case STRING:
+       case TEXT:
+         str = stringify_text (data->data, &position);
+         break;
+       case BITMAP:
+       case DRAWABLE:
+       case PIXMAP:
+       case WINDOW:
+       case COLORMAP:
+         str = stringify_xid (data->data, &position);
+         break;
+       case INTEGER:
+       case PIXEL:
+         str = stringify_integer (data->data, &position);
+         break;
+       case SPAN:
+         str = stringify_span (data->data, &position);
+         break;
+       default:
+         {
+           char *name = gdk_atom_name (data->type);
+           g_print("Can't convert type %s (%ld) to string\n",
+                   name?name:"<unknown>",
+                   data->type);
+           position = data->length;
+         }
+       }
+      gtk_text_insert (GTK_TEXT (selection_text), NULL, 
+                      &selection_text->style->black, 
+                      NULL, str, -1);
+      gtk_text_insert (GTK_TEXT (selection_text), NULL, 
+                      &selection_text->style->black, 
+                      NULL, "\n", -1);
+      g_string_append (selection_string, str);
+      g_free (str);
+    }
+  gtk_text_thaw (GTK_TEXT (selection_text));
+}
+
+void
+paste (GtkWidget *widget, GtkWidget *entry)
+{
+  char *name;
+  GdkAtom atom;
+
+  name = gtk_entry_get_text (GTK_ENTRY(entry));
+  atom = gdk_atom_intern (name, FALSE);
+
+  if (atom == GDK_NONE)
+    {
+      g_print("Could not create atom: \"%s\"\n",name);
+      return;
+    }
+
+  gtk_selection_convert (selection_button, GDK_SELECTION_PRIMARY, atom, 
+                        GDK_CURRENT_TIME);
+}
+
+void
+quit ()
+{
+  gtk_exit (0);
+}
+
+int
+main (int argc, char *argv[])
+{
+  GtkWidget *dialog;
+  GtkWidget *button;
+  GtkWidget *table;
+  GtkWidget *label;
+  GtkWidget *entry;
+  GtkWidget *hscrollbar;
+  GtkWidget *vscrollbar;
+  GtkWidget *hbox;
+  
+  gtk_init (&argc, &argv);
+
+  init_atoms();
+
+  dialog = gtk_dialog_new ();
+  gtk_widget_set_name (dialog, "Test Input");
+  gtk_container_border_width (GTK_CONTAINER(dialog), 0);
+
+  gtk_signal_connect (GTK_OBJECT (dialog), "destroy",
+                     GTK_SIGNAL_FUNC (quit), NULL);
+
+  table = gtk_table_new (4, 2, FALSE);
+  gtk_container_border_width (GTK_CONTAINER(table), 10);
+
+  gtk_table_set_row_spacing (GTK_TABLE (table), 0, 5);
+  gtk_table_set_row_spacing (GTK_TABLE (table), 1, 2);
+  gtk_table_set_row_spacing (GTK_TABLE (table), 2, 2);
+  gtk_table_set_col_spacing (GTK_TABLE (table), 0, 2);
+  gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dialog)->vbox), 
+                     table, TRUE, TRUE, 0);
+  gtk_widget_show (table);
+  
+  selection_button = gtk_toggle_button_new_with_label ("Claim Selection");
+  gtk_table_attach (GTK_TABLE (table), selection_button, 0, 2, 0, 1,
+                   GTK_EXPAND | GTK_FILL, 0, 0, 0);
+  gtk_widget_show (selection_button);
+
+  gtk_signal_connect (GTK_OBJECT(selection_button), "toggled",
+                     GTK_SIGNAL_FUNC (selection_toggled), NULL);
+  gtk_signal_connect (GTK_OBJECT(selection_button), "selection_clear_event",
+                     GTK_SIGNAL_FUNC (selection_clear), NULL);
+  gtk_signal_connect (GTK_OBJECT(selection_button), "selection_received",
+                     GTK_SIGNAL_FUNC (selection_received), NULL);
+
+  gtk_selection_add_handler (selection_button, GDK_SELECTION_PRIMARY,
+                            seltypes[STRING], selection_handle, NULL, NULL);
+
+  gtk_selection_add_handler (selection_button, GDK_SELECTION_PRIMARY,
+                            seltypes[TEXT], selection_handle, NULL, NULL);
+
+  gtk_selection_add_handler (selection_button, GDK_SELECTION_PRIMARY,
+                            seltypes[COMPOUND_TEXT],
+                            selection_handle, NULL, NULL);
+
+  selection_text = gtk_text_new (NULL, NULL);
+  gtk_table_attach_defaults (GTK_TABLE (table), selection_text, 0, 1, 1, 2);
+  gtk_widget_show (selection_text);
+  
+  hscrollbar = gtk_hscrollbar_new (GTK_TEXT (selection_text)->hadj);
+  gtk_table_attach (GTK_TABLE (table), hscrollbar, 0, 1, 2, 3,
+                   GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
+  gtk_widget_show (hscrollbar);
+  
+  vscrollbar = gtk_vscrollbar_new (GTK_TEXT (selection_text)->vadj);
+  gtk_table_attach (GTK_TABLE (table), vscrollbar, 1, 2, 1, 2,
+                   GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+  gtk_widget_show (vscrollbar);
+
+  hbox = gtk_hbox_new (FALSE, 2);
+  gtk_table_attach (GTK_TABLE (table), hbox, 0, 2, 3, 4,
+                   GTK_EXPAND | GTK_FILL, 0, 0, 0);
+  gtk_widget_show (hbox);
+
+  label = gtk_label_new ("Target:");
+  gtk_box_pack_start (GTK_BOX(hbox), label, FALSE, FALSE, 0);
+  gtk_widget_show (label);
+
+  entry = gtk_entry_new ();
+  gtk_box_pack_start (GTK_BOX(hbox), entry, TRUE, TRUE, 0);
+  gtk_widget_show (entry);
+
+  /* .. And create some buttons */
+  button = gtk_button_new_with_label ("Paste");
+  gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dialog)->action_area), 
+                     button, TRUE, TRUE, 0);
+  gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                     GTK_SIGNAL_FUNC (paste), entry);
+  gtk_widget_show (button);
+
+  button = gtk_button_new_with_label ("Quit");
+  gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dialog)->action_area), 
+                     button, TRUE, TRUE, 0);
+
+  gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                            GTK_SIGNAL_FUNC (gtk_widget_destroy), 
+                            GTK_OBJECT (dialog));
+  gtk_widget_show (button);
+
+  gtk_widget_show (dialog);
+
+  gtk_main ();
+
+  return 0;
+}
diff --git a/install-sh b/install-sh
new file mode 100755 (executable)
index 0000000..89fc9b0
--- /dev/null
@@ -0,0 +1,238 @@
+#! /bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+tranformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+       -c) instcmd="$cpprog"
+           shift
+           continue;;
+
+       -d) dir_arg=true
+           shift
+           continue;;
+
+       -m) chmodcmd="$chmodprog $2"
+           shift
+           shift
+           continue;;
+
+       -o) chowncmd="$chownprog $2"
+           shift
+           shift
+           continue;;
+
+       -g) chgrpcmd="$chgrpprog $2"
+           shift
+           shift
+           continue;;
+
+       -s) stripcmd="$stripprog"
+           shift
+           continue;;
+
+       -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+           shift
+           continue;;
+
+       -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+           shift
+           continue;;
+
+       *)  if [ x"$src" = x ]
+           then
+               src=$1
+           else
+               # this colon is to work around a 386BSD /bin/sh bug
+               :
+               dst=$1
+           fi
+           shift
+           continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+       echo "install:  no input file specified"
+       exit 1
+else
+       true
+fi
+
+if [ x"$dir_arg" != x ]; then
+       dst=$src
+       src=""
+       
+       if [ -d $dst ]; then
+               instcmd=:
+       else
+               instcmd=mkdir
+       fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+       if [ -f $src -o -d $src ]
+       then
+               true
+       else
+               echo "install:  $src does not exist"
+               exit 1
+       fi
+       
+       if [ x"$dst" = x ]
+       then
+               echo "install:  no destination specified"
+               exit 1
+       else
+               true
+       fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+       if [ -d $dst ]
+       then
+               dst="$dst"/`basename $src`
+       else
+               true
+       fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='   
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+       pathcomp="${pathcomp}${1}"
+       shift
+
+       if [ ! -d "${pathcomp}" ] ;
+        then
+               $mkdirprog "${pathcomp}"
+       else
+               true
+       fi
+
+       pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+       $doit $instcmd $dst &&
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+       if [ x"$transformarg" = x ] 
+       then
+               dstfile=`basename $dst`
+       else
+               dstfile=`basename $dst $transformbasename | 
+                       sed $transformarg`$transformbasename
+       fi
+
+# don't allow the sed command to completely eliminate the filename
+
+       if [ x"$dstfile" = x ] 
+       then
+               dstfile=`basename $dst`
+       else
+               true
+       fi
+
+# Make a temp file name in the proper directory.
+
+       dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+       $doit $instcmd $src $dsttmp &&
+
+       trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+       $doit $rmcmd -f $dstdir/$dstfile &&
+       $doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
diff --git a/ltconfig b/ltconfig
new file mode 100755 (executable)
index 0000000..e9d3a83
--- /dev/null
+++ b/ltconfig
@@ -0,0 +1,1415 @@
+#! /bin/sh
+
+# ltconfig - Create a system-specific libtool.
+# Generated automatically from ltconfig.in by configure.
+# Copyright (C) 1996, 1997, Free Software Foundation, Inc.
+# Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# A lot of this script is taken from autoconf-2.10.
+
+# The name of this program.
+progname=`echo "$0" | sed 's%^.*/%%'`
+
+# Constants:
+PROGRAM=ltconfig
+PACKAGE=libtool
+VERSION=1.0f
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.c 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.c $LIBS 1>&5'
+rm="rm -f"
+
+help="Try \`$progname --help' for more information."
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s/\([\\"$\\\\]\)/\\\1/g'
+
+# Same as above, but don't quote variable references.
+double_quote_subst='s/\([\\"\\\\]\)/\\\1/g'
+
+# Global variables:
+can_build_shared=yes
+enable_shared=yes
+# All known linkers require a `.a' archive for static linking.
+enable_static=yes
+ltmain=
+silent=
+srcdir=
+ac_config_guess=
+ac_config_sub=
+host=
+nonopt=
+verify_host=yes
+with_gcc=no
+with_gnu_ld=no
+
+old_AR="$AR"
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+old_CPPFLAGS="$CPPFLAGS"
+old_LD="$LD"
+old_LN_S="$LN_S"
+old_NM="$NM"
+old_RANLIB="$RANLIB"
+
+# Parse the command line options.
+args=
+prev=
+for option
+do
+  case "$option" in
+  -*=*) optarg=`echo "$option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$prev"; then
+    eval "$prev=\$option"
+    prev=
+    continue
+  fi
+
+  case "$option" in
+  --help) cat <<EOM
+Usage: $progname [OPTION]... LTMAIN [HOST]
+
+Generate a system-specific libtool script.
+
+    --disable-shared       do not build shared libraries
+    --disable-static       do not build static libraries
+    --help                 display this help and exit
+    --no-verify            do not verify that HOST is a valid host type
+    --quiet                same as \`--silent'
+    --silent               don't print informational messages
+    --srcdir=DIR           find \`config.guess' in DIR
+    --version              output version information and exit
+    --with-gcc             assume that the GNU C compiler will be used
+    --with-gnu-ld          assume that the C compiler uses the GNU linker
+
+LTMAIN is the \`ltmain.sh' shell script fragment that provides basic libtool
+functionality.
+
+HOST is the canonical host system name [default=guessed].
+EOM
+  exit 0
+  ;;
+
+  --disable-shared) enable_shared=no ;;
+
+  --disable-static) enable_static=no ;;
+
+  --quiet | --silent) silent=yes ;;
+
+  --srcdir) prev=srcdir ;;
+  --srcdir=*) srcdir="$optarg" ;;
+
+  --no-verify) verify_host=no ;;
+
+  --version) echo "$PROGRAM (GNU $PACKAGE) $VERSION"; exit 0 ;;
+
+  --with-gcc) with_gcc=yes ;;
+  --with-gnu-ld) with_gnu_ld=yes ;;
+
+  -*)
+    echo "$progname: unrecognized option \`$option'" 1>&2
+    echo "$help" 1>&2
+    exit 1
+    ;;
+
+  *)
+    if test -z "$ltmain"; then
+      ltmain="$option"
+    elif test -z "$host"; then
+# FIXME This generates an unnecessary warning for sparc-sun-solaris4.1.3_U1
+#      if test -n "`echo $option| sed 's/[-a-z0-9.]//g'`"; then
+#        echo "$progname: warning \`$option' is not a valid host type" 1>&2
+#      fi
+      host="$option"
+    else
+      echo "$progname: too many arguments" 1>&2
+      echo "$help" 1>&2
+      exit 1
+    fi ;;
+  esac
+done
+
+if test -z "$ltmain"; then
+  echo "$progname: you must specify a LTMAIN file" 1>&2
+  echo "$help" 1>&2
+  exit 1
+fi
+
+if test -f "$ltmain"; then :
+else
+  echo "$progname: warning: \`$ltmain' does not exist" 1>&2
+fi
+
+# Quote any args containing shell metacharacters.
+ltconfig_args=
+for arg
+do
+  case "$arg" in
+  *" "*|*"     "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+  ltconfig_args="$ltconfig_args '$arg'" ;;
+  *) ltconfig_args="$ltconfig_args $arg" ;;
+  esac
+done
+
+# A relevant subset of AC_INIT.
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 5 compiler messages saved in config.log
+# 6 checking for... messages and results
+if test "$silent" = yes; then
+  exec 6>/dev/null
+else
+  exec 6>&1
+fi
+exec 5>>./config.log
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+    ac_n= ac_c='
+' ac_t='       '
+  else
+    ac_n=-n ac_c= ac_t=
+  fi
+else
+  ac_n= ac_c='\c' ac_t=
+fi
+
+if test -z "$srcdir"; then
+  # Assume the source directory is the same one as the path to ltmain.sh.
+  srcdir=`echo "$ltmain" | sed 's%/[^/]*$%%'`
+  test "$srcdir" = "$ltmain" && srcdir=.
+fi
+
+trap "$rm conftest*; exit 1" 1 2 15
+if test "$verify_host" = yes; then
+  # Check for config.guess and config.sub.
+  ac_aux_dir=
+  for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+    if test -f $ac_dir/config.guess; then
+      ac_aux_dir=$ac_dir
+      break
+    fi
+  done
+  if test -z "$ac_aux_dir"; then
+    echo "$progname: cannot find config.guess in $srcdir $srcdir/.. $srcdir/../.." 1>&2
+    echo "$help" 1>&2
+    exit 1
+  fi
+  ac_config_guess=$ac_aux_dir/config.guess
+  ac_config_sub=$ac_aux_dir/config.sub
+
+  # Make sure we can run config.sub.
+  if $ac_config_sub sun4 >/dev/null 2>&1; then :
+  else
+    echo "$progname: cannot run $ac_config_sub" 1>&2
+    echo "$help" 1>&2
+    exit 1
+  fi
+
+  echo $ac_n "checking host system type""... $ac_c" 1>&6
+
+  host_alias=$host
+  case "$host_alias" in
+  "")
+    if host_alias=`$ac_config_guess`; then :
+    else
+      echo "$progname: cannot guess host type; you must specify one" 1>&2
+      echo "$help" 1>&2
+      exit 1
+    fi ;;
+  esac
+  host=`$ac_config_sub $host_alias`
+  echo "$ac_t$host" 1>&6
+
+  # Make sure the host verified.
+  test -z "$host" && exit 1
+
+elif test -z "$host"; then
+  echo "$progname: you must specify a host type if you use \`--no-verify'" 1>&2
+  echo "$help" 1>&2
+  exit 1
+else
+  host_alias=$host
+fi
+
+# Transform *-*-linux* to *-*-linux-gnu*, to support old configure scripts.
+case "$host" in
+*-*-linux-gnu*) ;;
+*-*-linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
+esac
+
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+case "$host_os" in
+aix*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "${COLLECT_NAMES+set}" != set; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR cru $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+
+# Set a sane default for `AR'.
+test -z "$AR" && AR=ar
+
+# If RANLIB is not set, then run the test.
+if test "${RANLIB+set}" != "set"; then
+  result=no
+
+  echo $ac_n "checking for ranlib... $ac_c" 1>&6
+  IFS="${IFS=  }"; save_ifs="$IFS"; IFS="${IFS}:"
+  for dir in $PATH; do
+    test -z "$dir" && dir=.
+    if test -f $dir/ranlib; then
+      RANLIB="ranlib"
+      result="ranlib"
+      break
+    fi
+  done
+  IFS="$save_ifs"
+
+  echo "$ac_t$result" 1>&6
+fi
+
+if test -n "$RANLIB"; then
+  old_archive_cmds="$old_archive_cmds;\$RANLIB \$oldlib"
+  old_postinstall_cmds="$old_postinstall_cmds;\$RANLIB \$oldlib"
+fi
+
+# Check to see if we are using GCC.
+if test "$with_gcc" != yes || test -z "$CC"; then
+  # If CC is not set, then try to find GCC or a usable CC.
+  if test -z "$CC"; then
+    echo $ac_n "checking for gcc... $ac_c" 1>&6
+    IFS="${IFS=        }"; save_ifs="$IFS"; IFS="${IFS}:"
+    for dir in $PATH; do
+      IFS="$save_ifs"
+      test -z "$dir" && dir=.
+      if test -f $dir/gcc; then
+       CC="gcc"
+       break
+      fi
+    done
+    IFS="$save_ifs"
+
+    if test -n "$CC"; then
+      echo "$ac_t$CC" 1>&6
+    else
+      echo "$ac_t"no 1>&6
+    fi
+  fi
+
+  # Not "gcc", so try "cc", rejecting "/usr/ucb/cc".
+  if test -z "$CC"; then
+    echo $ac_n "checking for cc... $ac_c" 1>&6
+    IFS="${IFS=        }"; save_ifs="$IFS"; IFS="${IFS}:"
+    cc_rejected=no
+    for dir in $PATH; do
+      test -z "$dir" && dir=.
+      if test -f $dir/cc; then
+       if test "$dir/cc" = "/usr/ucb/cc"; then
+         cc_rejected=yes
+         continue
+       fi
+       CC="cc"
+       break
+      fi
+    done
+    IFS="$save_ifs"
+    if test $cc_rejected = yes; then
+      # We found a bogon in the path, so make sure we never use it.
+      set dummy $CC
+      shift
+      if test $# -gt 0; then
+       # We chose a different compiler from the bogus one.
+       # However, it has the same name, so the bogon will be chosen
+       # first if we set CC to just the name; use the full file name.
+       shift
+       set dummy "$dir/cc" "$@"
+       shift
+       CC="$@"
+      fi
+    fi
+
+    if test -n "$CC"; then
+      echo "$ac_t$CC" 1>&6
+    else
+      echo "$ac_t"no 1>&6
+    fi
+
+    if test -z "$CC"; then
+      echo "$progname: error: no acceptable cc found in \$PATH" 1>&2
+      exit 1
+    fi
+  fi
+
+  # Now see if the compiler is really GCC.
+  with_gcc=no
+  echo $ac_n "checking whether we are using GNU C... $ac_c" 1>&6
+  echo "$progname:394: checking whether we are using GNU C" >&5
+
+  $rm conftest.c
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+  if { ac_try='${CC-cc} -E conftest.c'; { (eval echo $progname:402: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+    with_gcc=yes
+  fi
+  $rm conftest.c
+  echo "$ac_t$with_gcc" 1>&6
+fi
+
+# Allow CC to be a program name with arguments.
+set dummy $CC
+compiler="$2"
+
+echo $ac_n "checking for $compiler option to produce PIC... $ac_c" 1>&6
+pic_flag=
+profile_flag_pattern=
+special_shlib_compile_flags=
+wl=
+link_static_flag=
+no_builtin_flag=
+
+if test "$with_gcc" = yes; then
+  profile_flag_pattern='-pg?'
+  wl='-Wl,'
+  link_static_flag='-static'
+  no_builtin_flag=' -fno-builtin'
+
+  case "$host_os" in
+  aix3* | aix4* | irix5* | irix6* | osf3* | osf4*)
+    # PIC is the default for these OSes.
+    ;;
+  os2*)
+    # We can build DLLs from non-PIC.
+    ;;
+  *)
+    pic_flag='-fPIC'
+    ;;
+  esac
+else
+  # PORTME Check for PIC flags for the system compiler.
+  case "$host_os" in
+  aix3* | aix4*)
+    # All AIX code is PIC.
+    link_static_flag='-bnso -bI:/lib/syscalls.exp'
+    ;;
+
+  hpux9* | hpux10*)
+    # Is there a better link_static_flag that works with the bundled CC?
+    wl='-Wl,'
+    link_static_flag='${wl}-a ${wl}archive'
+    pic_flag='+Z'
+    ;;
+
+  irix5* | irix6*)
+    wl='-Wl,'
+    link_static_flag='-non_shared'
+    # PIC (with -KPIC) is the default.
+    ;;
+
+  os2*)
+    # We can build DLLs from non-PIC.
+    ;;
+
+  osf3* | osf4*)
+    # All OSF/1 code is PIC.
+    wl='-Wl,'
+    link_static_flag='-non_shared'
+    ;;
+
+  sco3.2v5*)
+    pic_flag='-Kpic'
+    link_static_flag='-dn'
+    special_shlib_compile_flags='-belf'
+    ;;
+
+  solaris2*)
+    pic_flag='-KPIC'
+    link_static_flag='-Bstatic'
+    wl='-Wl,'
+    ;;
+
+  sunos4*)
+    pic_flag='-PIC'
+    link_static_flag='-Bstatic'
+    wl='-Qoption ld '
+    ;;
+
+  uts4*)
+    pic_flag='-pic'
+    link_static_flag='-Bstatic'
+    ;;
+
+  *)
+    can_build_shared=no
+    ;;
+  esac
+fi
+
+if test -n "$pic_flag"; then
+  echo "$ac_t$pic_flag" 1>&6
+
+  # Check to make sure the pic_flag actually works.
+  echo $ac_n "checking if $compiler PIC flag $pic_flag works... $ac_c" 1>&6
+  $rm conftest*
+  echo > conftest.c
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS $pic_flag -DPIC"
+  echo "$progname:507: checking if $compiler PIC flag $pic_flag works" >&5
+  if { (eval echo $progname:508: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.o; then
+    # Append any errors to the config.log.
+    cat conftest.err 1>&5
+
+    # On HP-UX, the stripped-down bundled CC doesn't accept +Z, but also
+    # reports no error.  So, we need to grep stderr for (Bundled).
+    if grep '(Bundled)' conftest.err >/dev/null; then
+      echo "$ac_t"no 1>&6
+      can_build_shared=no
+      pic_flag=
+    else
+      echo "$ac_t"yes 1>&6
+      pic_flag=" $pic_flag"
+    fi
+  else
+    # Append any errors to the config.log.
+    cat conftest.err 1>&5
+    can_build_shared=no
+    pic_flag=
+    echo "$ac_t"no 1>&6
+  fi
+  CFLAGS="$save_CFLAGS"
+  $rm conftest*
+else
+  echo "$ac_t"none 1>&6
+fi
+
+# Check for any special shared library compilation flags.
+if test -n "$special_shlib_compile_flags"; then
+  echo "$progname: warning: \`$CC' requires \`$special_shlib_compile_flags' to build shared libraries" 1>&2
+  if echo "$old_CC $old_CFLAGS " | egrep -e "[         ]$special_shlib_compile_flags[  ]" >/dev/null; then :
+  else
+    echo "$progname: add \`$special_shlib_compile_flags' to the CC or CFLAGS env variable and reconfigure" 1>&2
+    can_build_shared=no
+  fi
+fi
+
+echo $ac_n "checking if $compiler static flag $link_static_flag works... $ac_c" 1>&6
+$rm conftest*
+echo 'main(){return(0);}' > conftest.c
+save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$LDFLAGS $link_static_flag"
+echo "$progname:550: checking if $compiler static flag $link_static_flag works" >&5
+if { (eval echo $progname:551: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  echo "$ac_t$link_static_flag" 1>&6
+else
+  echo "$ac_t"none 1>&6
+  link_static_flag=
+fi
+LDFLAGS="$save_LDFLAGS"
+$rm conftest*
+
+if test -z "$LN_S"; then
+  # Check to see if we can use ln -s, or we need hard links.
+  echo $ac_n "checking whether ln -s works... $ac_c" 1>&6
+  $rm conftestdata
+  if ln -s X conftestdata 2>/dev/null; then
+    $rm conftestdata
+    LN_S="ln -s"
+  else
+    LN_S=ln
+  fi
+  if test "$LN_S" = "ln -s"; then
+    echo "$ac_t"yes 1>&6
+  else
+    echo "$ac_t"no 1>&6
+  fi
+fi
+
+# Make sure LD is an absolute path.
+if test -z "$LD"; then
+  ac_prog=ld
+  if test "$with_gcc" = yes; then
+    # Check if gcc -print-prog-name=ld gives a path.
+    echo $ac_n "checking for ld used by GCC... $ac_c" 1>&6
+    echo "$progname:583: checking for ld used by GCC" >&5
+    ac_prog=`($CC -print-prog-name=ld) 2>&5`
+    case "$ac_prog" in
+    # Accept absolute paths.
+    /*)
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+    "")
+      # If it fails, then pretend we aren't using GCC.
+      ac_prog=ld
+      ;;
+    *)
+      # If it is relative, then search for the first ld in PATH.
+      with_gnu_ld=unknown
+      ;;
+    esac
+  elif test "$with_gnu_ld" = yes; then
+    echo $ac_n "checking for GNU ld... $ac_c" 1>&6
+    echo "$progname:601: checking for GNU ld" >&5
+  else
+    echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+    echo "$progname:604: checking for non-GNU ld" >&5
+  fi
+
+  if test -z "$LD"; then
+    IFS="${IFS=        }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+    for ac_dir in $PATH; do
+      test -z "$ac_dir" && ac_dir=.
+      if test -f "$ac_dir/$ac_prog"; then
+       LD="$ac_dir/$ac_prog"
+       # Check to see if the program is GNU ld.  I'd rather use --version,
+       # but apparently some GNU ld's only accept -v.
+       # Break only if it was the GNU/non-GNU ld that we prefer.
+       if "$LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+         test "$with_gnu_ld" != no && break
+       else
+         test "$with_gnu_ld" != yes && break
+       fi
+      fi
+    done
+    IFS="$ac_save_ifs"
+  fi
+
+  if test -n "$LD"; then
+    echo "$ac_t$LD" 1>&6
+  else
+    echo "$ac_t"no 1>&6
+  fi
+
+  if test -z "$LD"; then
+    echo "$progname: error: no acceptable ld found in \$PATH" 1>&2
+    exit 1
+  fi
+fi
+
+# Check to see if it really is or isn't GNU ld.
+echo $ac_n "checking if the linker ($LD) is GNU ld... $ac_c" 1>&6
+# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+echo "$ac_t$with_gnu_ld" 1>&6
+
+# See if the linker supports building shared libraries.
+echo $ac_n "checking whether the linker ($LD) supports shared libraries... $ac_c" 1>&6
+
+allow_undefined_flag=
+archive_cmds=
+old_archive_from_new_cmds=
+export_dynamic_flag_spec=
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+hardcode_runpath_var=no
+hardcode_shlibpath_var=unsupported
+runpath_var=
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+  # See if GNU ld supports shared libraries.
+
+  case "$host_os" in
+  sunos4*)
+    ld_shlibs=yes
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  *)
+    if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      runpath_var=LD_RUN_PATH
+      hardcode_runpath_var=yes
+      ld_shlibs=yes
+    else
+      ld_shlibs=no
+    fi
+    ;;
+  esac
+
+  if test "$ld_shlibs" = yes; then
+    archive_cmds='$CC -shared ${wl}-soname $wl$soname -o $lib$libobjs$deplibs'
+    hardcode_libdir_flag_spec='${wl}-rpath $wl$libdir'
+    export_dynamic_flag_spec='${wl}-export-dynamic'
+  fi
+else
+  # PORTME fill in a description of your system's linker (not GNU ld)
+  case "$host_os" in
+  aix3*)
+    allow_undefined_flag=unsupported
+    archive_cmds='$NM$libobjs | $global_symbol_pipe | sed '"'s/.* //'"' > $lib.exp;$LD -o $objdir/$soname$libobjs -bE:$lib.exp -T512 -H512 -bM:SRE$deplibs;$AR cru $lib $objdir/$soname'
+    # Note: this linker hardcodes the directories in LIBPATH if there
+    # are no directories specified by -L.
+    hardcode_minus_L=yes
+    if test "$with_gcc" = yes && test -z "$link_static_flag"; then
+      # Neither direct hardcoding nor static linking is supported with a
+      # broken collect2.
+      hardcode_direct=unsupported
+    fi
+    ;;
+
+  aix4*)
+    allow_undefined_flag=unsupported
+    archive_cmds='$NM$libobjs | $global_symbol_pipe | sed '"'s/.* //'"' > $lib.exp;$CC -o $objdir/$soname$libobjs ${wl}-bE:$lib.exp ${wl}-bM:SRE ${wl}-bnoentry$deplibs;$AR cru $lib $objdir/$soname'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    ;;
+
+  # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+  # support.  Future versions do this automatically, but an explicit c++rt0.o
+  # doesn't break anything, and helps significantly (at the cost of a little
+  # extra space).
+  freebsd2.2*)
+    archive_cmds='$LD -Bshareable -o $lib$libobjs$deplibs /usr/lib/c++rt0.o'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  # Unfortunately, older versions of FreeBSD 2 don't have this feature.
+  freebsd2*)
+    archive_cmds='$LD -Bshareable -o $lib$libobjs$deplibs'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  # FreeBSD 3, at last, uses gcc -shared to do shared libraries.
+  freebsd3*)
+    archive_cmds='$CC -shared -o $lib$libobjs$deplibs'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  hpux9*)
+    archive_cmds='$rm $objdir/$soname;$LD -b +s +b $install_libdir -o $objdir/$soname$libobjs$deplibs;mv $objdir/$soname $lib'
+    hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    ;;
+
+  hpux10*)
+    archive_cmds='$LD -b +h $soname +s +b $install_libdir -o $lib$libobjs$deplibs'
+    hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    ;;
+
+  irix5* | irix6*)
+    archive_cmds='$LD -shared -o $lib -soname $soname -set_version $verstring$libobjs$deplibs'
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    ;;
+
+  netbsd*)
+    # Tested with NetBSD 1.2 ld
+    archive_cmds='$LD -Bshareable -o $lib$libobjs'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  openbsd*)
+    archive_cmds='$LD -Bshareable -o $lib$libobjs$deplibs'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  os2*)
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+    allow_undefined_flag=unsupported
+    archive_cmds='echo "LIBRARY $libname INITINSTANCE" > $objdir/$libname.def;echo "DESCRIPTION \"$libname\"" >> $objdir/$libname.def;echo DATA >> $objdir/$libname.def;echo " SINGLE NONSHARED" >> $objdir/$libname.def;echo EXPORTS >> $objdir/$libname.def;emxexp$libobjs >> $objdir/$libname.def;$CC -Zdll -Zcrtdll -o $lib$libobjs $objdir/$libname.def'
+    old_archive_from_new_cmds='emximp -o $objdir/$libname.a $objdir/$libname.def'
+    ;;
+
+  osf3* | osf4*)
+    allow_undefined_flag=' -expect_unresolved \*'
+    archive_cmds='$LD -shared${allow_undefined_flag} -o $lib -soname $soname -set_version $verstring$libobjs$deplibs'
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator=:
+    ;;
+
+  sco3.2v5*)
+    archive_cmds='$LD -G -o $lib$libobjs$deplibs'
+    hardcode_direct=yes
+    ;;
+
+  solaris2*)
+    archive_cmds='$LD -G -z text -h $soname -o $lib$libobjs$deplibs'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_shlibpath_var=no
+    ;;
+
+  sunos4*)
+    archive_cmds='$LD -assert pure-text -Bstatic -o $lib$libobjs'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+   uts4*)
+     archive_cmds='$LD -G -h $soname -o $lib$libobjs$deplibs'
+     hardcode_libdir_flag_spec='-L$libdir'
+     hardcode_direct=no
+     hardcode_minus_L=no
+     hardcode_shlibpath_var=no
+     ;;
+
+  *)
+    ld_shlibs=no
+    can_build_shared=no
+    ;;
+  esac
+fi
+echo "$ac_t$ld_shlibs" 1>&6
+
+if test -z "$NM"; then
+  echo $ac_n "checking for BSD-compatible nm... $ac_c" 1>&6
+  case "$NM" in
+  /*) ;; # Let the user override the test with a path.
+  *)
+    IFS="${IFS=        }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+    for ac_dir in /usr/ucb $PATH /bin; do
+      test -z "$ac_dir" && dir=.
+      if test -f $ac_dir/nm; then
+        # Check to see if the nm accepts a BSD-compat flag.
+        if ($ac_dir/nm -B /dev/null 2>&1; exit 0) | grep /dev/null >/dev/null; then
+          NM="$ac_dir/nm -B"
+        elif ($ac_dir/nm -p /dev/null 2>&1; exit 0) | grep /dev/null >/dev/null; then
+          NM="$ac_dir/nm -p"
+       else
+          NM="$ac_dir/nm"
+       fi
+        break
+      fi
+    done
+    IFS="$ac_save_ifs"
+    test -z "$NM" && NM=nm
+    ;;
+  esac
+  echo "$ac_t$NM" 1>&6
+fi
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+echo $ac_n "checking command to parse $NM output... $ac_c" 1>&6
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRSTU]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+symxfrm='\1 \1'
+
+# Define system-specific variables.
+case "$host_os" in
+aix*)
+  symcode='[BCDTU]'
+  ;;
+solaris2*)
+  symcode='[BDTU]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+  symcode='[ABCDGISTUW]'
+fi
+
+# Write the raw and C identifiers.
+global_symbol_pipe="sed -n -e 's/^.* $symcode $sympat$/$symxfrm/p'"
+
+# Check to see that the pipe works correctly.
+pipe_works=no
+$rm conftest*
+cat > conftest.c <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+echo "$progname:900: checking if global_symbol_pipe works" >&5
+if { (eval echo $progname:901: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.o; then
+  # Now try to grab the symbols.
+  nlist=conftest.nm
+  if { echo "$progname:904: eval \"$NM conftest.o | $global_symbol_pipe > $nlist\"" >&5; eval "$NM conftest.o | $global_symbol_pipe > $nlist 2>&5"; } && test -s "$nlist"; then
+
+    # Try sorting and uniquifying the output.
+    if sort "$nlist" | uniq > "$nlist"T; then
+      mv -f "$nlist"T "$nlist"
+      wcout=`wc "$nlist" 2>/dev/null`
+      count=`echo "$wcout" | sed 's/^[         ]*\([0-9][0-9]*\).*$/\1/'`
+      (test "$count" -ge 0) 2>/dev/null || count=-1
+    else
+      rm -f "$nlist"T
+      count=-1
+    fi
+
+    # Make sure that we snagged all the symbols we need.
+    if egrep ' nm_test_var$' "$nlist" >/dev/null; then
+      if egrep ' nm_test_func$' "$nlist" >/dev/null; then
+       cat <<EOF > conftest.c
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+        # Now generate the symbol file.
+        sed 's/^.* \(.*\)$/extern char \1;/' < "$nlist" >> conftest.c
+
+       cat <<EOF >> conftest.c
+#if defined (__STDC__) && __STDC__
+# define __ptr_t void *
+#else
+# define __ptr_t char *
+#endif
+
+/* The number of symbols in dld_preloaded_symbols, -1 if unsorted. */
+int dld_preloaded_symbol_count = $count;
+
+/* The mapping between symbol names and symbols. */
+struct {
+  char *name;
+  __ptr_t address;
+}
+dld_preloaded_symbols[] =
+{
+EOF
+        sed 's/^\(.*\) \(.*\)$/  {"\1", \&\2},/' < "$nlist" >> conftest.c
+        cat <<\EOF >> conftest.c
+  {0},
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+        # Now try linking the two files.
+        mv conftest.o conftestm.o
+       save_LIBS="$LIBS"
+       save_CFLAGS="$CFLAGS"
+        LIBS='conftestm.o'
+       CFLAGS="$CFLAGS$no_builtin_flag"
+        if { (eval echo $progname:962: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+          pipe_works=yes
+        else
+          echo "$progname: failed program was:" >&5
+          cat conftest.c >&5
+        fi
+        LIBS="$save_LIBS"
+      else
+        echo "cannot find nm_test_func in $nlist" >&5
+      fi
+    else
+      echo "cannot find nm_test_var in $nlist" >&5
+    fi
+  else
+    echo "cannot run $global_symbol_pipe" >&5
+  fi
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.c >&5
+fi
+$rm conftest*
+
+# Don't use the global_symbol_pipe unless it works.
+echo "$ac_t$pipe_works" 1>&6
+test "$pipe_works" = yes || global_symbol_pipe=
+
+# Check hardcoding attributes.
+echo $ac_n "checking how to hardcode library paths into programs... $ac_c" 1>&6
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" || \
+   test "$hardcode_runpath_var" = yes; then
+
+  # We can hardcode non-existant directories.
+  if test "$hardcode_direct" != no && \
+     test "$hardcode_minus_L" != no && \
+     test "$hardcode_shlibpath_var" != no; then
+
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action=immediate
+  fi
+elif test "$hardcode_direct" != yes && \
+     test "$hardcode_minus_L" != yes && \
+     test "$hardcode_shlibpath_var" != yes; then
+  # We can't hardcode anything.
+  hardcode_action=unsupported
+else
+  # We can only hardcode existing directories.
+  hardcode_action=relink
+fi
+echo "$ac_t$hardcode_action" 1>&6
+test "$hardcode_action" = unsupported && can_build_shared=no
+
+
+reload_flag=
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+echo $ac_n "checking for $LD option to reload object files... $ac_c" 1>&6
+# PORTME Some linker may need a different reload flag.
+reload_flag='-r'
+echo "$ac_t$reload_flag"
+test -n "$reload_flag" && reload_flag=" $reload_flag"
+
+# PORTME Fill in your ld.so characteristics
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+postinstall_cmds=
+finish_cmds=
+shlibpath_var=
+version_type=none
+dynamic_linker="$host_os ld.so"
+
+echo $ac_n "checking dynamic linker characteristics... $ac_c" 1>&6
+case "$host_os" in
+aix3* | aix4*)
+  version_type=linux
+  library_names_spec='$libname.so.$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX has no versioning support, so we append a major version to the name.
+  soname_spec='$libname.so.$major'
+  ;;
+
+freebsd2* | freebsd3*)
+  version_type=sunos
+  library_names_spec='$libname.so.$versuffix $libname.so'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+gnu*)
+  version_type=sunos
+  library_names_spec='$libname.so.$versuffix'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+hpux9* | hpux10*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  dynamic_linker="$host_os dld.sl"
+  version_type=sunos
+  shlibpath_var=SHLIB_PATH
+  library_names_spec='$libname.sl.$versuffix $libname.sl.$major $libname.sl'
+  soname_spec='$libname.sl.$major'
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+irix5* | irix6*)
+  version_type=osf
+  soname_spec='$libname.so'
+  library_names_spec='$libname.so.$versuffix $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+  version_type=linux
+  library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so'
+  soname_spec='$libname.so.$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+
+  if test -f /lib/ld.so.1; then
+    dynamic_linker='GNU ld.so'
+  else
+    # Only the GNU ld.so supports shared libraries on MkLinux.
+    case "$host_cpu" in
+    powerpc*) dynamic_linker=no ;;
+    *) dynamic_linker='Linux ld.so' ;;
+    esac
+  fi
+  ;;
+
+netbsd* | openbsd*)
+  version_type=sunos
+  library_names_spec='$libname.so.$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+os2*)
+  version_type=none
+  libname_spec='$name'
+  library_names_spec='$libname.dll $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4*)
+  version_type=osf
+  soname_spec='$libname.so'
+  library_names_spec='$libname.so.$versuffix $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+sco3.2v5*)
+  version_type=osf
+  soname_spec='$libname.so.$major'
+  library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+solaris2*)
+  version_type=linux
+  library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so'
+  soname_spec='$libname.so.$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='$libname.so.$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so'
+  soname_spec='$libname.so.$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+echo "$ac_t$dynamic_linker"
+test "$dynamic_linker" = no && can_build_shared=no
+
+# FIXME add checks for striplib and old_striplib here.
+# strip -x works for most platforms, though not for static libraries on NetBSD
+# HP-UX requires "-r" for library stripping
+striplib=
+old_striplib=
+
+# Report the final consequences.
+echo "checking if libtool supports shared libraries... $can_build_shared" 1>&6
+
+echo $ac_n "checking whether to build shared libraries... $ac_c" 1>&6
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix*)
+  test "$enable_shared" = yes && enable_static=no
+  if test -n "$RANLIB"; then
+    archive_cmds="$archive_cmds;\$RANLIB \$lib"
+    postinstall_cmds='$RANLIB $lib'
+  fi
+  ;;
+esac
+
+echo "$ac_t$enable_shared" 1>&6
+
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+
+echo "checking whether to build static libraries... $enable_static" 1>&6
+
+echo $ac_n "checking for objdir... $ac_c" 1>&6
+rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+echo "$ac_t$objdir" 1>&6
+
+# Now quote all the things that may contain metacharacters.
+for var in old_CC old_CFLAGS old_CPPFLAGS old_LD old_NM old_RANLIB \
+  old_LN_S AR CC LD LN_S NM reload_flag reload_cmds wl pic_flag \
+  link_static_flag no_builtin_flag export_dynamic_flag_spec \
+  profile_flag_pattern libname_spec library_names_spec soname_spec RANLIB \
+  old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \
+  archive_cmds postinstall_cmds \
+  allow_undefined_flag finish_cmds global_symbol_pipe \
+  striplib old_striplib \
+  hardcode_libdir_flag_spec hardcode_libdir_separator; do
+
+  case "$var" in
+  reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \
+  old_postinstall_cmds | archive_cmds | postinstall_cmds | finish_cmds)
+    # Double-quote double-evaled strings.
+    eval "$var=\`echo \"\$$var\" | sed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\"\`"
+    ;;
+  *)
+    eval "$var=\`echo \"\$$var\" | sed \"\$sed_quote_subst\"\`"
+    ;;
+  esac
+done
+
+ofile=libtool
+trap "$rm $ofile; exit 1" 1 2 15
+echo creating $ofile
+$rm $ofile
+cat <<EOF > $ofile
+#! /bin/sh
+
+# libtool - Provide generalized library-building support services.
+#
+# Generated automatically by $PROGRAM - GNU $PACKAGE $VERSION
+# This program was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# CC="$old_CC" CFLAGS="$old_CFLAGS" CPPFLAGS="$old_CPPFLAGS" \\
+# LD="$old_LD" NM="$old_NM" RANLIB="$old_RANLIB" LN_S="$old_LN_S" \\
+#   $0$ltconfig_args
+#
+# Compiler and other test output produced by $progname, useful for
+# debugging $progname, is in ./config.log if it exists.
+
+# The version of $progname that generated this script.
+LTCONFIG_VERSION="$VERSION"
+
+# Shell to use when invoking shell scripts.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Whether or not to build libtool libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build old-style libraries.
+build_old_libs=$enable_static
+
+# The host system.
+host_alias="$host_alias"
+host="$host"
+
+# The archiver.
+AR="$AR"
+
+# The default C compiler.
+CC="$CC"
+
+# The linker used to build libraries.
+LD="$LD"
+
+# Whether we need hard or soft links.
+LN_S="$LN_S"
+
+# A BSD-compatible nm program.
+NM="$NM"
+
+# The name of the directory that contains temporary libtool files.
+objdir="$objdir"
+
+# How to create reloadable object files.
+reload_flag="$reload_flag"
+reload_cmds="$reload_cmds"
+
+# How to pass a linker flag through the compiler.
+wl="$wl"
+
+# Additional compiler flags for building library objects.
+pic_flag="$pic_flag"
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag="$link_static_flag"
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag="$no_builtin_flag"
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec="$export_dynamic_flag_spec"
+
+# Pattern to match compiler flags for creating libNAME_p libraries:
+profile_flag_pattern="$profile_flag_pattern"
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec="$libname_spec"
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec="$library_names_spec"
+
+# The coded name of the library, if different from the real name.
+soname_spec="$soname_spec"
+
+# Commands used to build and install an old-style archive.
+RANLIB="$RANLIB"
+old_archive_cmds="$old_archive_cmds"
+old_postinstall_cmds="$old_postinstall_cmds"
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds="$old_archive_from_new_cmds"
+
+# Commands used to build and install a shared archive.
+archive_cmds="$archive_cmds"
+postinstall_cmds="$postinstall_cmds"
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag="$allow_undefined_flag"
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds="$finish_cmds"
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe="$global_symbol_pipe"
+
+# How to strip a library file.
+striplib="$striplib"
+old_striplib="$old_striplib"
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec="$hardcode_libdir_flag_spec"
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator="$hardcode_libdir_separator"
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to yes if using RUNPATH_VAR=DIR during linking hardcodes DIR into the
+# resulting binary.
+hardcode_runpath_var=$hardcode_runpath_var
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+EOF
+
+case "$host_os" in
+aix*)
+  cat <<\EOF >> $ofile
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "${COLLECT_NAMES+set}" != set; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+
+EOF
+  ;;
+esac
+
+# Detect if we are using a relative or absolute path to ltmain.sh.
+case "$ltmain" in
+/*) cat <<EOF >> $ofile
+# Execute the libtool backend.
+. $ltmain
+EOF
+  ;;
+*) cat <<EOF >> $ofile
+# Find the path to this script.
+thisdir=\`echo "\$0" | sed -e 's%/[^/]*\$%%'\`
+test "X\$0" = "X\$thisdir" && thisdir=.
+
+# Execute the libtool backend.
+. \$thisdir/$ltmain
+EOF
+  ;;
+esac
+
+echo 'exit 1' >> $ofile
+
+chmod +x $ofile
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/ltmain.sh b/ltmain.sh
new file mode 100644 (file)
index 0000000..cb46c84
--- /dev/null
+++ b/ltmain.sh
@@ -0,0 +1,2372 @@
+# ltmain.sh - Provide generalized library-building support services.
+# Generated automatically from ltmain.in by configure.
+# Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+# Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+#FIXME: echo=echo
+echo='printf %s\n'
+if test "X`$echo '\t'`" = 'X\t'; then :
+else
+  # The Solaris and AIX default echo program unquotes backslashes.
+  # This makes it impossible to quote backslashes using
+  #   echo "$something" | sed 's/\\/\\\\/g'
+  # So, we emulate echo with printf '%s\n'
+  echo='printf %s\n'
+  if test "X`$echo '\t'`" = 'X\t'; then :
+  else
+    # Oops.  We have no working printf.  Try to find a not-so-buggy echo.
+    echo=echo
+    IFS="${IFS=        }"; save_ifs="$IFS"; IFS="${IFS}:"
+    save_PATH="$PATH"
+    PATH="$PATH":/usr/ucb
+    for dir in $PATH; do
+      if test -f $dir/echo && test "X`$dir/echo '\t'`" = 'X\t'; then
+        echo="$dir/echo"
+        break
+      fi
+    done
+    IFS="$save_ifs"
+    PATH="$save_PATH"
+  fi
+fi
+
+# The name of this program.
+progname=`$echo "$0" | sed 's%^.*/%%'`
+
+# Constants.
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION=1.0f
+
+default_mode=
+help="Try \`$progname --help' for more information."
+magic="%%%MAGIC variable%%%"
+mkdir="mkdir"
+mv="mv -f"
+rm="rm -f"
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s/\([\\"$\\\\]\)/\\\1/g'
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+
+if test "$LTCONFIG_VERSION" != "$VERSION"; then
+  $echo "$progname: ltconfig version \`$LTCONFIG_VERSION' does not match $PROGRAM version \`$VERSION'" 1>&2
+  $echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+  exit 1
+fi
+
+if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+  $echo "$progname: not configured to build any kind of library" 1>&2
+  $echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+  exit 1
+fi
+
+# Global variables.
+mode=$default_mode
+nonopt=
+prev=
+prevopt=
+run=
+show="$echo"
+show_help=
+execute_dlfiles=
+
+# Parse our command line options once, thoroughly.
+while test $# -gt 0
+do
+  arg="$1"
+  shift
+
+  case "$arg" in
+  -*=*) optarg=`$echo "$arg" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$prev"; then
+    case "$prev" in
+    execute_dlfiles)
+      eval "$prev=\"\$$prev \$arg\""
+      ;;
+    *)
+      eval "$prev=\$arg"
+      ;;
+    esac
+
+    prev=
+    prevopt=
+    continue
+  fi
+
+  # Have we seen a non-optional argument yet?
+  case "$arg" in
+  --help)
+    show_help=yes
+    ;;
+
+  --version)
+    $echo "$PROGRAM (GNU $PACKAGE) $VERSION"
+    exit 0
+    ;;
+
+  --dry-run | -n)
+    run=:
+    ;;
+
+  --features)
+    $echo "host: $host"
+    if test "$build_libtool_libs" = yes; then
+      $echo "enable shared libraries"
+    else
+      $echo "disable shared libraries"
+    fi
+    if test "$build_old_libs" = yes; then
+      $echo "enable static libraries"
+    else
+      $echo "disable static libraries"
+    fi
+    exit 0
+    ;;
+
+  --finish) mode="finish" ;;
+
+  --mode) prevopt="--mode" prev=mode ;;
+  --mode=*) mode="$optarg" ;;
+
+  --quiet | --silent)
+    show=:
+    ;;
+
+  -dlopen)
+    prevopt="-dlopen"
+    prev=execute_dlfiles
+    ;;
+
+  -*)
+    $echo "$progname: unrecognized option \`$arg'" 1>&2
+    $echo "$help" 1>&2
+    exit 1
+    ;;
+
+  *)
+    nonopt="$arg"
+    break
+    ;;
+  esac
+done
+
+if test -n "$prevopt"; then
+  $echo "$progname: option \`$prevopt' requires an argument" 1>&2
+  $echo "$help" 1>&2
+  exit 1
+fi
+
+if test -z "$show_help"; then
+
+  # Infer the operation mode.
+  if test -z "$mode"; then
+    case "$nonopt" in
+    *cc | *++)
+      mode=link
+      for arg
+      do
+        case "$arg" in
+        -c)
+           mode=compile
+           break
+           ;;
+        esac
+      done
+      ;;
+    *db | *dbx)
+      mode=execute
+      ;;
+    *install*|cp)
+      mode=install
+      ;;
+    *rm)
+      mode=uninstall
+      ;;
+    *)
+      # If we have no mode, but dlfiles were specified, then do execute mode.
+      test -n "$execute_dlfiles" && mode=execute
+
+      # Just use the default operation mode.
+      if test -z "$mode"; then
+        if test -n "$nonopt"; then
+          $echo "$progname: warning: cannot infer operation mode from \`$nonopt'" 1>&2
+        else
+          $echo "$progname: warning: cannot infer operation mode without MODE-ARGS" 1>&2
+        fi
+      fi
+      ;;
+    esac
+  fi
+
+  # Only execute mode is allowed to have -dlopen flags.
+  if test -n "$execute_dlfiles" && test "$mode" != execute; then
+    $echo "$progname: unrecognized option \`-dlopen'" 1>&2
+    $echo "$help" 1>&2
+    exit 1
+  fi
+
+  # Change the help message to a mode-specific one.
+  generic_help="$help"
+  help="Try \`$progname --help --mode=$mode' for more information."
+
+  # These modes are in order of execution frequency so that they run quickly.
+  case "$mode" in
+  # libtool compile mode
+  compile)
+    progname="$progname: compile"
+    # Get the compilation command and the source file.
+    base_compile=
+    lastarg=
+    srcfile="$nonopt"
+    suppress_output=
+
+    for arg
+    do
+      # The only flag that cannot be specified is the output filename.
+      if test "X$arg" = "X-o"; then
+       $echo "$progname: you cannot specify the output filename with \`-o'" 1>&2
+       $echo "$help" 1>&2
+       exit 1
+      fi
+
+      # Accept the current argument as the source file.
+      lastarg="$srcfile"
+      srcfile="$arg"
+
+      # Aesthetically quote the previous argument.
+
+      # Backslashify any backslashes, double quotes, and dollar signs.
+      # These are the only characters that are still specially
+      # interpreted inside of double-quoted scrings.
+      lastarg=`$echo "$lastarg" | sed "$sed_quote_subst"`
+
+      # Double-quote args containing other shell metacharacters.
+      # Many Bourne shells cannot handle close brackets correctly in scan
+      # sets, so we specify it separately.
+      case "$lastarg" in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*)
+       lastarg="\"$lastarg\""
+       ;;
+      esac
+
+      # Add the previous argument to base_compile.
+      if test -z "$base_compile"; then
+       base_compile="$lastarg"
+      else
+       base_compile="$base_compile $lastarg"
+      fi
+    done
+
+    # Get the name of the library object.
+    libobj=`$echo "$srcfile" | sed -e 's%^.*/%%'`
+
+    # Recognize several different file suffixes.
+    xform='[cCFSfm]'
+    case "$libobj" in
+    *.c++) xform=c++ ;;
+    *.cc) xform=cc ;;
+    *.cpp) xform=cpp ;;
+    *.cxx) xform=cxx ;;
+    *.f90) xform=f90 ;;
+    *.for) xform=for ;;
+    esac
+
+    libobj=`$echo "$libobj" | sed -e "s/\.$xform$/.lo/"`
+
+    case "$libobj" in
+    *.lo) obj=`$echo "$libobj" | sed -e 's/\.lo$/.o/'` ;;
+    *)
+      $echo "$progname: cannot determine name of library object from \`$srcfile'" 1>&2
+      exit 1
+      ;;
+    esac
+
+    if test -z "$base_compile"; then
+      $echo "$progname: you must specify a compilation command" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    # Delete any leftover library objects.
+    if test "$build_old_libs" = yes; then
+      $run $rm $obj $libobj
+      trap "$run $rm $obj $libobj; exit 1" 1 2 15
+    else
+      $run $rm $libobj
+      trap "$run $rm $libobj; exit 1" 1 2 15
+    fi
+
+    # Only build a PIC object if we are building libtool libraries.
+    if test "$build_libtool_libs" = yes; then
+      # Without this assignment, base_compile gets emptied.
+      fbsd_hideous_sh_bug=$base_compile
+
+      # All platforms use -DPIC, to notify preprocessed assembler code.
+      $show "$base_compile$pic_flag -DPIC $srcfile"
+      if $run eval "$base_compile\$pic_flag -DPIC \$srcfile"; then :
+      else
+        test -n "$obj" && $run $rm $obj
+        exit 1
+      fi
+
+      # If we have no pic_flag, then copy the object into place and finish.
+      if test -z "$pic_flag"; then
+        $show "$LN_S $obj $libobj"
+        $run $LN_S $obj $libobj
+        exit $?
+      fi
+
+      # Just move the object, then go on to compile the next one
+      $show "$mv $obj $libobj"
+      $run $mv $obj $libobj || exit 1
+
+      # Allow error messages only from the first compilation.
+      suppress_output=' >/dev/null 2>&1'
+    fi
+
+    # Only build a position-dependent object if we build old libraries.
+    if test "$build_old_libs" = yes; then
+      # Suppress compiler output if we already did a PIC compilation.
+      $show "$base_compile $srcfile$suppress_output"
+      if $run eval "$base_compile \$srcfile$suppress_output"; then :
+      else
+        $run $rm $obj $libobj
+        exit 1
+      fi
+    fi
+
+    # Create an invalid libtool object if no PIC, so that we don't accidentally
+    # link it into a program.
+    if test "$build_libtool_libs" != yes; then
+      $show "$echo timestamp > $libobj"
+      $run eval "\$echo timestamp > \$libobj" || exit $?
+    fi
+
+    exit 0
+    ;;
+
+  # libtool link mode
+  link)
+    progname="$progname: link"
+    CC="$nonopt"
+    allow_undefined=no
+    compile_command="$CC"
+    finalize_command="$CC"
+
+    compile_shlibpath=
+    finalize_shlibpath=
+    deplibs=
+    dlfiles=
+    dlprefiles=
+    export_dynamic=no
+    hardcode_libdirs=
+    libobjs=
+    link_against_libtool_libs=
+    ltlibs=
+    objs=
+    prev=
+    prevarg=
+    rpath=
+    perm_rpath=
+    temp_rpath=
+    vinfo=
+
+    # We need to know -static, to get the right output filenames.
+    for arg
+    do
+      case "$arg" in
+      -all-static | -static)
+        if test "X$arg" = "X-all-static" && test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+           $echo "$progname: warning: complete static linking is impossible in this configuration" 1>&2
+        fi
+        build_libtool_libs=no
+       build_old_libs=yes
+        break
+        ;;
+      esac
+    done
+
+    # See if our shared archives depend on static archives.
+    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+    # Go through the arguments, transforming them on the way.
+    for arg
+    do
+      # If the previous option needs an argument, assign it.
+      if test -n "$prev"; then
+        case "$prev" in
+        output)
+          compile_command="$compile_command @OUTPUT@"
+          finalize_command="$finalize_command @OUTPUT@"
+          ;;
+        esac
+
+        case "$prev" in
+        dlfiles|dlprefiles)
+          case "$arg" in
+          *.la | *.lo) ;;  # We handle these cases below.
+          *)
+            dlprefiles="$dlprefiles $arg"
+            test "$prev" = dlfiles && dlfiles="$dlfiles $arg"
+            prev=
+            ;;
+          esac
+          ;;
+        rpath)
+          rpath="$rpath $arg"
+         prev=
+         continue
+         ;;
+        *)
+          eval "$prev=\"\$arg\""
+          prev=
+          continue
+          ;;
+        esac
+      fi
+
+      prevarg="$arg"
+
+      case "$arg" in
+      -all-static)
+       if test -n "$link_static_flag"; then
+          compile_command="$compile_command $link_static_flag"
+         finalize_command="$finalize_command $link_static_flag"
+        fi
+        continue
+       ;;
+
+      -allow-undefined)
+       allow_undefined=yes
+       continue
+       ;;
+
+      -dlopen)
+        prev=dlfiles
+        continue
+        ;;
+
+      -dlpreopen)
+        prev=dlprefiles
+        continue
+        ;;
+
+      -export-dynamic)
+        if test "$export_dynamic" != yes; then
+          export_dynamic=yes
+         if test -n "$export_dynamic_flag_spec"; then
+           arg=`eval \\$echo "$export_dynamic_flag_spec"`
+         else
+           arg=
+         fi
+
+          # Add the symbol object into the linking commands.
+         compile_command="$compile_command @SYMFILE@"
+         finalize_command="$finalize_command @SYMFILE@"
+        fi
+        ;;
+
+      -L*)
+        dir=`$echo "$arg" | sed 's%^-L\(.*\)$%\1%'`
+        case "$dir" in
+        /*)
+         # Add the corresponding hardcode_libdir_flag, if it is not identical.
+          ;;
+        *)
+          $echo "$progname: \`-L$dir' cannot specify a relative directory" 1>&2
+          exit 1
+          ;;
+        esac
+        deplibs="$deplibs $arg"
+        ;;
+
+      -l*) deplibs="$deplibs $arg" ;;
+
+      -o) prev=output ;;
+
+      -rpath)
+        prev=rpath
+        continue
+        ;;
+
+      -static)
+       # If we have no pic_flag, then this is the same as -all-static.
+       if test -z "$pic_flag" && test -n "$link_static_flag"; then
+          compile_command="$compile_command $link_static_flag"
+         finalize_command="$finalize_command $link_static_flag"
+        fi
+       continue
+       ;;
+
+      -version-info)
+        prev=vinfo
+        continue
+        ;;
+
+      # Some other compiler flag.
+      -* | +*)
+       # Unknown arguments in both finalize_command and compile_command need
+       # to be aesthetically quoted because they are evaled later.
+       arg=`$echo "$arg" | sed "$sed_quote_subst"`
+       case "$arg" in
+       *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \   ]*|*]*)
+         arg="\"$arg\""
+         ;;
+       esac
+        ;;
+
+      *.o | *.a)
+        # A standard object.
+        objs="$objs $arg"
+        ;;
+
+      *.lo)
+        # A library object.
+       if test "$prev" = dlfiles; then
+         dlfiles="$dlfiles $arg"
+         if test "$build_libtool_libs" = yes; then
+           prev=
+           continue
+         else
+           # If libtool objects are unsupported, then we need to preload.
+           prev=dlprefiles
+         fi
+       fi
+
+       if test "$prev" = dlprefiles; then
+         # Preload the old-style object.
+         dlprefiles="$dlprefiles "`$echo "$arg" | sed 's/\.lo$/\.o/'`
+         prev=
+       fi
+       libobjs="$libobjs $arg"
+        ;;
+
+      *.la)
+        # A libtool-controlled library.
+
+        dlname=
+        libdir=
+        library_names=
+        old_library=
+
+        # Check to see that this really is a libtool archive.
+        if egrep '^# Generated by ltmain.sh' $arg >/dev/null 2>&1; then :
+        else
+          $echo "$progname: \`$arg' is not a valid libtool archive" 1>&2
+          exit 1
+        fi
+
+        # If there is no directory component, then add one.
+        case "$arg" in
+        */*) . $arg ;;
+        *) . ./$arg ;;
+        esac
+
+        if test -z "$libdir"; then
+          $echo "$progname: \`$arg' contains no -rpath information" 1>&2
+          exit 1
+        fi
+
+        # Get the name of the library we link against.
+        linklib=
+        for l in $old_library $library_names; do
+          linklib="$l"
+        done
+
+        if test -z "$linklib"; then
+          $echo "$progname: cannot find name of link library for \`$arg'" 1>&2
+          exit 1
+        fi
+
+        # Find the relevant object directory and library name.
+        name=`$echo "$arg" | sed -e 's%^.*/%%' -e 's/\.la$//' -e 's/^lib//'`
+        dir=`$echo "$arg" | sed 's%/[^/]*$%%'`
+        if test "X$dir" = "X$arg"; then
+          dir="$objdir"
+        else
+          dir="$dir/$objdir"
+        fi
+
+        # This library was specified with -dlopen.
+        if test "$prev" = dlfiles; then
+          dlfiles="$dlfiles $arg"
+          if test -z "$dlname"; then
+            # If there is no dlname, we need to preload.
+            prev=dlprefiles
+          else
+            # We should not create a dependency on this library.
+            prev=
+            continue
+          fi
+        fi
+
+        # The library was specified with -dlpreopen.
+        if test "$prev" = dlprefiles; then
+          # Prefer using a static library (so that no silly _DYNAMIC symbols
+          # are required to link).
+          if test -n "$old_library"; then
+            dlprefiles="$dlprefiles $dir/$old_library"
+          else
+            dlprefiles="$dlprefiles $dir/$linklib"
+          fi
+          prev=
+        fi
+
+        if test "$build_libtool_libs" = yes && test -n "$library_names"; then
+          link_against_libtool_libs="$link_against_libtool_libs $arg"
+          if test -n "$shlibpath_var"; then
+            # Make sure the rpath contains only unique directories.
+            case "$temp_rpath " in
+            *" $dir "*) ;;
+            *) temp_rpath="$temp_rpath $dir" ;;
+            esac
+          fi
+
+         # This is the magic to use -rpath.
+          if test -n "$hardcode_libdir_flag_spec"; then
+            if test -n "$hardcode_libdir_separator"; then
+              if test -z "$hardcode_libdirs"; then
+                # Put the magic libdir with the hardcode flag.
+                hardcode_libdirs="$libdir"
+                libdir="@HARDCODE_LIBDIRS@"
+              else
+                # Just accumulate the unique libdirs.
+               case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+               *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+                 ;;
+               *)
+                 hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+                 ;;
+               esac
+                libdir=
+              fi
+            fi
+
+            if test -n "$libdir"; then
+              flag=`eval \\$echo \"$hardcode_libdir_flag_spec\"`
+
+              compile_command="$compile_command $flag"
+              finalize_command="$finalize_command $flag"
+            fi
+          elif test "$hardcode_runpath_var" = yes; then
+            # Do the same for the permanent run path.
+            case "$perm_rpath " in
+            *" $libdir "*) ;;
+            *) perm_rpath="$perm_rpath $libdir" ;;
+            esac
+          fi
+
+
+          case "$hardcode_action" in
+          immediate)
+            if test "$hardcode_direct" = no; then
+              compile_command="$compile_command $dir/$linklib"
+            elif test "$hardcode_minus_L" = no; then
+              compile_command="$compile_command -L$dir -l$name"
+            elif test "$hardcode_shlibpath_var" = no; then
+              compile_shlibpath="$compile_shlibpath$dir:"
+              compile_command="$compile_command -l$name"
+            fi
+            ;;
+
+          relink)
+            # We need an absolute path.
+            case "$dir" in
+            /*) ;;
+            *)
+              absdir=`cd "$dir" && pwd`
+              if test -z "$absdir"; then
+                $echo "$progname: cannot determine absolute directory name of \`$dir'" 1>&2
+                exit 1
+              fi
+              dir="$absdir"
+              ;;
+            esac
+
+            if test "$hardcode_direct" = yes; then
+              compile_command="$compile_command $dir/$linklib"
+            elif test "$hardcode_minus_L" = yes; then
+              compile_command="$compile_command -L$dir -l$name"
+            elif test "$hardcode_shlibpath_var" = yes; then
+              compile_shlibpath="$compile_shlibpath$dir:"
+              compile_command="$compile_command -l$name"
+            fi
+            ;;
+
+          *)
+            $echo "$progname: \`$hardcode_action' is an unknown hardcode action" 1>&2
+            exit 1
+            ;;
+          esac
+
+          # Finalize command for both is simple: just hardcode it.
+          if test "$hardcode_direct" = yes; then
+            finalize_command="$finalize_command $libdir/$linklib"
+          elif test "$hardcode_minus_L" = yes; then
+            finalize_command="$finalize_command -L$libdir -l$name"
+          elif test "$hardcode_shlibpath_var" = yes; then
+            finalize_shlibpath="$finalize_shlibpath$libdir:"
+            finalize_command="$finalize_command -l$name"
+          else
+            # We can't seem to hardcode it, guess we'll fake it.
+            finalize_command="$finalize_command -L$libdir -l$name"
+          fi
+        else
+          # Transform directly to old archives if we don't build new libraries.
+          if test -n "$pic_flag" && test -z "$old_library"; then
+            $echo "$progname: cannot find static library for \`$arg'" 1>&2
+            exit 1
+          fi
+
+         # Here we assume that one of hardcode_direct or hardcode_minus_L
+         # is not unsupported.  This is valid on all known static and
+         # shared platforms.
+         if test "$hardcode_direct" != unsupported; then
+           test -n "$old_library" && linklib="$old_library"
+           compile_command="$compile_command $dir/$linklib"
+           finalize_command="$finalize_command $dir/$linklib"
+         else
+           compile_command="$compile_command -L$dir -l$name"
+           finalize_command="$finalize_command -L$dir -l$name"
+         fi
+        fi
+       continue
+        ;;
+
+      # Some other compiler argument.
+      *)
+       # Unknown arguments in both finalize_command and compile_command need
+       # to be aesthetically quoted because they are evaled later.
+       arg=`$echo "$arg" | sed "$sed_quote_subst"`
+       case "$arg" in
+       *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \   ]*|*]*)
+         arg="\"$arg\""
+         ;;
+       esac
+        ;;
+      esac
+
+      # Now actually substitute the argument into the commands.
+      compile_command="$compile_command $arg"
+      finalize_command="$finalize_command $arg"
+    done
+
+    if test -n "$prev"; then
+      $echo "$progname: the \`$prevarg' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    oldlib=
+    oldobjs=
+    case "$output" in
+    "")
+      $echo "$progname: you must specify an output file" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+      ;;
+
+    */*)
+      $echo "$progname: output file \`$output' must have no directory components" 1>&2
+      exit 1
+      ;;
+
+    *.la)
+      # Make sure we only generate libraries of the form `libNAME.la'.
+      case "$output" in
+      lib*) ;;
+      *)
+       $echo "$progname: libtool library \`$arg' must begin with \`lib'" 1>&2
+       $echo "$help" 1>&2
+       exit 1
+       ;;
+      esac
+
+      name=`$echo "$output" | sed -e 's/\.la$//' -e 's/^lib//'`
+      libname=`eval \\$echo \"$libname_spec\"`
+
+      # All the library-specific variables (install_libdir is set above).
+      library_names=
+      old_library=
+      dlname=
+      current=0
+      revision=0
+      age=0
+
+      if test -n "$objs"; then
+        $echo "$progname: cannot build libtool library \`$output' from non-libtool objects:$objs" 2>&1
+        exit 1
+      fi
+
+      # How the heck are we supposed to write a wrapper for a shared library?
+      if test -n "$link_against_libtool_libs"; then
+        $echo "$progname: libtool library \`$output' may not depend on uninstalled libraries:$link_against_libtool_libs" 1>&2
+        exit 1
+      fi
+
+      # Add libc to deplibs on all systems.
+      deplibs="$deplibs -lc"
+
+      if test -n "$dlfiles$dlprefiles"; then
+        $echo "$progname: warning: \`-dlopen' is ignored while creating libtool libraries" 1>&2
+        # Nullify the symbol file.
+        compile_command=`$echo "$compile_command" | sed "s% @SYMFILE@%%"`
+        finalize_command=`$echo "$finalize_command" | sed "s% @SYMFILE@%%"`
+      fi
+
+      if test -z "$rpath"; then
+        $echo "$progname: you must specify an installation directory with \`-rpath'" 1>&2
+       $echo "$help" 1>&2
+        exit 1
+      fi
+
+      set dummy $rpath
+      if test $# -gt 2; then
+       $echo "$progname: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
+      fi
+      install_libdir="$2"
+
+      # Parse the version information argument.
+      IFS="${IFS=      }"; save_ifs="$IFS"; IFS=':'
+      set dummy $vinfo
+      IFS="$save_ifs"
+
+      if test -n "$5"; then
+        $echo "$progname: too many parameters to \`-version-info'" 1>&2
+        $echo "$help" 1>&2
+        exit 1
+      fi
+
+      test -n "$2" && current="$2"
+      test -n "$3" && revision="$3"
+      test -n "$4" && age="$4"
+
+      # Check that each of the things are valid numbers.
+      case "$current" in
+      0 | [1-9] | [1-9][0-9]*) ;;
+      *)
+        $echo "$progname: CURRENT \`$current' is not a nonnegative integer" 1>&2
+        $echo "$progname: \`$vinfo' is not valid version information" 1>&2
+        exit 1
+        ;;
+      esac
+
+      case "$revision" in
+      0 | [1-9] | [1-9][0-9]*) ;;
+      *)
+        $echo "$progname: REVISION \`$revision' is not a nonnegative integer" 1>&2
+        $echo "$progname: \`$vinfo' is not valid version information" 1>&2
+        exit 1
+        ;;
+      esac
+
+      case "$age" in
+      0 | [1-9] | [1-9][0-9]*) ;;
+      *)
+        $echo "$progname: AGE \`$age' is not a nonnegative integer" 1>&2
+        $echo "$progname: \`$vinfo' is not valid version information" 1>&2
+        exit 1
+        ;;
+      esac
+
+      if test $age -gt $current; then
+        $echo "$progname: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
+        $echo "$progname: \`$vinfo' is not valid version information" 1>&2
+        exit 1
+      fi
+
+      # Calculate the version variables.
+      version_vars="version_type current age revision"
+      case "$version_type" in
+      none) ;;
+
+      linux)
+        version_vars="$version_vars major versuffix"
+        major=`expr $current - $age`
+        versuffix="$major.$age.$revision"
+        ;;
+
+      osf)
+        version_vars="$version_vars versuffix verstring"
+        major=`expr $current - $age`
+        versuffix="$current.$age.$revision"
+        verstring="$versuffix"
+
+        # Add in all the interfaces that we are compatible with.
+        loop=$age
+        while test $loop != 0; do
+          iface=`expr $current - $loop`
+          loop=`expr $loop - 1`
+          verstring="$verstring:${iface}.0"
+        done
+
+        # Make executables depend on our current version.
+        verstring="$verstring:${current}.0"
+        ;;
+
+      sunos)
+        version_vars="$version_vars major versuffix"
+        major="$current"
+        versuffix="$current.$revision"
+        ;;
+
+      *)
+        $echo "$progname: unknown library version type \`$version_type'" 1>&2
+        $echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+        exit 1
+        ;;
+      esac
+
+      # Create the output directory, or remove our outputs if we need to.
+      if test -d $objdir; then
+        $show "$rm $objdir/$output $objdir/$libname.*"
+        $run $rm $objdir/$output $objdir/$libname.*
+      else
+        $show "$mkdir $objdir"
+        $run $mkdir $objdir
+       status=$?
+       if test $status -eq 0 || test -d $objdir; then :
+       else
+         exit $status
+       fi
+      fi
+
+      # Check to see if the archive will have undefined symbols.
+      if test "$allow_undefined" = yes; then
+        if test "$allow_undefined_flag" = unsupported; then
+          $echo "$progname: warning: undefined symbols not allowed in $host shared libraries" 1>&2
+          build_libtool_libs=no
+         build_old_libs=yes
+        fi
+      else
+        # Clear the flag.
+        allow_undefined_flag=
+      fi
+
+      if test "$build_libtool_libs" = yes; then
+        # Get the real and link names of the library.
+        library_names=`eval \\$echo \"$library_names_spec\"`
+        set dummy $library_names
+        realname="$2"
+        shift; shift
+
+        if test -n "$soname_spec"; then
+          soname=`eval \\$echo \"$soname_spec\"`
+        else
+          soname="$realname"
+        fi
+
+        lib="$objdir/$realname"
+       for link
+       do
+         linknames="$linknames $link"
+       done
+
+        # Use standard objects if they are PIC.
+        test -z "$pic_flag" && libobjs=`$echo "$libobjs " | sed -e 's/\.lo /.o /g' -e 's/ $//g'`
+
+        # Do each of the archive commands.
+        cmds=`eval \\$echo \"$archive_cmds\"`
+        IFS="${IFS=    }"; save_ifs="$IFS"; IFS=';'
+        for cmd in $cmds; do
+          IFS="$save_ifs"
+          $show "$cmd"
+          $run eval "$cmd" || exit $?
+        done
+        IFS="$save_ifs"
+
+        # Create links to the real library.
+        for link in $linknames; do
+          $show "(cd $objdir && $LN_S $realname $link)"
+          $run eval '(cd $objdir && $LN_S $realname $link)' || exit $?
+        done
+
+        # If -export-dynamic was specified, set the dlname.
+        if test "$export_dynamic" = yes; then
+          # On all known operating systems, these are identical.
+          dlname="$soname"
+        fi
+      fi
+      ;;
+
+    *.lo | *.o)
+      if test -n "$link_against_libtool_libs"; then
+        $echo "$progname: error: cannot link libtool libraries into reloadable objects" 1>&2
+        exit 1
+      fi
+
+      if test -n "$deplibs"; then
+        $echo "$progname: warning: \`-l' and \`-L' are ignored while creating objects" 1>&2
+      fi
+
+      if test -n "$dlfiles$dlprefiles"; then
+        $echo "$progname: warning: \`-dlopen' is ignored while creating objects" 1>&2
+        # Nullify the symbol file.
+        compile_command=`$echo "$compile_command" | sed "s% @SYMFILE@%%"`
+        finalize_command=`$echo "$finalize_command" | sed "s% @SYMFILE@%%"`
+      fi
+
+      if test -n "$rpath"; then
+        $echo "$progname: warning: \`-rpath' is ignored while creating objects" 1>&2
+      fi
+
+      if test -n "$vinfo"; then
+        $echo "$progname: warning: \`-version-info' is ignored while creating objects" 1>&2
+      fi
+
+      case "$output" in
+      *.lo)
+        if test -n "$objs"; then
+          $echo "$progname: cannot build library object \`$output' from non-libtool objects" 1>&2
+          exit 1
+        fi
+        libobj="$output"
+        obj=`$echo "$output" | sed 's/\.lo$/.o/'`
+        ;;
+      *)
+        libobj=
+        obj="$output"
+        ;;
+      esac
+
+      # Delete the old objects.
+      $run $rm $obj $libobj
+
+      # Create the old-style object.
+      reload_objs="$objs"`$echo "$libobjs " | sed -e 's/[^       ]*\.a //g' -e 's/\.lo /.o /g' -e 's/ $//g'`
+
+      output="$obj"
+      cmds=`eval \\$echo \"$reload_cmds\"`
+      IFS="${IFS=      }"; save_ifs="$IFS"; IFS=';'
+      for cmd in $cmds; do
+        IFS="$save_ifs"
+        $show "$cmd"
+        $run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+
+      # Exit if we aren't doing a library object file.
+      test -z "$libobj" && exit 0
+
+      if test "$build_libtool_libs" != yes; then
+        # Create an invalid libtool object if no PIC, so that we don't
+        # accidentally link it into a program.
+        $show "$echo timestamp > $libobj"
+        $run eval "\$echo timestamp > $libobj" || exit $?
+        exit 0
+      fi
+
+      if test -n "$pic_flag"; then
+        # Only do commands if we really have different PIC objects.
+        reload_objs="$libobjs"
+        output="$libobj"
+        cmds=`eval \\$echo \"$reload_cmds\"`
+        IFS="${IFS=    }"; save_ifs="$IFS"; IFS=';'
+        for cmd in $cmds; do
+          IFS="$save_ifs"
+          $show "$cmd"
+          $run eval "$cmd" || exit $?
+        done
+        IFS="$save_ifs"
+      else
+        # Just create a symlink.
+        $show "$LN_S $obj $libobj"
+        $run $LN_S $obj $libobj || exit 1
+      fi
+
+      exit 0
+      ;;
+
+    *)
+      if test -n "$vinfo"; then
+        $echo "$progname: warning: \`-version-info' is ignored while linking programs" 1>&2
+      fi
+
+      if test -n "$rpath"; then
+       # If the user specified any rpath flags, then add them.
+       for libdir in $rpath; do
+          if test -n "$hardcode_libdir_flag_spec"; then
+            if test -n "$hardcode_libdir_separator"; then
+              if test -z "$hardcode_libdirs"; then
+                # Put the magic libdir with the hardcode flag.
+                hardcode_libdirs="$libdir"
+                libdir="@HARDCODE_LIBDIRS@"
+              else
+                # Just accumulate the unique libdirs.
+               case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+               *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+                 ;;
+               *)
+                 hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+                 ;;
+               esac
+                libdir=
+              fi
+            fi
+
+            if test -n "$libdir"; then
+              flag=`eval \\$echo \"$hardcode_libdir_flag_spec\"`
+
+              compile_command="$compile_command $flag"
+              finalize_command="$finalize_command $flag"
+            fi
+          elif test "$hardcode_runpath_var" = yes; then
+            case "$perm_rpath " in
+            *" $libdir "*) ;;
+            *) perm_rpath="$perm_rpath $libdir" ;;
+            esac
+          fi
+       done
+      fi
+
+      # Substitute the hardcoded libdirs into the compile commands.
+      if test -n "$hardcode_libdir_separator"; then
+       compile_command=`$echo "$compile_command" | sed "s%@HARDCODE_LIBDIRS@%$hardcode_libdirs%g"`
+       finalize_command=`$echo "$finalize_command" | sed "s%@HARDCODE_LIBDIRS@%$hardcode_libdirs%g"`
+      fi
+
+      if test -n "$libobjs" && test "$build_old_libs" = yes; then
+        # Transform all the library objects into standard objects.
+        compile_command=`$echo "$compile_command " | sed -e 's/\.lo /.o /g' -e 's/ $//'`
+        finalize_command=`$echo "$finalize_command " | sed -e 's/\.lo /.o /g' -e 's/ $//'`
+      fi
+
+      if test "$export_dynamic" = yes && test -n "$NM" && test -n "$global_symbol_pipe"; then
+        dlsyms="${output}S.c"
+      else
+        dlsyms=
+      fi
+
+      if test -n "$dlsyms"; then
+        # Add our own program objects to the preloaded list.
+        dlprefiles=`$echo "$objs$dlprefiles " | sed -e 's/\.lo /.o /g' -e 's/ $//'`
+
+       # Discover the nlist of each of the dlfiles.
+        nlist="$objdir/${output}.nm"
+
+       if test -d $objdir; then
+         $show "$rm $nlist ${nlist}T"
+         $run $rm "$nlist" "${nlist}T"
+       else
+         $show "$mkdir $objdir"
+         $run $mkdir $objdir
+         status=$?
+         if test $status -eq 0 || test -d $objdir; then :
+         else
+           exit $status
+         fi
+       fi
+
+        for arg in $dlprefiles; do
+         $show "extracting global C symbols from \`$arg'"
+         $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+        done
+
+        # Parse the name list into a source file.
+        $show "creating $objdir/$dlsyms"
+        if test -z "$run"; then
+         # Make sure we at least have an empty file.
+         test -f "$nlist" || : > "$nlist"
+
+         # Try sorting and uniquifying the output.
+         if sort "$nlist" | uniq > "$nlist"T; then
+           mv -f "$nlist"T "$nlist"
+           wcout=`wc "$nlist" 2>/dev/null`
+           count=`$echo "$wcout" | sed 's/^[   ]*\([0-9][0-9]*\).*$/\1/'`
+           (test "$count" -ge 0) 2>/dev/null || count=-1
+         else
+           $rm "$nlist"T
+           count=-1
+         fi
+
+         case "$dlsyms" in
+         "") ;;
+         *.c)
+           cat <<EOF > "$objdir/$dlsyms"
+/* $dlsyms - symbol resolution table for \`$output' dlsym emulation. */
+/* Generated by $PROGRAM - GNU $PACKAGE $VERSION */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Prevent the only kind of declaration conflicts we can make. */
+#define dld_preloaded_symbol_count some_other_symbol
+#define dld_preloaded_symbols some_other_symbol
+
+/* External symbol declarations for the compiler. */
+EOF
+           if test -f "$nlist"; then
+             sed -e 's/^.* \(.*\)$/extern char \1;/' < "$nlist" >> "$objdir/$dlsyms"
+           else
+             $echo '/* NONE */' >> "$objdir/$dlsyms"
+EOF
+           fi
+
+           cat <<EOF >> "$objdir/$dlsyms"
+
+#undef dld_preloaded_symbol_count
+#undef dld_preloaded_symbols
+
+#if defined (__STDC__) && __STDC__
+# define __ptr_t void *
+#else
+# define __ptr_t char *
+#endif
+
+/* The number of symbols in dld_preloaded_symbols, -1 if unsorted. */
+int dld_preloaded_symbol_count = $count;
+
+/* The mapping between symbol names and symbols. */
+struct {
+  char *name;
+  __ptr_t address;
+}
+dld_preloaded_symbols[] =
+{
+EOF
+
+           if test -f "$nlist"; then
+             sed 's/^\(.*\) \(.*\)$/  {"\1", \&\2},/' < "$nlist" >> "$objdir/$dlsyms"
+           fi
+
+           cat <<\EOF >> "$objdir/$dlsyms"
+  {0},
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+           ;;
+
+         *)
+           echo "$progname: unknown suffix for \`$dlsyms'" 1>&2
+           exit 1
+           ;;
+         esac
+        fi
+
+        # Now compile the dynamic symbol file.
+        $show "(cd $objdir && $CC -c$no_builtin_flag \"$dlsyms\")"
+        $run eval '(cd $objdir && $CC -c$no_builtin_flag "$dlsyms")' || exit $?
+
+        # Transform the symbol file into the correct name.
+        compile_command=`$echo "$compile_command" | sed "s%@SYMFILE@%$objdir/${output}S.o%"`
+        finalize_command=`$echo "$finalize_command" | sed "s%@SYMFILE@%$objdir/${output}S.o%"`
+      elif test "$export_dynamic" != yes; then
+        test -n "$dlfiles$dlprefiles" && $echo "$progname: warning: \`-dlopen' and \`-dlpreopen' are ignored without \`-export-dynamic'" 1>&2
+      else
+        # We keep going just in case the user didn't refer to
+        # dld_preloaded_symbols.  The linker will fail if global_symbol_pipe
+        # really was required.
+        $echo "$progname: not configured to extract global symbols from dlpreopened files" 1>&2
+
+        # Nullify the symbol file.
+        compile_command=`$echo "$compile_command" | sed "s% @SYMFILE@%%"`
+        finalize_command=`$echo "$finalize_command" | sed "s% @SYMFILE@%%"`
+      fi
+
+      if test -z "$link_against_libtool_libs" || test "$build_libtool_libs" != yes; then
+        # Replace the output file specification.
+        compile_command=`$echo "$compile_command" | sed 's%@OUTPUT@%'"$output"'%g'`
+        finalize_command=`$echo "$finalize_command" | sed 's%@OUTPUT@%'"$output"'%g'`
+
+        # We have no uninstalled library dependencies, so finalize right now.
+        $show "$compile_command"
+        $run eval "$compile_command"
+        exit $?
+      fi
+
+      # Replace the output file specification.
+      compile_command=`$echo "$compile_command" | sed 's%@OUTPUT@%'"$objdir/$output"'%g'`
+      finalize_command=`$echo "$finalize_command" | sed 's%@OUTPUT@%'"$objdir/$output"'T%g'`
+
+      # Create the binary in the object directory, then wrap it.
+      if test -d $objdir; then :
+      else
+        $show "$mkdir $objdir"
+        $run $mkdir $objdir || exit $?
+      fi
+
+      if test -n "$shlibpath_var"; then
+        # We should set the shlibpath_var
+        rpath=
+        for dir in $temp_rpath; do
+          case "$dir" in
+          /*)
+            # Absolute path.
+            rpath="$rpath$dir:"
+            ;;
+          *)
+            # Relative path: add a thisdir entry.
+            rpath="$rpath\$thisdir/$dir:"
+            ;;
+          esac
+        done
+        temp_rpath="$rpath"
+      fi
+
+      # Delete the old output file.
+      $run $rm $output
+
+      if test -n "$compile_shlibpath"; then
+        compile_command="$shlibpath_var=\"$compile_shlibpath\$$shlibpath_var\" $compile_command"
+      fi
+      if test -n "$finalize_shlibpath"; then
+        finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+      fi
+
+      if test -n "$perm_rpath"; then
+        # We should set the runpath_var.
+        rpath=
+        for dir in $perm_rpath; do
+          rpath="$rpath$dir:"
+        done
+        compile_command="$runpath_var=\"$rpath\$$runpath_var\" $compile_command"
+        finalize_command="$runpath_var=\"$rpath\$$runpath_var\" $finalize_command"
+      fi
+
+      case "$hardcode_action" in
+      relink)
+        # AGH! Flame the AIX and HP-UX people for me, will ya?
+        $echo "$progname: warning: using a buggy system linker" 1>&2
+        $echo "$progname: relinking will be required before \`$output' can be installed" 1>&2
+        ;;
+      esac
+
+      $show "$compile_command"
+      $run eval "$compile_command" || exit $?
+
+      # Now create the wrapper script.
+      $show "creating $output"
+
+      # Quote the finalize command for shipping.
+      finalize_command=`$echo "$finalize_command" | sed "$sed_quote_subst"`
+
+      # Only actually do things if our run command is non-null.
+      if test -z "$run"; then
+        $rm $output
+        trap "$rm $output; exit 1" 1 2 15
+
+        cat > $output <<EOF
+#! /bin/sh
+
+# $output - temporary wrapper script for $objdir/$output
+# Generated by ltmain.sh - GNU $PACKAGE $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of \``pwd`'.
+# If it is, it will not operate correctly.
+
+# This environment variable determines our operation mode.
+if test "\$libtool_install_magic" = "$magic"; then
+  # install mode needs the following variables:
+  link_against_libtool_libs='$link_against_libtool_libs'
+  finalize_command="$finalize_command"
+else
+  # When we are sourced in execute mode, \$file and \$echo are already set.
+  if test "\$libtool_execute_magic" = "$magic"; then :
+  else
+    echo='$echo'
+    file="\$0"
+  fi
+
+  # Find the directory that this script lives in.
+  thisdir=\`\$echo "\$file" | sed 's%/[^/]*$%%'\`
+  test "x\$thisdir" = "x\$file" && thisdir=.
+
+  # Follow symbolic links until we get to the real thisdir.
+  file=\`ls -ld "\$file" | sed -n 's/.*-> //p'\`
+  while test -n "\$file"; do
+    destdir=\`\$echo "\$file" | sed 's%/[^/]*\$%%'\`
+
+    # If there was a directory component, then change thisdir.
+    if test "x\$destdir" != "x\$file"; then
+      case "\$destdir" in
+      /*) thisdir="\$destdir" ;;
+      *) thisdir="\$thisdir/\$destdir" ;;
+      esac
+    fi
+
+    file=\`\$echo "\$file" | sed 's%^.*/%%'\`
+    file=\`ls -ld "\$thisdir/\$file" | sed -n 's/.*-> //p'\`
+  done
+
+  # Try to get the absolute directory name.
+  absdir=\`cd "\$thisdir" && pwd\`
+  test -n "\$absdir" && thisdir="\$absdir"
+
+  progdir="\$thisdir/$objdir"
+  program='$output'
+
+  if test -f "\$progdir/\$program"; then
+EOF
+
+        # Export our shlibpath_var if we have one.
+        if test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+          cat >> $output <<EOF
+    # Add our own library path to $shlibpath_var
+    $shlibpath_var="$temp_rpath\$$shlibpath_var"
+
+    # Some systems cannot cope with colon-terminated $shlibpath_var
+    $shlibpath_var=\`\$echo \$$shlibpath_var | sed -e 's/:*\$//'\`
+
+    export $shlibpath_var
+
+EOF
+        fi
+
+        cat >> $output <<EOF
+    if test "\$libtool_execute_magic" != "$magic"; then
+      # Run the actual program with our arguments.
+      args=
+      for arg
+      do
+        # Quote arguments (to preserve shell metacharacters).
+       sed_quote_subst='$sed_quote_subst'
+       arg=\`\$echo "\$arg" | sed "\$sed_quote_subst"\`
+        args="\$args \\"\$arg\\""
+      done
+
+      # Export the path to the program.
+      PATH="\$progdir:\$PATH"
+      export PATH
+
+      eval "exec \$program \$args"
+
+      \$echo "\$0: cannot exec \$program \$args"
+      exit 1
+    fi
+  else
+    # The program doesn't exist.
+    \$echo "\$0: error: \$progdir/\$program does not exist" 1>&2
+    \$echo "This script is just a wrapper for \$program." 1>&2
+    \$echo "See the $PACKAGE documentation for more information." 1>&2
+    exit 1
+  fi
+fi
+EOF
+        chmod +x $output
+      fi
+      exit 0
+      ;;
+    esac
+
+
+    # See if we need to build an old-fashioned archive.
+    if test "$build_old_libs" = "yes"; then
+      # Now set the variables for building old libraries.
+      oldlib="$objdir/$libname.a"
+
+      # Transform .lo files to .o files.
+      oldobjs="$objs"`$echo "$libobjs " | sed -e 's/[^   ]*\.a //g' -e 's/\.lo /.o /g' -e 's/ $//g'`
+
+      if test -d "$objdir"; then
+        $show "$rm $oldlib"
+        $run $rm $oldlib
+      else
+        $show "$mkdir $objdir"
+        $run $mkdir $objdir
+      fi
+
+      # Do each command in the archive commands.
+      if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+       cmds=`eval \\$echo \"$old_archive_from_new_cmds\"`
+      else
+       cmds=`eval \\$echo \"$old_archive_cmds\"`
+      fi
+      IFS="${IFS=      }"; save_ifs="$IFS"; IFS=';'
+      for cmd in $cmds; do
+        IFS="$save_ifs"
+        $show "$cmd"
+        $run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+    fi
+
+    # Now create the libtool archive.
+    case "$output" in
+    *.la)
+      old_library=
+      test "$build_old_libs" = yes && old_library="$libname.a"
+
+      $show "creating $output"
+
+      # Only create the output if not a dry run.
+      if test -z "$run"; then
+        cat > $output <<EOF
+# $output - a libtool library file
+# Generated by ltmain.sh - GNU $PACKAGE $VERSION
+
+# The name that we can dlopen(3).
+dlname='$dlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'
+EOF
+      fi
+
+      # Do a symbolic link so that the libtool archive can be found in
+      # LD_LIBRARY_PATH before the program is installed.
+      $show "(cd $objdir && $LN_S ../$output $output)"
+      $run eval "(cd $objdir && $LN_S ../$output $output)" || exit 1
+      ;;
+    esac
+    exit 0
+    ;;
+
+  # libtool install mode
+  install)
+    progname="$progname: install"
+
+    # There may be an optional /bin/sh argument at the beginning of
+    # install_prog (especially on Windows NT).
+    if test "$nonopt" = "$SHELL"; then
+      # Aesthetically quote it.
+      arg=`$echo "$nonopt" | sed "$sed_quote_subst"`
+      case "$arg" in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*)
+       arg="\"$arg\""
+       ;;
+      esac
+      install_prog="$arg "
+      arg="$1"
+      shift
+    else
+      install_prog=
+      arg="$nonopt"
+    fi
+
+    # The real first argument should be the name of the installation program.
+    # Aesthetically quote it.
+    arg=`$echo "$arg" | sed "$sed_quote_subst"`
+    case "$arg" in
+    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \      ]*|*]*)
+      arg="\"$arg\""
+      ;;
+    esac
+    install_prog="$install_prog$arg"
+
+    # We need to accept at least all the BSD install flags.
+    dest=
+    files=
+    opts=
+    prev=
+    install_type=
+    isdir=
+    stripme=
+    for arg
+    do
+      if test -n "$dest"; then
+        files="$files $dest"
+        dest="$arg"
+        continue
+      fi
+
+      case "$arg" in
+      -d) isdir=yes ;;
+      -f) prev="-f" ;;
+      -g) prev="-g" ;;
+      -m) prev="-m" ;;
+      -o) prev="-o" ;;
+      -s)
+        stripme=" -s"
+        continue
+        ;;
+      -*) ;;
+
+      *)
+        # If the previous option needed an argument, then skip it.
+        if test -n "$prev"; then
+          prev=
+        else
+          dest="$arg"
+          continue
+        fi
+        ;;
+      esac
+
+      # Aesthetically quote the argument.
+      arg=`$echo "$arg" | sed "$sed_quote_subst"`
+      case "$arg" in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*)
+       arg="\"$arg\""
+       ;;
+      esac
+      install_prog="$install_prog $arg"
+    done
+
+    if test -z "$install_prog"; then
+      $echo "$progname: you must specify an install program" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    if test -n "$prev"; then
+      $echo "$progname: the \`$prev' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    if test -z "$files"; then
+      if test -z "$dest"; then
+        $echo "$progname: no file or destination specified" 1>&2
+      else
+        $echo "$progname: you must specify a destination" 1>&2
+      fi
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    # Strip any trailing slash from the destination.
+    dest=`$echo "$dest" | sed 's%/$%%'`
+
+    # Check to see that the destination is a directory.
+    test -d "$dest" && isdir=yes
+    if test -n "$isdir"; then
+      destdir="$dest"
+      destname=
+    else
+      destdir=`$echo "$dest" | sed 's%/[^/]*$%%'`
+      test "X$destdir" = "X$dest" && destdir=.
+      destname=`$echo "$dest" | sed 's%^.*/%%'`
+
+      # Not a directory, so check to see that there is only one file specified.
+      set dummy $files
+      if test $# -gt 2; then
+        $echo "$progname: \`$dest' is not a directory" 1>&2
+        $echo "$help" 1>&2
+        exit 1
+      fi
+    fi
+    case "$destdir" in
+    /*) ;;
+    *)
+      for file in $files; do
+        case "$file" in
+        *.lo) ;;
+        *)
+          $echo "$progname: \`$destdir' must be an absolute directory name" 1>&2
+          $echo "$help" 1>&2
+          exit 1
+          ;;
+        esac
+      done
+      ;;
+    esac
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    staticlibs=
+    future_libdirs=
+    current_libdirs=
+    for file in $files; do
+
+      # Do each installation.
+      case "$file" in
+      *.a)
+        # Do the static libraries later.
+        staticlibs="$staticlibs $file"
+        ;;
+
+      *.la)
+        # Check to see that this really is a libtool archive.
+        if egrep '^# Generated by ltmain.sh' $file >/dev/null 2>&1; then :
+        else
+          $echo "$progname: \`$file' is not a valid libtool archive" 1>&2
+          $echo "$help" 1>&2
+          exit 1
+        fi
+
+        library_names=
+        old_library=
+        # If there is no directory component, then add one.
+        case "$file" in
+        */*) . $file ;;
+        *) . ./$file ;;
+        esac
+
+        # Add the libdir to current_libdirs if it is the destination.
+        if test "X$destdir" = "X$libdir"; then
+          case "$current_libdirs " in
+          *" $libdir "*) ;;
+          *) current_libdirs="$current_libdirs $libdir" ;;
+          esac
+        else
+          # Note the libdir as a future libdir.
+          case "$future_libdirs " in
+          *" $libdir "*) ;;
+          *) future_libdirs="$future_libdirs $libdir" ;;
+          esac
+        fi
+
+        dir="`$echo "$file" | sed 's%/[^/]*$%%'`/"
+        test "X$dir" = "X$file/" && dir=
+        dir="$dir$objdir"
+
+        # See the names of the shared library.
+        set dummy $library_names
+        if test -n "$2"; then
+          realname="$2"
+          shift
+          shift
+
+          # Install the shared library and build the symlinks.
+          $show "$install_prog $dir/$realname $destdir/$realname"
+          $run eval "$install_prog $dir/$realname $destdir/$realname" || exit $?
+          test "X$dlname" = "X$realname" && dlname=
+
+          # Support stripping libraries.
+          if test -n "$stripme"; then
+            if test -n "$striplib"; then
+              $show "$striplib $destdir/$realname"
+              $run $striplib $destdir/$realname || exit $?
+            else
+              $echo "$progname: warning: no library stripping program" 1>&2
+            fi
+          fi
+
+          if test $# -gt 0; then
+            # Delete the old symlinks.
+            rmcmd="$rm"
+            for linkname
+            do
+              rmcmd="$rmcmd $destdir/$linkname"
+            done
+            $show "$rmcmd"
+            $run $rmcmd
+
+            # ... and create new ones.
+            for linkname
+            do
+              test "X$dlname" = "X$linkname" && dlname=
+              $show "(cd $destdir && $LN_S $realname $linkname)"
+              $run eval "(cd $destdir && $LN_S $realname $linkname)"
+            done
+          fi
+
+          if test -n "$dlname"; then
+            # Install the dynamically-loadable library.
+            $show "$install_prog $dir/$dlname $destdir/$dlname"
+            $run eval "$install_prog $dir/$dlname $destdir/$dlname" || exit $?
+          fi
+
+          # Do each command in the postinstall commands.
+          lib="$destdir/$realname"
+          cmds=`eval \\$echo \"$postinstall_cmds\"`
+          IFS="${IFS=  }"; save_ifs="$IFS"; IFS=';'
+          for cmd in $cmds; do
+            IFS="$save_ifs"
+            $show "$cmd"
+            $run eval "$cmd" || exit $?
+          done
+          IFS="$save_ifs"
+        fi
+
+        # Install the pseudo-library for information purposes.
+        name=`$echo "$file" | sed 's%^.*/%%'`
+        $show "$install_prog $file $destdir/$name"
+        $run eval "$install_prog $file $destdir/$name" || exit $?
+
+        # Maybe install the static library, too.
+        test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+        ;;
+
+      *.lo)
+        # Install (i.e. copy) a libtool object.
+
+        # Figure out destination file name, if it wasn't already specified.
+        if test -n "$destname"; then
+          destfile="$destdir/$destname"
+        else
+          destfile=`$echo "$file" | sed 's%^.*/%%'`
+          destfile="$destdir/$destfile"
+        fi
+
+        # Deduce the name of the destination old-style object file.
+        case "$destfile" in
+        *.lo)
+          staticdest=`$echo "$destfile" | sed 's/\.lo$/\.o/'`
+          ;;
+        *.o)
+          staticdest="$destfile"
+          destfile=
+          ;;
+        *)
+          $echo "$progname: cannot copy a libtool object to \`$destfile'" 1>&2
+          $echo "$help" 1>&2
+          exit 1
+          ;;
+        esac
+
+        # Install the libtool object if requested.
+        if test -n "$destfile"; then
+          $show "$install_prog $file $destfile"
+          $run eval "$install_prog $file $destfile" || exit $?
+        fi
+
+        # Install the old object if enabled.
+        if test "$build_old_libs" = yes; then
+          # Deduce the name of the old-style object file.
+          staticobj=`$echo "$file" | sed 's/\.lo$/\.o/'`
+
+          $show "$install_prog $staticobj $staticdest"
+          $run eval "$install_prog \$staticobj \$staticdest" || exit $?
+        fi
+        exit 0
+        ;;
+
+      *)
+        # Do a test to see if this is really a libtool program.
+        if egrep '^# Generated by ltmain.sh' $file >/dev/null 2>&1; then
+          link_against_libtool_libs=
+          finalize_command=
+
+          # If there is no directory component, then add one.
+          case "$file" in
+          */*) . $file ;;
+          *) . ./$file ;;
+          esac
+
+          # Check the variables that should have been set.
+          if test -z "$link_against_libtool_libs" || test -z "$finalize_command"; then
+            $echo "$progname: invalid libtool wrapper script \`$file'" 1>&2
+            exit 1
+          fi
+
+          finalize=yes
+          for lib in $link_against_libtool_libs; do
+            # Check to see that each library is installed.
+            libdir=
+            if test -f "$lib"; then
+              # If there is no directory component, then add one.
+              case "$lib" in
+              */*) . $lib ;;
+              *) . ./$lib ;;
+              esac
+            fi
+            libfile="$libdir/`$echo "$lib" | sed 's%^.*/%%g'`"
+            if test -z "$libdir"; then
+              $echo "$progname: warning: \`$lib' contains no -rpath information" 1>&2
+            elif test -f "$libfile"; then :
+            else
+              $echo "$progname: warning: \`$lib' has not been installed in \`$libdir'" 1>&2
+              finalize=no
+            fi
+          done
+
+          if test "$hardcode_action" = relink; then
+            if test "$finalize" = yes; then
+              $echo "$progname: warning: relinking \`$file' on behalf of your buggy system linker" 1>&2
+              $show "$finalize_command"
+              if $run eval "$finalize_command"; then :
+              else
+                $echo "$progname: error: relink \`$file' with the above command before installing it" 1>&2
+                continue
+              fi
+              file="$objdir/$file"T
+            else
+              $echo "$progname: warning: cannot relink \`$file' on behalf of your buggy system linker" 1>&2
+            fi
+          else
+            # Install the binary that we compiled earlier.
+           file=`$echo "$file" | sed "s%\([^/]*\)$%$objdir/\1%"`
+          fi
+        fi
+
+        $show "$install_prog$stripme $file $dest"
+        $run eval "$install_prog\$stripme \$file \$dest" || exit $?
+        ;;
+      esac
+    done
+
+    for file in $staticlibs; do
+      name=`$echo "$file" | sed 's%^.*/%%'`
+
+      # Set up the ranlib parameters.
+      oldlib="$destdir/$name"
+
+      $show "$install_prog $file $oldlib"
+      $run eval "$install_prog \$file \$oldlib" || exit $?
+
+      # Support stripping libraries.
+      if test -n "$stripme"; then
+        if test -n "$old_striplib"; then
+          $show "$old_striplib $oldlib"
+          $run $old_striplib $oldlib || exit $?
+        else
+          $echo "$progname: warning: no static library stripping program" 1>&2
+        fi
+      fi
+
+      # Do each command in the postinstall commands.
+      cmds=`eval \\$echo \"$old_postinstall_cmds\"`
+      IFS="${IFS=      }"; save_ifs="$IFS"; IFS=';'
+      for cmd in $cmds; do
+        IFS="$save_ifs"
+        $show "$cmd"
+        $run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+    done
+
+    if test -n "$future_libdirs"; then
+      $echo "$progname: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2
+    fi
+
+    if test -n "$current_libdirs"; then
+      # Maybe just do a dry run.
+      test -n "$run" && current_libdirs=" -n$current_libdirs"
+      exec $SHELL $0 --finish$current_libdirs
+      exit 1
+    fi
+
+    exit 0
+    ;;
+
+  # libtool finish mode
+  finish)
+    progname="$progname: finish"
+    libdirs="$nonopt"
+
+    if test -n "$finish_cmds" && test -n "$libdirs"; then
+      for dir
+      do
+        libdirs="$libdirs $dir"
+      done
+
+      for libdir in $libdirs; do
+        # Do each command in the postinstall commands.
+        cmds=`eval \\$echo \"$finish_cmds\"`
+        IFS="${IFS=    }"; save_ifs="$IFS"; IFS=';'
+        for cmd in $cmds; do
+          IFS="$save_ifs"
+          $show "$cmd"
+          $run eval "$cmd"
+        done
+        IFS="$save_ifs"
+      done
+    fi
+
+    $echo "To link against installed libraries in LIBDIR, users may have to:"
+    if test -n "$shlibpath_var"; then
+      $echo "   - add LIBDIR to their \`$shlibpath_var' environment variable"
+    fi
+    $echo "   - use the \`-LLIBDIR' linker flag"
+    exit 0
+    ;;
+
+  # libtool execute mode
+  execute)
+    progname="$progname: execute"
+
+    # The first argument is the command name.
+    cmd="$nonopt"
+    if test -z "$cmd"; then
+      $echo "$progname: you must specify a COMMAND" 1>&2
+      $echo "$help"
+      exit 1
+    fi
+
+    # Handle -dlopen flags immediately.
+    for file in $execute_dlfiles; do
+      if test -f "$file"; then :
+      else
+       $echo "$progname: \`$file' is not a file" 1>&2
+       $echo "$help" 1>&2
+       exit 1
+      fi
+
+      dir=
+      case "$file" in
+      *.la)
+        # Check to see that this really is a libtool archive.
+        if egrep '^# Generated by ltmain.sh' $file >/dev/null 2>&1; then :
+        else
+          $echo "$progname: \`$lib' is not a valid libtool archive" 1>&2
+          $echo "$help" 1>&2
+          exit 1
+        fi
+
+       # Read the libtool library.
+       dlname=
+       library_names=
+
+        # If there is no directory component, then add one.
+       case "$file" in
+       */*) . $file ;;
+        *) . ./$file ;;
+       esac
+
+       # Skip this library if it cannot be dlopened.
+       if test -z "$dlname"; then
+         # Warn if it was a shared library.
+         test -n "$library_names" && $echo "$progname: warning: \`$file' was not linked with \`-export-dynamic'"
+         continue
+       fi
+
+       dir=`$echo "$file" | sed 's%/[^/]*$%%'`
+       test "X$dir" = "X$file" && dir=.
+
+       if test -f "$dir/$objdir/$dlname"; then
+         dir="$dir/$objdir"
+       else
+         $echo "$progname: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
+         exit 1
+       fi
+       ;;
+
+      *.lo)
+       # Just add the directory containing the .lo file.
+       dir=`$echo "$file" | sed 's%/[^/]*$%%'`
+       test "X$dir" = "X$file" && dir=.
+       ;;
+
+      *)
+       $echo "$progname: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2
+        continue
+       ;;
+      esac
+
+      # Get the absolute pathname.
+      absdir=`cd "$dir" && pwd`
+      test -n "$absdir" && dir="$absdir"
+
+      # Now add the directory to shlibpath_var.
+      if eval "test -z \"\$$shlibpath_var\""; then
+       eval "$shlibpath_var=\"\$dir\""
+      else
+       eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+      fi
+    done
+
+    # This variable tells wrapper scripts just to set shlibpath_var
+    # rather than running their programs.
+    libtool_execute_magic="$magic"
+
+    # Check if any of the arguments is a wrapper script.
+    args=
+    for file
+    do
+      case "$file" in
+      -*) ;;
+      *)
+       if egrep '^# Generated by ltmain.sh' $file >/dev/null 2>&1; then
+         # If there is no directory component, then add one.
+         case "$file" in
+         */*) . $file ;;
+         *) . ./$file ;;
+         esac
+
+         # Transform arg to wrapped name.
+         file="$progdir/$program"
+       fi
+        ;;
+      esac
+      # Quote arguments (to preserve shell metacharacters).
+      file=`$echo "$file" | sed "$sed_quote_subst"`
+      args="$args \"$file\""
+    done
+
+    if test -z "$run"; then
+      # Export the shlibpath_var.
+      eval "export $shlibpath_var"
+
+      # Now actually exec the command.
+      eval "exec \$cmd$args"
+
+      $echo "$progname: cannot exec \$cmd$args"
+      exit 1
+    else
+      # Display what would be done.
+      eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\""
+      $echo "export $shlibpath_var"
+      $echo "$cmd$args"
+      exit 0
+    fi
+    ;;
+
+  # libtool uninstall mode
+  uninstall)
+    progname="$progname: uninstall"
+    rm="$nonopt"
+    files=
+
+    for arg
+    do
+      case "$arg" in
+      -*) rm="$rm $arg" ;;
+      *) files="$files $arg" ;;
+      esac
+    done
+
+    if test -z "$rm"; then
+      $echo "$progname: you must specify an RM program" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    for file in $files; do
+      dir=`$echo "$file" | sed -e 's%/[^/]*$%%'`
+      test "X$dir" = "X$file" && dir=.
+      name=`$echo "$file" | sed -e 's%^.*/%%'`
+
+      rmfiles="$file"
+
+      case "$name" in
+      *.la)
+        # Possibly a libtool archive, so verify it.
+        if egrep '^# Generated by ltmain.sh' $file >/dev/null 2>&1; then
+          . $dir/$name
+
+          # Delete the libtool libraries and symlinks.
+          for n in $library_names; do
+            rmfiles="$rmfiles $dir/$n"
+            test "X$n" = "X$dlname" && dlname=
+          done
+          test -n "$dlname" && rmfiles="$rmfiles $dir/$dlname"
+          test -n "$old_library" && rmfiles="$rmfiles $dir/$old_library"
+
+          # FIXME: should reinstall the best remaining shared library.
+        fi
+        ;;
+
+      *.lo)
+        if test "$build_old_libs" = yes; then
+          oldobj=`$echo "$name" | sed 's/\.lo$/\.o/'`
+          rmfiles="$rmfiles $dir/$oldobj"
+        fi
+        ;;
+      esac
+
+      $show "$rm $rmfiles"
+      $run $rm $rmfiles
+    done
+    exit 0
+    ;;
+
+  "")
+    $echo "$progname: you must specify a MODE" 1>&2
+    $echo "$generic_help" 1>&2
+    exit 1
+    ;;
+  esac
+
+  $echo "$progname: invalid operation mode \`$mode'" 1>&2
+  $echo "$generic_help" 1>&2
+  exit 1
+fi # test -z "$show_help"
+
+# We need to display help for each of the modes.
+case "$mode" in
+"") cat <<EOF
+Usage: $progname [OPTION]... [MODE-ARG]...
+
+Provide generalized library-building support services.
+
+-n, --dry-run         display commands without modifying any files
+    --features        display configuration information and exit
+    --finish          same as \`--mode=finish'
+    --help            display this help message and exit
+    --mode=MODE       use operation mode MODE [default=inferred from MODE-ARGS]
+    --quiet           same as \`--silent'
+    --silent          don't print informational messages
+    --version         print version information
+
+MODE must be one of the following:
+
+      compile         compile a source file into a libtool object
+      execute         automatically set library path, then run a program
+      finish          complete the installation of libtool libraries
+      install         install libraries or executables
+      link            create a library or an executable
+      uninstall       remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE.  Try \`$progname --help --mode=MODE' for
+a more detailed description of MODE.
+EOF
+  ;;
+
+compile)
+  cat <<EOF
+Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'.
+EOF
+  ;;
+
+execute)
+  cat <<EOF
+Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+  -dlopen FILE      add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments.
+EOF
+  ;;
+
+finish)
+  cat <<EOF
+Usage: $progname [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges.  Use
+the \`--dry-run' option if you just want to see what would be executed.
+EOF
+  ;;
+
+install)
+  cat <<EOF
+Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command.  The first component should be
+either the \`install' or \`cp' program.
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized).
+EOF
+  ;;
+
+link)
+  cat <<EOF
+Usage: $progname [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+  -all-static       do not do any dynamic linking at all
+  -allow-undefined  allow a libtool library to reference undefined symbols
+  -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
+  -dlpreopen FILE   link in FILE and add its symbols to dld_preloaded_symbols
+  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+  -LLIBDIR          search LIBDIR for required installed libraries
+  -lNAME            OUTPUT-FILE requires the installed library libNAME
+  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
+  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
+  -static           do not do any dynamic linking of libtool libraries
+  -version-info CURRENT[:REVISION[:AGE]]
+                    specify library version info [each variable defaults to 0]
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename.  Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created, only
+library objects (\`.lo' files) may be specified, and \`-rpath' is required.
+
+If OUTPUT-FILE ends in \`.a', then a standard library is created using \`ar'
+and \`ranlib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.o', then a reloadable object file is
+created, otherwise an executable program is created.
+EOF
+  ;;
+
+uninstall)
+  cat <<EOF
+Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM.
+EOF
+  ;;
+
+*)
+  $echo "$progname: invalid operation mode \`$mode'" 1>&2
+  $echo "$help" 1>&2
+  exit 1
+  ;;
+esac
+
+$echo
+$echo "Try \`$progname --help' for more information about other modes."
+
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/makecopyright b/makecopyright
new file mode 100755 (executable)
index 0000000..5e17fd3
--- /dev/null
@@ -0,0 +1,124 @@
+#!/bin/sh
+
+
+copyright_glib ()
+{
+  cat << EOF
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+EOF
+}
+
+copyright_gdk ()
+{
+  cat << EOF
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+EOF
+}
+
+copyright_gtk ()
+{
+  cat << EOF
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+EOF
+}
+
+copyright_interp ()
+{
+  cat << EOF
+/* GTK Interp - The GTK Interpreter
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+EOF
+}
+
+
+exclude_files="./glib/gconfig.h"
+
+for file in `find . -name "*.[ch]" -print`; do
+  exclude=`echo $exclude_files | grep $file`
+
+  if test "x$exclude" = "x"; then
+    dir=`dirname $file`
+    if test "x$dir" != "x."; then
+      subdir=`basename $dir`
+
+      grepout=`grep Copyright $file`
+      if test "x$grepout" = "x"; then
+        backup_dir="$dir/bak"
+        if test ! -d $backup_dir; then
+          echo "making directory: $backup_dir"
+          mkdir $backup_dir
+        fi
+
+        echo $file
+
+        filename=`basename $file`
+        cp $file $backup_dir/$filename
+        copyright_$subdir > $file
+        cat $backup_dir/$filename >> $file
+      fi
+    fi
+  fi
+done
diff --git a/missing b/missing
new file mode 100755 (executable)
index 0000000..e4b838c
--- /dev/null
+++ b/missing
@@ -0,0 +1,134 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+# Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+# Franc,ois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try \`$0 --help' for more information"
+  exit 1
+fi
+
+case "$1" in
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+
+Supported PROGRAM values:
+  aclocal      touch file \`aclocal.m4'
+  autoconf     touch file \`configure'
+  autoheader   touch file \`config.h.in'
+  automake     touch all \`Makefile.in' files
+  bison        touch file \`y.tab.c'
+  makeinfo     touch the output file
+  yacc         touch file \`y.tab.c'"
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing - GNU libit 0.0"
+    ;;
+
+  -*)
+    echo 1>&2 "$0: Unknown \`$1' option"
+    echo 1>&2 "Try \`$0 --help' for more information"
+    exit 1
+    ;;
+
+  aclocal)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  It should be needed only if
+         you modified \`acinclude.m4' or \`configure.in'.  You might want
+         to install the \`Automake' and \`Perl' packages.  Grab them from
+         any GNU archive site."
+    touch aclocal.m4
+    ;;
+
+  autoconf)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  It should be needed only if
+         you modified \`configure.in'.  You might want to install the
+         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
+         archive site."
+    touch configure
+    ;;
+
+  autoheader)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  It should be needed only if
+         you modified \`acconfig.h' or \`configure.in'.  You might want
+         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
+         from any GNU archive site."
+    touch config.h.in
+    ;;
+
+  automake)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  It should be needed only if
+         you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'.
+         You might want to install the \`Automake' and \`Perl' packages.
+         Grab them from any GNU archive site."
+    find . -type f -name Makefile.am -print \
+      | sed 's/^\(.*\).am$/touch \1.in/' \
+      | sh
+    ;;
+
+  bison|yacc)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  It should be needed only if
+         your modified any \`.y' file.  For being effective, your
+         modifications might require the \`Bison' package.  Grab it from
+         any GNU archive site."
+    touch y.tab.c
+    ;;
+
+  makeinfo)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  It should be needed only if
+         you modified a \`.texi' or \`.texinfo' file, or any other file
+         indirectly affecting the aspect of the manual.  The spurious
+         call might also be the consequence of using a buggy \`make' (AIX,
+         DU, IRIX).  You might want to install the \`Texinfo' package or
+         the \`GNU make' package.  Grab either from any GNU archive site."
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+      file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+      file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
+    fi
+    touch $file
+    ;;
+
+  *)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and you do not seem to have it handy on your
+         system.  You might have modified some files without having the
+         proper tools for further handling them.  Check the \`README' file,
+         it often tells you about the needed prerequirements for installing
+         this package.  You may also peek at any GNU archive site, in case
+         some other package would contain this missing \`$1' program."
+    exit 1
+    ;;
+esac
+
+exit 0
diff --git a/mkinstalldirs b/mkinstalldirs
new file mode 100755 (executable)
index 0000000..fef1eb9
--- /dev/null
@@ -0,0 +1,36 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Last modified: 1994-03-25
+# Public domain
+
+errstatus=0
+
+for file in ${1+"$@"} ; do
+   set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+   shift
+
+   pathcomp=
+   for d in ${1+"$@"} ; do
+     pathcomp="$pathcomp$d"
+     case "$pathcomp" in
+       -* ) pathcomp=./$pathcomp ;;
+     esac
+
+     if test ! -d "$pathcomp"; then
+        echo "mkdir $pathcomp" 1>&2
+        mkdir "$pathcomp" > /dev/null 2>&1 || lasterr=$?
+     fi
+
+     if test ! -d "$pathcomp"; then
+       errstatus=$lasterr
+     fi
+
+     pathcomp="$pathcomp/"
+   done
+done
+
+exit $errstatus
+
+# mkinstalldirs ends here
diff --git a/stamp-h.in b/stamp-h.in
new file mode 100644 (file)
index 0000000..9788f70
--- /dev/null
@@ -0,0 +1 @@
+timestamp
diff --git a/tests/3DRings.xpm b/tests/3DRings.xpm
new file mode 100644 (file)
index 0000000..1ca75da
--- /dev/null
@@ -0,0 +1,116 @@
+/* XPM */
+static char * DRings_xpm[] = {
+"48 48 65 1",
+"      c None",
+".     c #104010404103",
+"X     c #1040208130C2",
+"o     c #104014515144",
+"O     c #000010402081",
+"+     c #1040104030C2",
+"@     c #208120815144",
+"#     c #28A241035965",
+"$     c #30C230C26185",
+"%     c #208130C24103",
+"&     c #104010402081",
+"*     c #104000002081",
+"=     c #000010401040",
+"-     c #492441036185",
+";     c #596559659E79",
+":     c #30C220815144",
+">     c #0820186128A2",
+",     c #000000001040",
+"<     c #2081104030C2",
+"1     c #514459659658",
+"2     c #514455556185",
+"3     c #104000001040",
+"4     c #000008200000",
+"5     c #618569A6AEBA",
+"6     c #618569A69658",
+"7     c #410345148E38",
+"8     c #104020814103",
+"9     c #79E782079658",
+"0     c #208120814103",
+"q     c #596571C69E79",
+"w     c #4103514471C6",
+"e     c #2081208130C2",
+"r     c #6185618571C6",
+"t     c #28A228A25965",
+"y     c #596561858617",
+"u     c #96589E79BEFB",
+"i     c #28A230C271C6",
+"p     c #38E345145144",
+"a     c #79E78207A699",
+"s     c #30C2492469A6",
+"d     c #410330C25965",
+"f     c #410351446185",
+"g     c #AEBAAAAAD75C",
+"h     c #38E338E34103",
+"j     c #EFBEEBADEFBE",
+"k     c #208130C25144",
+"l     c #9658A289DF7D",
+"z     c #208110404103",
+"x     c #28A228A26185",
+"c     c #8E388A28BEFB",
+"v     c #208118612081",
+"b     c #38E3451479E7",
+"n     c #4924618579E7",
+"m     c #86178617B6DA",
+"M     c #30C220814103",
+"N     c #104030C25144",
+"B     c #4103410371C6",
+"V     c #86178A28D75C",
+"C     c #DF7DDB6CE79D",
+"Z     c #BEFBC30BD75C",
+"A     c #410330C271C6",
+"S     c #30C228A230C2",
+"D     c #082008201861",
+"F     c #186130C238E3",
+"G     c #0000208130C2",
+"                                .Xo             ",
+"                              O+O@#$%           ",
+"                             &*=+X-;:           ",
+"                            >&=,=<11#2          ",
+"                            +O34,X567&          ",
+"                           8X+=,90q9w.          ",
+"                          +e<>3r tyu-&          ",
+"                          Xi%.=  paus+          ",
+"                         Od-@=   fga$h          ",
+"                         @y7X,  Xrjak           ",
+"                       2:eaw+   $ag;@           ",
+"                   .X@8@k@o@X+ +pl9tO           ",
+"                 +zX@x$$isikt8o02crv            ",
+"                8@%ip7757ywbs$Ohn6#.            ",
+"               &0%$p7r215ybw1pzp2-0=            ",
+"              8tk$#yw21665n;1+%-p$O             ",
+"             O<e7pbryq5am9ay6XMpM>3&            ",
+"            9.NtpBw16amclVcm1t%kX*88            ",
+"            +&etd7r6y9ulgglm6>e>3s@83           ",
+"            +0k$y-y69cgCCCZVam%+#ik8X           ",
+"           O&oi$d725amgCjCZu962ybtx8+p          ",
+"           &X0x$sBym9VZCCCZca;yBbi%08&          ",
+"           =++@sApMy5muZZgum6y2wds:>+&          ",
+"          #tp;1;yB#i25cVucma5;w-pti@8&          ",
+"        .#2alumnBp:@1r59y9y6ywBS$%0X+=          ",
+"      %$wmZVu;#tX8X07r1656y2wbp$k@%@OD          ",
+"     0Byc9a;h%0>&D&hBrr2r1bwB-AF:0<&*=          ",
+"    kBf;yr#@X+&<%MkhsBwBwpsB#Bktkt8+Oh          ",
+"   xt7B-t8*,3O.X00:$i#dBd#bptFek0X.+*           ",
+"  Xt#b#@=,  =&O+X0Ft%ibsp$p$ki%l5sX&=           ",
+" &<kvX&4    +O*&<X0e:%$pAti%:edugn0=            ",
+" +X@&+,     V,O&>+Xt>tktktv0%@k;Cls+            ",
+" =+O*4*X:p;9cy3&&8ve0FMtt$ee0>z7cZ6k            ",
+" D=D4,=.k$sBs$ee=+X0Fk%-#t%0X&O0nu9bG           ",
+" ,,434*&ze@F<eeeeee><tdhdSMe<&&XAaawx           ",
+"  4,4,=+><peeeeee&=<%M%$hSF0X&O&kw5r%Z          ",
+"                   D&vSFMF<>&D =0S-2i&          ",
+"                       +>puB>   >0h7s.          ",
+"                       SM5VqM   &0t#$8          ",
+"                        XpVV70  &0kMk.          ",
+"                         XdyB%z *X<%@+          ",
+"                         &k$b0X+=8X08o          ",
+"                          &e:e+=*X.X+&          ",
+"                           +X.O+X0O.=,          ",
+"                            +>&+0>3&*           ",
+"                             &X0k+O,            ",
+"                               >v,3             ",
+"                                                "};
diff --git a/tests/FilesQueue.xpm b/tests/FilesQueue.xpm
new file mode 100644 (file)
index 0000000..586d27e
--- /dev/null
@@ -0,0 +1,98 @@
+/* XPM */
+static char * FilesQueue_xpm[] = {
+"44 31 64 1",
+"      c None",
+".     c #E79DE38DDF7D",
+"X     c #CF3CC71BCF3C",
+"o     c #71C675D671C6",
+"O     c #B6DAB2CAB6DA",
+"+     c #CF3CD34CCF3C",
+"@     c #DF7DE38DE79D",
+"#     c #FFFFFBEEFFFF",
+"$     c #EFBEEFBEEFBE",
+"%     c #DF7DDB6CDF7D",
+"&     c #BEFBBAEAC71B",
+"*     c #BEFBBAEABEFB",
+"=     c #BEFBC30BC71B",
+"-     c #71C66DB671C6",
+";     c #D75CD34CD75C",
+":     c #9E799A699E79",
+">     c #E79DE38DE79D",
+",     c #CF3CCB2BC71B",
+"<     c #B6DAB2CABEFB",
+"1     c #BEFBBAEAB6DA",
+"2     c #B6DAB6DAB6DA",
+"3     c #618561856185",
+"4     c #C71BBAEABEFB",
+"5     c #AEBAAAAAAEBA",
+"6     c #965892488E38",
+"7     c #A699A699A699",
+"8     c #38E338E338E3",
+"9     c #F7DEF7DEF7DE",
+"0     c #E79DEFBEEFBE",
+"q     c #DF7DE38DDF7D",
+"w     c #C71BC71BC71B",
+"e     c #C71BC30BBEFB",
+"r     c #BEFBC30BBEFB",
+"t     c #B6DAAAAAAEBA",
+"y     c #410345144103",
+"u     c #D75CDB6CD75C",
+"i     c #C71BCB2BC71B",
+"p     c #BEFBCB2BBEFB",
+"a     c #9E79A289A699",
+"s     c #86178E388E38",
+"d     c #CF3CCF3CD75C",
+"f     c #CF3CD75CCF3C",
+"g     c #C71BC30BCF3C",
+"h     c #28A22CB228A2",
+"j     c #000000000000",
+"k     c #D75CD34CDF7D",
+"l     c #10400C300820",
+"z     c #E79DEBADEFBE",
+"x     c #DF7DDB6CD75C",
+"c     c #514459655965",
+"v     c #8617861779E7",
+"b     c #DF7DD34CD75C",
+"n     c #CF3CCB2BCF3C",
+"m     c #618555555965",
+"M     c #861786178617",
+"N     c #30C234D330C2",
+"B     c #EFBEEBADE79D",
+"V     c #DF7DDB6CE79D",
+"C     c #D75CE38DD75C",
+"Z     c #514449245144",
+"A     c #186120812081",
+"S     c #79E77DF779E7",
+"D     c #6185659569A6",
+"F     c #9E7992489E79",
+"                      .XoOX+                ",
+"                   @#$%&*=-o;:              ",
+"                  @>,=O<12*&:-<3X           ",
+"                 >%&1*4*2*OO**56758790      ",
+"               9qX+we=r*&e<<<251t5555yu9    ",
+"             $qu++;ipi=p*=p**2tOOO27a5s<-   ",
+"           #9udfXi;,gi&**4**4r*Ot5t55tehj   ",
+"          0qku+u;+d,gg=*=r*&**&<255t<*yl1   ",
+"       $$zq@%xk%uf;,w,i=i=e**r=12tO1=8cvj   ",
+"     $@%>.%.%%%xbkx,w+ni,wwrwe*4*1=;8mMNj   ",
+"    zz@Bz>>>V%%%C+u;;dfnnfwggi&=&X+yZsNll   ",
+"  af#9@B0>q>qqq>xk.;;;kfX+XnXw=g,fycMhhN5   ",
+"  al5#9$$>qzBV.%x%%b;x+fnf+,X,iiqym6NAo-j   ",
+"  #roS%#$zz>>V%%xkk%f;;+df,XnwnVZD:8AS-j*   ",
+"  D-9Oy*9$Bz>q%qx%%u;x;;dknX+d>Zm:hhSDjr    ",
+"  a3o+>S3z#90@@z.%>qCC%uu;ff%@Zm:NhMoj=     ",
+"  wlvvo#:3599$>B>q>%%%%+f;fk$ymaalMvjr      ",
+"  0.a--S49mct9$z@.qkkqC;xu%@Zm5AlvSj*       ",
+"  ohu%3:Z:9@y609q@@>..>Cx>$Zm5NhMvjr        ",
+"   -j797Zv5705y=#$0>>V.%>#Z378AMMj*         ",
+"     Zj9Xo-McBXDv%90.%%#9cc78AsMj*          ",
+"      8hM#M-DSF96cvz0>z#c35Nhs6j1           ",
+"        jl9#o63vx#-D###mmt8N66j*            ",
+"         5jc@fZF3o%+ZFDm<8A6FjO             ",
+"           :j50sSay<$ss2Nh:FjO              ",
+"            6880&SDMF.rNNFFj1               ",
+"              8jr#:SFScA6ajO                ",
+"                Alr$DSysajO                 ",
+"                 >jy#51:jO                  ",
+"                  %Dy*gjO                   ",
+"                    alla                    "};
diff --git a/tests/Modeller.xpm b/tests/Modeller.xpm
new file mode 100644 (file)
index 0000000..62e27f9
--- /dev/null
@@ -0,0 +1,117 @@
+/* XPM */
+static char * InterfaceModeller_app_2_Tile_xpm[] = {
+"48 48 66 1",
+"      c None",
+".     c #86174D344103",
+"X     c #69A651445144",
+"o     c #8617410330C2",
+"O     c #69A6410338E3",
+"+     c #30C218611861",
+"@     c #AEBA6DB66185",
+"#     c #71C638E328A2",
+"$     c #69A634D328A2",
+"%     c #30C228A228A2",
+"&     c #79E73CF330C2",
+"*     c #BEFB9E799E79",
+"=     c #8E3869A66185",
+"-     c #514424921861",
+";     c #A699A289B6DA",
+":     c #A6999E79A699",
+">     c #71C65D756185",
+",     c #9E799A69A699",
+"<     c #8E3882078E38",
+"1     c #861779E78617",
+"2     c #A6999A69AEBA",
+"3     c #8E388A289658",
+"4     c #71C675D679E7",
+"5     c #96588A289E79",
+"6     c #30C230C238E3",
+"7     c #C71BC71BC71B",
+"8     c #9E79A289AEBA",
+"9     c #AEBAAAAABEFB",
+"0     c #96589248A699",
+"q     c #A699AAAAB6DA",
+"w     c #AEBAAAAAB6DA",
+"e     c #D75CD34CD75C",
+"r     c #EFBEE79DEFBE",
+"t     c #BEFBB6DABEFB",
+"y     c #B6DABAEAC71B",
+"u     c #AEBAAEBAB6DA",
+"i     c #E79DDB6CDF7D",
+"p     c #96588E389658",
+"a     c #596559656185",
+"s     c #AEBA8E388E38",
+"d     c #CF3CCB2BCF3C",
+"f     c #9E799A699E79",
+"g     c #86177DF78E38",
+"h     c #69A6659571C6",
+"j     c #AEBAAEBABEFB",
+"k     c #96589E799E79",
+"l     c #B6DAA699A699",
+"z     c #E79DC71BC71B",
+"x     c #B6DAB6DAB6DA",
+"c     c #861786179658",
+"v     c #B6DAB2CABEFB",
+"b     c #BEFBAAAAAEBA",
+"n     c #C71BBEFBC71B",
+"m     c #514441034103",
+"M     c #41033CF34103",
+"N     c #492428A228A2",
+"B     c #AEBAA289B6DA",
+"V     c #618530C22081",
+"C     c #69A630C228A2",
+"Z     c #69A630C22081",
+"A     c #596528A22081",
+"S     c #492428A22081",
+"D     c #618528A22081",
+"F     c #596520811861",
+"G     c #69A628A22081",
+"H     c #FFFF14514103",
+"                                            .X  ",
+"                                           .oO+ ",
+"                                         @.o#++ ",
+"                                        @.o$%+  ",
+"                                       @.&#++   ",
+"                                      @.o#++    ",
+"                                     @.o$++     ",
+"                                    @.&#++      ",
+"                                    .O#++       ",
+"                                  *=-$++        ",
+"                                 ;:>+++         ",
+"                                ;,<1%           ",
+"                               2,34             ",
+"                             2;,51              ",
+"                            2,,,,6              ",
+"           7777            28888,6              ",
+"         77777777        2829,,,06              ",
+"    9qwwe7rrrrr77rr     828,9tyt,6              ",
+" uuwriirrieiiieii77pa< 82,8,,,8,06              ",
+" s=1ttiieeeeded77eufgh>j,8,8,k,0,6              ",
+" =@lzieeeeee77eeex:fpcg4>9,,,,qjv6              ",
+" =O=blt7eeee7deenw:ffp<gha:t979;06              ",
+" =OO@=@zieeee7ex:::fffff0,v72444h6              ",
+" =OOo&Osst7iee7wkf:f:ff;t721444ham              ",
+" =#&&&&OO@di7eu:ff:fferiv114444hmMX             ",
+" =O&&&..o.sdp33fff:errrii7cc1hhh6mmNX=          ",
+" =O&&&@.o.@sberrrrrriiuxuxnB;44aMmVCO#OX        ",
+" =O&&o@..o.zrrrie777nnxtuxx:x;n:>mV##&&O$mX     ",
+" =O&&o....zrrieieuxunx7txx:nnfwpMmVZ#$ZZZVVN    ",
+" =O&oooo.*rrde77ewxnxxtnw:f4M%M%+NA#$Z$ZZVmN>   ",
+" =Oo&ooo@iree7inxn7nnuuff4h%M>m%S-AZ$CCZDZmSX   ",
+" =O&o.o.@rrn7eulun7xxuwp4mm6ahM%--AZCCZDDDANX   ",
+" =Ooooo.*rixenuwwn7nxupph%M>>h6mAADVVZVVDDANX   ",
+" =O&o.o.zrexwwnwuxxnughX%mahhmMN-AZCCVVDDAAN>   ",
+" *XOoo.*iin7n777xxxtphaM+ama>MSNFVCZZVVDAAAS>   ",
+"   1O..izewxux7nuuux4%++%hha>%N-DDCZZVDAAAASX   ",
+"    1.=ituu:uButnxxuX%>hh>M%++NADZZZVDADAA--X   ",
+"     :e7f::lnn7*ppnx6ahm6++mNN-ADCZVDDAAAA-SX   ",
+"     7nupp:wxxg%MMau6%++NmmmADADVVVVVDAA---NX   ",
+"    7uBgh1wwxg6h>m%:MmmVNAVDZVZCVZZDAAAAF-S+X   ",
+"    nfgaM%pnwhX6%mXb6$DVVZC$C#C$ZZDVAAA---+NX   ",
+"   27a%MaM47:mN.OoolmODGZ####$$ZZVDDA-----SSX   ",
+"   2gmg<m6p7wmmOo...O$GZ####$$CZVVDAAA----++X   ",
+"  qBcaM  <gxgmXmo.@.o&$$##$$$CZZZDADA-A-++-NX   ",
+"   M6>    paMa HX.@@@oZ$###$$CZVDDAAAA---SS+X   ",
+"  43            p=&@@&&$##$CCCVVVAAA--+S+S+%X   ",
+"        k         =o@.##$VVmmmNNNSSSSSS%XXXX    ",
+"                   s>OSSNmN>>aaa177777          "};
diff --git a/tests/marble.xpm b/tests/marble.xpm
new file mode 100644 (file)
index 0000000..1ef2607
--- /dev/null
@@ -0,0 +1,408 @@
+/* XPM */
+static char *granite07[] = {
+/* width height num_colors chars_per_pixel */
+"   384   384       16            1",
+/* colors */
+". c #000000",
+"# c #111111",
+"a c #222222",
+"b c #333333",
+"c c #444444",
+"d c #555555",
+"e c #666666",
+"f c #777777",
+"g c #888888",
+"h c #999999",
+"i c #aaaaaa",
+"j c #bbbbbb",
+"k c #cccccc",
+"l c #dddddd",
+"m c #eeeeee",
+"n c #ffffff",
+/* pixels */
+"aacfedbbcbbaaaaaaaaabaabaaaaabcbcbbbabbchfdcccbbabbbaaabaabcbaa#aa#######a#aaaabcddeefhec##dgbabbaaadabbcfbaa##########aaabbaaa#a#####a#aa###a#aaabbbbcbbbccdedaaaaa#aaaaa#a#abaaabbabbbeddbbaaaaaca##a#aaaba########aaaadcababbabdehd.##.a######.cgdcb###b##.##.##aaaaa####abcba######a##aac#a##a####aa#aa##babbbcfccbbbcdccccecbbbcbbbcdccddcbcdfeecbhhjihhgffc.aaa####.#######aaaaaaaabbaaaaa",
+"aaacedccbbcbaaaaaa#bbaabbbaaaabcaabbbbbbafhfccbbbbbbabacbacbaaaaa##########a###abbcdeghhhcagb#ababaaccbacdfca#a####aa###aaaaabaaa#####aca#aabaababbcccccccbcdfdaaaa###aaaaaaaaaaabbbbbbccccccbbcbcaaa##aaaaabaaaa###abdaccceebaaaabehja####a######..#aeec#bb##########aa#####abba#########aaca########aa#aa###aaaabddbbbbbbbbbbccbbabbbbabbabbabcbcbcefhfeddccefhhijheecb#...a####aaaaaaaabaaaaa",
+"aaabccccccdbabcbaaa#aaaaaaaaaaabbabbbbbccabefdccabcbbabacccbaaabaa######a######aaabceiiiihije#bbabbaaeaabcedcaabaa########aaaabaa##a###ab#aabcababbccccccdeeeecc#a##a##aaaaaaaaaabbbbbbbcccbbbdcbbcdaa#a#aabbaaaaa###acbaa#bccaa#abcfig.#######.#######acddgefdda#######a########a#######aaaaaa#a######aaaa#####aaacdcbabbaaabbbcaaaaaaaaabbbaaabbaabbbcbcbabbabcdeefghjkjgc#..####aaaaaaaaaaaa#",
+"#aaaaaacbccbcabbbaaaaaabcaaaaabbbbbbabbbcbaabffccbccbccbbcbaaaabaaaa#aa#aa##a#aaaaabbikkjhijicabbbcc#faaacdebcbda#########aaaaaaaaa####aa##cacccabcccdccccdddfdcbaa##a##abbbabccbbcbbbccccaaa#abbaaba#a##abbbbbaaaaaaaaaaccaaca##aabcfic.###aa#######a####bddeeddb####.##.###aaa#########aaaa###aa####aaaa#######aabdbbbbcabbbaaaa#aaaaaaaaabaaabbbaabbbbdbbaaabccccccdcefhhkhda##aaaa#a#aaaaa##",
+"#aaabaabcecbaa##bcaaaaaaaababbabaaabbabbaabb#chhfdccccbcbecaaabaaaaaaaaaa####aaaaaaabdgjkkijijdabbdcabfaabcecbbec###########a#aaaabaa#######abbaaaadddedddeeefeccaa###a#aabcccdcbcbbbbccbbbbaaaaa#aabbaaaabbbbbbaaaaaaabbbbbaaa####acegha##a#aabbb####a##adccdedbcc#######.###a###a#######aaa#a#aa##..#aa#########abdbaabbabbbaa###aaaaaaaaaaaaacbaaababbdbabbabcbbcbcbccbbdegjkgb#aa#aa#aaaaaaa",
+"##aa#aabccccaaaaaaaa#aaaaaabbaabbbaaaaabbbcbbcfhhgfcccbbbbccbaabbaaaaaaabaa#aaaabaaaabbcehkljjdabacccbgbaaccdb#adea#########aa#abaaaaa#####ac#ba##accdedddefffeaba##a#aaaaacccccccbbbcccaabaaaaaaaaa#aaaaabcbbaaa#bbbbaaefccdbaaa#aaacdei##aa##aabbbaaa#a#cdcccccbcea.#########bbaaa######a###a#aaaa.#aaba####.###abcbaaabaabbbaa###aaaaaaaaaaaabbaaaaaaaaaaababcbbcbbaabbbdddeghheba##ab#abaa##",
+"#####bbaaaaabaaaaa##aa#adccaabaaabbbbabbabbbabccbccfdbccbbbbbcaabcaabaaabbaaaaaaaaaaaabbbcglli#accbbbddgabcddbbaacea#a##########aaa#aaa##aaaa####aabcddeeefffgdbbaaaa###baabbbbbbcdabdcbcaaabaaaaaaa#aaaaaabcbbbbadfbbbaejhhebbccaaaaaccfi.aba##abaaaba####ecbbccba#fc.####.##.bba#a#######aaaaaaaaaaa##aaaa######abcdaa#aaaabaaa###aaaaabaaabbbaaba##aaababcbbcbbbbbcbaaabbccccddgggeb#aadca###",
+"#####bcaaaaaabcbaaa#aaaabcccaaaaaaabaaabbbbbbbaacbabeeddddccbcbbcccbabaaaabaabaaaaaaaaabbbbglmdbcbaabebdgdbcecbbaabdbaa#########aabbaaaa#aa#a##a#aabbdceeedccdcbbaaaaa##aaabbcbbbabaaabbababbaaaa#aaaaaaaabcdccbbbabcbbbcfijfbcdcabb#abcbif#abb##aaabaaaa##fcccbbcaa#db#..##.##.aaa#########ab#aaaaaa#aabaaaaa#####abdbbaaaabbaaaa###b#a#aaaabaaaaaaaaaaaaaabbabbbbaabbbaaaabbbbbbbceffecccbaa##",
+"#####abaaaaa#accbbbbaaabaaaaaaaaaaadcbaabbabbbabbdcaacgfddddcdddcadfcaaaabcbbabaaaaaabcabbbdjliacbababcbdfcdeeaaaaaabba########a##aa#aabaa##a######abddeggca#bcbaaaaaa####aaaaaabbbbbcbbbbbaaa##a#aaaaaaaabcbccbbaaaabaabfgfiecccccbbaaaccicbbbcbaaabaaabb#ceccccdca##aacdb######aaa###a###aabaaaaaa#aabca#abba#####abca##aaaaaaaaa##a##aaaaaaabaaaaaaabaaaacbcbacdbaaabaaaaaabaaaaabbcddccbaa##",
+"####aa#aaaaaaabccbabbaaaaaaaaaaaaabfaaabbcbbbbbabdebaabdffddedefedccecccdcbbbbbccbccbbbbbbccekldaabaaabccbfaaaaaaaaaaaba########aaaaaaaaba##aaa###aabbccfgfaababbbaaaaa#aabbaabaaccaabcccbcbaa##aaaaaabaabbbccbbbaabbbbbbdddghdbbbcccb#abcdebcccbaabbbabbcbaecddddbaa##.#acdeca#######a#aaaaaaaaaaaaaaabba##abba####aacba##aaaaaaaaaaaaa##aba#abaaaaaaabaaaabbbbbbcbabbaabbaaaaabaaaaaaaaccbaa##",
+".####aa#aabaa##bccbaabbbba#aaaaabbaefdaabbbbccbbbaddaaabadeeffhhhffdedddeecbbbbcccbbabcbabbcfjjlkeaaaaacdadcaa#aaaaaaa#ab######ba#aaabbabcaa#aa###babcddcedba##acbaaaaaa#ababbbacbbbcccdfffbaa#aaaacbaabcbabccbbcbbbbbbcbbccedbbbccdccbaabcgb#bccbbbababbbcccdededcb#a####...addcba##aabbbbbbbbaaaaabba#aaa##abba####abbaa###a#aa#aa##aaa#a##abaaaaaaaaabababbcdbcb#baaaaaaaaaaaaaaaaaa#aaaaa###",
+"######a##aaaaaa#accbaaabbbaaa#aaababdcaaabbbbcccbbbdbabbbacdccgecadbbbcdccddeddcccccbaabcbbcgjhhjgeb#aacdcccaa#aa#aaa#a#aaa##aaaaa#aaabbaabb#aa###aabccddeccbbbaabcbbbcbbb#aacbbadbabcccddbaaa#aaaaabbbbabbbbcdbbbabbcddcbbbccaabbbccbbaaaadi##abbbbbbbaabbbacdeedbd######aa####bceda#aabbabaaaaaaaaba#aaaaa#aabaaa###acaaaa####aa##aaaaaaaa#aaaaaaaaaaababaaaaabcaaaaaaabbcbaaaaaaaaa###aaaa###",
+"##########aabaa#accbbabbbbbba##aaaabbcbbbbbbbbcbaaabdbbbbbbddccbbbbaaaabbabbbbcefefdcbaadbcddje#debgfbabecdc####aa##a###a#aa#aa##a##aaabbcabbaa###aabbcceedbcbaaaabdcccbabaaabbbbabbccbbaaaaaa#aaaaaaaabbbbbcbccabcccccdcccbbbbabbababbba#abfe#aaaaaaaabccbbaaaedddc######adcaaaa##dfcaaaaaaaaaa#aaaaa##aabcaaabbaa#aaab###aa###aaaaaaaaaaaa##aaaaaaaaaabaaabaaabcabaaaaaaabcbaabaaa##a###aa####",
+"#########aaaaaaabbcbbbbabcbaacbaa##aaabaaabccccccbaabecabbbcddbacdeba#aaaaabaaabbdfgedcbaccdcgica#aadghdbddd#aa#aaa#a###aaaabaa#####aaaaabbbbbba#aaabccceecbddbaa#bbccabcbbbbbacccdbbdabbaaaaaaa#aaaa#aabbbbcccdcbcbbccccccbcaababbdbabbba#bbgaabaaa#aaacccdcddbeedba#a##a#aba#aaaa##decbaaba#aaa###a#a###abba#bba###aaba####a####aaaaaaaaaaaa#aaabbbaaabbaabbaabbaaa#aa#a#abbaabbbaaa#aaaa#####",
+"############aaaaaaacbbbbbbbaa#aaa#a##aaaaaaaacbbbbbbabdcabbbcdbaccdba#aaaaaababbcbbdddedccddefihaa#aaahiiiffd#aaaa#abaa##aaaaacaa##a#bcaaaabbbcaaaabccdddecabaaaaacbbbabbccccccbbdbdfdaabbaaa###a#aaaaaaaabbbbbbbaaabdcddccbbbbabbbccaabbbaabfdaaabaa#aa##aabbbbbddba##aa#a#aa##aaaaaabcdbbaaa##aa#####a#aaabbaaaaa##abb######aa###aaaaaaaaaaaaaaaaabaaaaaaaabbbbaaabaaa#aaaaaaabbbaaaaaaaaa####",
+"###########aa#aa#aaaccabbaaaaaaabb#######a#aaabcbbbabbaeebbccbcbacdaaa##a#aabbbbccbbcbcdegifdfgifba##aaaagigha#aaaaabbaaaaaaaaabaaa##acaaaaabbbbbbabcdddefeba####abbaabccccbbbcbadcbcbaabba#aaaa#aaaaaababacccbaadbabbccedcccbbccbbabaaaaa##ade###abba#aa##abbba#cebb.#a####.#a#aaaaaaaaacfca#aaa###aa###abaabaaaaaaaabbaa#######aaaaa#aa#aaaaaaaaaaababdaaabbbbbababaaaaaa#aaaaaabbaaabaaaaa###",
+"##########a#aaabaaaaccaaaaaaabaaaaaaba###a##abaaabbababaccbcbbcccaaba#a###aaabbccdccccccdeegggfigaabb#aaa#fffcba#abbaaaaaaaaaaa#abba##aaa##aabbbcbbbbcdeegfeb####aabaabacbbbcbccaabbabaaaaaaa##aa#aaaaababbabbcbcdbbcccbddcdcccabcbbababba###afba#aabba#acaaabbbbaddb##aa####.####aabbaaaabffcaaaaaa##a##bcabbaaaaaaabbbc#a#a#######aaaaa#####a##ababbbbbaaaabbcbaaaaaaaaaaa#aaaaaabaaababaaaaa#",
+"#######a#####a#aaaaabcbaaaaaa#aabaaaaaa###abbabaaaaaccaaabdbccbccbaaca#####accddcccccccddeeefikjeabcca#a#abfifbaa#abbbbbaaaaaaaaa#bbba#bcaaaaaaaccbcccceffeccaa##aaabbbcabbacbddbbaabdbaaaaaaaaaaaaaaabbbaabbbbbbbbbcbbccccdcdcccabbbbbaaba###dcaaaabbaaabaabcbccaadba#aaa########aaaa##aaaacgdbaaaa####cfffda#a#aaaabbdbaa#aaa########aaaa#aa##aaabbabbbaaabbbaaaaaabaaaaaaaa#aaaaabaaaaaaaaa#a",
+"a###########aaaaaaaabbaabaaa###abaaa#a##a###a#aaaaabacaaabccbbbcbbbcbb####a#bdfbbccccccdefecdgiiddaabbaaaabacfeaaaaaabcccbaaaaaaabaaacaa##aaaaaaabccddcfgfgbabaaa#aaabbcccbccbcddbbacabbbbbbbbaaacbaaaabcbabbbbbcbbcbccbccdccdccdcbaabbbaabaaade#aa#baaabaa##abbcbacdb#.#abbccc#.##aaa####aa#aeeaaaaaaabbabddfgfba#aabcd#aaaa########aa##a##aaaaaababbaabbbbbabccbababaaaaaaa##a#aaaabbaaaaaaaa#",
+"#a###a######aaaaaaaacdaaaaaaaa#aaaaaaaaaa#####a###abbbbaaaaccbbbcbbbbaa#aaaaaeecabcccbccdedcdfgigeaaaacbaaabaacbaaaaaaabcbbbaaaaaaaaabccaaaaaaaaaacccceffffbabb#a####aaaabcccccddcdedbbbbaabcabbbccbccbcbcbbbbbbbbbcecbccccceccccdccbbaaaaaaabce#bbaaa###aaa##ababcacda#abb##a#######a#########bfdca#abcbaabaabcffddbabdc#aaaaa##########aa####aaaaaaabbabbbbbbbcbbbcbaaaaaaaa#aa#aaaaaabaa##b##",
+"##a#########aabaaaabcdbabaaaaa##aaaaabaaba######a##ababbbbbabbbbcbcdddbbaa#abceecabccccccdddfedgjgdbaaabaaabbbaaba#aabaabaccaaaaaaaabbccbbbaaabaaabcddefgfebbbb#aa####aaaabbcccccbbfeccbbbaaababbbbbbbccba#abbbabbcdccdcbddcddcccdcddcbaaaaaabcfbadaa#######a#abbacbbcc###a#a########a######a##aabdcabccbbababaaaacdfededbbaa#aa##aa######ba#aa#aaabbabaababcbbcbcbbbabbaaaaaaaa##aaabaaacba#a##",
+"##########a#abaaaaabbbcbbbcaa###a#aaaaa##aba#######aaaaaabbdccbaabccdddecaaaabccdbbacccddcdefdfgiifcba#bbaaabbaaaababbbbbbbabbaabaaaacbbbcbbaaaaaaaceeeefffbaaaa###a##aaaabbcbbbddcddddcbcbbaaabbbbababbabaaabababbbbcccdccddcddccccdecaaaa#abccfbbaaa#######aabbaacabe###a#aa#a#a##.aa#######a#aa#cfeecdcccccabbbabacggcabbaaabbaaaa####aabb#aaaabbababbbbbbcccbbbbbcccbbbaaaa#aaaaaababbaaaa##",
+"######a####abcbaaaaabbccbcbaa###a##aaa##a###aa######aaaaaabdgebaaabbbccacbaaaaabbbaaabccddcdeeffgigbaaaaaabaabcaaababbbbaabbacbaaabbaaaababccbabbabbdffefhdcaaa###aaabba#aababcbdeeccceccccbababbbbabbabbaaaaaabbaabbcbcccccdcddddccccdcaaaababcdeaba#####.###aaabaab#b####a####a##aa#b########aaaaabedddcccccaaaabbcabeaaaabbccbaaa#abbaaabbbaaaabbbaaacbcbcbbdccbaabbacbbbbbaaaaaaaaabbaa#####",
+"######aaa#abbcbaaaaabdccbbaaa#######aaa#####aaa##a#a##aaaababcbbaaaaabdebbbaaa##aaaaaaaabccddeefggieaaaaaaaacabaabbbabbbbaaaabbaaaaaaabbbabbccbaabbbdfgghebbbaa#####abba#aabbbcbccdcbbbcddcccbbbabbabbbabbabaaaaaaacbbabcbbccccddddccbcccaaaaaabbdcbc##########aaacbbaa####a####aa###a#aa###aaa###abbceddedcccbaaaacccdca##a#abbbabaaaabaaabbba#aabbbbbbccbbbbaaacccbbcbbaaabbbbbbabaaabaaaa####",
+"#######aa#aaccabbabaabdecbb#a########aaaa####aaa#aba##a#aaaaaaabbdcaabdcbcaacb####abb#abaabccdeffghfdabaaaa#acbbbbcbabcabcbaaaabbbabaaaabbbbbcccbbbccdfedccbbb#########aaaababbacccbcbbbddbdcccccbbbbaaaabbaabbaaaaabaabbbbccdcceedccccacbaaaabbbbddb####aa######aabbaa####a####aa#aa###a#####aa#aabbddeccddccbbbabbbbceb###aa#aaaaaa##aa####aaaa#abbbbbccacccbaa#accbbbbbaaababbabaaaaaaaaa####",
+"##a#####aaaaaabbbbabacdddccaa########aa#a#####aaa#aa#aaaaaaaaaaaabcabbcbbbbababa###baaaaaaabccdeeehifbabaaa###abbcbbcaccbcbbbaabbbbabaaabbbbbbbbcccccddbccbbbbba#######aaabbbaabbcccbdcbbdbbddcdcccbabaabaaaaaaaaaaaaaaaabbcccddecccbbacccbbbaabbbceca############aaaaa#############a#############aaaaabccddcbbbabbbbbbba#####a##a####aaa#######aaa#babaabbcbaaa##abbbaabbcbbbbaaaaaaaabbaaa####",
+"#########abaaabbabbbbbddeccca##aa######a#aa####bbaaaaaaaaaaaaaaaaaabccbcccebacfdb#####aaaaaaabcdddcfgfccbaa##a##abcbbcbbdcccccabbabaababbbbbbbbbbcdccddbabbbbbba########aaababbbacdccccaabcbbcabddddbbaaabbabbbaaaaaaaaabbbddcddecbccbbbdcbabbbaabbcda#############abaaaa############a####bb##a####aaaaabcffdcccbbbbbbbb#######aaa###aaaa#######aabaaaabbcbaaaaaaaa#aaaaaabbccbbaaaaaabbbaaa####",
+"#########aaabbabcbbbbbdddcbaaaaa###############aabaaaa#aaaaaaaaaaabbabbdefffccbba###aa##aaaaaabcdceecggdcbbaa##aa#aacbb#bcdddddabbbbbabbbabbbbbbbccfeedbbbbbbcbba#a#####a#acababbbdcbcbabbabaabaabeedcaaaaaaaabcbbaaaaaaabbcdfdddccbbbbcbccbabbbaaabcda########a#aaaaaaa#aa#####aaabaaaaaaacb##aaa#aaababbcdefddbbcbccbaa#####aaaaaaaab##a########aa#abbcccbaaaaaa###aaaaabaabccbbbaaaaaaaaa####",
+"########aaaaaaabbbbbbcdedbbbbabaa##########aa###bbb###a##aaaaaaabbaabbbdfeedb##a#a##aa###aaabbbbccdefbfecbbbaaa####a#adb#acdecdfcbaabcbbbbcbbbbbbcdeffbcccabbcdbbba#a###a#aabaaaaaccccbaaaaabbbbaabdfedaaaababbbbbaaaaaaababbcedcccbbbbaccccbaaaccbbabeb######aaaaa#aaa###a######aaaaaaabacbca#aaaaaabbbbccdegfeccccccbcbaaa#####aaaa#aaaaa###a###aaaabbbcccb##a#aaa#aaaaaaaabbdeddcbabaaaaa####",
+"#########a#aabbbbbbbbdddccbbba#aaaa##aa##a####a#bba#a#a#aaaabaabbbabbeedeeefdaaaa#####bb##aaabbabcddehgifffdcbaaaa#aa#aaaaaccdeddcabbbcbbbccbabbccdceeecdcaaaabbcccaaaaaaaaaaaaaabacdddbaabaabbbbcccccfdbaabbaabbcaaaaaaababbcccccbbbbbbbccbcca#acbbbbbda#####aaaa####ab##a######aaaaaaabaccbaaaaabbbbbbccceffcdeedcbbbbaaaa#aaaaaaaaa#aaabaaaaaa##aaaabbbcbbcbaa#####aaaaaabbbcccddcbbaaaaa####",
+"##########a#aabbcbcbbcecccbbbabaaaaaa#####a#aaaabbaa##ba#acaaababbbbbbbcdcfgdbbbaa####aba##aaaabbbccdfefhfgedecaaa##abaaaaacbabebbbbbbbbcccbcbbbbddbedbddcaaaaaabdccaaba#aaaaaa#bbbbbaddccaaabcbbdcbbcbddabbbbbbbccaaaaaaaaabcddcbbbbbbbbbbbbbbaaaabbaabe#########a####bb#aa#####aa#aaaabccdbbbbabbcbbbccccdccbaaeffdbca#aaaa#aaaaaaa#aaaaabaaaa#aaaabaabbccbbcceb#bcaaaaaaaabbbbcdcbbbaaaaa####",
+"#######aa#aaaaabbccbbcdccddcabaaaaaaaaa###aaa#aabcaaa#bba#aabaabbbbbbabcccdfedcaa##aaa######aaaabbbbcdddghhgfedcbaaaa#aaaaabcbbbccbbbbbbbcbccdcccccbeebccbbbaaaaaccccccba#aaaaaaabaaabbbddbbbbcccbcccbaceeacbbbcbccbaaabbabbbbceccbbbbbabbbbbbbab#aabbbbcc#.######a####.bcbcba####aaaa#bedccbbbbbbbaabccddedaaaaa##beeda#aaaaaaaaaaaaaaaaaaaaabba##babbabbbbcbbbccccbbaaaaabbabaabddcbbbaaaa####",
+"##########aaaabbbbccccbcddddbaaaa##a#a#a###aaaa#baabbaaaaaaaabbbabcbaabccbddfebaaba#ba######aaaabbbbbcddfiiigggedbaaaaaaaaaabcbabccbbbbbbbcccddddccceecccccbbaaaabccddbbba#aaaaaaaaabcbbbcccdccbcbabcbabceecbabbbbbbaaaabaabbbcddbbbbbbbbaabbbcbbbbaaabcbdc########..####ccccba#abbaaaabddbabbbcabbbbcccceeca###aaa##aaa##a#aaaaaaaaaaaaaaaaaaaaa##aabcbbbbbbbccbbbbcddaaaaacbaaaabddbbaaaaaa###",
+"############aaabbabcddccdbcdcbcbbbaaaaa##a##aaaa##abaaabaaaaaaabbaacaabddabcefc#aabaaa###a####aaabbbbbbddgihhfffgeaaaaaaaaaaaaabbbcbbbbbbbbbcddeeedceccdcccccaaaaabcbddbaa#a#ab#aaacbbbbbbddebbbbccbbbabbbedbaaaaaaaaaaaabbabbccecbbbbccbbbbaabbbbcc#aaabbcc######a#####.bccabbacbababaabdcabbbabbabbbcbdecabaa##aaaa####aaaaba##aaaaabaaababa##aa#aaabbbbbbbbcbbbbacbedbaaa#bbaaaabcbbbbaaaa#aa",
+"#######a####aaaaabaabbcccbabbbbbbbcbaaa######a#aa######aaaa#aaa#acbbbabeeebabddbaaabaa####aa#a#aababbbbbcehhgeeffdca##aaaaaaaaaabbbbabbbbbbcdcdddfgfhcbbcbbbcbaaaaabcccdbba###baaaabcbbaabcdeecaaabbbbbbaabddecaaaaaaaabbbbbbbccfcbcbbbbbbbaaaaabbbcca#aabacc#######a####acdcbbbbbbaaaabbccaabbbbbbbabbceecabb#aa#aaaa#######aaa##aaaaaaabbaaaaaaaaaaaabbbaabccbbcbaaacgdaaaa#aababbbabbbbaaaaa#",
+"###a#####a#aaaaaabcbacbbddcaaabbbbbbbaaaaaa##a#####a####aaaaa#aaabdbcbbedefcaaabaaaaabaaa#a##abaaaaababbbcfgggfeefea##aaaaaaaaaaabcbbbbbbbbcdcdddefgeabbbbaabccaabaaceddeeaaa##aaaaaabbbabbcdedbabbbaaaaaaaacfecaaaaabaabbbbbbcdfdbccbbbbbaaaaaabbbcdbaa#aabdb#########a#acdcccbaaab#aabccbbbbbbabbbceedccbcbbaaaa#baa#a###a#a##aa###aaaabaaaaaaaa##aaaabbaaabcbbbbbabbdfeaaaa#ababbcbbaabaaaaaa",
+"#####a#####aaaaaabbbbbbbcddcbabccaaabbaaaaa#a##a##a######aaaaaabaaaaacbbbffeaaaababbabbbbbaa##bbaaaabbbbcccghghgeffbaaabbaaaaaabbabccbbbbbbcdddefggecccbabaaabbbacbabbdddecbaa####aabaababbcccdcabaa#aaa###abceedcaaaaabbbbccddefdccdccbcbbaaaaabbccdccdb#abbd###a#####a#a#cddcccaaaaaaaaabccbbbbdeefbba##aabaaa#aaaaaa#aa###aaa##a####aaaaaaaaaaaa##aaaabacbabbbbbcbbbbcfgbaaa#aa#abbab#aaaabba",
+"##########abaaabbbbbcbcdcccdcbbbcbbbbbba#aaaaa#a############aa#aaaaaaababbdeaaaacbbbbbddcbaaa##abaaaabbbbcccghhhedecababcbaaaaaababcbbbbbccbddceggffecccbbbaaabca#aaaadddedcb#a##aaaabbbabbbbcccdd###aaaa#aa##bcefeddcddccefdddfdcccccccccbbaaaaaabccccdddaabbda########ab##bbbddcbbaa#aaaabcbbbcdddccaaaaa#abaaaaaaaaaa#aa#aaaabaa#####aaaaaaaa#######aabaacbabbbbbbcbbbbdfbbaaaa###baabaabaaba",
+"###########aaaabbcbbbcccbddbcdccbbbbcabbaaaaaaaaa###a##aa###aaaabaaababbccbbdb#abccabddbbbba#aaaabdbbaabbbbcdehihbaabbbbcdcbbbbaababbedcbbaccdddeeefedabbabaaa#aaa#aa#beeeeffca###aaabbbcbbbbbbcced#a###a##aaa#abffgfedcccfhcbdebcbccdccccbbaaaaaabbcccccddbaabdcb#.#aa#aaa##abdddcbbbaaababbbbbcbdbabbbbbb##ababbbaaaaa#aa#aa##aaa######ababaaa#####a#aabcbbbabbbbbbcccbbbeabcbba###aaaaaaaaaab",
+"b#########aaaaababbbbabbbbdebcccccbbbabaaaaaaaaaaaa########aa#abbaaabbabbdbcbbbaaadcbcbdbabba##aa##abcb#aaabcdcfhgdabbbccdcbcbbbbbbabcgdcbdbbdedeeehfgdbbbbbaaaa#aaa#abddddgeedcaaaaaabbbdccccccbceeaa###a###aaaacfghhgedccggefbccccccccccbbbbbbaabbcccccccdaabaaccb#aaa###a##adedccbcbaaabbbbcbbcddbaaabbbbaadbbaabbaaa##abaaa#aaaaaaaa#aaabaa########abbadccaaabbbcccccbbdcbcbbba###aaaaaaaabb",
+"aa##########aaabbbbbbbaabbaccbceeebbaabbaabaaabbbbaaa###aaaba#aabaaaaababbccggcbaabccbbbccbca##aaaabdbbabbabbcdddghbabbccddcbbbcbbbbbccgfcbccceddddeddedddcbababaaaaaa#accdeffedbaaaaaaaacccccbbbccffb#a#####aaaaabfhgghhhhgghecbccbccccccccbbbbaaabbbbcbbbcdcbbabbcb#####abca#abccccccabbbbbbbbbdddbaaaaabab#cdba#aabaaaaaaaa#aaa#a#aa#####aaaa#######aabbbbccbbbabbdeddcbbeaabbcb###aaaaaaaaab",
+"baaa######a#aaabaabdbbcbabbaccccedaaaaaaaaaaaaaaadbaa#aaaa##aaaaaaaaabbbcbcccdbaaaaabdcbacbcdcaaaaaaaabaaccbbccdddhgcabcccdecbcbbcbbabadedbbcdedcddeeccdddeeedcbbcbaabbbabbcddddec#aaaaaabbcccccbccdffc##a##a#aaaaaafheffhgeccefcbbcbcccccccbbbbaaabbbbccbbddedbabbcc.##a##abc###cdcccbcbbbabbbaddccababbbaaabaddba##aaaaaa#aaa#a#aaaaa##aa##aaaa#######abbbbccbcbbbbdefeeccecaaaaa####aabaaaaaa",
+"bb#a########aabbbaaababcccdaacdbbaba#aaaaaa#aaa##acaa###aa#aaaaaaaaaaabcdcccaaaaaaaaadbcbbbbacc###aaaaaaaacbbccdcdfggbbbcccdecccddcbbbacdfdbcdebbbcccdcccccdcbefccbaaaaabcbbccabdfcaaaaaaabbdddccccccefe##a##aaaaaaaadfghhhdbbcccccbcbbccdccbbbcaaaabbbbdccddeeba#bbda######.acabbddccabcbbbbbbbddccaaaaaaaaaaabdca#a#aaa#aaaaa##a#aaaaa##aa##aaa#a##a##abbbbccbbdbbccefffeccd#a########abaaaaaa",
+"aa##########aaaaabaabbaaccdcaacbbaab####aaaa#aaaaaa#a####abaaaaaaabcaaabddcacda#aaabacbbbbddddcbaaa##aaaaa#abbdcccdegfbbcdcdefccddccccbcbbfdccecabccbcbbbcdddcbffdcccb#aacbaabcbbeecaa#aaaabcedddccccddfeb#####aaaaaabbehhfcccbcccccbbccccccbcbcbbaaabbbcdcceddcbbabba########bcbbcdcbbbbbbbbaacccccaaaaaaaaaaaabcba####aba##aaaaaa#aaaaaa##a#aaaaaaa#aaabaabbcbbbbbbbdffffeeeaa########aabcaaaa",
+"aba#a#aa####aaaaabbabbabbaccaaabaaaa#######a####aaaaa####aaa#bbaaaabaaacbddcbccaaaaaaaaaaacdeabcbba#a###a#aaabccccdeegfcbcdddeedcdccddccccfedddcbbccbbbbbbccddedecccdca#aaaaaaabacedcddcbabaabccccccccceccd####aaaaaabaacdghhfecccccbbccccccccbcbbbaabbbcccccddcddceaca########cdccdccbbbbbbbbbccbcdcaaaaaaaaaaaaaaba#####aaaaaaa###aaaaa##a####aaaa###aabbbbbbccbdbbbcdefffgaa#a#######aabaaaaa",
+"aa#####aa###aaababbccccbbbbcbaaababa#######a#aabaaaaaa####aa#abbaaaabbaabbdcbbcdbbbbaaaaaabcddbcbba#####a#aaabcdccceefhgbbdcceeeeccccccddeefeeecccacccbcbabbccdefdbcebaaaabaababbbcdcdfffdabbbbbcccccccecade#aa#aabaaaabaackijkidbbbcbccccccccbcbbbbaabbccccccccddegfdaa#######ceedcbbcaacccccbcccccbaaaaaaaaaabaaaaaaaaa####aaa.baa######aaaa####baaa#aaaabbbbbccdcbbcddedfgfb##########abbaaa#",
+"#a########aaaaaaccbbcdcccbbbba#aaaaaa#####aa#aaab#aaaa#.###aa#aabababcbabaccbccdedaaaa#aaaaabccacbaa#a######aacbcccdffhigeccccdeedddccbcddffdefcbabbbcdecbabbbbcddecddbbaaabbabbbcccddeeffabbabbbbcccccdecdedb#a#aaabbaaaaahifgikfcbcccccccccccbbaaabbcbbbccbbbbcccdhea#a#####aedfebccccbbcbcccccccbaaaaaabaa#aaaaaaaaaba#b###aaa#b#######a####aa##abbbabaaabbbbbcdecbbcdedefghc#########abcedcb",
+"a############a#abcbbbcddccbbbcaaaaaa#a####a#a###ba#aa#######aaba#bbbbbccaabcccddeebaaaa##aaaabaaabaaaa#####a#aaaabcbdeggihfccccdddffdcbcccdfcbcbbbbbbccbbbbabaabcdfebcbbca##aabbbbcdcdfffeeaabbbccbbcccdeeddeed##aaabaaaaachgcccfijebbcccccccccbbaaaaabbbaabbaabbcbbcfecaaa#aaadcddbbdcccabbcccbbbabbaaaa#aaa###aaaaaaaaaaaaa##aaaaba######a######a#abbbbbbabbcbbbddcabcddddefgfa########aacedcc",
+"#######aaa#####aaaccccddcdcccbbaaaaa####a####a#aaaa#aa#######abaaabbccacdaadccdddccba#aa#bbaaabaaabaaaaaa#aaaaaababbbdeffiiebcccdddeedcccdcfbcbbbbaabcbbbbbbaaaabcdeefeeddedbaaabcbdccefffffabbbbbbbbbcdcdddddefbaabbbbabaeidccddcejgbbccccccccbbbbaaabaaaaabaaabccccdffebaabbaaddcc#cdccabcccccbbbbbaaaaa#aaaa##aa#aaaaaaaaabaaaba#b##a####a#a#a##a#aabbabbaabbbbddecbbdcccddeega.##.#a##aab###",
+"#########a#####ababccbbbdcccccabbb##aaaaaa#aaaaa##aaaaaa#..###aaaaaaccbbdcbbccdbccdaa##a#a#aaaaaa#ba###a#a#aaaaaaabbbcdeefhgeccedbbcdedeedgebbbbbbbbcdcbbbaabaaabacccddccccbdcaabbadddeefffgfbabbbbccccccccdddbggbaabbbbabhefcccddddihdccccccccbbbababaaa###aa#aabbbcdeeffa.##abcfedabccbcccabcbbbbbbabaaaaa###aaaaaaaabaaaaaaaaaaaaba#######aaab#####aaabaaaabbbaceffecbccddccdec#####.##aa#aa#",
+"#aa########a####abbccbbccdcccbbbbba#a##aaaaabaa#aa####aaba#.##baaaabccdabdbabbbbbcccbaa####aaaaaaa#aaaa######aaaabbabccdfeehihfggfdbceedddeddfdccbbcbbbbbbbbbbaaabaccccbbccdddecababedefffffhgdaaabccbcccccdddbfhfbbbcbbackdeeccdddccfhgbccccbbbaabaaabba#####a#aabbbdeddeda.###aeddcbaaccccccccbbbbbabaaaaaaaaaa##aba##abbaaaaaaaaaab######aa##aa###aaabbbaaaaabbbeffffdcdcdeffda######.###aaa#",
+"#aaa############aabcdcbcdcfedeecbbaba##aaaaabaa###b#a##aaaa####abaaacdcaacdaacbcaaaaaaaabc##aaaabaaaaaa######aaaaabbbdddeddfhhhhhhfcccffffdbaabcbdbabbbbbbbbbbaaaaabbcccbbbbcfdedbbadeddeefdefhffecbbcbcccccceddgibbbbbbdecccbbccccddddhidccccbbaacaaabba########aabccedddeda####cdcecbccccddddcbbbbbabbaaa#a#####a#######abaaaaaaa#aaaa#a##aaaa#a####aabaaaaaaaaabccddfgfddefge################",
+"##aaaaa#aa######aaabdccbccdeefebbaccb###aaabcbaa########aa######aaba#bdbbbcabbbbbbaaba##aba#####ababaaa##a#a##aaaabbcddedddeeefhghfddccdhecbbbaaaababbbabbabcbaaaaaabbccbbbbbbeefdbbbddbddffdggihiebbbcbbcccccedeicbcbbcdccccccccddddddcfifccbbbbabbabbbaaa####aa#aabcedddefeb##.bdcdeccbcccdddcbabbbbaaaaaa#aa############abaa#aaaaa#aaaaaaaaaa#######aabaaaaaaaabbabbcefgecbcc############a#a#",
+"##aaaa####aa##a##aaabcdcbbccdcdccbcaba##aaaabbbaa#aa#a####a######aabaaabaaaaaaaabbba#aa###a##a###abbbaa#aaaa#a##aabbcededddddeghggcdfedffddcbbbaaabbbbbccabbbbbcaaaaabccbbbbbbeccefdbcdbcbcefefhgghdbbcbcccccccdcefedbadccbbcccccddddddddeggcbbbaacaabbbaaa######aaaabdcdeedefbaa#deddcdcbbcdedccbbbcbaaaaaa##################aaaaa#aa##abaaaa#aaa#aa##aaaaaaaaaabaabbacdbacbaaba###############",
+"##a#aaa####aa##a##aaabbbbbcdeccbbaaaaabbaaabbaabaa###aaaa#########aaab#aaaaaaaaabbaaaa#a#a#aa#a#aabaaaa###abb##aaaaabcdeeddefghhhebbbfebbdddccbbbbbaaabdcbcbcbacbaaabbabcbbcccddbbcefecdcbbbcddehgggcbbcbcccccccdddffbbdbbbbbccccddddddddddegcbbaabaaabbbaaa######aaabbbcdefdeca#ddedcdddbacadedccbbbbbabaaaa###############.####aaa##a###a##aaa#aaa#abaabaaaaaaaaaaaaabcdbaaaa#a########a##a###",
+"a##a#aaaa#####aaaaaaabcccbbcdebbaaba#a#bbaaabbaaaa####aaa#####aa#abaaaaaaaabaaaaaabbbaaaaaa#aaaaaababaaa####aaaaaaaabcddddefedhhgbbbbcefbcdedcedabbbababbbcbbbbbbaaabbaabbbbbcbcddbbbcdcebbbbdcabehhebbbbcccccccceddhfddbbbbbccccddddddddddcdfdaaaaaababbaaaaaaaaaaabbbbccddcdfededffddddcbcabcddccbbcbbaaaaa#####################aa##a#a#######aa###aaaaaa###aaaaaaaaaabbccaabaaaa######a######",
+"aaaabaa##aa####aaaaaabbccccbcccaabbba#a##aaaabbb######aaaaba##aaaaababb##aaaaaa#aabaaaa#aaa#aabaaaaaacbaa####aaaaaaabcdeddefefhheabbbbbdfgfgedcfaaabbbbbbaaaaaacabaa#baaabbabaabbdeeeccabdccbbbcaachifbbbcccccbcccddejkeabbbbccccddddddddddccceebabbaabaaaaaaa#aaaabbbcbbcccddefgedfedddcccbaabcdcccbcbcaabaaaa########.##.########aa###a########aaaaa#a###a###aaaaaaaaababccaabaa#########aa#a#",
+"##aaaacb########aaaaabbbbcccbdcddbbcbc#aaaca##a#aba######abca#aaaa#aa###aa###aaaaaabbaaa#a###aaaaaaa##bcbba###a#aaaabbceedddehgfdaaabaccbfhiihffcaaaaccbaaaaaaacabaaabbaabcbbbbbbbcbdeffedfdb#acaabafjgbbcbcccbccccdefiicbbbbacccddddddddccccbbcfbbbbbabaaaaaaaaaabbbcbbbbccccdegfecfdbaabdabbbbcccdcccbbbbaaaa###################a#aa##a#a##a####a#aaaaa###########aaaaaabbbbbaabaa#######aa###",
+"###aaacba#######abaabbdcbbcdcbbefcbabcbbaaaaa####aa#a#a#a#a##aaab###a#aa####abb#a#aacbaa####aaaaaaa#aaabdcbaaaaaaaaabaceefeeffffbaaabbabccehigfeeddefdbabaaaaabbbabaabaaaaabbbbbbabccbabdedda##aaabbachhbbcbccccbbcccdeghebbbaccddddddddddccccbacecbabaaaaaa#aaaaabbbccbbbbcccdcdgfdfebbbbbcccbcbcddccccccbbaaaaa################aabbaaaa####aa###a##aba#############aaaaabbbddbbaba##########.#",
+"####aaaba#######aaaaabdfdbbcccbbdebbaaaab#aaa#a###aa###aaa###aba#####aaa#####aba#aaa#baaa#####aaaaa###aabcccaabbbbbcbbbdfffgeccebaaabbbbcbbeffedccfghhebaaaaaabbaaaaaaaabaabbabbbbbacbbbbcbdda####abbabghabbbccccbbccddddghdaabcddddeedddddcccbbabdfdaaaaa##aaaaaabccccccbbccddcbefdffdcbbbcdccbbccddcccccbbbaaaa################bbccbaabaa#aaaaaa#aabba##a#########a#aaaaabbccbcabaa###########",
+"#####aaaba#######aaacccefcccbcdccbcbbaaaaa#abcba#########aaaaaaa######aaaa####aa##aaa#aaaaaaa##aaaaa##aaaccddcccdddddcceeffdccdccbaaaaabbbbcfggdddfffggfebaaaaaaaaaabaaabccbbbbbbbabccbbbbbcbdb###aabbbbghbacccccccccccdddfigdbcddddddeddddcccbbbabbfeabaa#####aaaabcccccbcbdddecegfffcccabbccccbbccdcccccbbbbaaaa############a#aaaababaaaaaaa#aaa##aaaa#aaa##########aaaaaabbcccbbdba#########.",
+"#####aaaaa######aaabddefcccbabdccccbaaaaaa###aaa######aaabaabbba#######aaaa####a###aaaaaa#a##a#aaaaaaaaaabcddddcdeeedefgfefecdaabbaaaaabbbbbadfebcfdfgffeeecaaaaaaabaaacabdbaaabbbcdcbbbbbbbbccb#a###abbaegcabccccdcccccdddcfihfdccdddddddddcccbaaaaaddbaa######aaabccccbcbccdddhfcfgecccbbbbcbccbccbccbcccbbbbaaaa#a##########aaaaaabccbcba#aa#aa#aaaaa#aaaaa###########aaaabbaddedaa##a#.#####",
+"####aaaaaa#######cffdabcbcdcbbadfbcbbaa###a#aaa#aaaaaaabaaaababaa#######a##a#########aaa##aa##aa#aaaaaaaaabdeddccddddddffeeeec#a#aaabbbaaabbbcggdcfeeeeegfdccbabccbbaaabbbcaaaaabbbcdbbbbccbbbdbaaa###abbccebabbccccbcccccddcdfhjhedddddddddccbbaaaaaabdda#######aaabbddccbbdddedccdgeeedccbbccdccbccbcbccccbbbaaaaa#########.##aaabbaabbbcbaaa###aaaaaaa#a#a#a########aaaaabbaccddeb###########",
+"########aaa######acddbabcbbcccabcddcaabbaaa##aaaaaabbbcaaaabbaaaaaba########aaa#aa###aaa###aa##abaaaaaacbbbcdffeddeccdffffeddbaaaa#abbaaaabaabegebdfeddeffeddddcdddcabbacbcbccbaabbacccbcdbbbcdb#aa##aabbbbbffbbccccbccccccdddedfkkidddddddcccbbaaaaabbabdb#a#####abcccdbccccddfcccdfgeedccbbbcbccccbbabbcccbbbbbbaaa############a#a#aaaacacbaaa####aaa#aa###a##a######aaabaabbbbbbdfa##########",
+"#################abbcbaacccccbccaacbcaaaaaaaaaaaaaaabccabbbbaaab##bb######a#aba##aa##aaaaa##a#a#acabbbacdcbcddffffdgeefefeddcb#a##aaaaabaaaaaaddfdcfdccccccdcbcbcccecbbabccdddddcbbbbccccccbbbceb#aa###aaaabbfgbacccbcccdcdddeedgjkihccddcccccbbaaaabaabaadca####aabbcccbcddccefdcdeeeedddcacbccccccbabaaabbbbbbbaaaa###########.#####aaaabacbba##aaaaaaa####a####a######abbabbcbcbcdb###a##.##.",
+"###########aa#####bdbaaaaccddbbdcba#bbaa##aa#aaaabbbbbbaaabaaaaba##aa.####aaa##a#aaaaaabbbaa#####abaabbbbbccdddeefeffddefdccaa####aaaaaaaaaabaeefdedeccbabbbdddbbccccabbbbbbbbcdcccbcccccccccbaaaa#a####aaaabacgcabbcccdddefffedgijfehdcccccccbbbaa#aaaaaaabcbaaaaaabbccdcdddefgecddeefedccbbbabccbbbbaaaaaabbbbaaaaaa################aaabcbabbaa#aaaaa#aaa###a####a####aaabaabcbbbcbba###aa####",
+"############a#####abaaaaaabddccbcdddbaaaa###aaaabaaabbbaaaabbabba###b######aa######a##aacbcbba##a##babbccccdddddeeefgfeedccdb####a#aaaaaaaaaaadefedecbabbbbbcddddbcddcaabaaaaaabbbbbaabbccdcccbbbcb#a##aa#aaabbbfdbbccddddeffffefggeedjhedcdcccbbaaaaaaaaaaabbcaaaaabbcdcccdeefgdcccdefeccbbbbbbbccbbbbaaaaaaabbbaaaaa#######aa######aaabbbcab#a#aaaaaaaa#a##a#####abaaa#abaabbbbbbdccc####aa#.#",
+"###aaa###a#a#a####aabaaaaaabdbbbcecdcbaaaaaaaa#aaaaaaaaaaaaabccbb###a########a#a#aaaaa##aaaabca#a##aabbccccccdcccbbbbcbcabbbb#a#a#a#aaaabaaaabbeffddeabcbbbbcccccdccbbbaaaaa#abaaaaaaaaaababbbbbcbb#a##a##a#aaaabefcbdeeddeffffffeddfbchjieccccbbbaaaaaaaaaaaacfcabbbbcdddcdehggffeeddgfecbbccbbbccbcbbaaaaaaaaabaaa######a##aaa####aaaaaaabbaa##aaaaaaa#aaaa#####aabbaaaabbbbbbccccddbaaaa####.",
+"####aaaaa#aaaa#aaaaaaabbaaabccbbbcddbbdcbaaaaaabaaaaaabbbbaaaaabaaa###############aaaaa##a#aaaaaaaaaaabbccccdcbbbaaaaaaaabaaa#######aaaaabbbabaacffffbbbbbbbbbbbbccccbaaaaaaaaaaaa##aaaaaaabbccca#######aa###aaaabcgfcdeeefgggggggeffcbbehkjebbcbbaa##aaaa#aaaadheabbbcdddcegfbccdfffgggedccccbbbbbabbbaaaaaaaaabaaaaaa######aaaaa#aa##aaaabaaaaaaaaaaaaa##aaa##aaa#acbaaabababbcccdecbaaaa###a#",
+"#######a###abaaaaaaaaaaabbdccccbbbceefebcaaaaaa#aaaaaabbbcccaabaaa###aaa#######a###aaaba##aaaaaaa#aaaabccccccbbbaaaaaaaaabaa###a###a#aaaaacbababa#eeedbbbbcddbcbccbccccaaaaaaaa#a#aaaaaaaabbbbcba########aa####aabbbghdeeegggggghggfedbbbcdikgbbbbbaa#aaaaaaaaaabheaabccddegdccccdddccfffddbbabbbcbbbbbbbbbbbaaaaaaaa########a###aaaa#a#abaaaaaaaaaaabbabaaaaaaa#a##ccaaaaaaaaaabcccbacaaabaa###",
+"##a#aa#####aaaaaaaaaa#aabbbabbcbbabcdeedcbbbaaaaaaabbbccdddccccbbccbdcbcca########aa####aa##a#aaa###aabbccdccbbbaaaaaabaaaaa#########aaaaabcaaabaa#dfcccbcccbcccccdccccdbbaaaaaa###aaaaaaabbbcb######aa###aaaa###abbcfheeffghhghhijifcbbbbbehjhcbbba##aaaa##aaa##afgdbbcefecdcdccddddddeedcbabbcbbabbcbbbaaaaaaaabaa######a#a#a###aaaa#aaabaaaaa#aaaaaaaaaaaaaaaa#a#bcaaaaabaaaaabbcccbcabbbaaa#",
+"aaaaaaaaaa#aaaaaaaaaaaa#abaa#aaaaaaaaabcbbaabbbabbbbccddddddefdbcdccdecddcaa##aab######baaaa##ab###aaaabbbcccbbaaaaaaaaaaaaaa########aaaaaacdbaabaa#dcabccdddcccccdeeddddddbaaaaaa###aaaaabbbca#a#########a###a##aaabcegefgfhhggiiihddbbccbbfegihfb###aaaaa#aaaa##adgfefecbddccccddcedccefdcbabcdcaabbbbbbbaaaaaaaaaa#a####aaa#aa###aaaabaaaa#aaaaaaa#aaa##aaabaa##abcbaaa#aaaaaaabbbbdddbbbaaaa",
+"aaaabbabaaaaabaaaaa#a#aaa#abaaaaabaaaaaaaaababbbbccdddeeefdfffedccbbbbcccccaaaaacb#abaab#aaba#aaa###a#aaaabccbaaaa##aaa#abaa###a##a#aa#aaaaacca#abaaadbabddddfededcbbcaaabcddcaaaaaa###aabbbcdca######a####aa##aaaaabbcdkgghhhhhgiigecabbbccffedgiida#aaaaaaa#aaaaaabfecbccccbbbabbbddddddccbaaacdcbbcbbbbbbbaaaaaaaaa##################baaaaaaaa######aa#aaaaa#a##abbbbaaaaabbaaaababbddcbbbbaa",
+"aaaaabcccbbbaabaaaaa#aaaaa#aaaaaaaaaaaaabaaabaaabbbcdffefgffdcccdddcccccbaabaaacbab#aa##aaabb#a#a##aaaaaaabbbcaaa###aaaa#aaa#a###aaa#abaaaaaacccbaaaabcbaaccbbdccbbbababba#abccbaaaaaaaaaabdeabaa##########aa####aaaabbceghghhihiihhgcbbbbbbegdcdedhhdd#aaaaaaaaaaaaabdccccccaaabbbbcddddfeffdbbabcbbbbbbbbbaaaaaa###a#########aa#######acbaaa#####aaaa##aaaaaaaaa#a#aaaaaaaaaabbbbaabbccddbbbba",
+"aaaababbbccbbcbaaaaaa#aaabba#aaaaabaaaaababbbbbaaaaaa#aabbcaaabbbbbbbbbcbaaaaaabaaaa####a##aaaa######aaaaaabbbbb#######a#aaa#a###a##a#aaa#aaacbbcbabbabcabbbcddbaaabbaaaa##aaaabbaaaaaaaabbcdbaaa###########a####aaaaabbbcfihghhhihhhdabbbbbbeeccccbdehfaa##aaaa#aaaaaabedccbaaaabcdcddcbfeffddeedccbbbbbbabbaaaaa#############aa########ababaa###aaaaa###aaaaaaaaa##abaaaaabbbbbbbbbbbbcdffabaa",
+"aaaaabbacbbbabaaaa#aaa#aaaacba###aaabaaaaaababaaaaaaaaaa##aaaaaaaaababbccc###aabaaaa##a##aaaaa#aa##aa#abaaaacccb##a#a#a#aaaaa####aaaa###a#aa#ababdbbbabcbabbbbbbbbbcbbaaaaaaaaaaba#a###aaacbcdaaaa#########.#####aaaaaabbccfkjgfhhifdfdaaababbffcbbbbbacgda#aaaaaaaaaaaaaddcba#aabccccdbbdeefeddfdfecbbacaaaabbaa##############aaaaa#######a#aa###aaa####aaaaaabaaaaaaaba#aaababbbcccddddgihcabb",
+"baaaaababccccbbaaa##aaaaaaa#cddb#####aabbbbaaaaaaaaaaa#####aaa##aa#aabadedca#abbaaaaaa####aaaa#a#aaaaa##aababcbca#aaaa#####aa###a#aa##aaaaa#a#aaacbaabbbcbabcccbbbbcbabba#aaaaaaaa#bbaaaaabbadb###################aaaaaabacbgkkihhggfedaaaaaaaceecbaaaaabffgeca#aaaaaa###acdca#aaacbbccbcbeeefffdabdfecabaaababbaa#a##########aaaaaa#######abaa##aaaa#####aaaaaaaaaaaaaabaaabaabbbbbcdegghffdabb",
+"bbaaaaaabbcccccbbaaaaaaabaaaabccca###aabcceebaaaaaaaaaaa#a##a#####aa#aaaddbbaaabaaaaaaaaaaaaabb##abb#aaaaaaabcbba##aaa###aaa#########a#aaaaaaaaaaaaaabbbccbaabccbcbbbbbaaaaaaaaa##aaabaaaaccbed#################.##aaa#aaaaacekljihhhdbaaaaaaabdeedbaaaaaabceffdaaaaa#####abdd##abbbbccccbcedfeddbbbbdddbbaaababaaa#################aa#aa.###aa##ba##aa###aaaaaaabaaaaabaaaaababbabbbdfhjifeecba",
+"bbbaaababaabbcccbaaaaaa#aaaaa#aaba##aaabcbbccbaaaaaaaaaaaaa#aa####aaaaaabccbaaa#aaaabaabaaaa#abdca#acaaaaabaabbaba#aaaaaaabba##aaaaaaaaaaaa##a#aabbbbbbbccbbbacbcbabbbbbaaa#aaa##aaaaaacbccccdbbba#a########a#.####aaaaabaaaaafklljhfcaaaaaaaa#dcgfcbbaaabccccdggcbaaaaa#aaaacdaabbbbbbbbcbddeeddccccbbcecbaaaaaaaa#a##############aaa##a####aa##b###aa#aaaaaaaaaaaaaa#aabaaaaaabaabbdggghhfbdeb",
+"bbabbaaaaaabbcbccbabba#aaaa##a#aaa#a#aaabbabbbaaaaaabbabaaaa#a#####aaaaaadcba###aaaaaaaaaaaaaaabbaa#abaaaabbbcbaa#aaaaaaaaaaaa#aaaaaaaaaa#aaaaaaaabbbbbbbcbababbbcbbbbaaaa###a###aaaaaaaccddcddbaaba#aaaa####a#.#.#aaaaabbaaa##djlljc#aaaaaaaa#afdfebaaaabccccddegfdbaabbbbbbabddbbbbbbbbbadceedcdcccbbabdebaaaa#aaa#############aaaaaa#ab####a##ba#####aaaaaaaaaaaaaaaaaaaaaaaaaabcdfebbbabbbcc",
+"ecabbaaaaababcdcccbbbcdbaaaabbaa#aaaa##aabcbbbaabaaabbaabaaa#aa###aaaaaabecbaa#a#a#aaaaaaaaaa#aaaaaaaaaaaabbcbaa###aaaaabaaaaaaa#a####aaa#aabaaaaaabbbbbbdcbbabbbcbbaaaaa####aaa#aa###aaabcccccbaabbba##a####aa#####aaaabaaaaa##ahlkfa#aaaaaaa##fbbecaaaabccbcdddceghecbbccccbbbccddbbabaa#ccedddddccbbaaacfbaa#a##a############a##aaaaaaaaa##a###ca#aa###aaaaaaaaabaaaacabbaaabbbbddea###aaaabc",
+"abbcbbbbaaaabbccbbbbaaaa#a#aaaabcaaaaaa#aabbbbaabaaccbbabaaaaaaaaaaaabbabdcbaaaaa###aaaaaaaa#aaaaaabbbaabbbabaa#aaaaaa#aaacbbaaa##aa##aaaaabcbaaaaabacbccccabaabaacbcbaaa####aaaaa####aaaabdccdba#abbaaa#######a######aaaaaba#####dljfa#aaaaaaa#ddaadcbccbbbbccccdccehihfddccccccbbdfaaaabbbceefedddcbbbbaaaecaaaaa##a###a####a##a##aaaaaa####a###ba#aa###aaaaaaaaabbbbacbbbbbaaacccdd#####aaaab",
+"babbbcccbbbaacdbccbbbaaaaa######aaaaaaaa##abbbbabaaabbaaaaaaaaaaaa##abbbdcccbaa#aa#####aa#aaaaaaaaaaabcbabbabaa##aaaaaab#accbaaaaa#aaaaaaabcddbaaaaabbbccccbaabbbbaabbbbaa###aaaaa#####a#abceeeaaa#aaaaba#######a#######aaaaaaa###.cgjgb#aaaaaaaafcaacdcdcbcbbcbbccdeefeeghfeccccbcddc#aabaaaeffeccccbbbbbaaacdcaaba##aa##a#aa#aaaa#aa###a####a####b#a##aaaaaaaaaaaaabbbbcababbbbcdddeb#a#####aa",
+"bacbbcddcbbbbacddccbabbaaaaaa#a##aaaaaa####aabbaaaaaaabaaaaabaaaaaaaaabbcccbbabaaaaa#a#aaaaaaaaaaaaaaaabbccbbba##aaa#aaaaaabbbaaaa#aaa##abbaabbcbaabbcccccbbbbbabbbabbbbaa#############aaabbcedbaaaaaa#aaa######a########a#aaaa##a##adhjc#aaaaaaacdb##bddcbbbbaabbccefgecceffgfcbceccedabbaaacffdccbbbbbbbbbaabccbbaaa#aa####a###aaaaa#a##bb##a###ab##a###aaaaaaaaaaabaaabbbcbcbbbcefeb#####aa#a",
+"aaccbcddcbbabcbcddcbbbcbaaaaaaaa#aaaabaa##a#aaaa##aaaaaaaaaaaaaa#aaaaaaaaabbccaaaaaaa#aaabbaaaaaaaaaa##aabccccbaa#aaaa#abaaaaaaaaaaaaaabbbbaabbaccbddedcbbbbbabbbcbcbbcaaaa############a#aacbcba##aaaaaa#aaa#a###########a###aaaaa####adid#aaaaa##eca##addcbbaaaabbcddefddefddgiedccccffbaaaaaefeccbbbbbbbbbaabacdbbba####aa#a##a##aaaaaaccbba###.aa#aa#ba#a#aa#aaaaabbabcbccbcbcccegc######ba#a",
+"abcbbccdedcbbbabdddcbabbbbbaa##aa#aaabaa######aaaaaaaaaaaaaaa#aa#######aa#aabcbbaaaaaaaaabcaaa###abaaa#aaabcbcb#aa##aa#abbaaaaaaaabbcaaaaaabbgecbbbbccbbbbbabcabbcbbbbaaaaa##############aaabaaaa#aaba#######a###########ba#aaa#aaa###aabffcaaaaaabeb####cdcbaaaaaaabbccdeffeeegihfddddffcaaaabefeccaabbbbbbbaaaabdba#aa####aaaaa###aaaacccbbba#######aaaa#aa#a##aabbbbbbbccccccccddgf#aa##a#aaa",
+"aabcdddddddbbbccabcdccbaaaaaa#####bbaaaa#######aaaaaaa###a#####a#########aaaacbbbaaaa#accdddba#a#aaaaaaaaabbbcbaaaaa#aaaabaaaaabba#bdaaaaabeecbbcbcbccbbbbabbbbbbbabbbbaa#aa####a########aaaaacaabaabaa#######aa########abbbbaa##aaaa###aaegfb#aa##dcaaaabddbaaa##a##aaabcdfgffgiggfffedefea#aabffccbaaabbaaabaaaaacbaaaaaaa####a##aaaaaabbabaaa##aa##aaaaa######aabcbaabbccccbbddedeeaaaaa#baaa",
+"aabbdeedeedddaccbbbcbcccbaaaaaabbaccaaa#a#aa###aa#aaaa#########aa#a#####a##babbbbbcbbcfdccccbbaabaaaaabaabbbccbbaaaaaaaaaabaaaaaaaaacfcaaabcbbaaababbcaabbbabbbbbaaacbabaaa####a##.########a#abd##baaaaaa##.###aa#######abbadb#a#########aaeiib####bca#aabadcba########aabccdgghgfeddddeedegdaaabdedbbaaabbabbaaaaa#cbaaaaaaaa#a##a#aaa#abbbbaaa#aa##aaaaaaa#####aaabaabbbbccbbbcdecef######acaa",
+"baabcccddedddbacccbccdcbbbbaa####aa##aaa###a###aaaa#a#####aaaa#a#aaa###aaaaabbbbbabcgjfdccbbbaaaaaaaaaaaabbacccba###aaaaaaab##aaaabbbdfdbaabdecbbbabaabbbbbbbbbbbbababbaaaaaa######.########a#acdb#aaaaaaa######aa######abbccb####aa######afiifa###bca#aaaabcbba#a######aaabcdeefcbcedccccceffaaaaacdbaaabbbaabbabaaabcbbaaaaaaaaa##a#a##abbaaaa#ba##aaa###a####aaaaaaaaaaccbbbcccdeff.######aaa",
+"a#aabbbcdeddcccbcccccdcbbabaaaa##a###aa#a#a#####aa##a###a##aaa####aa#a#a#aaabbaabbbbbffdccbbbabbaaaabbbbbabcbbbaaa##aaaaaaaaa###aabcbbcdfdaacebbbbbaaabbbbbbbbbaaaaabbabaaaa###aa############abcdcaaaabbaaa######aa#####abbbdc#############adghf###cdaa##aaaabbaa##.##.##aaabcdecedbbcdecbbbccebaabacdaaaaabbbbbbbaaaaabdcbaaabaaaaa##aa#aaabaaa#bcaaaaaa###aa#a#a#aaaaaaaaababccdceec##########",
+"###bbbbcdeddddcccccbccbccbbbaaa#####.#a##aa######a##aaaa###aaaaa##a###aaaaaabbbbbbbccddcdcbbbbbcdbbbadecccccbcb###a###aaaabaaaa###accbbccfhcacbbbabbabbbbbbbbaaabbbaabbbaa####aa#########.####aabcbaaaabbaaaa#####a#####aabacfb###############dhhc.ddb###a###bbca#.#....##aaabcdccecbbccedbbcccedbabbdcbaaaaaaaabaaabaaaacccaabaaaaaaaaaaa#abaaabbcaaaaaa###########aaaaaaababbbceeda.#####a###a",
+"#baaabbcdeddddddddbbcccbcbbbbaaaa################aaababba####aaaaaa###aaaaaaabbaabbdecbccccccbbbccccbcbbbcbbddeeca###aaaabccaaaaaa##abbbbcdedbbabbaaaaabbbbbbbbaaaaaaabbaa#######aaa##########aabbbaaabbaabaaa########aaaaaabdfb####aa#########cghhceba###a##aabaa#.....###aaabcdceebbbbbddcbccbcdcabcedbbaaaaaaaabaaaaaa#cddbbbaaaaaaaaaaaaaaaaccbaaaaaba#a#a######a##a#aaaaaaccdeed####aa####a",
+"aaabaabccceeddeedcabbbcbbcbbbbbbaaaaa#########a##aaaaabbcbaa#aa#aaaaa#aaaaaaaaaaabbcddcbbbbbbbbbbbbbabbbbbbaabbdgfba#aaaaabbaaa##aaaaaabbbcceedaaaaabbabbbabbbbbbaaaaaabba#######aba#########a##abbcaabcbaabbba########aabbaabddca#aaaaa#########adjhaaa#aa#####aaa#...####aaabbcccfdabbbbbddcccbbccacffccbaaaaaaaaababaaa##bccccbabaaaaaa#aaaaabdcaabbaaaaa#########a#a#aaa###bcddhga####aa####",
+"##aabbbbcdffeddeebdcbbbbbcbbcbcbaaaaaa##.##aa######aabbbbaaaa#aaaaaaa##aaabb#aaaaacddfbcbabbccbccbbbaabbaaba#abadfdbbaaaabcaaaaaaaaabbbababbceedaaaabbabbbbbbbbbbaaaaaaaaa##.#####aa#########aaa#aacdabbbaaaaaaaa#######bbbbccdcddbaabbaaa####aa###bhgea#######.##aaa#####aaaababbbcebababbabdeccbbbceffeecbaaaaaaaaabaaaaaaa#bcccbbbbaaaaaaababbbbbaaaabaaa#######a##a#aa#aaaaabddhg###########",
+"#a#aaabcdddffdddeeedbbbbbcbbbbcbbbaabaaa#a##a##aacaaaaaaaaaa#a##aaaaacdaaaabaaaa#accdeaaaaabbbbccbbbbaaaaabbbababcdddcccbbaaaa#aaaabbbaaaaaabdeeeaaaaaababbbbbbaaaaaaaaaaaa###a####ba####a####aaaaaabecaa######aaa#####a#ababccccbcbabaaaaaaa###a####dijdb########a#a###aa##a#abbbbddbaaaaabbabdddcfeffffeccbbaaaaa#aaaaaaaaaa#abccbcabaaaaaaaabbaaababaaaaa#aaaa###aaa#aaaaaaaaabchga#####aaa##",
+"#a#a###abccdddefdeeecbbbbbbaabbbbbbbbba#########abaa#aaaaaaa##a#aaaaaccbaaabbabbcbbccfbcaaaababbbbbaaaaaaaaaaaabbbabbabaabaaa#aaaaaabbabaaa#abcdfea#aaaabbbbaaaaaaaaaaaaaaaa#######bba##########aaaabcedbb#######aa#####a##abdcbbccbaaaaaa#aaaaa#aa###bgjjga#######aba#aadba##aabbbccbaaaaabbaaabedffeffffdcbbaaaaaaaaaaaaaaaa#aaaccbbbaaaaaaaaaaaababbbaaaa#aaa#####aaaaaaaaaaabbbghc#####aaaaa",
+"a##a#aa#aabccbdfgeefeccababbbaabaabbbaa#a##.######aaaaaaabba##aa##abbbcbcbbccacbbdedgheccbbabbaaaaaaaaabbaaaaaaaaaaaaaaaaaacbbba#ababbbbaaaaaaabdeeca#aabcbaaaaaaaa#aaabaaaaa####.##ba###########aaabbceeba########a#########cbbbabbbaaa#aa#aaaaaaaaa###djkjb#b#..#abbcaaabcba##aaabbcaaa#aaaaabaacfffffedffccbaaaaaaaaaaaaaaaaaaaabcbbaaaaaa##aaaaabaaabaa#aaaaaaa#a#a#a#aaaabbbbccgc######aaa#",
+"##aaaaaa##aaccbaeihfgggcbabbbaaaaacbbceceeca########aaaaaabaaaaaaaabbbdcccdebbcbbabacedecbbbabaa#aaaaaabbbbaaaaaaaaaa#aaaaa#abbbbacbbbbbbaaaaaaaccddbbbbbbbaaaaaaaaa##aaa#a##a#####aa#############aaabbceeea########a########aaaaaaaabbaa###a###aaa######agjkhgfb.#aabddaaaaaaa###aabdb##b###aaaaa#cffffeeeeeccbaaaaa#aaaaaaaaaaaaaabcbaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaabbbbbdfeba####aaa#",
+"#a#aaaaa###aacca#cjjhhjebcbaa##a##acegebdcbdb#.#cbcaaaaaaaaaaaaaaaaaabbcdgiecbbaaabbbcbcdcbbbbbaaaa#aabaabcbaaaaa#aa#aa#aaa###aaaaaa####a###aaaabcddbcbbbaaaaaaa#aaaa#aaaaa##a#####baa#.#######a##aabbcdddffa##.####aa##.####aaaaaaaaaabaaa###########a####chhiihc..ceffbabaaabaaaaabccaacc###aaccbbegfffededdccbaa#a#aaaaaaaaaaaaaaaabcbbaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaabcccefeaaa###aa#a",
+"aaa#abaaaa##aaba##eiiikhccbddefeeffgecccdccdeffefddc#aaaba#aaabaabbaaaabcdhfbbbbaaacdecbbaabbbcbbbbaaaabbbbbbaaaaaa#######a###aaa#aaaaa######aaaaaccbcbaaaaaaa####aa##aaaaa#####a##############a##aaabcccccdfb##.#####a######aaa#aaaaaaaaaaa##########aaa##.#aejjifb#cffacbbbaaa#acbbcc##ddda##cddeefgfffeedddcabbaa#aaaaaaaaaaaaaaaaaaacbbaaaaaaabbabbbcaabaaaabbabbbbabbbbbbbbbbbdfc####a##aa#",
+"#aaa#a#a##a####b###dgkkjgccfiifdfdeeccddddcdcccccbca#aa##aa#aaaaabbbaababeggdbaaaaadfcbbbbbbcccbabcbaaaaabcabbbcbaaaaaa##########a#a########aa##a#accbbaaa#########aa###aaaa###aaa####.#########b##aabcbbcddfb###############aaaa###abbaaba#aaa#########aa#####djjjifbcebccdcba#bbacbcb##addccdcdeeefgfffeecbccbbbaaaaaaaa#aaaaaaaaaaaaaabbaaaaaaabaabbbbbaabababbbbbbbbbccccbbbbcced####a###aa#",
+"a##aaaaaaaaa#a#ba..#agkgfecfikgddcccdcccbcccbcbcbbdba##bccaaa#bbccccbaabbefffcaaaabdfbbbbbbbbccaaabaaaaaaabcbbbabbbbaaaa#######aaa############aa###abbaaa####a############a####a#######.#####a##aaa####aaaacfa#######..######aaaa###a#cdcbbbabcbaa#aab#########.chiiihfcddeghhgdccdabdaa#addcddceefeeffeeeedbbcccbbaaaaa#aaaaaaaaaaaaaaaaabbbbaaaaaaabaabbaaaababbbbbbbcccdccdcbbceea####aa###aa",
+"a####aaaabaaabbab#.#aaeecdhfijfcccddcccbbbbccbbbccaaa###.a#abccccbcbcbbbbbff#a###abcebabbbbccbcaabbaaaaabccbbbbbbbbbbbaaa#aa####aa##############aaaa#ababaa##############a#a######a####################aabbcacaaab#####.#.##abbaa###aaabcacbcaaaaaaa#aa#########.bgihiifcdgijjjiidaaabe#a#bdcbccccddddddecdecbbbccbbaaaaa##aabbaaaaaaaaaaabbbbbabbbaaaabbbbbaaabbbbbbbccdddedddefeffa####a#####a",
+"#######aaaaaaaaaa#.#abcdaahkkjgbbcccbbbbbcbbcbbbbaaaa#a######abddedccccbbacffcbb##acccacdcabbdccdbabaaaa#abbbbbaabbbbcba###a############.##.###########ababaa##################a##a###.################aaabcbcdbbbaa##.#.#.#aabaa###abcdcaabaa####aa#aabbb###a###.#bgjhacegijjjjjjhedfgea##cbbbccbbbcccccdcccbbbccaabaaaaaaaaaaaaaaaaaaaaaabcbabaaabaaabbbbbaababbbbbbccddddedffceedb######aa###",
+"aaa#a####a##aaa##a.##acda#cejjfdbbbbbabcbaabbcbbaa#aaa##a#a###baecbdfedddefhhgefea#cedbafecbbcbecbbccbbbbabbbbbbbccabbcdcaa####################.#######aaaaca##########################.########a######aaaaccccbbca#a########aaaa####bedcaabaa##aaaabaaabc########..#figefhikjihhhhiijiihd##bbcdbcccbcccddebcbbbbcdbaaaaaaaaaaaaaaaa#aaaaaabbcbbbbbbbabbbbbbbabbbbbccddedeedffa###a#####aaaaaaa#",
+"###aa############a#.##bccbbbbehhaabbbaaabbabbcbaba#aaa#######becdda#fgecddeehghegdabdecaabedbcaacbbddbbbbbbcbbbbbbdbaaccccba#########a################aaaaabcaba###############################a#####.###aaaabccbcb##a######aab##a###accbca#b#####aaaaaaaaa###.####...diihiiihfgeffeffhijid##ddcdccccccddddccbbaabddcaaaaaaabaaaaaaaaaaaaaaabbcbbabbababbbbbbbabbcbccdddedefc.##########aa#aaaa#",
+"#aaaaa#aaa##a######.#abbccaaaabgfb#ababa#aaaacbaaaaabbbab####edeefeccgedcddehhfacebadecaaaabcccbbbbcbabbbbbcbbcbccccccabccdb#######abb###a##############aaaacbccba##########a######.########a###a#########aabcceccb###a#####aaaa##aaaaacbb##ac######aaaaa##aaa#######..diihffffffdeddddefiigaaeddddbbcdddccdccbaaabcedbbbaababaaaaaaaaaaaaaaaabdcbaabbababbbbbbbbbbbbcceeegc.#############aaaaaa",
+"aabcbbaaaaaaaa########bbcdbaaaaaffa#aaaaa#aaabbaaaabcdeddabaefcdddefcgfddddeghcccffddbaaabbbbbccbccdbcbabbbbbbcbbbbbdcabbbddb########bca#a#######a##a###aaaaaaabdbaa#aaa####aca##...###aa####a##a########aaabbbdecc##aaa############aa#abba##a#########aa#aaaaa########.bgiedcccdccccccccdhigdeeeeedcdddccbcebaaaaaaceebbbbbbbababaaaaaaaaaaaabcccccfedcbbbbbbbbbbbbabcfffe############a###aaaaa",
+"a#aaedbbbbaaa#a#######abddca#aaaadcaa##aa####aabababbbccccfggcbcccccfgeccccdddffedfecddcbbbbccbbccdcddbbbbbbcbbbaabbcc#abaacba########aa##..#######aa####aaaaa###bbaaa#aaaaa#cc###a.####aa##aaa#########aaabbbbadcdaaabba##########a#aa#bbaa##a#######a#aa#aaaaaa#######.ageccbbbbbbbbbbbcbehigffeedddddccbcccbbaaa#accdcbbbbbbaaaaaaaaaaaaaabbcbccdbaadfdcbbbbbbbcbcefccba#################aaa#",
+"#aaacbaabbcbbbaa#######abcca##aaabbcba########abbaaabaabccdcbabbbccbcedccccccccccccedbbcdbbbccbcbbcbcbbbbbbbbbbabbbbcccbbaaaaaa##a####a#aa####.#####aa##a#aaaaa##abbcaaaabbbabcaaa#.#.###aa#a##a########aaabccabbddbaabaa####.##.aaaaaa##bba##############aaaa##a########.#bddbbbbbbbbbaaaaabfhhgfeedddccbccbdabaaabbbccddcbbbbbbaaaaaaaaaaabacbbcceb#a#babcbbbbbbcbce##.####################aa#",
+"aaaaaa#aaaababba#######abcccb#a#aaacddb######aaaaa#aaaaabbbbbbbcbbbbcdcbcbccbccccddbababcccccccccbbbbaaabbbbccbdcbbbbabcbbaa######aa#aaa############aa#####aaaaa#acbabaa#baabbcb#a##.#####baaa#########aaaabcdcccccbaaaa##########abaaa###aa##############a####aaa########.##dcbbbbbbbaaaaaaaabghgffedccccccbbcabbaaabbcbdedbbbbbbaaaaaaaaaabaaabccdecbcabbbcbbbbbcbeea###aa####################",
+"aaaaaaaaaaaaaa##########acceeba###bbbcda#######a####aaaaabbbabbabbbbbcccccccccbcbbcdcbaabbcbcccccbbbbbcabbbbddegebbbbbbbcaaaaa#########a######aba#####aa#####abaaaabcbb#aa##abaaba#####a##aaaaa######aaaaaaacccccbccaa##a#######aa#aabaa##aaa####aa########a#aaaaaa###########addcbbbaaaaaaaaaa#fieeeddcccbbbbbaaabaabbaaabdedcccbaaaabaaaaabbaabbbcdebaaccbbdddcbbcdc#aaaa###########.########b",
+"aaaaa#aaa#aa#############abcdfdaaaabcdf###aaaa##a#####aaaaabbccabbaaaabbbcccccbcbabbccbbbbbbbbbbbccbbcccbbbcdcdedecabbbbaaaaaaa########abb##aa#aaabaa#aba###a#aa#aabcccbabb###aa#aaa######aa##aa######aaaaaaaccccdaba###########aaa#aaba#aaaa#aa##a########aca##aaa######a######cffaaaaaaaaaaaaa#ehfeeedcbbbbbbcbaabbbbbbbaadeeefedcbaabbabbccbabbdcbcaabdcccccceedffb##aa####################a#",
+"aaaaa###aaaaaa#####.####aabccfgbaabbcfeda##aaabaaaaaa#aaaaaaaccbccbaaabcccbbccbbbbbbcbbbbbbbcbbbbbcabcccbababccdeccbabbbbaaaaa#aa########aaaaaaaabedaa##a#aaabaaaaabaccbaaaca###aaaaaa#####a###aa###a##aaa#aaaccbbabaa############aaaaaaaaaaaaa#########a##acdaabaaaa############acecaaaaaaaaaaaaafhffeddcbbabbcbbabbbbbbbbaabbdeddfeddbabbbdcabbabbababbbcbcbccddffcdaaaa##a###################",
+"aa#a#####aa#aaaa#########abcdcfeaaacbdccfcbbbdddbbbbbaaaaa#aaaabcbaabbbcccbbbcbbcccccccccbbcbcccbbbbbcccbbabbacddedcaabbabaaaaa##aa########cb##aa#cfdaa##aaababbbbaaaabbbbaabaaa#abaaa#####a#bbaaaa##a##aaaaaabbccdaaaaa#####bb#####aa##aaaaaaaa############aabbbbaaaa##aa##########deaaa###aaaaabcgiggddccccccccabbbbbabbaba#aabcaacccccbbcdbaacbbabbbbabcbcdddd####abaa#a##a#a#aa############a",
+"aaa#####aa#a#aaaaaaa######abccdfa#bbcddbcccdcdaaccdecbbbbbbbaabccbaaabbcccbbbccbccccddccccccddccbbbbbbcccbbbbbcccdddbabbbabaaaa########.####bba##a#aca###aaaaaaaaaaaaaabbbaabaabaaabba#######ababba.##aaaaaaaaabcdcb#aaaa#####a##########aaaaaa#a####aaaa##.##abbba#aab#aba#aa#a#####cgeaa####aa#aabfiigdccccbccccbbbbaabbbbaaaaaabccbbccccdabcbccaaaaabbbccdebdbaaaaaaaaa#a######aaaaa#########",
+"#aa#a###aaa####aa##a#####aabbbbeb#abbceeba#a####aaaba##cdbbbcccdccbbbbbbccbbabcbbbcbcddccccccddddddccdcabbbcbccbbbddcbbbbbbbaaaa#########.####aaa####a#a#aaaaaaaaaaaaaabbbbaaabaaaaaaba####a#.a##ab##.a##a##aaaabbddb##aa#####aa######.##aaaaaa#aa####a#aaa###abbb###acaacaaaa##a#####bff###a##aaa#aacghhfccbcbcbbcbbbbbbbcaaaabababbdccccddbbccccaaaaaabbccee##aaaabbacaaaa######aaa#aaaaaaa###",
+"#aaa##########aaaaa########bbbbbea#babcea#a######aaa####bccddcddedcccccccccbcbccbbbcbcddddcccbbbcccdefedcbaacbbcbbbbbbbbababaaaa############.###aa#a##aaa#aaaaaacbba##abbcbaaa#aaa#aa#########a#######a##aa#a#abbcbcc#a############aa####aaaaaaaaaa#######aa###aabaa##bbaaaa#a##aa######dea#####aaaaaa#behhdccbccacbbbbbbbcbbbaabbabbbcdcccdddbbbba#aaaaabbddb#######bcaaaaaa######aaaabbbaaaaaa",
+"aa#aa##########aaa########aabbbbbedbaabddcb#aaaa#aaaa####cccaacdeeggecccccccbbabbbbbbbbccddcccbbbbcbcddeedcbaaabbabbbbcbbbabaaaa###########.#####aba#######aaaaaabbba#aabbbbaa###aa##a#####.#a#.#.####aa##aa#aaabccbca#aa#..########a######aaa##aaa#########aaa#aaaaaabcaaaa##a##a###a#a#bdb#aaaaaaaaaaabcfhfccccabbcbbbbcbcbbbaabaabbabcddcdcccbba##a#a#abddb########aaaaa#aaa####aaaaaaaabbaaa",
+"aaa#aa##########aa#a#a#######abbabgebaabacca#ba#aaabaa#########a##bdeddeedddcbbbbbbbcbabacdddcccccbbbcdcdcdcabbbbbbababbbccbabaa###############aaabb####aa##aaaaabbbaaaa#abbbaa###aaaa###a###a##....###a##aa##aaabbbca##aa#.#######aaa##aa######aaa#########abaabaaaaaacbaaaaaa##a###a##a#afb##a##aabbbaaaaeggecebcbbbabbbcbbabaabbbbbbabbdddccccccabaaaaaaccc#####a#aaaa#a#####aaaaaaabbbaaabaa",
+"aaaaa############aa#a########.#abbcffcabbceccaaaaaaaaa###a###aa#######aaeebccccccbbbbcbbccbdddccccccbbbccbbbbbbbcbbabbbbbccbbbbaaa########.#aaa#a##aba#aa##aaabbbabbbaaa###abaaa#########aa##a############aa###aabcc#aa#aaa#######.##aaba#aaaaaa##aaaaa######baaaaaaa#aaaaaaaaaa###aaaaaa###ebaaaaaaaaaaaaabbfhgedbbbbbcbbbbbbabbbbbbbabbbbddecbcbbbbbbcbbbceaa#####aabca#a#a#a##a#aaaaaabbbbbaa",
+"aaaaaaa####aaaa#aa###########..#aabdddbbcccccaaaaaaaaaa##a##aaa###aa#####eddedddcddccbccbccccbbcbbcedbbcccccbbbbbbbbababbbcbbcbaaaaa############a#a#aa#aaaaabbaabaabaaa#aaa#abaaa#######aaaa#a###########.#aab##aacc#aa####a######..##aa#aaabbaaa##aaaaaaabbaabaccbaa###aaaaaaaaaa##aaaaa##a#ccbaaaaaa###aaaadgggfeababbcbcbcbbaabbbbaaabbbccddbcbbbbbcdccccca#a#a###aaaaaaaaaaaa#aaaaaaababccba",
+"aaabaaa#a#######a#aaa####aa###.###bcdcbcbabddbaacbbababaa#a##aaaa#aa#aacdccbddddddbbbbbaa#aaa######bfggfdcccbabbbbabaaabcbccabbaaaa#########a#aaaaa#######aabaaabbabbaa####aaaabaaa##aa##aaa#b####.#########abb#aaee##a###.##.##.###..####abccccbaaaaaaaaabcdaabbccba##a#aa#aaaaa#a#aa#aaaaaaaabebaaaaa#a##aabbfghhgedaaabbbccababcccbbbaabccbcccbbcbbcdcdcaaa########aaaaaaaaaaa#aaaaaaababbccb",
+"abaaaaaaaaaa######aaa########aa####bbccbbaabceaa#cbbbbbba#a##aaaa#aa###debacb#aacabaa##aa###########.#afhgeecbccbbbabaacbcccbbbbbbaa#a#########aa#aaaa####aaaaaabbbbbbbaa###aaabbba###a##aaa###.#######ba##aaadbaabeaa##aa#..###.##########abaaabdbaaababababbaabddbaa##aaaaaaaaaaa#aaaaaaaaaaa#aecaaaaa#aa#aaabdghhhfecccbcbbabbacccccbbbbbcbbbbbcbabbdcbcba########aaabaaaa##a###aaaaaaaaaabbb",
+"baaabbaaaaaaaaaaaa###########aaa####acccbaaaabcbcabbbbbbba#####aaaba#acbcaa#aaaa#abaa############.#####.dhihgeefccbbbbaabccbbbbbbaaaa##########a#aa#aa####aaa#aabaabcbbaa####a#aaaa###a#aaa################abbeebbbdd##a#######..####.######aaaaabcbbbbbbbbbbb#abcccbaaa#aaa#aaaaaa###aaabaaaaaaa#bcbaaaaaaaaaaaabehhhfedaaabaaabbccccbabbbbccbbabccbbbdcbbaaa#######a#aabaaaaa#aabaaaaaaaaaaabb",
+"bbaaaaaaaaaaaaaaaaaaa#########a#a####bbcbaaaaabeecbbaaabbaba###a#aaa##cedb#aaabaaaaa##a#########.##.###a#bfgedeffdccccbaaacdccccbbaa###########aaa######aaba###aabaabbbaaaa#####aa#a##abbaa####.##.####aaa#acbddddfega#a#######.######.##a#aaaa#aaaaaaaabccddebaba#bcba##aaaaaaaaab#aaaaabbbcaabaaaaccaaaaaaaabaabbehhfgebaaaaaaacdcccaabbcbbcbbbbbcdcbbcaaa#a######aa#abbaaaaaa#abbaaaaa#aaaaab",
+"bbbaaaaabbbaaabaa#aaaa###.#######a####abb#aa#a#cfecaabbaaaba#######aaa#bddcdaaabaaaa#a#aa######.########ba.a####bfddcccbbacdccccccaa############aaa######adb###aaaaaaabaaaaaa###aaaa##abaaa#####..#####aaaaabbcdeedfgd#aa########.#######a##aa#aaaa#a###a#abeedecc##aaba#aaaaaaaa#bbaaaaabbbbaaaaaaaaaccbaabaaababbadgggfdb#aaaaaabcbbbbbbccccdcaabbcdcccbaaa#######aaaaaaaa##aa###aaaaaaaaaaaba",
+"bbbbaa#aaaabaaaaaaaaaba#a######.#######abbbca##acdedcaabca#a#.###a######bddcfcaabaaa##a##a#####...##aa####a####a#abbccddcbbddedccccbaa####a######aaa#####acb###aaaaaaaaaaaaaa###########aaa####.####a##aaaaacdeceeeedc##aa########..#########aaaaa##a###aaaaaabcdedcb##aa#aaaaaaaaacbaaaaabbbbaaaaaaaaadfdaabaaaabbbbcdggfebaaaaaaacccbbbbbbccdcccbbbdcecba#####a####abbaaa#######a#aaabbaabaabb",
+"bbaacbabaabaaaabbaaabbaabb#.####.#######abbcba#aabecdbaccaa#a#.##aa##a###acacecbaaaaaa##########..######..abaa#aa####aceeddceggeddccbaa##########a#aaaa##aaa##a##aaaaaaaaaaaaa#########aaa####a#aaa####aaaabbdffffgebca#ab#######.#..#aa######aa###aa####aaaa#baabbdcc##b##aaaaaaaaabaaaaaabbbbaaaaaaaabcegcabaababbbbabgfgfdaaaaaabbabbbabbbcdddbcbccccdbaaa#a##a###aaaaaaa#########abbbbccbaab",
+"baaabbaaababaabbaaaaaaaaaaa##############abbaa##aadd##abbaaaa#.##aaa##a####aabcbaaa#aaa###a######..####.#..cdcbbbaa###abdcdedfghffddcbba###########aaaaaaaaaaaaaaaaaaaaaaa#aaaa########a#aaa#####aaa#a#aabbccddghhhfcca#aa##########...##########aa#aa###aaa##aaaa#a#bb####aaaaba#a#aaaaaaaabbcbbaaabaaabbefdabaabbbbbbbbfgggfdcaaaaabbbbbbbccdbdbcbcccbcbba##aaaaaa###aa#aaaa########bbabbbbaaa",
+"aa#a#aaaaaaaaaaaaaaaaaabbabaa#######.#.####aaaaaaabdeb#aababaa####aaa#abba#####aaaaa###a##bdba##a######....acdbabbaaaa#####cddaeggffedcba##########aaaa###aaa#abaaaababaaaaaaaaa##a###abaaaa###.#bbaaaaabdcddeefhhifdda#bb#aa##aa######..########ab##a###a##a#aaaa#abaabaaa#aaaaaaaaaaaa#aaaababbbbaaaaaaabcffbbbabaabbbaacefggdba#aabbbbcbacddccecbbbcccbba##aaaaaaaaaaa#a##a#a#######aaaabaa#a",
+"ba###aaaaa#cbaaaaa#abababa#a################aabbbbbbbea#aaabbaa#####a##adc##aaaaaaba##a####a########.#####...aca###########.####cffdcdecaaa#######aaabaa##aaaaaaa#aaabbbaaaaaabaaaba##babba######accbbbbbfccdeegdgfggeb#dc#####aaa#####...#######aaaa#aa##a#aaabaaa#bbaaaaa##aaaaaaaaaaaaaaabaabbbbbaaaaababbegdbbaaababbaabffffecb#aabbbbcbbcdddecbaabcbaaba#aaaaaaaaaaaaa###a########a#abbaabc",
+"a#######a###aa#abaaaabbccba###.##############abcbcbbcbea#aaaaaaa#######.##ba#a#aa#a#a#a##a####.###########..###ba##############a#aeedbadfcdddcbb##aaaaaaa#aa#aaaa#aaccbbbaabbbbbabcbbcdccb######abcdbddeeefddddb#afdcfebdca#####aaa######.#####aaca####abaa#aa#abcb#accaaaa##aa#aabbaaaaaaaaaaaabbbaaaaaaabbbbbgdbaaabbbbaaaccffgfdcaabbccccccddddfcbaaaaaaaaa#aaabbaaaaaa#a#aab####aa##aaa#bcc#",
+"aa###########aa#aaaaabbabbaaaa##..###########abdcccccbcdcaaaaaa#a##########aabb#abaa##########...#.########.######################.bfdaaccefddddbaaaaaaaaaaaaaa#aaababcccbbbbbccbbcddcabca####aaacdcabeggfdda.##.#cc#aefdbaaa###aaa###.##.####aaaaa#a###abd##a###ababbdc#aa#aaaaaaaabaaaaaaaaaaabbcbbaaaaaaabbbbgfbaaabbbbaabbbcefffddbabbcdccccedcabaaaaaaaaaaaaaaaaaaaaaaaaaaa#####aaa#aaaaaaa",
+"aaaa##########a######.#a#abbaa##########a####abdedcccccccba##########a######aaaa#abaaaaa#######..################aa#aa###############ddabedcgededbbbaabbabaaaaaaaaaaabbccccccbccdddba###abacbbcccba####aaaaaaaa##.###acfcaaa##aa#a############aa#####a#a##aea#aaa#aabbcda##aaa#aa#aaaaaaabaaaaaaababcbaaaaaaaabbbgfbabbbabaabcdcbdefffdbbcccccccdda#aaaaaaa##abaabbaaaaaaaabbbaaaa####a##aaaabaa",
+"aaaaabaa#######a###a##.###abbaa###############acdeccbbccdga##########a######.#aabaaaaaaaaa#a############.###aa###aaaaa###############.cdbbdefhhhfdccccbbbaaabaaaabbbbbccccdddcdccdb#####bbcbcddba####aa####a#a#####.##aedaaaa###aaa#######..#########a###a#bbbbbaaabbbbaba#aaaaaaa#aa#aaaabbaaababbabccbaaaabaabbbggdabbbbcbbbddcbcbdffdcaccccacccd#aaaaaaaaaa#abbbaaaaaaaabbabbabaa#aa####aabaa",
+"aaaa#aaa##########a###.##aaaaaaa####.##aa#####abccdcaabccffa##########a###aa####aabaaabaa#aaa####a######..###a#####aaa############aa###bdddeeddfgfeeeddcabaaabbbbbbbbbbcdddddeeeecaa####abbaaaa#######a#a########.###aaadaaaa#####aa########.#..##.##a######aaabbba#bbca##a###aaaaaaaaaaaabbaaaabbbaabddcaaaaaaaaabfgdaaabbbabdacdbcbdfffdbbdccbc#cbaa##aaaaaaa#aaaaaababaaaa#abbaaaaa#aaaaaaa#a",
+"###a#aaaaaaa######accbaaab#####aaaa####a#######accccabacccfe##.############aa####aa###aaa#aa####.#########.##########a############abca##bfcfabbbcaafffffdbbbbbbbbbabbcccdeeedefcaaaaaa##aaaaaaaa################a#.###abbcaa#aa#aaaaa#######....########aa####a#abba#bbbbaaaaaaaaaaaaaaaaaaabcabbbbbbabeedaaaaaaaaacfgecaabbabbacdbabcffffccccdda##aaaaaaaaababaaaaaaabaaaaaaaaaabaabaa##abb####",
+"a########aaa#######cddebba########aaaaaa#######abccccbabcdefea#.########aaaaabb##aaa#####aaa##.....#.##.##############a#####.#####aabcbaabfc######.afggggcbbbcbcccbbbccceeeeffhgccbaaa#aaabbaa#a######aaa########a#.##aacdba##ab#aabb##.#.####...########aa#####aaaaaaaabbaaaaaaaaaaaaaaaaaaccbabbbbbbabefdaaaaaaaaabeffabaaababdedabbcfffecccddaaaaaaaaababaaaa#aaaabbbaaaaaaaabbaaa#aa##ba###b",
+"#####aa#####aaaabbaaaacdb.#a#########aaa########abcbbbbbcdeeeefc.######aaaabaacbaaaaa##########..#..#....##############a###########abbbba#bd#a######aabbcfedccdddccccdddeeeeefgiedeebaaaaaabaaaa#aaaaa#aaaa###########aabcca##aabaaabba#....#....##.###.#aaa#######a#abaabbaaaaaaaaaaaaaaaaaaddbbbabaabbbddaaaaaaaa##adfecbbbbacddedbbccdffdccddaaa#aaa#bbaabca##a#aaabbaaaaaaaaaaaabb#aaaa###a#",
+"####aaba######aa#abbaaaba###aa#############.####aabcabcbbdegfebc.########abbbaaaaaaaaaa#########.....#.#.######.#######aa#####.#.##aaabbbbbc##a#######..##ehfeeeedddcedeffeeeeehf#abcecccbabbbbbaabaaaaaaaa########a###aacdba#aaaabaaaaa#..##..##.#..####aaa##a####aa#aaaabaaaaaaaaaaa#aaaaaabeeccbababbbbbaaaaaaaaaaaabcffbbbbcdccdcbbbcdfgfedcabaaaa##bbababa#####abbaaaaaaaaaaaaaaaa#aaaaaa##",
+"#a###aabaaaa###ba###ab##ba###a#############..###aaabcaabbdedefgb####aaa###aaaaaaaaabaaaa###########...#.############################aabbbadcaaa#####.######bfhhgggffffffffeeeefhhcaa##acfffeedddbaabaaaabaa########a####abebaaaa#a#a#aa############.###..#aa##a###aba##aaaaba#aaaaaaaaaaaaaaaaccdcdcbbbbabbbaaaaaaaaaaaaacfeaabbbbccdabccbdfffed#aaaaabaaaaaa#aa###aaaaabaaaaaaaaaaaaaaaaaaaaa##",
+"###aaa#aaaa#a##.a##a#aba#aa###########.#.#....####abcbbbbccdffegb...##aa###abaaaaaaaa#a#aa#######aaa###.####.#####################a##abbcfda#aaa###########.#acfhihhhijiiiihgfhhgcaaaa#..acccddccecccbaaabcb#######aa###abcdbaaaaa#aaa#aa##########.##########aa##aaa#aaaa########aaaaaabaaabbaaababaacbbabbbaaaaaabaaaaa#cefdabbbabbcbbbccdfggeb#aaaaaa###aaa#a###aabbaaaaaaaaa#aaaaaaaaaaaaaa#",
+"#aaaaaaaaaa##aaaaaaaa#aaaaaa##.###aa###.###...####aabdbbabbcfeced.#########aaaba#aaaaaa##ca#######aaaa######.########.########a#####aaabdhgfeaaaa#############.#aaba#addfghiiiiheb###aaaa###.####bdbcdcdcbbca##a##a##a##aabbdbaa####aaaaaaa#############a#.##aaaaaaaaa##aaa##a#a#acbaabbabbbaaaaaaaabbbbbaabbbaaaabaaaaa#a#bfgebaaababbbbbbbcggfeaaaaaaaaaaaaaaaa####aabaaaba###aaaabaaaaaaaaaaa",
+"a##ba#abaaaaaaaa####aa###bbaa##.#######b#####.#.###aacbbaabcdeccc##.########aabbba#a##aaa#bba######aaaaa#################.######aa##aabbfhhihdabaa##############aa######.##a#bgfb###aaaaaa########cbacccdfeecaa###aa##a#aaabcdbab##ababaaaaa##########aaa#####aaaaaaaa#a#aaba##aabfdaa#aaaaabbbabaaababdbbbbbbbbbbbbbaaaaaaa#dffcbaabbbbbbbbbcefgdba#abaaaaaaaaa#aa##abbbaaacba##a###aaaaaa##aaa",
+"aaaaaaaaaaaaaaaaaa#####a##aaaa########ab##.####..###aadccbbacdcaa###.######aabaaabb#aaaa###############aa#####a#####.##############aabbbehhhfcaaaa#####.########aaaa##aaa##a#.#caa####aa##########cdbbbbbcedefdcbbaa##aaaababbdbaaaaaaaaa#aba#########aa######aaaaaa#a#aa##aaa##addbbaaaaa#aaaaabaaaaaaccccdcbbabbbcbaabaaaaa#cfgdbabbbbabbbbbcfgedda#aaaaaaaaaab#a##aabbbaaaba#aa###a#aaaaaa#aa",
+"aaaaaabaaaaaaaa#accb#########babaa###aaa##.##a##.####abcbccabdeaaab#..######aaaaaaa#####################aaa####a#####.############aaaabdgihgcbaaa################aaaaaaaaa#aa###a######a##########dbaaaaaaaacbcefgfddcccddegdcbdbaabaaaaaaaaaaa######aaa####aaaaaaaaa#############aaaaaaaaaaaacaaaaaaaaabbbbdeccdccbbbbaabaaaaabefecbbbabbbbcbcegededcaabaaaabaaaaaa##aabbbaaaa#aa#aaa#bbaaaaa#a",
+"a##a#aaaaaa###aa#bbcbaa##aaa#aaaca##abb########a#####aacbbccbdeaaaba#########aaa##a#a####.################ba#########.##..######.bbabaaehhhgbaaaa#################aab#aabaa#aa###a##########a.###.ab#aa#abababbbcbcdcaacecccdefdc##abaaaaa##aa########aaba#aaa#a#aaaaba#a#aa#a##.##abaaaaaaaaabbabbaaaaaaaaaaccbbbcdbbbbaaabbbabbdgfdbbbabcbcccdddeeedcaaaaaaaabaaaaa##aabbaaaaa##aa####aaaaaaa#",
+"####aaaaaaa######abbcca##aaaaa##abbabba#a#####aaa######aabccedfaaaab#########aaa###.#######################b########.#ba#...##.#acbccccfgggebaaaa##a###############aababaaaa#a##a#a####a##a########c#aaaaaaaabbaaaaabccdebabbbdgeaaabbbaaaaa##a#######aaab##a##aaaaaabaaa###aaaa####ba#a##aaaaaabbaaaaabbaaaaacbbbcbbbcbbaaabbbbcbcfgecbcbbbccddccceddccaaaaaa#bbaaaaaaaaaaaa#aaa##a#aa#a#aa####",
+"##a###aaaaa#######aaaaaaaaaaaaa#aabbcaaaaa#a###aa########aabeeea###aaa#######aabb#####a######.#######aa##.######aaaabedccbbb##bbbbaabbbbccdeaa##a##a########aaa#####aabbbba#a#aaa#a####a###########caba###ababbbaabbabcdcddcbabehcaaaaaaaaaa############ab##aaaaaaaaaaaaaa#baaaaa###bb#a##aaaabbbbbaaaaabbbaabbbbcccbabbbaaaabbccccbfffcccbccccbccccddeedaab#aaaabaaabaaabaaa###aaa###bb##a#####",
+"aaaa##aaaaa#aa#######a#abbaaaab######aaaaa#aaaa#aa#######aabdefb#aaa#bc#######abcb#####a#################aa#a..###aabcdfffggfdcbbbbbaaaaaabdeaaa###########aaaa#####aabbbbbaaa#aaa#####aa#a##.#####aaaaaa##abaabcbbbaaabaabbbbcdefaaaabaaaaaa##a######aaa######aaaaa#aaaaaa##aaaa###aa#aaabbbabbaabbaaaaaaaabbbbbacccbaaaaaabbccdccdefegffdccecbccccdeeddcbaaaaaaabbbcbaaabaaaaaa#######aa######",
+"#aaaa##aaaa#############abaaaaaba##aaaaaaaabaaaaaba#####a##abdgca#aaadeb########bba#####aa#aaaaaa###aaa#ab#aa#.###.#acfhfddgccbaa#aaaaaa#abcfaaaa#######aaabbaaa#####aaaaaaaaa#aaaaa#aaaa##########aaaa#aa##aaa#acccabaaba#a###acdbaaaaaaaaaaa###a##.##aaaa###a###aaaaaaaaa###aaaa#abb#aaaabbbbbbbabaaaaaaaaaacbbbccbbbbaabaaacccccdfdbdfgeefcddabccbcedddccbbaaaaaabbbababbaa#aaaa#a##ab##a####",
+"##aaaa#############aa#####abaaabda##abaaaababbaaaaba####aa#abbdeaaaaaadf###############a#aaabbbbba#aa#aaaa#baba.#accbffffgddcbbaa#####aa##acfeabaaaaa###aabcdcbba######aaaaaaaaaaaaaaa#aaa##########dbaa########bbdcaab#abaaa##abceaaaa#a#aaaaaa#a###.######a#####aabaabb#aa#####a#bcbaaaaa#aaaabbbbbaaaaaaaaaaccccbccabacaaaabceeeeggdcdfffccccca#bbcbddeccccca#abbbbbbbaaabaaa#a#aaaaab#######",
+"##aaaa####.##########baaa##aaaaabda#aaaabbaaccbaaaa#####aaaaabbcbbaaabdgfe###aaa#######a##aaabbabbb#a#a#aabdceeedcabcaeddcfhecdb#########aacdhcbccbbbbbbbbdehhedba##aaaabbbbbaaaaaabbaaaaaaa########cba#######a#abbda#aabcbaa##aabceaaa######aaa##aa########aaa##aaaaaa#aaa###.###aabaaa#aaa#aa##abbbaa#baaaaaaabbbbbbdbbabaaaacaddacbbbbddccccbbda#cbbcdcddeccccbaabbbbca#aabaaaaaaaaaaaaa#####",
+"#aa###a####.##########aa#a##aaabaccaba#aabbaccbaaaaaaaaaaaaaabbccabaabeffeebbcb#.####.#aaabbaabbccccccccdddcec.#aaaaaaadccbbcccca.#######aabdhecdddeeeddeefecbbeedcaaaaabbbbbbabbbbcbbaaaaaaaaaba##aba####a####aacdccaa#ccbbaa##aabcdaa########a##aa########aaaa##aaaaa##aaa#########aaa##aa#aba#aabbbaaaaaa#aaaaaabaaaccbaaaaabccababbbb###bcbcbbecabbccdcddcdcccaaababbbbaaaaaaaa#aaaaaaaaa###",
+"#aa#aa##########a######a#####aaaaabc#abaaaabbcbbaa#a##aa#baaabbbbbabbcfffgghebdcbbacacbbbbbbbcbccdccfdaaabdedcaaabaaaaacccbbbbbbcb########abcfgedeffeeeegfcbbcbadgdddaabbbbbbbbbbcccccbbaabababbbaacbaa#########abcccbabccbbbaa##aabcb#a#######aa######a#a##abbbbabaa###a#aa########.bbaaa#aaaaaa#aaabbbccbaaaaabbbbbbbaaaaaaaaabbbccccaaa###bcdbabcbbbabcdddcbddccbbaaaabcccabaaaa#aabaaaaaaba#",
+"#aaaaa#######a####a###aa##.###aaaaabc#abaaabbcbba###aa####a#aaabbbaabcdcdeccdecccccba##aaabbaaaaaa##beaaabacfdeaabdecb#bdcbbbbbbaca#######abcdegeeeeffgfdabbccddeehhhfdbbbddeeccdcccdccbbbbbbcccbcca##a###a########aa#.aceccbbaa#aa#acb###.#####aa#####aba###abcdcbcbaaaaaaa#####a###bc#abaaaa#aaa#ababbbbccbaaaaabbcccbcbaaaaaabccdacccb#a###abddbbbbbbabbcebcbbdcccbbaabbabcabaaaaabcbaaaa#aaa",
+"aaaaaaaaaaa####aa#####aaaaa.###a#aaaccaaabaabccaa##aa#######aaaaaaaaadc##abaaaaa###a#######a#########cb#aaaacdddb#bbdda#becbbbbbbac#######abceffhffffda##babcccdeeddbddeecdcdebdeeccdddeddcccdeba#b###aa##a#########a###bedbbbbaa#a##aca###.#####aa####aaa####bbcdddbaaaaaaaaa#######adbbabaaa##aaaaaaacbabbccbaabaabbccccaaabbcbdcbcecccaa#a#a#adcabbbbbcbbcbccaabccdcbbbbcacbaabbaabcbaaaabaab",
+"bdbaaaabbaaaa#aa##a#aba#############abcaabababcba##aa#########aaaaaaabdb##aaaaaa###a##################b####aaccdeaabcbbaaeddbabbbabb#######bdfhghhgda###aabbcccecbbbdcccefdbbcbcb#eefgghggfeegdaa##a###aa#######aaa#####bedcabbaa#####acb##########a##aaaa####acbccccaaabaabbbba####a##dbba#aaaaa##aaaabdababbccbabaabbcddcbacbbccdacdbba#####aaaabcbbbbbbbccbbababbcddcbabbbabaaabcaaabaaacabaa",
+"aacdbaa##.##a##aa#aa#aba###.#########abca##aabbbca#..###########aaa##aab######aaaa#########aaa#a###aa#######aaccdfbabbaaaeeddbbcbbbdbaa#abcdfhjigca######abccbadb###cfbcbbecabbba#begfhggddcggdbbaaa##############a#aa#.cddccbaaaa#####ab##########aaaaaba####accbbbbaaabaabbbabb#######aba###aaa#aa#aaabcaaaaabccbabbcccdedcbdbbacdcdccaa##a#aaaaabcbbbbbacccbaaaabaccccbaaaaaaaabbbbaaaaababba",
+"aababbaa#####a##a##a###a####.##########aba###abbbbba####.#.#######a###aab######aa#a#########aaa#####aaaaa#####bbceebbbba#ceedccedcegdcbcddedbcbed#######aabccdbdda##adeeb##abbaaaaacbadeddfdghdcbbbaaa###########abbbcdbbdcbbca##aa#####bd###.#.###aaaaaaaba##abbbbbbbaaaaaaaabbaaa#######aa###aaa#aaaaaabcaabb##abcbbaabcedccdcbaaccccba####a#aaababcbaaaabbccbbaaababccbaa##aa##aaabaaaaaaabaa",
+"aabaaaaa#a#####a###aa##########..######aaba####aaaabb#.###############aaab##.###a#a#######aaaaaaaaa#a#aa###a##aacdceddfgfcfffgdccdeeefggdbaabbbbdcaa###aaabbcddeb##a#adfeaaaaaaaaa#bbaaccbeedhecbabbaaa#########.adccbcdbdbbcbba#######a#cda########abbaaaba##abbacbbaabaaaaabaaaaaa########aba##aaaaaaaaabcaaa#a##abca#aaabdefecbaadbbbaa##aa#aaaaaabdcbaaaaabcbaa#aaaabbbaaaaaaaaaaaaaaaaaaaaa",
+"aaabbaaa#########a##aaa###########.##.##aaaa#####aa#cba################abcb.####aaaaaa##aaaabbabaabbbaaa##aaaaaccgghggecdfihhg#a####a#a#abbccccacdcabbbbbacccdfeba#####aaaaaaa###a#ababbccadcgedccbaaa############ccbabccbcacabaa#####a#bacd###.####aaaaaaa###aaabbccaaaaaabbabbaaaa###.##..#bbb###aaaa#aaaaaaa########a#aabccceecbbdbbbbaa#aaaaaabbaadccbaabaabba#####aaaabaabaaa##aaba#aaa#aaa",
+"aaaa#aa##############bba##########..#.############aaaaaa#####.##########abca..####abaaaaabbbcccbbccddbbabbbbbcdefebdfd##a#.bedaa#########aabbbcbcddddcbbbcdeffd#########aaaaaaaa#aa#baaabcbacegedbbaaa##########bcdbaabbcccbbbaaaaa#####abbcca####.##aaa####aaabbcccdbaaaaaaabaaaaaaaa####.###abba##aaaa#aa##a############aaaa##cfebdcabcb###a##aaaabbabacbaaaaaba#a####aaa#aaaaaaa####aaaaaaaaa",
+"abbaaaa####a##########aa###################aaa####abaa#a################aabc#.#####aaaabbbcdddcdfffefgffeddfgdcdcb####aaaa###bb#######a##aabacdcddbdccacdefecc#a##a#####aaaaaaaaaa##aaaaabbbabfgdcbaa########aaacbbbbabbbbcdaba##a#####a#abccda####aaaaa#aaa#abaaaccbbbaaaababbaa##aaa#########bbba##abaa#####aa#a##aaa#a###aaa##defdcabbbaa##aa#aaaabbbaaccaaaaab######aaba#aaaaab####abaaaaaaa",
+"aaabaaa#################abba###############aaaaa##aaaaa#a###############aacaca.#####aabbbbccddfda#adeca#####b###aa#aa#aaaa##aaba#a####aa#aabccdccedebaacccb####aaaa###a###abaaabaaaaa#aaaaaababdgdbb##########cabbdbbbaaaaaccaaaaaaa##aaa##acdc#.#aaaaa##a##aabaa#ccaaabaabbaaacbb##abaa######..abca##aaaa#####aa#aaaaaa######abaabdggcaaa#aaaaaaaaaaacba##bbaaaabba#aa#aaaaa##aaaba###aa#aaaaa#",
+"#########.#################aaaa#.#.##aaa###aaa##aaa##a##aa###############abbbba#.##.#aabbbbcefc####...#####aa#####aa###aa####aa#######a#aaacbacbbdddbbccdfecbcc###aa####aa#aaaaaa###aaaaaaa##aaacfdaaa#####aaaabbabbbbaaabbabbaaa###aaaaaaa#abce..##ababc####aaaaabdaabbbbbbaaabbbaaa#a##.#######abaa#aaaba##aaaaa#a##aaa###aaa##ababehcaaaa##aaaaaaaadc####abaaaaaba###aaaaaaa###aaaaa#aaa#####",
+"####a######################aab#....##aacaaa#aabbaaaaa#####a##############aabbbcb##.###abbcceca###################aaaaaa#a#aa##a#aaaaaabaabbbbbacaaabbabaafddcbcb###aaa#aab##aaaa######a#######a##cfeaaa#####abcbbbbaaaaaabbabba###aaaaa#aaaabaaee#.##ddaaa####aaaaacaaabdcbbbbaabaaba#aa##.#######aaaa#aaabaaaaaaa##aaa#a##a#aaaaaaabbcgebbba#aaaaabaabbaba###aaaaabbaaaaaaaa#aaa##aa#a##baa#a##",
+"####a##aa##################aabda#.#####bcaa#abaabaaaaaa###################aaabcdb.####bbbdea##########.###########aaaaa##aaaaa##aaabbbbcbccbbaaaaaaaabbbaaaacdcbbbaaaaaaaabaa#aaa################abecaa####aadcabcaaaaaaabbaab#####aab#aaaaabaaade#..#ca.#a####abcbbb#abbccaaabbbabbbb#a############aa#aaaaaaaaaacaa##aaa##a#aaaaaacabccfebbbbaaaaabbbbaaba####ababacbaaabaaaa##a#aaaaaa##aaa###",
+"#####aaaa###.#a######a#######aab##..####abbbbbbbbaaa#aaa####aaaaa##########aabddea.###abda#################a#########a#####aaa###aaabbcdcbdbbaaaaaaaaabbbaaaaacddcbaaaa###abaa######..############abeda###ababbbccbaa#aaaaaabaa##a###ab#aa#aaaaaacec##ab.########babbaaaabbababababbcda###############a#aa###aaabcbbaaaaa###aaaa#ababbcdcdecaabaaababbaaa#######aaabbbbaaaaaabaaaa######a#aaaaa#",
+"a#######aa#a######aa#a#aaa###aaac#########abddccbbaaaaaaa####aa#aa########.abehghhc##abca##aaa##################################a#aabccb#aabaaaaaabbbaaaaaabaaabbbdba#aa###aaa##################aa#abefccaabbbcbabbaaaa#aaaaaaaa#aa###abaa##aaaabbcfdaba.#a######bacc##aaaabaababaabcbca##.#####a#####a#aaa#####aaaaab##aa##aaaa#aaaabccebbffbaaaaaabcaa###a#####bbbbbbbaaaaabaa#aa######aa#aa#a",
+"#baa#aaaaa###a#a#aaaaaaa####b#aaba#########aacbdcccaaa##a###aaa#aa##########bbfikjicacc###aa#aaaa#############a###################aaabccca##aaaaaabbaaaaabbbbaa#aabcbbaa####a#################a#aabaabdfbdcccbbbbbbbbaaaaaaaabbaaaaa#a#aaa#aaaaaabbcfdbb#######a#aaac##a#ababaaaabbcdaaaa##########a#aaaa#a#aa##a#aaaaaa#aaaaaaaaaaabbccdcaaegcbaaaaacaa#####a####bbbbbbbaaaabba##a###aaaaaa####",
+"####aa#aaaa##a#aaaaaaaaa##a#####aba##########aadcbbba####a####a#aa##########abcdfhiigc#a##aaaaaaaa#aa#####################a#######aadccccaba##aa#abaaaabbbcaabaaba#aaaaaa####a###a#a###.#####acbbcbaabcehfdccccbbbbbbbaaaaaaabaaaaaabaaaa###a#aaaabbcddca####.#####aa##aaacbabbbbaabcba#bc############aaa##aa##aaaaa#baaaaaa#aaaaaaaabccdeba#cgfbaaabca#a###aa#a###bcbbbbbbaabbba##b###aaaa#a###",
+"###a#aaaaa#aa######aaaaaaaa######aaaa#######a##aaaa####.###aaaaa#a###########abacdhiiga##abbaaaaaaaa##############a########a##a##abbcabc#abbaaaaaaaaaaaaaacaaabaa###a###aa###a###aaa########bbbbcbbbbddceihebbcbbbbbabbaaaaaaaa#aaaaaab#a#####aaaabbcccfb#.########aa##abaaaaaaabbaaaabbcbc#####a######ba##aaa###aa###aa##abbaa#aaaabbbdcccbbabdhebcbaaaaa####a#####accbbbbcbaacba#aa###a#aaa###",
+"#a####a#aaaaa#aaaaaaaaaaaaaa#######aba#######a####ab########aaaa##a#a##.#..#####aehhjihb#abacba#aaaaaa############a#a########aa#aabdcc####abaa##a##aaaaaa#ababa#a##aaaa#######a#aaaaaaaa##aacaabcccbcbabbcghgdbbabbbccba##aaaaaaaaaaaabaaa####aaaabcbcdccaa#########.##aaaaaaaaabababbabaa#######a#a##abbba#a######a###aa#aaaaaabbaabbcdbbbbabbadffbbaaaaaa#a##a####aabcbbbccabbabaaaba##baaaa##",
+"##aa###a#aaa#a##aaabbaaaaaaaaa##aa###a#############bba#.###aa#aaaaaa#######.####adfehjif###aaaaaaaabbaaa#a########aaa###a######abbbbcca.###a###########a###aa###a#############aaabbbbbaaceb#aaabbbccbaaabbbdggdcbbabbbbaa###aaaaaaaaaaba#aa#a###aabbbbcdc#####aa#######aaaabbbaaabbbbbbba#aa#######a##aabbaa#######aa###aa#aaaaaabbbbbccaaccbbbccdfgedaaaaaaaaaaaa##aaaccbcccbbccba##aa##abaaa##",
+"########a#aaaaa#aaaaaaaaaaaaa#aa#ba###########a####aaaaa#.##aaaaaaa##a#a########bbceeijfc####bbababaaaaaaa#########aa##a#aaaaabbadcccba####.############aaa#aa#############a##abbabbbaa##ceaaa#aaaabbbaaaaabbdgfbbbbbabba####aaaaaa#aaaaa#####a#aabbbccdccca#aaaa######aaaaababbaaabcabba##ba##a##a#aaaaaaaaa#######a#a##aaaaaaaabbbcccaabbddcaabbabdffdbbbaaa#aa####aabbccbbcbbddbaaa####acbaa#",
+"#######aa#a#aabbaaaaabaaaaaaaaaa##aa#a#############abaaaa####abb###aaa#a########babcfhiiea###acbbabbaaaaaaaaa####aaba#aaaaa#aaabaccbcbaa###############aaaa###a##############aabaaaaaa####bbbabaaaabbbbaaaabbbcffbbbbbbbbaa##aa##a###aaaa####aa##aabccefcadda##aaaabb#aaaaaaaaaabbbbbbbba##abb######aaaabbba###############aa#aabbcccbabbaabdccccaabacfggccbaaaaaa##a#aabccbbcaabdbacba####bbaaa",
+"aaa####aaaaaaaaaaaaababaaaaaaaaaaa#aa##############abbbbaaaaa##bbbaaaaaaa######ab#bccehiic###abcaabbbaaaa#aaaaaaaa#aaaaaaaaabcbccacba########.##########aa###############a#aaa#aa#a##a#####acbddcbaaabbbbbaaaabbefcbbbabaaaaaaaa######aaa###aa#####abcdghedcbbbbbcccdcbbaaaaaaaabbbbbbabaa#.acca#a###aaaaaaa########a##a###aaabbcdcaaaaaabbaccddaaaaacaadggfdbaaaaa#aaaaaabccbbaacbaababaaaabbaa",
+"aaa#a#####aaaaaabaaaabbbaaa#aaaaaaa###aa#######.#a###abbbaabbbbaaaaaaaaaaaa####a##ababchie###aabbbaaaaaa#aaaaa#aaaaaaaaaaaabccccbccb####a#############aa######.###########aa###aa#aaaa#a###abcccdbbbbaaaabbaaaabbceebbaabbaaaaa#########aaa##aa#####acdfdefebcddcbbdffdcbaabbaabbbbbcdbbaaa##abca#####aaaa#a##a#aa####a#a##aabbdedaaaaaa#aaccbeda#aabbaaaacefgfdbaaaa#aaaaabcccbccabaaabbaaaacc#",
+"##a##aa###aaabbbaaaaabcbaaa#aaaaaaa#a##########a#####aabbaaabaabaaaaaabcccca########aaacfhc##aaabccba#aaaaaabbaaa##abbababbcccbeecba#####a########a####a#a#####.##########b######a##a##aa###aababaaabbaaaaabaaaaaabdfcababbaaaa##############.#######bddcbdeffcbbba##dihdcbaaaaacaabbbdcaaabaa#aba#####aaa######aa##a###aa#abcdccdb#aa###aaaccdcbaaaaaaabbaaabehhebaaaaaaabaccbcbbbaaaaaaaaaaacb",
+"a##aa#####aaaabbbaaaaaababaaa#abaaa#############.###aaaabcaabaaaabbbbacdedaaaa######a##bccdccaaaaaacdcaaababbbaababbbccbcbbcdcceedc####a##a###########a#aaa######..####.####.###aa######abbaaaabaaaaaaaaaaaaaaaaaaaacfeedbbaa############.######aaaa#abbaaaaccbabaaa###igdccbbbaaaaaaabcbabcbcb##a######a####a#aaaaa####aaaacb#abdcaaa#a###a#acddcbaabaaaaaaaaadfhhedaaabbabbcccbbaaaaaaaaaaaaaa",
+"ba##a##a#aaaaa#aaabaaaaaaacaabcbaaaa#aa#########.#########aaaaaa##ababdefcab#aa########aabdfgbaaaaaacdcaaabaaaaabbbbabbcbbbcccddaaaa####aa#aa########a#aa#########..##.##..###.###aaba###aaaaa#abaaaaaaa#aa#aaaaaa#aaaegdcbbbaa###########.######aaa##aaaaab#abaaaaaa#.febaaabcccbcbbcbbaaadbcecbaa#####a#aaaaa###aaa#aaaaabaaaabccaaaaaa#aa###adbbbcbbaaaabaaaabbchifbabcccabbccaacbaaa##a#aaba",
+"#ba########a###aaaaaaa#a#aaa#abaaaaabaa##a#aa###############aab####aaaaabccaaa##a#.#####abcdfb#aaaaaaaaabaabbbcbbbbbababbcdddfedcb#a##aaa#aaaaa###aaaa##aaa##.######.###.###########a#########aaaabbaaaaaaa###aaa##a###bfedcbbaaa############a####a######a#aaabcbbbaaa#gdaaa###bcddcecccca#addefgfddca###a##aaaaaaa##aabaacb####bbdcaaaaaa#aa###ccbbbccbaaaaaaaaabaadhieabaabbccdcbabbaa#####aaa",
+"#aab####aa###aaaaaaaaaaaaaaaa#aaaaaaa#####aaa#a##.############aa#abaaaaaaabaaaaa########abccdfcaaaaaaabbbaa#abbcbbaacabbbbcddecdcc####aaa#aaaaa#aaaaaaa##aaaa###..######.#####a########aaa#a####aaaaa#aaaaa########aa####dedbbbaaa##############a###a#####ababccbaaaaa#gcaaaa####bdebbbbbca#bddcbaabccaa##a##aa#aaaaaaabbaca####abdbaaaaaaaaaa#a#ccbbbbbbbaaabbaabba#adhgcbaccccccdccba######aaa",
+"a##aa#a###aaaaaaaaaaaaaaaaaaaaaaaaa#aa###aaaaa###.#############a##abababbaaaaaba######aaabbcddhcaaab##baaababaabaaabbabbbbcdddffeeb###aaabcaaaaaaaa###aaa#aa####.######a#######b#####aaacb#######ababaa#aaa##aa########a#aaeecbbbaa##################a##a##bbaabb#aaaa#cd#aaaaaaaace.aaa#bdccdcaaabcacbaba###aaaaaaaabaabccaa#aaabbd#aaaaaaaaaaa#bcccbbbcbbaaaaaaabbaabbhidbbcccbdeddaaa#aa#aa#a",
+"aaaa#aaaa##aaaaaaaaaa#aaaaaaaaaaa######aa#aaa####..#########.###aaabbbcbbbaaaaaaba#####aabbcccegcbaaaaaaaacbaabbaaabaaaabcccdeeffddaaaaabcbbbcfffecdcba#abb#############aa#a##acbbcba#bbaa########aabba###a##########aa#aaa#eedccbaaa#####a#a###########aaa#aaa#bcaaaaaafaaaaaaaaacfa##a#aaaba#abaaccbcbbccbaaaaaaabbbbbbaaaa#a#abccc#aaaaabaaaaaadcbbbcbcabbbbaaaaabaaccfjgbccbcccccaa##aabaa#a",
+"#a#aa#aabbaa#aaaaaa##abaaaaaaaaa##aaabaa##aa#a###.#.##############aabbbcacbaca#aaca#####aabbccdeedbaabbaaaabbabababaaaabbccdddffedffb###bbccefebccbdeda#aaabbaaa#######aaaaa###aabcca#adaaa#####aba#aaaa##aa################.cedcbbbbaaaaaaaaa##a######aa####aa#bbaaaaaadc#aaaaaabbee####abaaa#aa##abaaabbabdcccdcbbaccbcb##aaaaabbcdbaaaaababaaaacbccbbccbaaabbbbaabababadjiedccccbbbaaaa#aa#a#",
+"aaaaa###aaaa##aaaaa####abaa#aaa#a###aaaa######aa#################a##abbbcccbbbaaabba##.#aabbbbddedd#aacb#aaaaaaaaaaaaabbbccdddggffghecbbaabbbddabaa#aaaabaaa#bbbaaaaa##a##aba###aaabb##bbaa####aaaa###########a########.#####aaeecbaabbaaaaaaaaaaaaaa###aaa##a##aa###aaabeabaaaaaabchca###a#aa#a###a##aa####bca#abdecbcdbaaba#aaabbdcaaaaaaaabbaaaaccbbbccdbabaaabbbabbbabacjkjgfdccbaaaabbaaa##",
+"#a#aaaa###caa#####aaadb#aaa#aaaa#aaa##aaa###aaaa#a####a##a######a#a##aabbbbabba##aabaa##aaaabacdececaaaba#aaaabaaaa#aaaaccdeeefgeeefbcbbbcbbbcbaaaaaaabaaaaaa##abba##a#####aaa###aaaa##.#ba##.###aa############.##.#############dedcbaabbaaaaaaabaa###a###aa##aa#aaaaaaa#dbbbbbbbaacgg#b####a####a##aaabaaabbcaa#abacdcaaaabaaaaabbccaaaaaaaabbbbcbabcacccccbabbaabbbabcbbaaejklhfcbcbbaaaa#aaaa",
+"####aaaaa##aaaaabaaaaabbaaa##aaaa###aabbaa###aa#aaaa###aa#######aa#a##bcccaaabbaa#acaa###aaaabbcdcdcbaabaaaaaabaa##aaaabbccdfffghffdaabbaabccddbabaaaaaaaaaaaaaaaaa##a#######a####aaa###.aba######a#################a############bfedbaabbbbbaaaaabaa##a#########abbbba##dcbabbbaaabcgdc#####aabaa###a#bbbbbbbbbbaaabbcbbabbbaaaabbbdebaabbbaabcbbbbacbabbabbbbabbbaababbbbbghillgcbbbbbaabbaaa#",
+"###aaaaaaccdcaaaaaaba##aaaaa##aabaabaaab########aaaba####a###a##aaaaaabccbba##bbba#bca###aaaaabdcddcda#abaaabaaaaccaaabbbccefgfghffaaaabbaaabefbcbaaaaaaaaaaaabaaaa##aa#########a########aaa###a##############.##.#.############a#abdebabcdcbbcbaabba############acdea#abecbaabbbaabbdfc##aaaa#a#aaa##abbbcaba#adebaecabbaccdcbbabbcbdddbabbbabccccbbacbbbbbabccbbbbbaaaabcbcfijjkjfddcbabdebaaa",
+"db#bdccbbcb##aabbbbaa###aaabbbbaccaaaabca####.#####baba##a#aaaaa#aba#accbbbbaaaaaaaacbaaaaaaaaacccdccc##abaabbaaabdbabbcccdffffhggbaaaaabdbaaaababbaaaaa#a#a#aaaaba#a#a################aabaaaaa###########.#####...#####.##.####aaaa#bedcccaaaaabbaaaaa##a#####aaaaddaabdebabbbbbabbbbgcaa#a#aaaa###aaabdaddabaadcfdfgdacbaabcbbbcccbdcdffdacdcedccbbbacbbbbcccccbbbbabacabbdgigbbgjjedcbbbccaaa",
+"#bbbaaaaaabaaabbbea#aaa#abbbbabaaaaaaaaba#############b####aaaaaabaa###abbbbbaaaaaaaacbaaaaaaabbcccccdd##cbcbcaaaaaaabcdeffgggiigabbbbbaabcaaaaaaaaaaaaaa#aaa##aaaaaaa################aaba###baaaa#######.#####....#########.#a##aa##a#adfca###abbaaaaaaa#####a####bdbacfdaaaaaabbaacedfa#aa#########abefeddcccdebccfggfedaaccbacddecdccdeddccefddcccccccabaabbabaabbaabacbbhijgdbacfkjeedcba#a#",
+"###aaaaa#abbaaaaaaa#a####bcaaaba###a#aaaa######a####aa######aaababaaaa##aabbaaaaaaaaabcaabbaaaaabcbccccbcbaaaaababbcccdefgfgghkgbaabbcbccbaaaaaabaaaaaaaa#aaaa#aaaaaaaaa####a########aaabba#aaaa#####a#.###.######.#####.####.##a#abaaa#aaddaaabbaaaaaaaa#########aabgggfbaaaaaabbbabbcfea#a#####aa##afghhfggghhgccddffhfffcccbccdfgeeeceec#aabcddcdddccebaaabaaabaaacbbbb#ejhjgbbceceikibbceba#",
+"aaa##a#aabbabbaaaaaaab####bc#aaaa#aaaaaa#ab##aaaa##a#aa######aa#baaaaaaaaaaaaaaaa#aaaaacbaabaaaabbcccccdbaaaabbbbccddeeefeegjheb#a#aabaccdcaaaaaaabbabaa#aa##aaaaaaaaaaaa#######a###aaaabba#abaa####..###.###.####..#####.#######aa##ba#####bcbaaabbaaaaaa########abdfggebabaaaaaabbbbbchfaaa######abbfegggefgghgffeecefggfhheecdddeeefdcefcabaabccbaabcbcbaaaaaaabbabbbbbbfghggdbcbcbbgkjfbbecb",
+"#aa#a###aababbbaaaaaaac###.acaaaba#aba####ac#aba###aaaaaaa#aa##a#a########aaaaa#aaaaabbbbbaabbaaabbbccccebaaaabbccddddedegggfhbaaa##aaabcccaaa#aaabbbbcbaaa#####aaaaaa#aaaaa#####a###aaaaaabbdaaa########...##.###..########.#####aa#aba###a#accbaaaaaaa#######aaaaabccdeeccbbaabaabbbbegfgeca#####adefffefgggfghggfeeccegihijigedbccfeceddfeaaabcacbbaaabbaaabaaaabbbbbcbchgghfgdabbaa#bgkjgcdd",
+"d#a#a####aaaabbbabaaaaaa####abaabaaaaaaa###acdbaa#a###aaaaaaaa###########aa#a####aaa#abbbbbaabaaaaaabcbccdaaaaabccddeefefhgefgbaaaaaaabaabbaa##ababbaaabcca#aa#aaaaaa##aabaaa####a####aacba#bcb#aa#.####.#...##.##..################a########a#adbaaaabaa#aa##aaaaabbbcdeddddcbabebbcbbffeefdec##adeeefeffefghgghghhgfedfheabfghhfdcegecbbbbccaaaabcaaaaaabaaabaabbbbabbcdfffgffffabbbbbcabgkjec",
+"cdaa##aa#aaababbbaabbaaaa####bbabcaaaaaaa##.acaaaaaaaa#aaaaa#ba###########aaa#a###aaaababbaabaaaaaaaabcccdgbbbccccddeffefgfeffbaa###a#aaaaaa#aaaaaaabbbccaaabaaaaa##a###aaabfd#####aaaabbaba#aa########.###.##.###############################bacedcbbbbabaaaaaaaaabcccccddedddbbdeecdefeededdeeffdegffeddefgfgggggcb##abbca###bbefeefeddcdcbeeaaaaab#a###babbbbbababcbccfgfeeefegcbaaabbca#afkh",
+"gdcbaaaaaabbbaaabaaabbbbaaa###bbcbaa#aaaa#####a###aaaaaa#aaa#aaaaa##a#####a#aa#aa#a#aaaabbaaacaaabaaaabccdfgddddddccdfhhffddfbaaa####aaaaaaa##a#aaaaaabbdb#aaaaba#a#######aacegdbaa#aaabaabbb########.#.##.##..#...####.#######################babedededcbaaaaaaaaabccddeedefecfffeeffddddddeddeeeddeggfddeeffbaaaaaaaabdb#baa#a##cbdfeaaabbcdfbaaaaa####a##abbbbaabbbbdcgfgeeedeefabba#aaaaaabg",
+"gjgccbaaaaabbbbbbbbaacbaaaaa###aaaaaaaaaaa####aaa#####aaa##aaa#a#a#######aaaaaa##aaaaaaaabba#acaacbaaa#acccfgdefefcdecfhhddbcaaa#a#####aaa#aa###aaaaaaabbeebaaaaaaa####.###aaacdcbaaaa#aaabba#############.#.#.#...###########..###############aacddeeededceeedccefggfgggfedggghfdfecdddccccddeeeeefddfffddddbabbbaaaaabefcdb#aa##aaabcaaaaa#bdgb#abaa#######ba#bbaabaaeegfgfeeeecfcaaa#aa#aaaa#",
+"#bgifcbaaabbbcbbbbaabbbaba#a#aa##aaaaaaaa######aaaa##a#aabaaaaaaaaabaaaba##aaba###aaaaaaaaabbabbabaa#a#abcceffeecb#cddeeggcdb##a##aa##aa#########aaaaaaa#bedaaaaaa##########abaa#aaaaaa#aaabaa#####a####################..######.#a##.#########aabcccbcda##afgggffdbbbabdhheghifedddeecbccdcdefffeeffdfggfdbaaaaa#aababbacdddb#bb#aaa#a####ababbdebbbaaa####a#babbaaacddfgffeefeeddcbabbaaaa#aaa",
+"a##ehiecbbbccdccbbbbaabbaaa#aaa##aabaaaaaaa####aaaa#####aaba#aabcbbbaabbba##abaaa######aa#abbacbaaaaaaaaabcccdfcaa##bbbbceabaa######aa##a##aa####aaaaaaaa#abaaaaaa###a######abbbaba##aaa#a####aaa###a############.########################a####aa#dcddcdb#a#dedeedcaa#baacgegiifedddddddcdddefeffggfgeedbba#aaaabbaabaaaaabceebbdaaaaa######aaaaabdddb#aaaaaabacbbbaabdfffgfgfeeeeddgcbaaaaa####",
+"#b##adiifdbcefedccccbaabaaaa#aaaaaaaaaaaaaaaa##abaa######aabbaabbcbbaaaaaaa#abaaa#######aaaaabcca#aaa##aaaabbccc#########a###aa##a###aa########aaa##aaa#aaa#aa#aba##a#######aabbabcaa#ababbca##aa####a#####a.#########################a###a##acba.ddeecccba#cfeeedcaaaaabccbaigfeeeddddcbcdcddfeffggeedaabaaaabaaabbabaaaaa##cffedeaa#a#aaa#aaaaaa#abfebabaaaaaacadcaaffecffffgfffeeggaaabaa####",
+"#caaa#.ahjgffefgggffecbbbabaaaaaaaa#aaaaaaaaababaa#aa#a#aaaabaaaacccaaaaaa#a#aaabaa######aaababaaaaaaaaa#aaaabccb####aaa##ab###aa#####a#a####.#aabaaaa########a##aba########acbbaaaaaaaaaabbbaaa################a###a####aa############aaccb#adcbbdddccbcdebdedccba#a#aabdcbaggeeddedcbbbccdeeffffhggfcbaaaabbbcaabaaaba####a#debceea#aaabaaaaaba#aaa#cfgcaa##aabcbcbdffedfeeeefefeedhcaaaa#a###",
+"####aa##.behhgfeeeddefedbbbbaaabaaaaabaaaaaaaabaaaa#aaaa#a#abbaaabbcbbaaaaaaaaaaaba####aa#aaabaaaa##a#aa#a#aaabbcc.##ab##aabca##aaaa############aabaaaaa#a#a#####aaa#bb#.####bccbaa##aaaa###aaaaa######a#######bbabba####bb###a#a###a###bcccccdcdccddcbbabcdcddccba####bdddb#bdcecdedcbbbbbcceeeeehhcdaaaababcbcaaaaabaaa#####ab#aabb###bb##abcaa###a##adfeba###aabaaefefffedddeedefefhbaaa###.#",
+"#####aaaa###chikjiigedcegcccbabbaaaaaabbaaaaabaa#aaa#a#a##aaaaaaaaabaa#aaaaaaabbbaa######aaaaabaaaaaa##aaba##aaabab.###aaaaaabaa#aa#a#############a###aaba########aa#cbb####abcbaaa##aaa#a######a#.####aa###bbccbbdccbaaabb###a#aaaaa###cbbbaccccbbcccaaaabbccccbbaaa#accdcb##bacgeeedccccbccdeeefggebdaaaaabbbbbbaaabaa#####a#a#aa#####aaaa##ca#####a####beeca#b#abadgefffedeedfdcffeff#a#a###.",
+"..######a#aaadd#acdhihecdgecbcaa#aa####ba#aaa##aa##aaa###aaaaaaa##ababaaa#aaaaabbbaa######aaaaaaaabaaaa##baa##a#a#b######aaaaaaaaa#################a#aa#bcb#####aba##a######bbbcbaabcaa#################a#abcdbdefededcbcbaa##aaa#a###bcbababbccbbbbbcaaaaabcccbaabaaaabcdbba###bhhfhgeddccbccddfhhhfbbaaaaaabbbccaaaabaa####aa#a#####b####aa#aa#ab###a##aaabefd#a#abbfgfeeeeeedeeddefggbaaa####",
+"##.######aaba#abaaaabeiiebceddcbaaaaa###aaba#########a##aaaaaaaa###aaaaaaaaabaabbbbaaa###aaaaabbbaaabbaaaaa###a###bb#####aa###########a######a#####aa#baaaba##abcedcbaa##a##bcccbaaaddccaa##############a##bbceffgfededdedcbaa#a#aaa#bcabaaabbbccbbbbbbaaaabbcbbbbaaaaabbcda#a##ehgfeeeeecddbcddfhhgcbbbbbbaaaabcbbbaaaaa###.#a#a#a####aaa###aa##a########aabbbedbacfegggfeeefeddccddgihdaaa####",
+"##.###a####aaaa#bacbaa#chidccdfdbbabaaa#ababaaa###a###aa#aaaaaaaaaba#aaaabccccbcccccabb###aabaabbbcbaabaa########aaab.####aaa##################a####b##aaaabb#aacdddcbb#######bccaaaabdbba#####aa#a#########abccccccddcffhigcbaaa#aa#acaabaabbbbaaabbbbbaaaabbbbaaaaaabcccdda#a#higheddefedeecdffffeeaaabbbbaaabcbaabaaaa#########a####aaaa######a#######aaabdcbadgfdeddegfgfeedcccccehigaaa####",
+"###########aa#####aacdb##ejgcbbfedcaaaaaacbabaa#####aaaa#aaaaaaaaaaa##abbbbbbaaabbcddddbccdcccbababaaaaaab#########aba..####aa###################aa########aa##aaaabbbba##a####ccaababdaa#aa#####aa##########aaaaabbccdfgjjihdcaa#aaaacbaabbababbaabbbabaabbbbbbbbbbbbbcccddebadhggfffeeffffeeeffdccddaaaabaaabbabbbbaaaa######..######aaaaaa#a###a#aaa###aaaccc#ceggedddcffffedcbabccdfgebaa###",
+"#########aabaaa####a#aabbachjgbacdedcccbabaaaaaaa#####aa#######aaaaaa#aaaaaaabaaaabbccdccddcbbbabaaaaaabbaa########aabb.#######a##################aaa##########aa##abaaaaa######bbaaaaba#a#a#.##.#a#aa###aa###aaaaaabcddgijijjigeba#abdcbbcdcabbbbaabbabaaabbbbaaabbbbbcacddee#dfeeeffeccdghhfffebccccaaaaababbbbaaabba#a########.###a##aaaa##aa##aaaaa####aababbddceggfedcdffedcbaabcdeeffaaaa#",
+"#######a#aaaaaa#a#####aaaabcdiibaaacecddcbaaaaaaaaaa##aaa########a#aa###aaaaaaaaaaaaabcccbbaaaaaaaaabaabbaaa######aaaaca.###.##a#a####a########aaaaaaa##...###a###a##a#aaaa#####bdaaaaaa########a########a##a##aaaaabbbbegfeedeghgeccddeeefgcbbaaaabbbbaaaabbbaababbbbcccbceeebegdddeffedbdeiihecbcbdbaabaaababcbbaaabaaa#a#.############aaaa##b#a##aaaaa##aabbbbccdceghgeddefedcaaaaccdedfaaaa#",
+"########bcaaaaa##########aaaa#gidaaabedcccbbbaabdbaa####aba#a#############aaaa###aaaaaaacbbaaaaabbabbbbbcbbabaa######aabb..##.####aa#aaa######aaaaaaa####a#.####aa##ba#aaaba#####dbaaaaa######aaa#aa######aa###aaa#aaabccebabaabbdfhhhgfghggdbaaabbcaaabbaaabaaaaaaabccccccedchigdcdddcedccabghdbaaabcaaabaaaaabbbbcbbaa##a########a##.#aaaaaaaaa#aaaaaaaca#acbbbbbcccdefeddeecdcbaababcfdfeaa##",
+"########baaaaba#aaaa#####a####aciib#aacdddbabbaabbb#aa#####aa#############aaaa##aaaabaaaabaa##aabababbbbccbbbcb#######aaaa#...##.#####aa########aaaaa######a############a#aaaab##abbaaaa#######cb############aa#aa#aaaaabaaa#######bfhigihhfbaabaaaaaabaaaabbaaaabaaaccbccdcchiihhdbcddcddccbbeeaaaabbbaaaababaabbbeeeaa#####.###.aaaa#aaaaaa#aaa#aaaaaa#bbadccbbbbccccbcddddcbcccbaaaaddddge###",
+"########a##abbaaa#########a#aaabcfjhaaabcdecaabaaaaaaa#######a########a#aa#abaa#####aaabaabaa##ba#abbccbaccaaca########abcb..######################aa###ceb#######aaa#####a#aaa###acaa#aa#######b############a#a##aaaaaabaa########abacfhhfcbbaaaabaaabaaaaccaaaaaaaacbcbbcffgfgcegeddeddcdccbcd#aaababbbaaababcaabaaccba########a#abaa##aaaa##aaaaaaaaaababcbbbaccbbcbccdddcbbbcbbcbbadcdeehd##",
+"########bb####aaba#########a####aabfjfbbcbcfdbabaaaaaaba######aa######aaaaaaaaa##a#####aaa######aaaabacbbaaabaa#########aadc...#######.##########aaaaaa#ddeb#a####aaaabeb######a###bbaaaa##b####aa#.##########a#a#a#aaaabaaa##b###.adbaabeecbaaaaaababaaaaabcabaaaabbbbbcdcfgeddgbbggeedddcccccc####aabaaaaabbaabaaa#acda############aaaaaa#aaabaaaaaaaaaabcbabbbabcbbbbcddccbcbbbabbbbccdfggf#a",
+"aaaa####bc##a#aaaaaaa###.#####.####aciiecccbceebaabbabbb######a#a####a##aaaaaaa########aaa#######aaabcbbabbaaaaa#########acfc..####.#.###.###aa###a#a#aaabcaaaa###aaaa##########a##bdcaaaa#ba###baa##########aaa####aaa#bbababdcbaacbbbaaaabbaaa##aaaaaaa#aabbbaaabbbbbbcdcccddcdec#adfedddcccbe#####aaaaaaaaaabbbaaa#bdb##.#######.####aaaaa###aaaaa##aaabccbbbaababbbbbcdccccbcbbbcbbbdcefghc#",
+"########a#####aa#bbaaaba######...####adhifegfddfdcabccbaa###aaaaaaa######aaaa##aa##a###b##########aa#aaaaaabaaa######a###abdfb..#######.##.#####aaa#a###baaa####aaa#########a####a#bddcbaaaa####aaaa####ad##aaaaaa#######abadddccccdcba##a#ababa###aaaaaaaaabaaabbbbbcbbcbbccdccbaba##afedddccbfa######a#aaaaaabbabaaaaab#####.##..#..a###aaaaa#aabbaaaaaabcccbbbabbbbbbbbddccbbcbbbcbbcfdeeffha",
+"##############aababaaaa##########.##.#..chjjhjifffdeccdbaa#aaa###aa#####.##aa#######.#######a#########aaaaaaaaaac########acchc.....#..###########aa##aa#abaaa##aba##a######aaaa##a##bdcbaaaa#####a#aa###bd###aaaa#aa##a####adgdcbbcddbb###aaa#a#####aaa##aaa##abbaabbbbcbbbcccddeccc#a#bhggfedaec##########aa#aaababaaaaaa#####.##.##.####aaaaaaaaaaaaaaaabdcbbbababbabbbabddcbbbbbbccbbdifdefge",
+"a###a##########abb#aaab#a#######...#####.##a#acgkigfeefdcaaa##aa#aaba####..######.#a###a#aa#aa##.#######aaaaaa##ba#####aaabbeha...###.###.#######a##aaa#aaa#a#aaaa###aa#a###aa###a###cdcaaa######a#####abb####aaaaa####a####deebbbccdbba##aaa#aa####aabaa#a#aabbbaaaaabcbcbbccbcedbba###cdffffeefba###########aaaaaabcaba#####.####.#######a#aaaaaaaaaaaaacdccabbababbabbaabcccbbbbbbbccdeeedefh",
+"f#######aa##a##aaa#aa#bba#########..############afkjgfgfeeeba#aaa##a#######.####.#.#####abbbaa##########aaaa##a#a#######abbcdhe#...######.##a####aa#a###aa#a#aaaaa######aaa###########bdbbaaa####a######aa##.##aaab####aabdecdcbaabbbaba##aaa#########abaaa##abbbaaaaabbbcdbaccbcebaa####adghfedeeba#############aaaaabbcb##########.######aa#aaaaaaa###bcdccbbabbbacbaabbbbbbdcccbbbbbcccccddeh",
+"hc#####aa######aa####aaaa#####a###.......##aa##a###gijhhhggeb##baaaa####...#####.#..a###acccaaa##########aa#####aaa####aacdddhf#..###.#..####aaaaaaaaaa###a#aa#aaaaa#####aabb##########cecaaa####a##############aabb##aabacddbcbbabbbaaaaaaaa##a#######baaaaa#abbaaa#abbbabcbbbcdgd####a##adcgfecdeb######a########aaaa#baaba########.######aaaaabbbbbbcbccbbbbbbbbbaaaaabbbbbbccbcbbbbcccccdeed",
+"egb##baaaaa####a##aa#aaa#a#######.#..###.###########adfilkhfca#abaaa#####..##....#....###bbccaa##a##aa####aaaaa##a##a##abbcfhjfb#..#####.######aaaaaaa######aa##a#abbbba###aba#aa#######cecaaaa###a#.#######aa##aa#aa###aaabcbcbbcbbaaabb##aaaaa#######abaaaaaabbaaa#abbbbbabbabdfeaaaa##a#ca#eecccfcaaaaaaaaa#a#a######aaaaabca########a####aaaabababbbbbbbbbbbbbbbaaaaaaabababccccbcccdccbdffd",
+"cfhd#acaaaa##a#######a#a##a###a##.....######.##########bddjkidca#########..###....######acaacbbb#a###ab##aaaaaaaaaaaaa#aabcfgejfa#.###a######a##aaaa#aaa#a###aa##a#abbcba#####aa####a###aeedbaaa##aa####...#aaaa#bcaccbaaaabcdccabcbbbaaca#aaaaa#########aaaaaaabaaaaabbbbbbbaaabbecbbcaaaaaa#adecccedcaaaaaaaaa##a###########abaa######a####aaaabdbbbbbbbaabbbbbabbaaaaaaaabbaabccbccbccdccdefg",
+"fedfea#a####a##a#a#######a####a#.##..#.####...########aaaaaeikhea#####################aaacbabbdfdbbaa#aaabbcbbaabaaaaaaabcdfbbeica..#a########aabaaaaaba#a###aa#######aaa#####aaa#.aa###adffdbaaa##ca####.#########abbcdeeeefcdcbabbbbbaacbbaaaaaa##a##a##baa##aa###aaaabbabbaabaadfb#bbbbbaa###feccbeecbbabaabaaaaaaa#aa###a####a########a##aaaaabbbbbbcbabbaaaaaabbbaaaaaaabbbabccccccddddeeee",
+"fggehdaaa######a##########aaaaa#.##.####..#..##.#######aabbaadjljgda.#################aaaccbccddcccccccccccccdcbbccbcbaabbcfdcbgf#...#aa######abcbaaaaabaaaaa############.##aa##a########dffedcbaa#cc##########a####bbbbcdffeedaaabbbbbcbabbaaaaaaa#######abaaaaaaaaaaaabbabbaa#a#bdcbbbaaaaa###cfeeehhecabbbbbbaaaaaa##aaa##a###a########aa#aaaa#bbcbbbabbbbaaaaabbbbbabaaaaaaaabbbbbcccddddeee",
+"edehhg#aaa######a#a#####a##abbaa###.###################aaabbcaacjllkhbaa#######a######bbaefddddcbbbaaaababefeedddccffdccdfgeeeefec#...#ab#.####abccbbba#aaaaaa###########..###a##########bfdfdccaaacfb.######aababaaaccccbdffebbbbcbbaacccbabbabaaaa######aaaaaaaaab#aaabaaaabaaaabbeffcaaaa####aeeeefiihfcabbbbbbabaaaaaaaa##a######aaaa####abbabbabcbaaaaccbbbbbbbbcbcaaaaaaaaaaaacbbcdddddede",
+"eefgghcaa#######a##aa######abbbcc#.############.###a#aaaaaaaaccbafjllkjecbaaaaaaaa##aabcccgefeecccbba#aaaa.acffffffcacdccbbbfffefda#.##########aabcedba##aa#a#####a#####..#####aa###.####bceecccbaabdfa##aabbbaabbbbdcbbccdcceebabbbaaabcdcbbbbbaaaa######a##aaaaaaacaaaaabbaba###acdeegcbbb#####aeffgfgijkgcbbbbbbbbabbaaaaa##a#aaa#abaaaa##aacdbabbccbaaa#bbbbaabaabccbaaaabbaaaaabbbccdeedddd",
+"deeffdfd#####a######a#######aaaca#a############bdca###aca##aaaceddfijjnligdcbbcbaaaaabcddchgedddbccaaa#aaaaa##accfbbbaa####bdhfedhd#.###########bbcccdba###aaa#####a##a#.#####a####.####.#abedebdcbbcfe#####adcbcddbbdbaaacbcbccbbbaaa#bbcbbbbbbaba#a############aaaaaaaaaabaaaaaaabdfcccbbba#####aceffgiijihedccbbbbbabbaaaaaaaaaaaaaaaaa#####aabaaabbbaaaaaabbaabbbbbcabaaaaaaaaabbbbcccdddddd",
+"ddddecbdca###a###a##baa#aa##abaaba#a###.#####.#aabaaa#aaa##aa#acdhilmklmlmkheegecbbbbccbcefgedcdcbbbbaaaaa#aba#a#cdabcbaaa#achihggfa############abdb#bcaa##aaa#########a###.######..########beddecbcdffc###.#acdfffdabcca#aabacbbbbbaa#abbbbbbbbbaa#############a#aaa#baaaaaba###aaadfd#babacababbbcegfhhiihgfdddcccbbbaabbaaaaaaaaaaba#aaa###a#aaaaaaaaaaaabbabbaabaaabcbbbaaaaaaababbccdddddcd",
+"deddddcacaba###a####aaaaaa#aaaa#aaa###aa#########a##aa#aaa##aba#.cfehhjkjllmllihfedcccbbdefgdcccecbbbccbaaaaaaaaabdbbbcbaaaabhjjhggea#.####a##a#accaa#cdaa#aaa#.#############a##a##.###a####.cedccccefbbaa#####deffeaacdaaaa#aabbbbbaaaaaabbaaabbaba#####a.###a###a#a#aaaaaaa#a##aaacdecaaaabaa#aa#bdgfeeefhhfdccccddcbbaaababaaa##aaaaaaaaa###aaaaaaaaaaaaaaaabbaaababbbbabbbaaaaaabbbbcdcdccdd",
+"dddcccdbbbcba#bb#aa###aa##a##a####a##.####aaa##a#aa##a#a#ba######.fffkjlhkkljmmmlieeddccefaeeeccdedbcdccbcbaaaaaabaccbccaaaabeijjigieba.#######aacbaa#accaaaaa##########a#a###aaa#############decabdeeeaba###..adeddcaabcbba##aabbbaaaaaaaaaaaaaaaaa#####a###########aa#abaaaa##a#abbcdeba#b#aa#####cefedcbbdeedcccdddcbbbaabbaaaaaaaaaaabaaa###aaaa#aaaaa###aaaaaaaaaabbbaabbcbaaaaaabcccccccdd",
+"ddccbcccbcedaddaaaaaaaaaa#aa#a######...###########aaaaaaaaaa####..cfhjjkmlmklkklmnjfeedeefebdeddegheeedddccbbbaaabbccbcbbaabbbgjkjjhifda.#######aaaaa###abaaaa####aaa###########aa##########..adccaddcecbabbaa##dedddcbabcbca#aaaabbaaaaaaaaaaaaaaaaaa###############aabaa##a####aacbcddebaaa########cffecdcbceeefdddddcbbbaabbbaaaabaaaaaaaaaa###aaa#a#aaaaaaaaaaaaaaaabbbaaaacbbaaabbbbcdcdccb",
+"cdcccccbbcdbaacbbbbbbaaa#aa#aaaa#####..#..##.#####a#aaa####aa######eigfcfgijjjlmmmmnlhfhiggdddeefgegfgffdeddcdcbaaccccbcbaaabbcfjkkkijgfb#######a#aa######a#############a###aaaaaba############abcc#ddcccbdecdcaddddddecbbbccaa###aabaaabaaaaaa#aaa#########.####a##a##a#aa#a######abccdgbb#ba#a######cffgfdefffehgdddeccccbaabbbaaabbabaaaaaaaaa###aa##aaaaaaaaaaaaaaaaaaaaaaaabbba#aabbacddccc",
+"cddcccbbcccaabbabaacbaaaaa#aa#aa#.#...#...#..###a###a#########aa##adeaaa#abedefijlkmnnlkkjdddfdcebb#degfaefgfeddcbdcddbacbbbbbbdjjklkkihgc#aa#####aa################aaa##a#aaabaaaaa###########aabdbedcabdddeeddddedcccddccbbbca###aaaaabba#a#####a#a###aaa###.###a#######aaaaa###aabbbbcdaaabaa##a####aeghhhggghhhfedddcccccbbbbbbbbbbbbbbaaaaaa####aaba#aca#aaaaaaaaaaaaaaaaaaaaabaaaaabbbcddd",
+"dddcccbbdedaabdaaaabbabbbbaaaaaa#.##.##.#.#####################aaaddbbaa#aa##a##aceejnllkkhfhfccfbbaaaabafabdeffgfcdddcabbbbabacgjkkllkhjhbaa#####aa############a##aaaa###aaa#aa#a#####.####a##aa#deedcabdeeeedeeddeedbccdcccdcb####aaabbbaaa#####a##a##a####################aa####aabbbcdea##a########aaabehiiiiiihfedfdccccccbacbbabbbcbbbbaaaaaaaa##ab##bbaaaaaaaaaabaaaaaaaabbbaaaaaabbbbbdd",
+"ddccdbcbedcaabbbbaaaaaabbababbaa#################a##########a###a#ecbaababaaaa#####abkllllljgbaaccbababbabaaaa#cedfheedcabbbbbbbchkkkklkhggeba###aba####.####a####a##aa##aaaaaaa##aa####.####a####dfdcba#bdeeeeeefedddcbbcdbbadcba###abaaacaaa###a##a###aa#####.####a######.##a####abbbbccbbc#ab##a#aa#ca###cfggihhihffffedcccccbbabccccdccbbbaaaaaaa#aa#aa#aaababaaabbaaaaaaaaaaaaaa#aa#abbcccc",
+"dedcccbcecaaacbababbbaabbbbbcbaaa#..###.#########a##############.cdabbbbbbbba###aabcddilmmljeaaabcbbbbbbbbbbbabaabcefgfecbbbbbbcdfjjkkkmkhfgecbaaabb########a######aaaaa####aaa###################befcbaabbadfeeeeffededcbbccabccccaa#aaa#abaa#######a########...###########.##..###abbbbcbbf#aa###abaa#a#####acfgffgfggefddcccccbbabcecbbbcbbaaaaaaaa##aa#aaaaababbbabbbbbcbbabaaaaa##aaaaabbcc",
+"cddecccccdcaaaaaabbbbaaaabbbbaaaa########.####################..aaababaaacbba#abddbcdfeejmllf#aabbbaabbbbbbaaaaaaa#afffdedcbbbddffjfijjkkkhgfed####aba#######a####aaaa#aa#####a######a############adffddcaa#befefedeeddccccbcbaacbaabbaa###aba####a###############.###########.######aabcddcefbb###bbaaaaaabba#cffffghhgfffedccccccbcbbebbbbbbbaaaaaaaa####aaba#aaaabbbbbbcbaaaaabbcbaaaaaaaabcc",
+"dddddfebdfeba##aaaaaaabbbbabaaaa####.#########################.abbaaaaaaaaabbaaabba##aceeilmme#aaaaaaaabbbbaaaaabbbbbefgeddcddddegiighiiggjggfdba##aaaa##############ba#b###aaaa#######a##a#aaa####dfgffgcaabefeeededccccdddcbbbbbaaacbab###aaaaaa########a#a########.#########..####aaabdcdecbdc#aa###aabbcccaacegggfgghggfeeeddddcccbccbbbbaaaaaaaaaaba#aaaabaaaaaaaaaaaaaaaaaaabbaaaaabbabbbc",
+"bcdeeeeedeeda##aaaaaaaccbbaaaaaaa####..##.#########a##########aaaaaaaaaaaaababba#aa####abbdhkmgbbbaaaaabbabaaaaababbbaehfcdeeeegghkkjjigdeehfeccaaaabcba########a####aaa#####aa####a####aa###baba##adfgfffdeeffdcddddddbcccdccbbbbbbb##bdb###aadb#a##############.##.######.##########abcdcedecegdb#a#aaabbcddaa#adfghfghgffefeefeeddcccccbbcbaaaaaaaaaaa#aa###aaaaaa#aaaab##aaaabbbabaaaabaaabb",
+"cbceeeefffffd#aaaaaaaaaddbaaaaaaaa#############.#############cbbaabaaaaaaabaaaaaaaaa###aaa#achlkigdaabbabbbbaabcaacaababccdbbdedcdfehkkjgeceheccda#aabbba###.######a#aaa#####aa######.#a#aa##aa#aa##adgggfeeggffdcccddcccbbcbccbbbaaa####ca##abcba#aa##########.#####a######.#.#######abbcbddbdfhgeaaa##abbcdcaaa##aaceghdfgffffffeeddddcccbbbaaaaaaaaaaaa##aa#aaaaaaaaaaab##a#baabbabbbaaaababb",
+"ccddefgfefffd#a##aaaaaabccbabaabaaa##########...############acbaabaabaaaaaaa#aaa#aabaaaa#aaaabgkjiifbabbabbaaaabaaabbabaaaaaaabcc#####cgkmjgfhfcbcaaaabcbaa########a#aa###a###########.####a######aa##bghfefgeddeccbbbccccccbcdcaaa#a##a#aa#a#aaaacbaa##.############aa########.#######bbbccddddggfbaa###abbcbaaaa#aaabeeeeggghgggffeedcccbbbbbcbaaaaaaaaaa###aaaba#aaaabbaa#a#abbbbbbabdbbaaaab",
+"bcceddefhgfcbaa#a#aaa###aaabbbaaaaa#######################aababaaaaa#aaaaaaaaaaa#aaaaaaaa#aa###cefllgabaaaaabbbaaaaabaaabbabaaa#ba######bfjljhghcac##aaacaa########a###############aa#.##a#############afgfgfedcccccbbccccccddcccaa##a####aa#aaaaaabaa#################a#a##.#########aaabccccddeegfbaa###abbaaa#aaaaaabdfceghhhhhhgfedddcbbbbbbbbaaaaaaaaaa###a##aaaaaaabbbaaacbbabbbbbcccdaaaa",
+"bbcccdefhiea###a##aaa######aaaa#aacb##############a####aaabcbbabbaaaaabaaaaaaaaa##a#aaabaaaaaaaaabekljbaaabbaabaabaaaaaaaabbaaaa#a#aa#####aekkhhiba###aabbbb#####a.#########a#a#####a#######aa####.#aba##gggfeedccbbbbbbcbaabccbcbaa##a###aa##abaaa#aa###..###########.###a##.#######aaaabbbcdddcefgaaaaa##abaabaaaabbaabdeffghighhgfffeeccbababbbbbaaaaa#aaaa#a####aaaaaabbaabbbbbbbcccbcccdbaa",
+"bcccccdefgeaaaaaaaaa#a#a#a##aaa#a#aba#######a#.###aa######bcaaaaaaaaaaabaaaaaaaa###aaaaaabbaa#aaabbchkkc#aaaaaaaaaaaaaaaaaaaaa#a#aaa#a#######dkklibca#aaabcdca#a#aa#################a######aaaa######aab#cghhgfddcbbbbaabaaaaabbca##a##abaaa##abaaba#a#aa############...##.###.#..####aaacbbcdccdcdedbaaa#a#acbaaa#aaaaaaabcffffghhhfggfeddbcbbbaaaabbaaaaaaaaaaa#aa#aa#aaabbbcccbbbbbbbbbbcdccb",
+"bbbccccdfcec##aaaaaa####a####aa#aa#aca##a####baa#######a##bbbaaaaaaaabbbbbaaaa#aaaa##aaaaabbba#aaaaaadijgaabaabbaaaaaa###aaaaaaaaaaaaaa#######behlidcdbaaabbcecaa######a###aaa###########a####a#######aaacghihgfedcbaaaaaaaaaababbbaa###aaa####a#aba##a#a#####..######......#...#.#.####aaccbcccdcdehhdaa####bcba###aaaaaaabaaadfeeegihgecdedcbcbaaaabbaaabaaaaaaa##aaaa#aaabcbbbccbbbbbbbbbcbbb",
+"babbcdddddde######aaa###########aaaabda##a####abaaa#####abbaaaaaaaaaaaaaaabbbaaa#aa##aaaaaaaaabaaaaaabcdkib#aaaabbaaaaaa####aaaaa#aaaaaa##a##a##acgjhfgefcbbacccbaa####a######aaaa########a#############bfffhjigedddbaaaaaabaabbbbccaa####aa###a##aa#################a##.....#..#########aabbbbcccddfheaaa####bba####abba#aaaa##bca.#bghfedecbccbbbaaaaaabaaaaaaaaa#a#aaaaabbbbbbbbbbbbbbbbbbaba",
+"bbabbdcdddcec#####aaaa#a####a###abaaaaaa##bda##aaa######aaaaa#######aabbbaaaaaa##a##aa#a#aaaaaaaabaabacbdjjbaaaaaabaaaaaa##########a#aa##aaa##a#a##cfhhededabbdcbcca##########aaaaa############a######a##dffgjiiheedcbaa###bbaabbbddba#########aaa####################a###..###..##..###aaaabbbbcbcfffebaaaa#aabaa##a#aaaaaaa#####aa#.bdegfeccbbaabbaaaaaaaaaaaaaa#aaaaaaaababccbcbaabbbbbbcbbab",
+"dbbbbcdcdcdcea###a####a#aab#aaaa##aaaaaaa##a####aaa###.##aa###########aaaabaa#aaaaaaaaaaaaa#aaaaaaabbaabbbhkfcaaaaabbaaaaa##########aaa###aaba######.ekjgddbabbaabccbba########aaa####.#######aa##aaa#####dgfgghgggedcbbaaa#aabbbcbedba#######aaa#a####################aa#.......##..####aabbbbcbcdefeebb#aaa#aaa##ab###aaa#######a###.##cgefdccbbabbbaaaaaaa#aaaa#a#aaaabbccbbcbbbaabbbbcbccbbb",
+"bcabbcceffabbc########aaa#aaaaaaba#aaaaaaaa########.#####aa######aa####aabbbaaaaaaa##aaaaaa###aa#aa#aaaaabbfkjhdaaaabaaa#aa##aa#####aa#a#a#aaaa######aikjjhbaaabbaacbaaa###############.###################bfhggggggfedcabaaaaabbcdeccaa########aa##########aa######a#a##a##..#.#...#####aabbbbbcccecdgccb##a####a##a############aaa######agfedccccbbaaaababaaaaaaa####aabbaaaaabbababbbccccbbcb",
+"ababbccdffdbbbba###aa#aaaaaaa#baaaaaaaaaaaa#########.####ab###########aaaaaaabcbbbaa###aaaa#ba###aaa###abbbbflljeaaaaaaaaa###########aa##aaaaa#######.afikkiba#abbaaba##########a############################ehffgggfeedcccbaabababcccbaa######aa##aa###.###aa####...#########...########abbbbcbbbcdecfgdaa#######################aa##a####bfeeddccbbbbbaaaaaabaaa#abaaaaaaaaabaaaabbbbbbccccccc",
+"adbbbbcdddecbaba#a#######a#a##aaaaaaaaa#aa##########.###aac##########a##aa#aaaabcbbaaaa##aaa####aa#aaba#abbbbdillhcaaaaa####aa####aa#aaaa##aa#########.#chkli#aaaaabbaaa########a#aa###a###############.###aa#fggffgffedeecbbbaaabbbbcbaaa#####aa###a############################.######aababbcbbbccedcfccaaaaaaaa###############.####a#####bffeddccbbaaaaaaaabaaa###aabaaaaaaaaaaababbbbbbbcccc",
+"ccbbccddeeeccaaca##a####aaaaaa##aaaaa#a#aaaa#########.###ab####.#a###aaa##aaa#aaaabbaaaaaaaaaaba#abaaaaaaaaaaachkklfbaaaa##########a##abaaa############..#bimiaaaaaabaaba##########aa#babaa##############.##a##aegfcbdeedfedbbbabbabbcbbbaa#####a#####aa######################.#########aabbbbbcbbacddddccaaa#aaaaaa###a#####################afgeecdccbaaaaaaa#abccbaaaaaaa#aaaaaaaaaaaabbbccbcc",
+"ccedcdddeeeccbbbcba#a###aaa#a#a#aaa#####aa#a#############ab#####.#####aa#a#aabaaaabbbbabbba##aa###acb#aaaaaaaaacfihkida##a#a###.####aaaaaaaa##a###aa######.ahljc#abaaaaaaa###.####a######abaaa############.#####.bababeedegdcbccbcbabaaabba#a##aa####aba#aba#a###################.####a##ababbbcbbbcdddedea#aaa#a####aa#######.###.######a##a##fgfedddbbaaaa#bcdccbbba####aaaaaaaabbabbbbbbbcbbc",
+"cddeddddeefddcbbcc#a#aa#aaaaaaa#aaaa####aaa######aa######ab#a########aa#a#aaaaaaaaaaabbaabba#aab###abb######aaabbcfheihc######a#####aa#aaaaaaa####aaaaaa###.aikjcaaaaaaaa#################aaccbaa#a################aaaaaaabdddcbccbaaaaaaaaaaa##b####abbcccb##.###a#############..###aaaaaabbbbbccbbccccddecaaa#aaaa###a########################effedccaabbaccbbaaaacc####a#aaaa#aabbbbbbbbbbbcc",
+"dcdcdcdeddfecdcbcdaa#aaa##a###a###aa##############aaaa###aba#############aaaabaaabaaaabbabbaaa#aba####a##a###aaabccefadhhb##aaa#####aaaaa#aa#a##aaa#aaa#####.aflkcaaaabaa####################ddcbaaa#################a#aaa#bdddbbcbaaaabaaaaaaa#a####a#baa####a###a###aa#############aaaabccccbcccbbcdcdedefb##a###aa##aa###############a##aa####efddcbcecbccabbaa#aacc###a##aa#aaaabbababbbbccc",
+"ccdddcbcfhfddcdcbbc#####a#aaa##a########a#a#aaa#####aaa##abaaa##.#######aabbaabbaaaaaaaababbaaa#aaaaa###a#a#a#aaabccdha#diga##aba#####ca##aa####aaaaa#a#######acildaababbaa###########a#######abccbaa#########.#########a###cdedbbdcbbabba#aaa###a####aaaa#aab###a##a#aa######aaa######aabbccccccccccddddeddfca#aa##aaa#aaa#####a####.###aa#a##a#cfeddedacaaabcaa###aacc###########aaaaaabbbbbcc",
+"ccccddccdeffdcccdccb########aa##########a#aaabaa#####aa##ab#aa###########aaaaaaababaaaaaaaabaabcabba############aaabcffb.afjfa#aba####a#a########a#a########aa#abhjb#aaaba#a##########a#######aabcccbb####.#..###aba#########abddbcecbbcbba#aaa########aaaa#a#a###aaa########aaaaa#####aabccdcddccccccccddedcec###ba#a####a#a##########.######aa#adedcbbaabaaabbaa###aabca##aaa#a##aaaaaaabbbbbc",
+"cccccdcedcddfebbdcbdb#######################abcbba#######bbaa######.######aaaaaabbabaaaa##aaabababaaaaa########aaaabbcfiea#bgjeaaa######aa#a#############a####a#acgigaaabb##########.##a#######aaa#adcba##########ba#a#a#####a#adfcddbcccbaa#aaa######aaaaaa##aa#aabbab#aa####aaaa#####aaabbccdddcdcbbbbcccddegd##baaaaa#########a################abbcccbbbbabbbba#####abca##aaa####aa#aaabbbbbb",
+"bbbccddcdcddefdbcdadcaaa#####################aabbbba#a#aabba#aa##########aaaaaabbaaaaaaaaa#a#aaabbbbbaaaa###a#aaaaaaaabfifa##ejgbaaa########a##################acbcfigba#aa###########a#########a#aaabbbba#######.#a#a#######aaaaffddccbccba##aaa##########a######aabaaa#.####aa######aaabbbccdeeefggecdedcdfedcbaacbaaaa##a#a####a############a##aa#accdcbcbbbbbba#####aaca#aaaaaaa###a#aaabaab",
+"bbbbcccccddddfecbccbdc#a############a###aaaa#aaa#aa##aabcccc###########aa#aaaaaabaaaaaaaaaa#aaa#aaabbbbbbaa###a#aabaaabbbhie#.bfhfbaaaa###aaaaaaaaa#######a####aaabdhifbaa########aabaa###a######aa#####bccaa#####.#####a########afgeddccdcba###aa########a#a#######aa######.##########aabcbcccdffghihgdcddcbacbbeabaaaaaa#a###################a##aaaa#bcddcdcbbbab##a##aaaba#aabcaa####a#aaaaba",
+"bbbbbbcccccdefedbbcacdc####aa##a#.##a#.##abb######a##aabbccc###########aa#aaaabbbbaaabaaaaaaaaaaaaaaabbbccbaa##aaabaabba##diic##adhebaaaa#aaa#aa##aa##########aabaaagjjf#a######a#aaaaaaa#a#######aa#a###bdddaa#a###.#a###########adcdddddcba#aaaaa#a###a##a##ba#b###aa####.###aa#####a#abcdcbbcdghihhgdcaaaaaabcfdccaaaaa#aa###################a##a#a##acbcdcbbcba#a#####aaba##abaaaa###aaaaaaa",
+"aaaaabbbbbcddeedccebaccb###a####a####a#..aba##########aaaaccb.############aaaabbaabbaabbaaaaaaaaaa#baaaccbbaaaa#aaaaaaaa####fjfb###egebaabcb##aaa##############aaa#achkjbaa######aaaaaba#a#aa###a###########abba###################abaceddcbaaaaaaaa#####a#####a####a##a######.###a##abaaccddedeeffdghfaaaaaaaabbdfcabbaaaaa###############.#########a###bccbedcbdaa######a#abaaaba########a#aaa",
+"#a#aaaabbbbbbcdedcccbabbb##aa######.######ba#############abcc##############aaaaababaaaaabbaaaaaaaaaaaaabbcbbccba#aaaaaaaaaaa#beihb##afgdbbcba#aaaaa######a######aa#abcilheba#####aaaaabaaaaaa#########a####a##a#aaa###############a#aaadedbbaaaaaaaaa##aa##a#######a##aab######.##aaaababceefcddcb#.#gfaaa#aaaaabcfgcaaaaaba########.#####################aabddcbcabaa##a##aaabaaaa######a######",
+"##a#aaaabbaabbccdcbcbbbacb###a###########.aba#######aa###aacf#######.#######aaaaaabcaaa#acaabbaaaaaaaaabababbbcdcbaabba#abaaaaabfje#a#aehdaaaaaaaaba#####ab#a####aabaabijiebaa##aaaaaabaaaba##aa#####a#a###########a###a###########aaaaaabbbaaaaaabaaa#aaaaa#####a##abaaaaaa########abbabcdgeba##.##.bdaaa#a#aaaacfgcaaaaaa########.a########.#######a#aa###abccbbbaaaa#aa#abbab#abaa####aa#####",
+"#####aaabbaaaabcbccccbbbcca###a############a#########aa##aaacb###.#.########aaaaaaaaabcbaaabaaaaaaaabaaaaaaaaaabcaaaaabaaaaabaabaejhbaa#aggcaaaaaaaaa####abb#a###aa##aabhigddbababba#acbabaaa###aa####a#c#a#############a#a########aaaaaaaabbaaaaaaaaaa#aa##a#####aaaaaa###aaa######aabbabege##b#######aa#a##aaaaaceecbaaa############################aaaa##aaacbbbaaa##aaa#aaaaa##aa#####a#####",
+"####aaaaaaaabbabbdcbcdccbbba#aa####a##a####a######..##aaaaabab###.###########aaaaaaabbbbbbaaaaa#aaaabcbaabaaabbaaaaaaabbaaabbabab#bghcaba#dhfaabaaaaaa#aa###aa##aaaaaaaabeegbccbaaabcbbbaababa######aa#aaaaa##aa#.######aaa#########b#aaaaaabaaaaaaaaaaa#a##aa#aaa#aaabbab##a####ab#aabbbbcfhaaca##############abbabddbbaa####################.###a##a#aaaaa#aabbbbbaaaaaa###aaaaaaaa#######a###",
+"#####aaaaaabbbbbccdbccdcbcca##########a#####aa##a######a#aaaabc###############aaacaabbabbbbbaaaaaaabccbbaaaaaaababcaa#bbaaaaaaaa#ba#eiebabaafhb#aaa###a#a####aaabbaa#baabbbigcebaaabcbbcdbbbcca#a##a###acbbaa#ab##########aaaa########aababbbaaaaabaaaaa##a###a#aa###aaaca##a#aa.bc#abbdccbdga#####.###########abbbbcdebaa##a##a##########a####.###a#aa###aaa##aabbabbba#a#####aaaaaa########aa#",
+"#####bbbabbbabbcddddcccbbbcca#a##aa###a#################aaaaabb#a####.########aaaacaaaaaacaaaaabcaaabbcdcbbbcbabbbabbaaaaaaaaa####aa#cijdbababhfa#aa###aa##a##a#aaaaa#aabbbflggfaabacbaabbbaacbba##aa#abccbbaa###aaa#####a#aaaba###a#aaaaabbacbaaaaaaaaaaaa###aaaaaaaaaacaaaa#bbab#abbcccccbdc#################aabdceedebaa#########################b#####aa#####bbbabbaa#a####a#aa##ba########a",
+"aa##aaabbbbccbbcccddcdccabbdfa####a###########aa######a#a#aacc#######.#########aaabababbaaaabbaaaaaaaabbbbaaaaaaabaabbbaaabaaaaacba#a#beijbaaaaehfa###########aa#abaaaabbbbdhjghffedccaaabaabaabbaaaacbcbcccbaa#aaaaaaaa#aaaaaaaa####aaaabbaadebbaaaaaaaaaaa###aaabaa#a#aaaaabbbbbbbabcdcccefe####.##.#######.##a#aacccccaa#aa#####.###############aaa###.#a###a##bbbbbaa#a########aaaaa##a#####",
+"###ab#ababbccbcbccdddccccbbbeda##aaa######aa###abaa####a###abdb#a###.######aaa#aaabbbaaaaaa#abbbaa#aaaaabdaabbcbabb#aaaaaaaabaaacbcba####ejdbbbacgjd##aa#aa#####aaabbaabaabbejiiiihhggfbaabbbaabcba#bcdcdddddcaabbbbcbaaaaabaaaaaaa##aaabbbbcdedbcbaaaaabbaa#aa#aabbaaaaaaabccbbbbbcdccddffebb####################aabccccca###########.#########a####aaa####a##aa#abbaaaaaa########aaa####a#####",
+"#aaaaabbbabbcccccdedccccedccdebabaa#aa###########baa##.##aaa#aca#######.#####aaa#aaabaaaaaabaaaacbaaaaaaabaaaabcbaabaa##aaabaaaaabaaaa###.cjgcbbbadiib##aaaaa####aaabbaaaaabdhlijjiiihfefcbaabbbbbbababdedfddedccbccdccbccdccccbaa#aaaaababcccdddcccbaaabbaaba#aaaabbaabbaccdddcdefffedeeed..################.######abcbdfbab#a###########################a#a#####aaaaaaaa##aaaa######a##.#a####",
+"###aaaaabcbabccccdcddcccccbbccebaaaa##############a#a####aaa##abb##############aabaaababaaabaaaabbaaaaaaaaaaaaaabbcbabbaabaaaaaaaaaaaa####.afhdbbaabfihb.#aa###aa###aaba#aaacclljjiijigddecbaabccbabbbdbadcbeffffeffgghhhighgfhgffcaaababdbbbbcfddddcbbbbbccabaaaaaaababddehggfegjiedaaaa#a####a##############.######bcdcddbaaa##a###################a#a#####aa####aaaa#aaa#a########a#######aaa",
+"aa##aaaabaaabbbdddccdbcddcccccdd##a#aa##aa########a######aaba###ab##############abaaaaacbaaaabaaaaaaaaaaaaaabbaabbaccbaaaaaaaaaaaaaa#########bfgbaabbdije.######aa#abbaaaaaaabellkkkkllkiiigfdcdcbabbcbcdcbcgijkjhhhhijjic#dcbcbddghffeeeihiggfgddedcccbcdcdcbcbcbabadeeffghhhebegdddb#########a#a####################babbbcbbb##a##################aa##a####aa#a###aa#a#aaa##a#######aaaaa##aa#",
+"a#aaaaabaaaaaabcdcceccefcadgeceebba###a#aaa########a#####aabaa#aabda########a####aaaaaaabbaaaabaaaaaabbaaaabbbbaaaaaabbcbaaaabaaaaaaa#aa######.eiebbbbcfihc#.###abaaa#aa##aaaabellkjlkjklmnnmlkgfccbbdddeefghjijkkllkhd#cfeabcbbcbbdgjjhgecccehieeededccceeedddddefcdffcedbacdec#bbaba#########aaaba#########.#######aaaacccdbbaa####################aa##a####aaaaa#aaaaa#a####aa######aa#aa##aa",
+"a#aaaabaaaaaaaabcccdddggedbdfccecaaa###aaba#a#######aa#.##aabba#aabc###########aaaaabcbaaaabaabaabbbabaaaaaabbcccaaaabbbbbbaaabaaaaaa#aa#aba###.bigbbbccdilid.##aaaaaa####aabbbcekmljgdfiijikmlmnkgdeefeeegieeddgdcghgdbabcfdebcccceffggfcbbbbbcefgedddcceeefdedcbccefgb####babedcaa##aa#######aabcda##.#############aaaaabcdcdbaa#########a########a###a###aabbbbaa#aa#aaaaa##aa######aaa##aaa#",
+"##aaaaabbaaaaaaabcdceeffedccfgedcaaa##aaaa###a#a#####aa..##abaaaabbd#########aaaaa#a#bbbbbbaaaaaaabbbbbaaaaaabccbbaaabaabbbbab#aaaaaaaaa#aaaaa###ahibbcdccgjkg####a#aa####aabbcddegkhddgihhghiibdilmljjjjiiihfaaa##aeeedcbbdghfdbbdfedfedccbbbbdbffhfededeefhhfc#####cea#####aaabdfda.a######.##abdfb##########.###a##aaaabadefecb#a##########aaa####a##aa####acbbbaa##aaaaaaaaaaa#####a######a#",
+"a##aaaaaabaaaaaabacddeddfdccefffd#aaaaabbaa#a#####a#.aaa###aaaa#abbdb########aaaaba#aaaaababbaabbbbbbbbbaaaaaaa#abcbaaababbbbcb#aa#abaaa###########fhdcccdcehihb###aa######a#bccdefggiglkjjhiihba#cglkjhiihgebcaaaaaa#aacdbbdefhfdbbeedbccbbbabdcbgjifefedeggfgfa#aa#a.aa######aaaacffba####.###abdeca######a###########aabbegffgedaaa##########aa####a##aaa#####aaaab#aaa##aaa#aa######a#######",
+"##aaaaa#aaaaaaaaabbcdddceddeeecdfbaaaaabbbaa#####ab#########aaaaaabbc########aababbaaaaaaaabbbaaaabcbbabbaaabaaaaaaabbbbaaabaabbbcaaaaaaa##########.bhfcccdddefigc#abaa#aaaaaacccdegeiihkihhjhbbaa#.#a##a#..##aaaaaaaaaaaacaabaacefedefbbedcbaccdbcfgiihhfdec.addb#ba###aa######aaaaadgeca#######aceaaa#################aaabdgeeghffb########a######aa####abaa#####a#aaaaaaa#aa###a#.######aaaa#",
+"a##a####aa#aaaaaaabccbccdedefebbef#baaaaaabaa#####a#aaa####aaa##aaaada########aaabbbaaaaabbaaaaccbbcabbbbaaaabaaaaaaaabbbbabbbbaabcb#a##a#########a##bifdccdddefgjeaaabaaaa##accbbcddfhehijhdb#aaaaa#a####a#abaa#aa##aa#aaaaaabbbaabefigffefdbcccdcbaacbbdhhfeaacbabb##a##########aaaaadhgb#####aabecaa########a###########baegfefgfeca##a#######a##aaaaa#aaaaa####aa#aabbaa#aaa###a#.#####a#aaa",
+"#aa#####a#a#aaaaaaacccbbccdcdedbcfcaaabbbaaaaa####a###a###abdb####aaeda######a#aa#aabbbabbaaaaacddbaaaaabaaaaaaabcbaabbbaabbbbbbababa####aa###aaa#####dihecccdedeejgaabcbaaaaabcbbbcdeheggeabaaa####aa########aa###aaaaaaaaaaaaaaccbaabdegedddddddccbbbba#abaabcbbaaaa##a##.#.#####a#a#abefb#####abdfaaa#####aaaa#a########aaadfeeffffc#######a######aa#aaaaaaa#aa##aa#aaabaaaaaa#######.###a#aa",
+"aaaaaa#aaaaaabaaaaabbcbbabbbcceedffdbaabcaaaa##abaa##aa###acefa####abdaa###.####a##aabbbcbcbaaaaabba##aaabaaaabaabbbaabbbaabbbbabbcbba#a##aa###aaa#####bhjgccdddefdhheabbaaababcbbabcdehfcaaaaaaaaa#aaaa#######aa###a##aaaaaabcdaabbbbabbbefedeccddcbbbaababbbcccca#a####aa#############aaceda###aabfebaa####aaaaa##########aaadefedegca########aaa##aaa#aaaaaaa##aaa##aaaaaaa#bcba#########aa##",
+"#aaa#aaa#aaaababcbbbbccbaaabbbbdgffgbaabbbaaaa#aaa####a##abbgea##aa##bca#########a#a#bcbabbbbaaaaaaaa##aabaababbbaabaabbbbbbbbbaaaabbaa##a#####aaa######adhidddddfhdfigbcba#aaaaaaaacbcfdabaaaaaa#aaaaaaa#######bb#####aaa##aabccaaabdcaaaeeefeddefcbbbbaaaabcbbbcdba#####a####..#######a##abdb#aabcefdaa####a#aaaaa#######aaaaaabacefc#########a###aaaaaa##aaaaaaaaaaaaabaaaa##aaaa###.#####aa#",
+"#############aabaaaabcbbaaaabbcceeeeeaaabbaa##a###ab#####abddb#####a##cb#######aa#a##aabbbbbbbaaaaabaaa##bbabbbaaabaabbbacbcbbbcbbbbaaa###a######aa##a#baaagkecdeegfeehfcbba##aaaaaaaaccdcbaccbaaaa#aaa##aaa#########a##a###aaabcaaaadeddbbdcdeigfdbcccbaa##cbabcbcdaaa####aaa######.######aa#debaacfdcaa#####aaaabaa########a##aabccdd#############aaaaaaa###aaaaaaaaaaaaaa###aaaaaa#########aa",
+"#############aabbbcbbccbaaaabbccddeedca#abaaa#aa###a##.##aaaa#######aaaca############aaaaaabaabaaaaaa##a#aaaaabbaaaaabbbabbbcbbccbccbaba##########a##aaabaabejfddddehddhgdbbba##aaaaabbbcccaabaaaaa#a#a##a#aaa###############aabcaaaaaegeddcecacdghfdccbaaa#cbabcbac#######bba#################bcdcbeebaaa###aaaa#aa#a###a####abaabdcdcba#a##a####aa###aaaaa##aaaa#aaaaaaaaaaa#aaa##aa#########a",
+"aca##########a#aaabdbcccbaaaabbccddeedbaaaaaa#aa#########abca#######a#aca############aaaaaaaaaaaaaaaaaaaaaaaaabbabaabbbbbabbbcbbbbcabbbba##########aa###aabbbeidbbccehefhhcbbaaa#aaabbaaabbcaaa#abcaaaaaaaaaaaaa#####.########aaabaacbedfdbbbdccccfhebaabaaa##a#acaba######daa###.######a####aa##acfdfdaa####aaaaaaaa###aca#aaaabaabccdeaaa###aa#aaaa##a#aaaaaa#abaaaaaaaabaaa##############.aab",
+"aa#bb#####.######aaabcccbbaaaabbbcddeebaaaa########.#####abca##########abaa####a#####aaaaaaaaaaaaaa#aaaaaaaaabcbbaaaaaaaabbbbbbbbbccabbaa#a#########a#####aaaachdbccdefehgiebbbaaaaabaaabccacbaaaacbaaaaaaa#aaaaaa#############a#baaaaceddbaabcbebbefdcaaaaa###ba#baa#####.aba##############a#a##aacfghdcaaaa#abaaaaaa######acbababbbdbaa###aaa#aaaa#a#aa#aa#aa##abaaaaaaabaaaaa##############ba",
+"a#aa#a#####.###a#aaabbcccbbbaabbbccccge#aa#######.#######abbba#######aaabbaa####bba###aaaaaaaaaaaaa#######aaaaabbbbabaabbaabbbbcbbbcbabbbaaa#a##a##########aaaabeccccddfgefhgaccaa#abbabbbbabbbba#aa#aaaaaaaaaaaaa#######a#####aaaaaabacdccabbbcecaacdfecbbaaaa#aaabaaa#####aa########aaab####a###aabeggbaaaaaaaaaaaaa#a##a###aaaabcccccaa###aaaaaaa#aa#aaaaaaaa#abaaaabaaaaaaa#a###########a#aa",
+"###aaaa###a######aaaacccbbbbbbbabccccehb#a########..#####abbca#######aaaacaa####cca###aaaaaaaaaaaaa#######aaaabaaaacdbaaabbbbbbbaabbbbcbccaa############a#aaaaabaccbdccegeccffbbaa######.#abaabbbaaaaaaaa#aaa#aaaaaaa#a##########aaaabbcc#abbabaabaddcbceebbba#aaaaaba######a############aba###a##aaaccggbaaaaaaabaaaaabaaaaa#a#bbabbccdb#aa###aa#aa#aaa#a#aaabaaaaab###abbabaaa###a#a########aa",
+"###aa#a######.######aacccbbbbbabbbccccfheaaaa#############bbcaa#######aaabcaa#####aa####aaaaaabaaaaa#aaa##aaabaaaaaacdcbaabcbbcbbbabbaabbbbca#a######aaa##a##a#aaacabccdeggacge.#aa####a#baaaabbabaaaaababbaaaaaaaaaaaa#########aaaaaaabda#aaabbbacbcdbbcdeca#a#aaaaa#a#aa#aa#############aa#####a#aaabcfgcabaaaaabaaaa#aaa#####babbbcccc##aa#a#aa#aaaa###aa#aaaaaaaaaaa#aabbaaaa###a#a#####abba",
+"###aa##aa##########a#acbcccbbbbbbbbbcceffebaa#############accbaaa######a#bdcaaa####aa##aaaaaaaaabaaaaaaaa#abbbaaaababcddccbcccccbaabaaabbbbbca####a######aaaaa##a##bbabcbdgefeed########a#a###ab#aabbbaaaaaaaaaaabaaabba#####a#.#a##aaaabca##abbbaccbbdcbcdedb#aaaaabaaa###aaa#########aa#aaaaaaaaaaaaabceecc##aaaaaa#a#aa########abbacccc##aaa#aa##aaaa###aabaaaaabaaaaaaabaaaa####aa#####a#a#a",
+"b###aaaaa#######.##a##abbdcbaabbbbaabccdegea########a#####abcbba###aa####acccaa######a#####aaaacbbbabbccbbaaccaaaaabbbcccbcbccbbaaaababaaaaabc###a#aa#####a#aa#a#aabdaaacbbafhgbfa.#####aaaaaaaaa#aabaaaaaaaaaaaabbbaaba###a###########baba##aaaabacaabccbccdeeaaaa#aaab####.########.##aabbbaaaaaaaaaaabccaccba##abbaa###a##a###a#aabbccca#aaa#a#abaaaaaaaaacaaaa#aaaabbaaaaa#aaaa#a#######a##a",
+"baabaa#######aaa#####aabbccbbaaabbaaabccdfeba#######aaa###abcabbaa##aaa####ddbaa######a###aaaaaaaaaabbcbbbbbccaaaaaabbbbbcccccbbbaaaaaaaaaa#abca##a#aaaaaa##aaaaaaabcaaaabaabgicce##.#a##aa#a#aaaaabaccbaabaaaaaaaaabbbaaa#aabb##########aa#aaaaaaaaaaabccccddfebaaaaabbaa################bbbbbbaaaaaaaabbbc##acbbaaaaaa####a#####aabbbcccb###aaaaaabbaaaa#a##aa####aba#bbaaaaaaabaaa#######a##a",
+"baaaaa#######aa#######aabccbabaabbbaabbbcdgdb#a########a##abdbbaaaa##aaa##abdcbaa#############aaaabbbbbbbbbabccaaaaaaaacbbbcccbccccbbaaaaaaaabbca#aaa#a#aaaaaacbabaa#aaaaaccbbjgabc###bb######abaaabbcccbabbbaaaaaaaaaaaaa##aaaaaa#######aa###aabcbaaaabbbccdeeefebaccbbbbb#.####a####.###abaabbbbbcbaa#aaabca.##acccbaaaa########aaababbcba##abaaaaaaaaaaaaaaaa#aaa#baaababa#bbaaaaaaa#######aa",
+"aa##aaa###############a#abcbabbaaaabaabbbcffcaa##aa##aaaa#abbbbaaaaaaa##a##abdbaa##############aaaaabbaacbabbbcaaaaaaaabbbaaabacbccbbbaaa#aaa#aabb#aaaaaaaaaaabbbbaaaa##aabbbadiabbc.##c#######aaaaaabbccbbabbaaababaaaaaaaaaa##aa#######a#####aabbaaaabcbbbcddcefhgceeaabba##############abbbbbbcbaa###.###aca####aacdba#a#a######aaaabbcbbaa##aaaaaaaaaaaa#aaaaaaaaaaaaaa#bababaaaabaaaaaaa#ab",
+"cb####aa################abcbbbaaaaabbaabbbdgdb##a#aa#aaaaa#abaabaaa#bba####aaddba#######a#########a#abbaaccccccbaaaaabaabccbbabaabcbbbbaaa#aa###acda####aaaabaaabbcbbaaaaa#bcbcebbccd#.aba######aaa#a#acbaaabbbbbaaabbdbbca##ba###abc.#.####.##a#bbaaaaaaccccdecdefghgfccccb#.####.#...###aaaabbabddba###...##bb#####a#bcba##########aaabbccaa###aaaaaaaaaaaaa##a#aa#aaaaaaaa##ababbaabaaaaaaaab",
+"ec##########a##aa#.#####abbcbbaaa#aa#ababccfffcaaa#aabaaaaaabbaaaaa#aba###aabbfdaa###.#############a#aaabbccbbccaabbaabbbbbbbbabaaabbbbbaaa#a###aacdba##aa#abbacbbcbbbaabaaabbceabccde.#c#aa######aaa#aaa#aaababbabaabbdefecd#aaaaaaec#.#########aaaaaa#aacdcbdbabdfegddffdba##.#.###.###aabbbbabbccbba###.#.##bc#######abbba########aaabbbddcaa##aaa##aaaaaaaaaa#aaa#aaaa#aaaaaababaabbaaaa##ab",
+"bca######.#####aa#######abbbbac#a##aa##abcdcehfaaaabbbaa#abcbbbaaa#aaba#####acegdaa####.############aaaaabbbbccccbabababcbbbbbaabbcbbabaa##aaa###aacebba###bffcdbcbbcbbcaaaabbbhbabbcee.##aa##aaa#acaabbaaaaaaabccaaaaaabdefge##aaaacea###########a######abdfdabaaaaababaceeb###.#...#.##aaabbbabbbaabaaa###..##bea###a##a#aca#a#a#####aaababb####aaaa##aaaaaaaaaaaabaaaaa#aaaaaababaaaaaaa###ab",
+".#a###########.b########aacaaaacaaaaaaa##acdffgbaaabaaa##aaehdbaaaa#aaaa#####acfgbaa#########.########aaaabbabcdecbaabbabbbbbbbaaababaaaa######a##aaddbaaaaab##a##abccccccbbaabfhaababgd.######aa#aaaaaaaaaaaaabacdddbaaaaaaddeda#aa#ba######..##a########abdcaaaaababcabbbcddb#a###..#.##aaabccbbaaaaa#########abed#########cb#a#a####a#aaaaacb###a#aaa##aaaaaaaaaaaabaa#aaaaabaaaababaaa######",
+"#########aaa###a########abbaaaaaaa#a#aaaaaacdegeaabaaccbaa#acefcaa###aabba###aadfdbbaa####.#############ababaaabcccaaaaabbbbbbbabaaabbbbaaa#####aaaabdeaabbba########aabdedcbabbffaababhd########a#aaaaaaaaaaaaaaacedbabaaba#bfggcaaa#########..#.########aabcb#aaaaaabaababccddba#..##.####aaabbaaaaaa##...#####acecb########abba#aa#a#aaaaabbca##aa#aa#aabbaaaaaaaaaaaaaaaaaaabaaaaaabaaa#aa##",
+"##########aa###a#####aaaaaaa##aaaacc#a###aabbcefbabbcfcddddbabgfa#a#aaaadbaa##abdedcaaaaaa#############a#aaaabbbbaacbbabbaabbaaababbaabababa##a##aaaaaccbbbb########.###abbacdcccgbabbbcida####aa#a#baaaaaaaa##aaabccaaaaaacbbabggb#a#####aa##..##aa######aabbcbaaaaaaaba#aabbcccca#.########aaaaaaaaa###...#######abdec########abb#aaaaaaaaaaabcbaaa#####aabbbb#aaaaaa#abba#aaaaaabaaaaaaaaabb#",
+"###########aaaaba###aaaaaa####aaabdebca###aabbcfgfbacdccdeheaadgea###a##dcabaaaabdedcbaa##################aaaaabbbccbaabcbaabbbbabbabbbaaabaa#####aa#abddbcb##a########a##.##accdeedbcccejcbaa####aaaaaa#a#aaaa###aabbbbaa#bdbb#chfa####a########.###########babbaaaaaabaa#aaaaabbcdc#..######aa#aaaaaa###.#..#####a#abdeba#######bbbbaaa#aaaaaabcca#aaaa#aaaabbbaabaaaaaaaba#aa#bbaabbaaaa#####",
+"######a##a###a#aaaaa#aabaaa##aaacddbbcaa##aaaabdifdadeeddfffaabdddbaaaaabd#aaaaaacfedcaa#################aa###aaaacccbbabbbbaaabbbbbbbbbaaaaa######a#aaacdddaaa#########a######aabbicceedghcbb##aa#aaaaaa#aaa#a####aaabbaa#adffbafgd####aa###################aaaaaaaaaaaaa#ababaaabbbcb#.####aaaa#a#a#a##..########a#aabbcdd#.###a##bbaaaaaaaaabbbbba######aaaacbb#abaaabaa#a#aaaabaabbbabaa####",
+"######aaaaa####aaaaba#abaaa###a#bddccaaa######abcfgghhhfdfffcacbabdecca#bca#aba##aeffeba##############.########aaaaccbbbabcbbbaaaababbbbbbbaaaa######aaaabeeaa#aaa######a###a#aaaabfgdbbddhhccb###aaaaaabaaa###aa##aaaaaaaa#bffgd#cda##a#a######a#a###########aaaa#aaaaabb#abaaaa#aaaabbca####aa#aaaa####.#############aaabcdc#####a#abba###aaabababc#aaa##aaabcaaaaabaaaaaaacaaaabaabbbbbaaa###",
+"a######aaaa##a#aabbaaaaacba##a##acccddbaa#a##aaaaacccdefefefdacaaaacgebcdb#a##aacbbegfdba#aba##############aa###aaabcdbccbbabcbbbbbbbaabbabaaa###a###aaaabcdb#baa#a###########aaabddgcdcbbcfidbcb#aaaaabaaa#a#a#abaa###a#aa##dfffeaa#####a#####aa##b.######.###aaaaaaaaaacbacaabaaaa#aaaacccaa####################a########abceca###aa#abaa#aaabaaaacda#aa###aacaaaaaabaaa#aaabaaaacbbbbacaaaaaa",
+"aa##a###aaaa#a##aaaaabbbbbbba####bbbacbaaaa##aaaaaabccbdedcefaccaaa#accccaa##aaabcddfgefeeffea################aaaaaabbcbcbbcbabbbaabbaacaaaa#a#######a#aaaacfcaaa##a############aacdee#a####eifccc#aaa#ccaa###aaa#ba###a###a#befffd######aaab###aa############aaaaaaaaaabbcbcdbbaa###abbaaabccdca...#######aa#a####a######aaaabcdc######aaaaaaaaaaabbcdbaaa##aababaa##aabaaaaaabaa#abbbbaaba#aaa",
+"#aaaaa##a#.###a#aaaaaceccbbbab##aaaaaaaaaba#aaaa#aaabccbcdddgfdaaaa######aa##a#aaaeggihgeefeddeca###############aaaaababcbbbbaabaaaaabacbaaa##a#####ba#aaabadgeaa#a##a####a##a##aabbeeaa#####bhibaca##aadbaaaaaca###########aadfddfda###abaabb#aaba#####a######baa#aaaa#abdc#bccbaaaa###ba#aaabdfeec#########aa#aaaa####aa#aaaaabde###a###aaaaba#aaaabbccbaaaaaaaaaa#a#aaabaaabbaaaababbbbaabaaa",
+"##aa####a#####aaaaabcccbbbcbbaa##aaaaaaaaabb#baa##aaabbcccdefgiecbaaa##aabba###a#affghihfccdddddeca################aaabaaaabaaaaaaaaa#aaaabaa########aaaabaabcgcaaaadda#aa#######aacdde#######aegbbdbaa#adbbaabcaa#aa#########acfeeecaaaaaaaabbaaaba###########aaaaaaaaabddfbaaababaaaaaaa##aba#acefgca###aa#####abb######aaaaaaabcfa##a###aaaabdaaaabbbbdb###aa#aaaaaaaaaabcbbbbbbabaabbbbbbaa#",
+"####aaaa#a#####aaabccccbaabcbcca##aaababbabbabaaaaaabcccbacddefffdccabccdedaaaabdeeffgggeccddccdcdca#a##############aaacaaaabaabaaaaaaaaaaaaaaaa###aa###aaaaacdgcaaabaaa#######a##abdchaa######.cfcbcb#a.bffcbbbab###aaaa###a###ceedddabcbaaaabbabbaaaa##..#####aa##aaaa#acecbbcbaaaaabaaaa##aba#aecbccdcabaaa##abbaa#a##aaaa##aaaabdd##aa##aaa#aaababbbbbdb#a##aabaaaaaaaaaaaaabbbbbbcbbbbcbbaa",
+"aaabaaaa####aaaacccbbcbbbaaaabdaaaaabcaabcbbbbbaa##abcddcbcdefedffedbdccdeec#aafffdddeffcccbcdcccccccaa#############aaaab##aacaaaaaaaaaaaaaaaaaaa###aba#aaababdefaaaaaaa##a###aaaaabccgcaa#######bgcdeca##bhgbabaac##a#aaa##a###befddfdddbddbaacabbbbaa####.#######a#aaaaaacbaabbbaa##ababa##aa##acaaaabbcb#aa#a#aaa##aa#####a#a#aaaabeca#aaaaaaaaabaabbbbbdb#aaa#abaaaaaaaaaaaaaaaaaabcbaababaa",
+"aaaaaa#aa#####abbbcbbabcccbbaaabbccccdbabccbbbbbaaabbcddcbceeeddeggddfbcdeec###dffedddeddcccedccccbbcdb#################aa#aaabaaaa#baabaaa#aaa######aaaaaaaabbcdfaaaaaaa#a####a#aaaabge##########bhcbccaabdeeaaaa###a###aaaaaabceedefeeedeeccabbabcbbaaaaa##.#.#######aaaabbb#aaaaaaaaaabaa##a##aaa#acbcabca###aa####aa#########a##aaaedb#abaaaaaaabbabababccb#aaaaba#aaaaaaaaaaaaaaaaabbbbbaaa",
+"aaabaaaaaa###aaabbbbbaaaacbbbbbcccddefdaabbbbccbbbbabbccbcdddddeeeffefcedffedbabeeecddcbcccbdbbbabbbabba#aaaaa##a######aa#a##aaaaa#a##aaaaaaaaa###aa##aa###aaabbdedaaaaab#a####aaaaabbgha#a########becaccdfgddda#aa#aaaabaaa#a#addeecdcdfeeeddcacbbbcbbaaaaaa###########aabacbaaaaabaaba#baba#aa##bbbdbacaabcb##aaaaaaaaaa#########a#aaabddbaaaaababbbbbaaabcccbabaaaabaaaaaaaaaabaaabaaaabbbbaa",
+"abbabbaaaaaaaaaaaabbabaaaaabbcbbcdedfggccbaaabbbbccccbccddeddccdddcddecddeffddecddccacbaacbbbbaabaabaaaaaaaaaaaaaba####a###ba#ba#aa#####aa#aaaaa############aabbcdebbbaaaa########ababdhf#a#########afecfffebceaa###aaa#aaaaa##abeeddddeegffdcfdbbabcccbaaaaba###########aaaabaaaabbaaabbbaabbaaaaacdcaacaaaabca##aaa#aa#aa#aa#######aaaaacee#bbaababbbbbbbbbccdcaaaabbaaaabbbaaaaaaaaaabaaaaaab",
+"babbaaabaaa#aaa#aaaaaaaaaaaabbbbcdbadccdbbbaabbbbbcbbccdeeedeabcccccccccdeedfddcccdbcbaaaaaaabbbaaaaaaaaaccaaa#aa##aaaabbaab#a####aa####aa##aaa###############abcdedbcba#####aaaa#aabbdhie.#####a#####fgffececeda###aaa#aaaaaa#cddecddcddefeegefeccbccccbaa##aaa#.#####.##aaaabaa#aaaaa#aab#bcccbbccbbaab#aaaabcbbaa#aaaa#a#a######aaa##aaabdfdbbbbabbbbbbbbbbccccaaaaaaaaaaabbbbbaaaaaaaaaaba#b",
+"bbaaabbaaaaaaaaaaabaabbbaaaabbabcedcbbabccaaaaabbbaabbceffcccbbcbbbbbbbbddcdddbbbabbbbaa####aaabaaaaa##aacfeaa######a##aaabbbaaa##aa#a#####bcca#a##aab##aaa#aaaacccgdbbb#######aaaaabbbdhhb###########aeifddbbceda#aaa##aaabaabefffcdddccdeeeedeffefeddccbaa##aaa###.###..aa##aba##aaa#aaabaaabccddcccaabaababaabcca###aa#aaaaa####aa#####aaacffbbbbbbbbbbbbbbbbcdcaaaabbaaaaaabbaacbaaaaaabbbab",
+"babbbabbaaaaaaaaaaaaabbbaaaaabbbceddcbaaabbbbbaaaaaaabcdffdcabbccbbaaaabbbbbbbbaaaaaabaaa#a##aaaaaaa####aadd######a########abbaaaa##a#####a#aa########aaaaaa#aabbbbdgcaaa###aa##aaaaabadfgb######aa###aadidcdbaceca#aaaaaa#abcdeeeccdeddccddeadeefffffffecbaba#######.###.##aa#abaaaaaaaaabcaaabaabcbd#abaabbbbaaabdba#a#a##a###aaaa#########aacefdbbbbbbbbbbbbcbcccaaaabaaabbaabaaccaaabbaabbaa",
+"baababbbbabaaaa#a##aaabbbaaaaabccehdbaaaaaaabbaaaa##aabdgieccccbcbaaaaabaaaaaaaaaabaaaaaaaaabaaaaa###a###aaa################aaaaaacba######a#a##########aaaa#abbbbbcdhb##a####aaaaaaaacbfe.##aaaaa#####aadhcbbaaefbdb##aaccddfgedbddccccbbcdedceceggfeefefdcbaaaa#####.###.###aaaaaaaaa##aba#aaaaababdb#aa#aaabaa###bcbaa#######aa#############abdffcabbbabbcbbcbcbcdcbbaaabbbbbbbaacabaaaaaaaaa",
+"bbbbabbbbbbbaaaaabdcabdcaaaaaabbcdffcbaabaaabbbaaaaa##bcgjfbbbcdddcbbbbbbbbbaaabaabbbaaaaaaaaaaaba#########a#a###############aaaaaabaa#######a######aa#a##aaaabcbabbcceda#aaaaaaaaaaabbbec.a#aaaaaaa####aadhcabbbeecbaaadefggfeddcddcccccbccdccdddeghggeeeddcbaaaaa############abbaabaa#aaaaaaaaba#ba#aaaa#abaaaaa##aabbb###aa#a#a##a##########abbcffdcabbcbbbcccbbccccbaaaaaabbbbaabbabaaaaabba",
+"bbbbbbbbbbbbbbaaabfdcccbcbaaaaacdceebaa####aaabbbbaa##bdghfcbaaacdddccccccccccbbababbbaaaaaaabbbaa#a##aa#a#b##a#aa###a#######abaa###aaaa##a################aaaaabbbcbbcffaaa#cbaaaaaaaacec.#####aadea##a#aabgdababdfda#adfggeddccccbbbaccbbcbcddddgghigffffbabbaaaa##########ab#aaaaaaaaaaaaa####aaaabaaaaaaaaaa####a##aaca##a######a#########acbbbbcdefdabbaabccbbbbccccbcbaaabbbaaaababaaaabcc",
+"bcbbbbbbbbbcbbbbbcecccbaccedaaabddcaaa#######aabcbbbaabdfhfdcaa###acdcabdfeeedcccccbbcbbaaaaaaacbaa###aaaa#aaa#####a#aa##aa###ba###aaaaaaaba############aa#aaaaaaaaaabbbfgaa#adbaaa#aaaaehaa###aa#adea#a#aaabgbabacefdb#dfffedccbbaaaaaaccbbcdecdggihihhfdffcbbaaaa###aa###..#aa####baaabaaaaaa#####aaaaaaaa#aba#a###abaa#cbaa##.##aa####aa##aa#baaaacccefdbbabbcccbbbdccdbaabbbbbbbaaabbaaaaabc",
+"cabaabbbbbbcbcccccddb##abaccbabbdbcaa#a##a####aabdcdbbcdddghcbaaa####bcacigggecbbbcbcbbabcaaaaaabaaa#a##abb#########a##aaaaaaaaaa###aaaaaaa########aa##aaaa#####aaaaa#acegfaaa#aac##aaaachfc###aa###aabb###a#bbabccddefdceffedbcaaaaa#aaabbbbcdegihhhhgggdcffecabaaaa##a##.###abca#aaa##aaaaaaaa######a###b###baa####aaaaaaaaabca###############aaaabbbbbbdfebbabcccbcdcbbdcbbaababbabaabaaaabbb",
+"febaaaabbbbcdcccccb#####abbabbcccbbaaa####aa#a#abdeccbddeeehgcaa#a#aa#addhifdddbbccbcccbbbbaaaaaababaaa#aaba####a##a#a##aaaa#aaaaa#a##baaaaaaa#####b###aaaaaa##a##aaaabcefihefc##aaaaaabbdha####aaaa#ab######aaaabbccdefegffdcccaa#a##aaaaaabbehhhhffffcddbdcdbbba#ac######..###bb###a#abaaaaaabba#####aaa######a#aa#####a#####bbca###########a##aaabbbaaaabdfdbaccbccbcbbccdcbbbbaaaabaaaaaaabb",
+"dedbbbbbbccbcdccddb#####bbbaacccacbaaaa###aaaaaaacfdcbcdegghigbaa#aaaaaadfhgedcccccbbbbbbbbbbbbbbbbaaaaaabbba########aa#aaaa#abaaa####aaaaaa############aaaaaaa###aaaabcfghgihfbcb#abaaabbge####aaaaab######a#aaaaaaccdeeddfdbcbaaa##a##aabaafhgggfedccccdccbaaabaaaaaa#########a#####a##aabaabcaa#aaa#a#####.####a###########a#aaaba##a####a#aba#aaaabbaaaaabdeecccbbcbbccccdcbabaaabbbaaaabbba",
+"bccdcbbbcccccbcdfda#####acbabcbaabaaa#a###aa#aabbbefedcdffiihhcaaaaaaaabacfffefedcbbbbbaaaabbbbbbbbcaaaaaabaaa####a###a##aaaaaaaaba#####aabaa###########a#a####a###baabccghfhiieaa##aaaaabdga##a#a#aaaa######aabbaaabbbcddegdcbbaa##aaaaaaabbfedfddecbbbbbbaabbabbaaaaaaaaaa####aa####a#a#aaaabcbaaaaaaaa##############.######a#a#aabbba#a####a#aaaabaaabaaabbabcfedcbbbcbccccccbabbabaaaaabbccb",
+"bbccccbbcccccdddeca####aabbccca##aaaa##a#####abbbbeeffeeccfjjifbaabaaabbbcdecdeffdbcbbbaabbbccccbbdcbaaaaa###########a#a#aaaaaba#a######aaabcaaabaa###aa#aaa######acedbcdfihfhifba####aaaadhc###aaa###########a#bbaaabbccccfecaaacca##aaaaaccffdfccedbbab#a#aaaabbaaabababaa###########aaa###bbaa#aaa#abaa##########.########aa####a#aabba#a###a###aaaaabaabaaabbbcdfedbcccbcccccabbbbbbabbbbbbc",
+"bcdcbbcccccddddddba####abbbbdca#a###a###aa####aaabcededcbbgiijjhcabbaaaaaccddddcceedddddddeeefedbbcbcccbbbbaaa#a###aaaaa###aaaacaaa##a###a##acca############acaaaaa#abbccdghccggfcaba#aaaacggdaaa###############abbbaabbdeefedbaaaadda##aabbchedeefedbaaab#####aabbaabacbabaaaa########aa#a###aa####aaabba##a##.#############a#a####aaa##abdba#########aabbaabbabbaabdeddcbbbcccccbbbbaabbbccbba",
+"bbddccbccdccdcebcbb#####abccbcd######aa##a######abcddcdddeggiihhhdaaaabcccceedccbbcbbccbccdeeeggfeddccdeccbbaaaaaaa#a##aaa###aaaba#a##aa######a#####a######aaaaaaabaaababcehb#adcbdbba#aaabdceaa#################abbbbbacgeeecca###bedcaa#adfhccdffbbbba###a####aaaaabbbbaaaba###aaaa##########aa#.##aaaaa#aa#b######a#######aaaa##aaaa###abcdb######a#aabcbaabaabbaaabcdedbbbcddcbbbbcabbbccbbb",
+"bcdfdddcccdddcecbb####a#aabccabaa#####aaaaa#####abbccdedeedcijfggfabaabbbbccddccbbbabaaaaaaaaabbbgihihffedccbbbbbbbba#a#aa####aaaaaaa##aa#######a###aaaa########abaabbbbaccega#cdaaabaaaaabbfea#a#################abbbbbaeedddcbaaabacceccefihdccedcbaa##########aaaaaaabbbaaaa#####aaa##a############aa####aaaa######a#####aa##a##aaa###aaa#a#abc#aa###aabcaaaabbbbbbbbbbcddcbccddcbbbbabcccdcc",
+"ccbcffhfdddddccadbaa#####aabbaaba##########a##aaabbaacdddfeehjifgha#aabcbacddccbbbbbabbaaa#aabcccefgdddeffeecdedbbbbcba###aa####a##aaaaa##a###aa###aba#aa######a#aaabbba#abbfcbcccccbaaa#abbfjg#aa###########aaabbaaabbcbdedcdbbaaabbbcceghhiiedcedbbaa######a###aaaa#abaaaaaaaa##aaa##a##############aa####aaaaa#####ab#####aa##a###aa#aa#a#####aaaa##aaaaabbbbabbbbbbbbbbbbdddccddccbcbbbcccdd",
+"eecbdggfdddedcacda####a###abbaaca######aa##aaa#aabcababcdeeedgigdfgbbcbbbbbcccbbbbbaaaaaaaaaccddddefdecccbbcbbddcbccddedcaaa#a#aa##########a########adbaa#########aabbbcbcabbdcdcbbbcbaa##abbfiaaa##############baaabbbbccedcccbaa#abbbbbefgihfdcccbaaaa###a######aaba#abaaaaaabaa#aaaaaa######...#a#.#####aa#aaaa########a##aaa###a###aa#aa#aaaa#aabbabaaaaabcbbbbbbbbbbbbbbbccdeddcccbdccccdde",
+"eedfhhfcba#abb##a#####a#aabcaaccbc#####a#aa#aa###ccbbbabcdfffhgifehfebbbabbcccbbbbbbbbaaaa#ccdcddfghfeccccbbbbabcddegcbccdcaaaaaa###a###a######a#a##accba#########aaaabbccbbcbcehb###cbba##bdehe###############aa##aabbbccdcbccba##aacccbcceffedcbbaaa#####a######aaba##aaaa#ababcbbbbcbaa########.#.##a####a####aa######aaa###aa####a###a##a#aaa####aaadbbaaacccbbbbbbccbcbcccbcceeeeededcdbccd",
+"dgghigdb##a#a########baaa#abbcbdbbb#####aa#aaaaaaabaababcdegiihdggffdcbaabbbbabbbbbabaaaaa#ccdccdegedccbbbbbbcbbbbaadbabaacdb###aa###############aaaab#aa##a#######aaaaababbbabbfieaaaa#aaa#chke.#########..#aaaaaaaaababbccbbcbaa#aabbcbabcdeedcba###a#####a#a##.###baabbaaaaaaaabbaaba#########....#.#######ab#a#######a######a#########a##aabba###aaabbbbbbacdcbbbbcbcccccbdddeededegeddddcdc",
+"dhghhfa##a######a######aabaacccedaaa#######aaaaaaaababbbccdghgfedgfgcabaaaaaaabababaabaaaaabdcceeeecdbbbababbbbccbbbbbabdbabcba#a############aa##aaaaab#aa###########aababcbbaabeggh######aaagj##############aa#####abbaabbbbbabbbabcabbaaaabcddccba#######.###########ccaaa###aa##aaaa###a###..##....#.aa##a############aaa#####a#####a###aaa#aaaa#aaacaabbbbbbeccccbbccddccdegghhgfeegd#bddccc",
+"ffhhhe###########a#####b#bcadddcbaaaa#####abcca#aaaaaaaaabdhihgddfgfgcaaaaaaabbbabbbaabaaaabedcefecbbbbbbabbbaaabbacdca#aaa#bbdb#aaa#########aa####aa#a###a#####.###aaaaadbbaabaddcggbaaaa#bbdia#a##########aaa###aaabaaaabbbbbbaacefebaa#aaaabcccbaaaa###########.#.##ad#####.##aaa#aa#aa#####...#...###ab#ba######a###a##ab#####a###aaa##aa#aaaaaaaabbbbbbbbbbceddeeccbccccddfhijjhggghb#bba##",
+"#afhgcaa###########a#a##aabcddca###aa######abbbabaaaaabaaaeiiihgbbgeddaaaaaaaaabbaabbbaaaaabdcccddddccabbbbacaaaaabbbaaabaa##acdd###a######..a#a#####a#aa##a########a##aaecb#abbbcccfgaaaaaaaeia#a#a##############aabbaaaababbababdgeca####aaaaabcbbba#####a####.#######da##############aaaa#######.##.#.#ba########.#a#aa##abba##aa#aa#aa###aaaaaaaaaabbbbbcbccccefgeeccbccbbbbdfiihgggeb#aaaa#",
+"##bhgd###############ab#ababcdd###aaaa####aaaaaaaaababaaaadhhigebabfddcaaaaaaaaaaaabaaaaaaabcbbbcbbcecbbbabbbaaaabbaaaaaba###abadea#########.#a##########aa#a###a###a####aabbabbaadccghbbbaaabfi#a##a###aa####a##a#aaabaaaaaaaabbacfdba##a#aaa#aaaabbb######a######.##a#######aa#a##a#a####aa#####a#.#a####aa#########aaaaa##aaa###aa#aaaaa#aaaaabaaaabcbbbbccccceeceeeefedddcbbceeffhgfebaa####",
+"##.dhdb#########ab###bdababaddc######a###.#a######aabacaaaadghfdbbabecdba###aaa#aaaaccabaaacababbbbbbbcbcbbcbaaaaababaaaba####abbcfbaa#aaa###.###ab#####aaaa##a######aa#ba#aabbbabdcabefbcaababhe#a##aa##aa###a#####aabba#aaaaabbbefcba###aaaa#aaaaaaaa#########a#.##############aa#bb#aaa##a####.###########aaaaa#######aaaa###a####a##aabaabaaaaaaaaaabbbcccddebbbbdedefdcccccbceeghgfdaaba#aa",
+"aa#aeea##########c####ba###aca#####aba#############abcabaa#acdefccbacdbdc##aaaaa###aabdbaaabbcccbbbbbbbccbabcabaabbabbaaaaa###addbcdba#a################a####aaaa#aaaaaaaa#aaacbabdcbbbehca#abbeh#aa######aa######aa#aacfbaaaaaabbdgdbaa###aaaa#aaaa########.###aa#a.###########aaa#bbaaaaaa####a#.##.#######aba#####a#############a#aaaaabbba#bbbbaaaaabbcddddddbaabcedccbaadfdcceeggdbaaaaaaa#",
+"aa##ada#a########aaaa###a###a######abaa#########aa#abbbaaaabbcddeeebcdbabb#aaaaaa####aaaabcccbccbaabbbabccbaaaaaaaabbaaaaaaa##aabcccfeb##############a####ab#aaa##aaabbaacababaaaabcdbccffc##abeh.##aa###a#########aaaaacbabaaaccddfgdbaaa##aaaaaaa#######.##.#######.#########aaabaab########a#a##.#########aaa#####aa##a#aa###bdaaba#aa#aabaaaabbbabbbbcddefecbcbaabbdcbaabcecccefgcaaaaaaaaa#",
+"aaa#aaaa#aaaaa#####aaaaaa###########a#####a##ab#a##aacabaaabcccbdhedfdbbabc#aaaaaaaba##aaaeheaaaaaaabbbacddbbaaabbbaaaaaaabc#aa#a###cfgb#a#########aa###aaaccaaaaaaaacbabcdaacbaaabcddcccgfcaabeg.#a#aa#a###aaaa####aaaaabaaaaaaceefhfdbaa###aaaaaa########.####.###.####.####aa#abcbaaa####aaa#############aaaaaaaa#aaaa#ba#babffb#acb#aaaabaaabbccabbcccfgdaa##bcbbaaacbcbacebbbcddbbaaa#a####",
+"accccedaa#aa#aaa##a#aabda#################a#a#a##aaaabbbabbcccdcccfcfecbaaceca#aacdbcccba#ahgabaaaaababbbccccbaabbbbbbbaaabcb###aca#aabcc##a##########a###a#abaaa#aaabbddddbbbcbaaaaabcdddhecccg######ba#a##.#a###aaceca#cbaaaaacdefhgfcaaa#aaaabba#########..#####...#.#######aaabccbaaa####aa########.####abb##aa#aaa#a#ba#abbefba##bbbaaaaaabbccc#ccddeffcaaaa#baaaaabebbbbcbbbbcbbbbbaa##a##",
+"#abeeebaaa###aa###aa###aaa###################aa###a#aabbbbcddddccefegfcca#adhbaacccaaabcbcdecaaa##aaacabdabdcbaabbabbaaababbcb#aabb#aa##dea##aa#######aaa##a##aabaaaacacdfebbbbbbabccccfeddfgfed...#a##aa###########acdbabbb#aa#acddegfecbaaaaaaabaa#########...#####.#########a#abbbabba##aa#####.##....#####a##aaaaaaaa#baaaceeebaaaaeedbbbabbbccb#cedddcccbaaaaaaabaa#bebbbbbbbbbbbbbaaaa####",
+"##aadba#aa##a#######abbda################a#######aaaa#ababccdeeddffhhgccbaabefdbbaaa#aabcbbabca#aaaababbbbcccbaaacaabaaabaaaabbaaaab#aaaaefaaaaaaa#.###a#a#a######bbbaabccabbdcbabbcbcdbbaaaefeiiffa####a#######a##aaaaabbcba#baabdddefffdcaaaaaaaaaa##########...##############aabbbbbdabaaa###.....########aaaaaaaaaaaaabcccbdfebaaaaaacfdccbcddc##baabcbabaaaaaaaaabaaaedbcbcccccbbccbaaaaaaa",
+"a##aba#a####.######a##bgb#######a########aa#######aaa##aabbcceedddeghiebaaabccebaaaaaaaabaabaaabbaaabbaaabbbbbaaabbaaaaaaaaabbccbbcba#####cfebbabbbacaaaaaa#aaaa###acbbbbbbbbcbaabbbccbaaab#.aceffdfghfa#a####aa#aa##acbacbbbaaaaabcedcddedbaaabaaaaaa#######..#.################aabccccdbbb####.#..#..#.#..########aa#aaa#aaabdddbcababbbdeddedeeb####aaaaaa#ba#aababcbbbaeccbcbcbcbbbbaaaa###a",
+"ba#a#####a#############cb#########aa##a###a####ab#aabaaaabbbbedcdccehihcbbbbbbccaaa#a#aaaaabbaaaabbbcbbaaabbbccaaabbaaaaaaaaaabbbbacda####aaedbaaabddba#aaab###aa####aaddcceebabbbcbcdca#aaba#aaabaabfmka##aabaaaaaa#abbabbbbaaa#acccdddccedbbbbaaaaaaaa##a####.#.###############aabddcbbcaaa####.#......aa###aa####aaaa#aa##aacccccbbbabbcdedddea####a##aa#a#bccbccbcbbaaaadddccbbbbbbaa#aa####",
+"ab##aaaa######a##########aa###b##aaaaa##a#a#####ababbbaababbbccccdcdgjifbbabbcccca#aaaaaaaaacaaaaabcccbaaa#bbbcaaaaaaaaaaaaaaaaccbaabbaa#a#a#bcbbaa##a###aaba######aaaaaaddfhgccddddacacaaaaa#aaaaaaabhnk.aabbb##aa####aa#acaabb#aabccddeecccbbbabaa##aa###aa#######.######a###aaaabdddcdedda#########...#####aaaaaaaaa##a###aabcbbccbbbbcddeeefc##a####aaaaaacdccbbaababaaabccdccccbbbbaa#a####",
+"#####a#aaaaa###aaa######ba###aa#bba#aa#abca##bb#abaabbbbbbaabbbbdccceihgecbcdccbcd#ababa##aaabaaaaaabccbaabbddbbaa#aaaaaaaaaaaaaccbaaa#a######aabdcb##aaa##a#a#####aaaa##aabffebccddcb#aa#######aaaaaadlnd#aabbabaaaaa##aaaa####aaaabccdeedbb#aa##a###############.##..#.#####aaaaabccdeecdaa#####.########.###aaa#aa###aaaa#aaabcbccccbbccddeef##aaaaa####aaaccbaabaaaaaaaaba#bcddcbbbbbb#aaa#a",
+"abaa###aaaaa##a#a##a#############a#a#ababda#aaaaaaaabbaabbbbcbbbddbddgifhedbcccbbcc##aabbaa#aaaaaaabaabbbccccdebaa##aa#aaaaaaaaaabedaaaa##########becaaaaa#a#########aaa##abceffdccb##aa########a#abbabilk#a#a######ab#aa#aa#####aaabbcddedbaa#a######a#####################a#aaaaaabdddfgfc##########...a#a###aaa#a#aa##a###aaaabbbbbcbbbcceghfaaaaaaaabbabccbbbaaaaaaaa#abba#aacedcccbaaaaa#aa",
+"bbaa##aa#aaaa#aaaaaaaaa#aaa##########abaaaa#baaaaabbbbbabbbbccccddbddggghhfdbbcaabbbbbaabbaaaa#aaabbaaabbb#bbbaaa#####a#aaaaaaaaaabb##aa##########aabdcbabaaaa####aa###aa#abbcdhhcaba#baaa#######aaaaabhlmc#a#####aaaaa#a##abba#aabaaabcdgfbb################################aabbaabbccdhigca#########.########aaa########aa#a##aaabbbbccbccdgfha#caaa.##fedbbcbaaaaaaaaa#aaa###aaadecccbbaaaaaa",
+"#aa###aaa#a#aaabbbbbcbaa##a#######aaabaababaa#aaaaabbbbbaaababccdecdfhhiihgfdbccbbcbabaaaaaadca##abbaaaaaaa#bb##aaa####aa#aaa#aaaabbda.##########aaaabddcbbaa#a##aa#aaa##aaabbdecca#a#aa#a########aaaaaeili##a######abaa###aaaaaacfeaabddcdbaa##############################aaabbbbbbcdfgjieba####.#####aa#aa############aaaaa###aaabcbbcbbcefggcbbfeedbedbcbabbaaaaaaaaaaaaaaa#aaa#cdcddcbbaaaa",
+"aa#a###aa#a##a#aaaabbccaa#aaa########bacbaaaaaaaaaaaabcbbbbbbcedcdccfhfhkhggfdbbccbbabaabaabdda###aaa#aaaaaaacb#########aaaaaa#aaaabec##########aaaaaaabddcbaaaaaaaaaaaa##aabacbaaaba#####a##a######aaabgklbaaa#####aaaaaaaaaaabbbfdaacddeddcbaaa#########aaab##########a##aaaabbcbbbbeffhjifdcb#####.##acbb#aaaa###########aaaa#aaacbcbbcbcegfaccgghgffdcbbaabbbaaa#aaaaaaaaaba#aaaabeecccbaaaa",
+"aaaa########aaaabbabbbbcbbbaaaa#####.##aaaaaaaaaaaaabbbbaaaaadedcdccegijkifddebccbbccaabaaa##aa######aaaaaaba#aa#########aaaaaaaaa#bccda#######aaaaabbaaabddcba#aaaaaaaaaaaaabcdaaaaa##abaaa#a#a#a##aaaafhlg.aa#a#a###ba##b#acaabcdfaaaccdccedba##########adcbca#########a#aaabbcddccbdefggiigecb########aaaa#abba###########aaaaaa#bdbccbccef#abdeddeeddccba#bbbbbaaaaaaaaaaabcaaaaaa#eedccbbba",
+"aa#aaaaa###aaaaaaaaabbbbbbbbaaaa#######aabaaaaaaaaaabbaaaaabbbfeccccdfiljigcdeccccbccbccbbaaaa#######a#aa##aaa#####..#..#aaabaaaaaaabacb######aaaaaaabbaaaacddcbaaa##cbabaaaaabcbaaaaa###a##a####a##aababchl#.###a#####aaaaaa#aabbdeaaacbbbbdfdccbabb####a#ddbbbba##########abbbccdcccddefghhfcaaa######aab#abaaddaa########ab###aaaacccccdefd#dbgebcccdcaabbbaaaaaaababbbaaabacaaaaaba#eeddcbba",
+"aa#aaaaba#a#a##aaababbccbabbbbba########aa#a#aaaaaaaababbaaaaadcccaddfhkjigdcdecccbbcdcecbaaaa######aca####aa#####a#####.#aaaaa#aabababb######aaaaaabbabaaaaabcdcbaaaaaaaaaabbbcaaaa#a####aa####a#aaaaaababjh.####a#####aaa##aaaabdabaaaabbabdeeeddddcb#.##debaaabaaaba####aaabbccdcccddeffgfgcaa##aa###aaaaaccaddca########a#a###aaaccbbceffbaacgeaabbbbabaaaaaaaaaaabaaaabbcaaabaaaabbbccdedcb",
+"ba#a#aaaaa####aaaaaaaaaaccbcbbaa#######aaaa###aa##aaaaaaaabbbabbcbbefffhjihfcbfcbcbbbcfhgcaaa#####a#deaa##aaaa###############a##a###aaaaa###aaaabbaaaababbbbbbbbedcbaa#abbbbbcccaa##a######aa##aaa##abaa#aabja##.#######a#a###aaabecaaaaaaacccbcaaaabbdddefedcbaa###aaaa#aaaabbbcccccccddfggghdba####aababababcbbddba###a###a#aaa##aabbcccegfbaabcaaaaaaabbaaaaabbaabaacaabbbabbadbaaaaabba#aefc",
+"ba#a#aa#######aaaaaaabaabbebdbbb######aa####a###a####aaaabbaabcabcccddffjhfdbaefcdbbbbdjkjebaa#####bccb##baba#####aa######a###a#a####aaaaa##a##aabaaaaaaabbbbbbabefdbbcbbbcbbbcbaa####aa#######aaaaadaaaaabbdg###a#a####a#aa#aabccccaaaaaabcdbccaaaaabbdeeedcdcba###aa#aabaaabbbcbcccddddeffffdbaa####abccbb#bbccdbccaa###a#aaaa#a#aabbdcdfgdaaaccaaaaaa#aaaaababbaaabbbbbabbbbbcbcbaaaabaa###be",
+"fcb#############aa#aaaaaaadegdacbaa###aa####aaa#a####aaaabbaaabaabddccehieabaabecccbbbbbikkgca####acbb###baba#####aa####aaaaaaaa######aa###aaaaaaabaaaaaaaacbbbbbbeffedccbcddddbaaa##aaaa###a##aaa#adba#aaabbie.#.#aa##aaaaaaacecaaaba###a##aabdb#a#aaccccccccbbba###aaa###aaabbbbcccdddedegcddcbbaaaabbabbabbaabbaaddbaa#####aa##aaabbddefgcabagbaaaaaaaaaaaabbaaacabaaaaabbbbabbaaaaaaaaaaaa#a",
+"bdeba#########aaaaa###aaaaacfebbbbaa###aa#####aa########aaababaacbdeccehhbaaaaaddcbbbbbcgijhea####acb########a##aa#a##a#aaaaabaaaa####aaab###aaaaaaaaaababbccbbbbacbedffedcdeeaaaab#aaa#aa##a##aa#a###aa#aabackc.#.##aaaaaabdefb#a#aaaaa#a####abc####abcbbeecbbaaabb#aaaaaaaabbbbcbcdededdefdcaccbca##aaaa###aaaaabaaeccaaa###aaa#aaabcccdffbbacfc#a#a#aaaaaaabbaaaaeabcbbabbbbcbbabb#aaaaaaa#aa",
+"##aba######aaaaaaaa##a#aaa#fdaabbccb###################a#aaaabbabccccdehibabbbbcfdcbbbabgihc#a####abbaa##a###aa##a#aaaa##aaa##aaaaba###daaa###abcaaabaaabbbbbccbcbcdcdddggfedbcbaaaaa##a#####aaaa#aa#####abbbbdjb.a##aaaaabeecabba##aabda######aa####aaabbdcdcbaa#bcbbaaaaaaaabbbcccddedefffdcbccbab####a#####a#aaabaabeeba######aaacbcddegebbacccba##a#aaaaaaaaaaaaccbbbbbabaaa#aaabbaaaaaaaaaa",
+"aa##baa####aaabaaaaa#####aacaababbccbaa##################aaaaaaaabbccbegifaaaabbcecbbbbaadgb#####aeeabc#.######aa##aaaaa#aaaaa###abaa##edaaaa##aabbaaaabbbbbbbccbbdccccdddehhdabbaaaaaa##a###aaaabb######cebcbcgj#aa##abdfggcbbbaaaabdfea####aaaaa##aa###aaa#aaaa#aaabbaaaaaaaabbccddeeddeffeeeefcabaa#aa#####aa#aabbbacccbaaaaaaaabcccdegfbbbceaacb#####aaaaaaaaaaaacccabaaaaa#a#abbccaabbaaaa#",
+"#aaa#daaaaaaaabbbaaaa####abbaabaabcbbbbb##aa################aaaaabbbddehecacbaaaabecbbbbabaa#####adcca#########a#a##daaaaacaaaaaa###aa#aca#aa##aaaabbbaabccbbbbcddaccdeddecfhgcabaaa#ab#a####a####aaa#aaaabbbcbcijdchihgighedbcbbcdfdabbbbccaaaaaa###caa#aaaa#a#a##aaaaaaaaaaaaabcccdddddeeedeeeffbaaaaaa##aa###aaabbbabcdeabaaaabbbbcdegibabbfaabca####a#acca#aaaaaaababbbaaaa##aaababbaaabaaaa",
+"#####adcbbbaabbbaaaa#a#a#####aaaabbaaabcbaa#################aa#aaaaabddgeadbcaaaaabccbbbbba#####a#a##aaaaa###aa#aa#bccaabaac#aaa#####a#..#####aaaaaabcbaaabbbbcdccdcddedceefgfccbaaaaaa#aa###aa##accaaaaaaaabbbbdjkfdfgjjhgfeeeeeedcaabaabaaaaa#####ab#a#aaaa###a####aaaaaaaaaaabbccddccccdccdeeegfbcbcaaa#aaba#aaabdcbbbababbbaabbcccdghg#aadbaabbaa###a##acdaaa#a#aa#baaaaaaaaa#a#aaaccbaabaaa",
+"a##a#aaedbbcbabaaaa##a##aa####aaaababbaabacaaa###a#######a####aaaaaaaccehbbbbcbaaaaacdbbbcb#a#a#a#.####aaa##a#aaaaaaabaaaaab##aaaaaaaa#####aaa##aa##abbaaabbbccbccbcdcdcddeffcaabaaaabba#aa####a##bcbaaaabababbbbejib#abccdcbbccba##a##aaaa##a######a##aaaaa#a###a#####aaaaaaaaabbccccccccccccdeegfcdabbaaaaaaa#aaaabccbbbaccbabbbcddefedea#cd##a#aaab#aaa##bcb###aaa##abaaaa#####aaaaabbcbaabbb",
+"aa##aa#bhgccbbccbbaaaaa########aaaaabcbaaaabbaaaa###aa#####a#a#aaaabbbbcega##acbabababecccdabaa##########aaaaaaaaaaaaaabaaa####aaaaaaaa##.##abaaa#aaaaabbbbbbbbcdbbccddcdcegeaaaab#aaaaaaaaa####aabbabbcbbbcaaabbcegiaaaaaa##abbcbca##.###aaaaa####aaa##abbaa#aaaaa####aaaabbaaabbbbccccbcccdddedfddcaaaaaaaaaaaaabbccdbbbcecbbccdefged#a###fa######aaaaaaaabaa#######aab#aaaa#aa#aaaaaabcccabaa",
+"aa##aadafhhfeccbbbaa#aaa##a####a#aaaaaaaaaaaaaaaaabaaaabaa#aa###aaaaaabbcfd#a#acbaaaaabeecdcc#############abbaaaaaaaababbba###aaaaaaa#a#####aa#aaaaaa#aaaabbbabcccehgeecdegebaaaaaaaaa#aaa#aa###aaaaababccbbaa#aabceggaaaaaa#aaaabcb####a###aaba######a#a#####aaaaba#####aabbaaaabcbbbbcbbacceeddeebabdbabbaaaaaababcdccdccdcbbccefecb#####cc#########aaaaaaaaaa##ba#aaaaabbbbaaa#aaaaaabcccdgdb",
+"##aaacdggggghgdbbbbbaaaaa#aa###a###aa##aaaaaaaaaaaaabcbbaaaaaa#aaaaaaabbbdfd#aaacdaaaaaadgefc#######a#a###abb##a#aaabaaaaaa#######aaa#a########aaaaa##aabbbbbbbbccefhfeeegfbbba#aaaaaaaaaaaa####aa##abbcdacbaa##aabcehfaaaa###aaababa##.##a#aaaca#a#aaaaaa#aaaa#aabcc#####aaaabbbbbadcabbbbbbceedefcaabcecaaabaaababccdcdddccbbcceda#####baeaa#aaa#####ab##aaaaa##aaa##abbbbbbbbaaaaaaaaabbbagig",
+"f#aaaehhfffeffhfbccbbaaaaaaa####a#aaaaa###aaa#a#abaabccabcbabbbbabbaabbbbcehdaaaaaaaaaab#dgeaa##a###########aa####aaaaaaa######a####aaaa###a###aaaaa###aabbbbbacccdedddfgebcbaaaaabbbaabaaba#########abcbdabaaa#aabcdeibaaa######aaaca######aabbb####aaaaaaaaaaa##bbdb####aabbbbaaaacdcaabbbbcceddeccccaba#aaabaaaabccddddddceddeec#aca#aabebaaa#######aaaba#######aaaaabbbabbbbbaaaaaaaaaba#dii",
+"hd#aaejiedefeeddedccbaaaaaa########aaa#######a#a#aaaabbaacbbababccbbabbbbbceidbaaaaaaaacbcgeca#############aaaaaaaaaaaba######.a############a##aaaaaaaaaaaacbbbccccedbcfcbbbbaaabbbbaaaaaaababaaa#baaaabababbabaaaaabdfhaaaaa#aa##b#bbaa#####abb##a##aaaabbba#aaaaaacda#####abbbbaa####a#abaabccbdecdbbaaaaaaaaaaaabccceeedcdfgffeba#aa#aa#bcaaa##########aa##a####aaaaa#aaabbbbaaaaabbbcbbbeefh",
+"ggecdhjkiefeeddcdefdababaaa########aa##a########abaabaabcdabbcdccbcbabbbbccchiecaa#abbbaaaadeca#####a#######aabaaaaaabba###a##.#############a##aaaaaaaaaaabbbccdddbbeccdbbcbbbabbbbbbcbbaaaabccaaaabaabcabbabaaaabaabcefeabaaaaa####aaccb####aaa###a###aabbab#a#aaa##aaa#####acbba#a######aaaabbbbfefdaaaacaaaaaaaabbbcefffeefbed########a##dbaaa#######a#############a########aaaaaaaaaccfgfhdf",
+"efddegijmkfeeeddccdgdbcccbaaa####a#aaa#####a####a###aabbcbabacccdccbbbbbcbbdfijhbaaaaabb###cedbaa###aaa#####aabbccbaaaaa###accb###a##########aaaaaaaaaaaabcbbccddddcddaaaabbbabbbbbbcbaabbbbbaaaabbaaaaabbbbaaa#ccaabbddheabaaaaa####abca#####ba##a####abcaaaaaaaaaa#aaaa#####bbaaa##aaaa##aaabbaaadfdbaabcbaaaaaaabbacehhhhcaaaa#####a#ab##ccaa########aa#############ba#a#aaaa#aaabdaaeffghgff",
+"eddcbcdefijgeedcccbbdeccccbaaaaaaaaaa#a#########aaa##a#abcaacccccccbcbbccccdefikibaaaaaaaabbdddca#a#a#aa####aaabbbaaaa##a##aaaba##aa##a######aaaaaaaaaaabbbbbccccddddaabbaabcdbbbccbacbabcbbccbaa#aaaa###baaaaa#a#aaabcdfjb#aaaaaa####abaa.####a##aa####bcbbaaaaaaaa#####aa##abaaa#a##aaaaaaaaaaaaabecbaababaaaaabbbcbcehhcaaa##aaa#######b#.cbabaa#####aa##a#####a#########aa#a#aaabdefffggfefe",
+"ddcaaabdefhihecdbbbbacdecccbbaaaaaaaa############aa##aa#ababbcbcbbbababccdceeegijgaaaaaba###bfcdc##aaaaa######aaaaaaaaa#aaaaaacba#aaa#a#ba#aa#aaaaaaaababcbbbbbcedabbaabbaaabbbabbdccbbbaabbbbbaaa#aaaaa##aaaaaa#####abcehka##aaa#####aaaa###..a#aba#####abcaaaaaaa#a##a##a###ba########aaaa####aa#deaaa#aaaaaaabbbbbccefcbaba##abaaaa.#a#ba##dc#a#a####abaabb#a##aa##a###a###aaaaabaceecddhhedd",
+"cccbabbcdfffhheccbbbbbcdfccbbbbaaaaaa###############a##aaaabacbbbbaaaacccddcdefhjjhbaaaabaa##dfbbc###aa#aa######aabaabaabbbbbabdb#aa#a###bba#a##aaaabbabbbbbcbbcedbaaaaaaaaabbbbbcbccbcebbbbaaaaaaaaaa#####aaa####aa#aabdegj.############a##a##a#aba####a##baaaaaa#a###aa#aa########a##a#aaaa####a#eeaa###aaaaaaaaabbcdgfdbaa####aabbcb#aabc###cda#aa##aababcbb#a#aa###a##aab#aaaaababdecbcdheed",
+"cbbaccbcddeffeedcbbbbbbccffdbbcbabbaaa#aa########a###ca#abaabbbabaaaaabcccddcdgiikjgbaaaaba##afcacba###aa########abbbbaabbbbbbbcbbbb#aa#a###aa##aaaaababbbbcbccdca#a##aaaaabaaabcccbbcbcbaabba##aaaaaba#####aa####aabbbddcdjd.#########.#..#######aba######aaaaaba########aa#######aaa#aba#aaa###aacaaaa##aabaaaaaaabbcefcbbaaaaa##aaacabaaaa###bca#####aaaaacaa#a###a##a#aaa#a#aabbbbcddcccegdd",
+"cbbabbbbccddeedddcbbbbbbbbdfheccccbaaaa###########aa#bd##baaaabaaaaaababcddcccggijjjbaaabbaa##bcbabba##aa#######aaaaaaabbbbbbbbbcccaaaa##a##aaa##aaaabbbdbcbbcdfbaaa#aaabbbbbbbbbcccbccdedaaa#aaaabbaaaa#a#aa####a#abcccdccfi###########....#######aa##aaaaaaaaaaa##########a###a##aa#aa#aaa#####aaa#aaaa##abbbaaaaabcdefbbaaaaabaa####aa####a#a#dba#####bb##b###########aaaaa#aaabbaabbbccddede",
+"baabbbbbccccdeedcccbbccbcbbcdiheccbbbaaaaa#aab##aa###aa###aaaacbaaaaaababccccdfhjjjl#abbbaaba#abeaabb######a#####bbaa#aaaabbbcbbabbaa###aa####a###aaaabacdcccdceaaaaaaaaaababbbbbbbcbbbcbdba###aabbbaaa#aa##########aabbabccgb.###.#########.########a#aaaa#abaa#########a##aa#####bcaabaaba###aaaaaaaa#####aaaaaabbbdhidabaaaaaaaa###########a###ebbb###aaa####a###aa#aabcaabbaaababaaabbbbbdcb",
+"abcbbbbbbbccbbcddbcbbbbbbbbbcfeghfccbbabaaaaabaaaa####a#b##aaaabbaa#aaaaabccbceefhegdedaaaaaaa#abdaaba#aa##a#####aaaabaaaaaaabbbaacc###aa#aa####a#aaaaaaabcccddfbba#aaaaaabbbbabbccccccbcbdaa#####ac#####a##########aa#aabcbdh..#########.#####.####aaa#aaa###abb###########accaa###a##aaabbbba#a##a#abba####aaaaaccegcbbaaaaaaa#aa###.##a########aeaaaa###a#a######aaa##aaaaaaaabbaabbaacaacced",
+"cadbbbbbbcbccbbacbbbbbbbbabccdeehgffccbcbaaabaaaaaa###a####aaa#aaaaaaaaaaabccbdeeffeehgcaabaaa##adb#aca##aaa#####aaabaaaaaaaaaabaacdb##aaaaaaa#abbaaabbbabbdecffbaaaaaaaaaaaaaabbaccbcbcccdcaa#############aabb######aaaaabbbehd..###d#.#.######.####adbaaaa##abba########aaaaaaaaaaaaa#aaaaaaa#a#aa#abaaa####aaacdeheaaaaaaaaa##aa#aa#####a####a#.cdaa######a##a###########aa##aabb#aabaaabbadf",
+"cabdabbbabcccdccbccbbbbbbaabdcdefdcfgccbbbbaabcbaaa###aa##aca####aaa##aabbbccccddffhihhfbaba#c###bdaaagaaa#a######aabaabaaaaaaaa#a#aa####aaaa#aabbaaaabbbbbcddfeca###aaaaabbaabbabbcbccbbbccdada###aa######aaba####a###abaabcafjlf..defe##...#########bbaaa###aab#a#######aaabcb#aaaaaca##aaaa####a##aab###a##aabdfiida###aaaaa##ca#aa#####a####a###ecaaa########a##a#####a####a###aaaaaaaaaabab",
+"ccbbbbabbaaabccdcbbbbbbaaaabcdbbbeeadgeccbbbbabbbaaa##aa#abedbaa####a####bbbcbccddehhhfdaa###da#a#ddaabhaa###########a#abaabbaa######a####aaaaaaaaaabbbbbbcbdeefcb###aaaaaaaaaabbbbccccbbaabbcaaa############aacbaabaaaaaaabccbdejkbd..bgccdcba########aa######aaa#a#######aaaccaba#bcaaba#a##aaa#####abba#aa#aabdgkjkihgdb#.cedcbb#.###dc########b##ebaaaa#########################aaa#aaaaaaba",
+"abeecbbaababbbabbdbabbbbbaaabcccbdcb#ehedccbbaabbbaaa#abaaaedba###########acbbbcceeeggdaaa#bacaa#aadabbdf#######.#######aaaaaa######bca###aaaaaaaaaabbbbbbbccfffbaaaa#aaaaa#aaaabbccabbcccbbbbaaaaa#######a#aa#acaaaaaaaaaaaabccceglh.#....#baacca..####ab########aaa####a##ababbbba#ceaaaaaa###a######aa##acbbbbchgcddfgjihddigefegfffba#affeecbbaaabda#aa######a#a################aaaa#aaaaaab",
+"babfdcbcbabaabababbbaaaaaaaabcccdbaaaacifddcbbbbbbbabaabaacecabaaaaa######aaabbcdeeedifba#adcbaaba#bcabbfe#aa####aaa###a#abaaaa######aaaac#aaaaaaaabbbdbbbbcceebbba##aaaaaaa#aaabbbbbbcccdcabaaaaab##a#aaaaaaa######abaaaaa#abbbbddei#####a####.#ee######aa######aaaba######abaaaa#a##bc##aa#a####a###a#aaaabcbbbceecbbcbdeffgfdccccdefeefgffedcefeb##cdbcba########a###########a###aaaabaaaaaaa"
+};
+SIMPLE  =                    T                                                  BITPIX  =                    8                                                  NAXIS   =                    2                                                  NAXIS1  =                  384                                                  NAXIS2  =                  384                                                  HISTORY Written by XV 3.10a                                                     END                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             3"3wUD3D3"3""3"3"333""""""""3DDDU3""""DªwUUD3333333"3""3""DfD"3"""""\11\11\11\11\11\11"""33DUfffUªw3"\11"UD3""3"\113D"33wf\11""\11\11\11\11"""\11\11\11"\11"3""""\11\11\11\11\11\11""""D\11""""""""333U3333DDff333"\11\11"""""""\11"""333333DDDUD"3"""""3\11\11"\11"""""""\11\11\11\11\11\11"3"""""\11"3333UUfª\11\11\11\11\11"\11\11\11\11\0\11ff\11\11\11\11\11\11""\11\11\11\11\11\11"""3"\11\11\11\11\11\11"3""""\11"\11\113D\11\11""\11"\11\11\11\11"\11\11\11"\11""""3D333DffD33D3Ufww\88wUDDDDUfwffw\88wwfUDfwf3\11\11DU3D3"\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11"\11\11\11""""3""""""""3ffD33""3"333"33U3"33333"""3DDD3UD3\11f\99fUDD33""333"""\11"3"""fU3"\11\11\11\11\11\11\11\11\11\11\11"D333DDfff\88\88U"""\113"D""\11""U"33Uw\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11""""""\11\11\11\11\11\113D"\11\11\11""""""""""3333333DDwww3""""\11"""""\11""""33DD"33DDD3333"""""\11\11\11\11\11\11\11"\11""\11"D""""""""""""3DDDf\88Ý\99\0\11\0\0\0\0\113""DD"\0\0\11\11\11\11"3\11\11\11\11\11\11\11\11"""\11\11\11\11"\11\11"3"3333"\11Df""""""\11\11\11"\11\11\11\11\11\11""\11\11"D3333D\99\88DUUw\88»ª\99UUª\88fwf\88www3"\11"wwffD33"""3U"\11""\11\11\11\11\11\11"\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""\11""""""3DD3333"33"""3DDUD333333""""3DU333ff"U\88fDD3333"333"""\11\11""\11"3fU3""\11\11\11\11"\11\11\11\11333D3DDUUf\99\99\99wU""\11\11\11U"\11"\11UU""3\99""\11\11\11\11\11\11\11\11\11\11\11"\11"3""33""\11\11\11\11\11\11"\11\11\11\11""""""""""333333D3UffwD3\11\11\11""""""""""3333DDDD33""33D"""\11\11\11\11\11\11\11\11\11\11\11\11""D3""3"""""""3DD3Uf»Ì3U\0\03\88DDUD3"\11\11\11\11\11\11\11\11""\11\11\11\11\11\11"""\11"\11\11\11\11\11\11\11"""DD"3"\113D""3"\11"\11\11"""\11\11\11\11\11"33"\11""\11""3U\88̻̪\99\88U3\11\0DfUD33\11\0\11\11\11UD\11\11\11\11\11\11\11\113\11\11f3""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""\11""""""3"D"3U"333"3DDDUDD3DD333333""3UDUfwUDw\88DD3333""3D3"""\11\11\11""\11\11"D"\11\11\11\11"""\11\11""333DDDDUUww\99ª\99\99w3"3"\11D\11\11\113U"""\88"""\11"\11\11\11\11\11\11""3""3""""""""\11"\11""\11\11\11\11""""\11""33""""33333DUUwfD"\11\11\11"""""33""33"33D3DD333DDU"U"\11\11\11""\11\11\11\11\11\11""3"\11\11\11\11"\11\11\11"3""3D"w»Ýw\0\0Ufwf\11\11\0\0\0\11\11\11\11\11\11\11\11\1133"""\11\11\11""3\11"\11\11\11\11\11\11\11"""3D3\11"""""D"\11\11""""\11\11\11\11"\11\11""3\11\11\11"\11\11""3UwªªU"\11\11\11"""""\11\11D"\11""\11\11\11\11\11"\11\11\11\11"\11\11\11fD"""\11\11\11\11\11\11\11\11"\11\11"\11\11\11\11\11"\11\11\11\11"\11\11\11""""""""""3"3D"U333333D3DD33"D33333333"3DDUff\99\88wwDD3D3"""3""""""\11\11\11"\11\11\11\11"""\11"""""""""""3DD3Uffwwff\99\88D""3"""\11\11"U3\11"D"\11\11"""\11\11\11\11\11"""3""""""""""3""DU3\11\11"""""""\11"33"""333"33UfDww3""""""""""""""33"DD3D3DDDUD""\11\11\11\11\11\11\11\11\11\11\11\11\11""33\11\11\11\11\11\11"""""333f\99U\0\0\11\11\11U\11\0\11\0\11\11\11\11\11\11\0\11\11\11\11"U3""""\11\11"33"\11\11\11\11\11\11\11\11"""""""""""""\11"""""""\11"\11""\11"3"""\11\11\11\11"""DUf\99f"""""""""\11\11""\11""\11\11\11\11\11"\11\11\11\11"\11\0DU""\11\11\11\11\11\11"\11\11"\11\11\11\11\11\11\11\11\11\11\11""\11\11""33\11""3"""33"Uw"3D3333333DD33DUU3D333333333Dwf\88\99wDD33"3"""""3""""\11\11\11\11"\113\11\11""""33""\11"""""3DD3Dffw\99f\88UfU"""""""\11"3U""3"\11""\11\11"\11\11\11\11\11""""3"""""""333""DD\11\11\11""\11""\11\11\11\11"\11"""""""3DDDUUw33"\11""""""3333"33DDDDDD3D3U""\11\11\11\11\11"D\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11""\11""3D3U\99\0\0\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\0\11\11\11\11"""\11"""\11\11\11"33\11\11\11\11\11\11\11\11\11\11\11"DD""\11\11\11"\11\11"""3333"\11"\11\11"\11"33"\11\11\11\11"""""DDf\88D33"""""""\11""\11\11\11\0\11\11"\11\11\11\11\11\11\11\11"f""""\11\11\11"\11"\11\11\11\11\11\11"""\11\11""""""""33""33""D""DDfU3""33333DDDDUffUDDD33DD3D33DUª\99fDD333"""""\11""3\11\11""\11\11\11""\11\11\11""""D3""""""3"3DDDDUw\99»»»Ý\11"333""3"\11"3f""33\11\11\11\11\11\11"\11\11\11\11\1133""\11""""333D33"33""\11\11\11""\11\11\11\11"\11\11\11""""3"DUDDDUDf""""""""""3"3333333D333D3U3"\11\11\11""333"""\11""\11\11\11\11\11\11\11\11\11\11""33"3DD\883\0\11\11\11\0\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11"\11""""\11"3""\11\11\11\11\11\11\11\11\11"\11\11""\11\11\11\11\113D""3""3"\11\11\11""""""""\11\11\11\11\11""""""333U\99ªU"3""""""""\11\11\11\11\11\11\11\11\11\11\11"\11\11\11f333\11\11\11"""\11\11\11\11"\11\11\11""\11""3D""33"""3"3"""33333UD3D33"3333DDUUffUUUD33333333Uw\99fDDDD3""""\11\11\11\11\11\11\11\11\11\11\11""\113U\11\113""""3""""""3"3DUUDDD\88\88ª»»»3"""33""\11\113D3"33"\11\11""\11\11\11\11\11\11\11"""""""333333333DDD""""\11\11"\11\11"""\11\11""""333U3D33DUw3"""\11"""333333333DDD3DDUfU"""\11""""33""""\11"\11""\11\11\11\11"\11"3DDDUDDwª\11\11\11\11\11\11\11\11\11\11\11\0\0\0\0\11\11\11\11\11\11\11""\11\11"""""""""""\11\11\11\11\11\11\11\11\11\11"\11\11\11"\11\11""\11""\11"""\11\11\11\11\11"""\11""""\11\11"333"""""3DUfw33"""""3""\11\11\11\11""\11\11\11\11"\11"\11U3"\11\11\11\11\1133\11\113\11\11\11\11\11\11\11\11\11\11\11"""""\11"""33""333DDUUfUfD33"DD3DUUfwwffUD333333DDwwU33D3"33"""\11""\11\11\11\11\11\11\11\11"\11\11\11D"\11"3""333"3"""""3DDDUUDU\88ªªÌ»\883""""3"\11\11"wD"D3"\11\11\11""\11\11\11\11\11\11\11\11"3333""3333333D3333\11""\11"\11\11\11""\11\11"""""3"3333D3DDUD"\11"\11\11"""""3"""3DDD33D3D3""33"\11\11"""""3"\11\11\11\11\11""\11\11\11\11""333UUDU»U\0\11\11\11\11\11\11\11\11\11\0\11\0\0\11\11\11\11\11\11\11"3"\11\11\11\11\11\11"""""3"\11\11\11\11\11\11\11\11""\11\11\11\11\11\11\11"""\11"3"\11"""\11\11\11""D""""\11\11""3"""""""33DfwD33"""""\11\11"""D"3""""\11\11\113D"\11\11\11\11\11"""""D""\11"\11\11\11"\11\11"\11"""\11"\11""3333DUUDDDf\88UUDDD3"33DUwww\99\99fDD33333DUwDD3333""""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11""""3"D3333""""DDDUUDUfw\99»»\993""""3""\11\11Uw33D\11\11\11""\11""\11\11\11\11\11\11""3""3""33333"3U3\11""\11"\11\11\1133"\11"\11\11""""33"33333D33DfU3"""""""""33333D3DD3Df3333""""""""""\11\11\11\11\11"""\11\11\11\11""\11""3Uf\88»\0\11\11\11\11\11\11\11\11\11\11\11\11"\11\11"\11\11"\11"3"\11\11\11\11"\11\113""""""\11"\11\11\11""\11""\11\11\11\11\11\11\11\11"\11\11"\11""""\11\11\11\11"\11ff""\11\11\11"""""""""33DU\88wU3""\11\11\11\11""33D3\11""3D\11\11\11DU"\11""\11\11""3"3D33\11"\11""\11\11\11"\11\11""3\11"""""3"3UfD3DU\99ffUUUD"""3Ufw\99ª\99fDU3333"DUfDDD33""""""""\11\11\11\11\11\11\11\11\11\11\11\11""\11\11""\11"3"33D3D333"3"3DDUDfff\88ª»\88"""""3"\11\11\113wDUD\11\11"""""\11\11\11\11\11\11"""""""""\11""""""D3"\11"""\11"\113"\11""\11""""""""3"3D33333DfU"33""33"""333"33UDD333""33333"""\11"""""\11\11""""""\11\11\11\11\11"3Df\99Ì"\11\11"""\11\11\11\11\11""""\11\11\11\0\0"\11"3"\11\11\11\11\11"3D"""""""\11"\11\11"\11\11"\11\11\113"\11\11\11\11\11\11\11\11""""\11\11\11\11""\11Uf"""\11"""""""33333DDfwD3"3"\11\11"3""""\0\11"\113"\11\11UD\11"\11"\11\11\11\11"3""33\11"\11\11""\11\11"\11\11\11"\11\11\11"""""3"DffDUU\99\99fUUfUUD3DUfwª»\88ffUDDD33UfDDDD3""""""""""\11"\11\11\11\11\11\11\11\11\11"""\11\11"\11"3D""DDDDDDD3D33DDDDUfwªÌª3""""""""33UUUD"\11"\11"\11""\11\11\11\11"""333""""\11\11"\11\11"""3"\11\11""\11\11"\11\11\11\11\11\11"""""""""""33333DDDDUUUU""33""3DU333DD3"D3"3D33DD3""\11""""\11\11\113"""""\11"\11"""3DUw»3\11""""""\11\11\11\11"3""\0\11\11\11\11"\11\11""\11\11\11\113D33""""""""\11\11\11\11\11""\11\11"3"""\11"\11\11"""""""""""""3fD3""3"3"""""333D3Df\99\99D"""\11\11"""\11\11\11\11\11\11\113\11\0D3"3""\11\11\11\11\11""\11\11"\11\11\11\11\11"\11\11\11\11\11\11\11\11\11""\11"\11"""3Ufwww\88\88wfwffwUUf\88ª»îÌwfffUUDDU\88U3DDD3"""\11\11\11\11"\11"""\11\11\11\11\11"\11\11\11\11"\11\11\11""33D3"3"DDDUDD33333D33Uwª»\993"""""33\11\11\11DfU3""\11\11\11"""\11\11\11\11\11""33DD3"""""\11\11\11"DD3\11\11\11"\11\11\11\11\11\11\11\11\11\11""""""""""""3D33DDUUUUDUU""""333"333333D3""33333""""33"""""3333"""\11DD""33UU\99f"3"""""\11\11\11\11"3D"\11\11\11\11\113"\11\11"\11\11\11\11"3D""""""""""\11""""\11\11\11\11\1133"""\11\11""""\11\11"""33"""UwU3""3D3"""""""33"Df\99\99\99\99D""""\11\11\11\11\11"\11"3\11\11DD""\11\11\11\11\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\113"\11"\11""""\11"""3U""fww\88\99\88ww\88\88fDU\99»ÌªfwffUUDUfwU"3"3"""\11\11\11\11\11\11\11\11""\11\11"\11\11\11\11\11\11\11\11"3""3""3DU"33DUDD3D3"3333DDD\99ªfD""\11"333""""UfD"\11\11\11\11\11"\11\11\11\11\11\11\11""3""""""33"\11\11\11"\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11"""""""""""333DDUUU33fDDU33D333"333333D33""""3DD""""3""3D"33"3""""3""3Dfwf"3"""""\11\11\11\11""DD3\11\11\11\11"""\11\11\11"\11\11\11""33"3\11"\11"""\11\11"""\11\11\11\11\11"D33"\11"\11\11\11\11\11\11""""3333wfwU""""D""""""""333Dfwwwffw3fU\11\11\11\11\11\11\11\11"\11\11U3"""\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11"""""""""DDw\88w\99Uw\99U\11""f»ªfUfwffUUfUDD3""""""\11\11\11\11\11\11\11\11"""\11\11\11\11\11\11\11"\11"\11""""33""D33"3"3DD33"33333DfªU3""""""""D3D\88fD"\11\11\11\11\11\11\11\11\11\11\11\11\11"""""""""""3"\11\11\11\11\11\11\0"\11\11\11\11\11\11\11\11\11\11\11\11"\11\11""""""""""""D333DDDDfU3DwD3333"""3333"""""""3"3"""\113""""3"3"33"3"""""3Uw\99"""""\11""\11\113\1133""\11\11\11\11\11"33\11\11"\11\11""""333"\11""""""DU"\11\11\11\11\11"3333""\11\11\11\11"\11"3""3DD3UfDU33""""""""""""3DDDfffUDUw\88wwf3"\11""\11""\113D"""\11\11\11\11\11\11\11\11\11\11""\11\11"\11\11\11\11"""""\11"""3333"""""333D333ffw\99w\11"""f\99\99wwwfww\99w3DD33"""""""\11\11\11\11"\11"""""\11\11\11"""\11"\11"3""3DD"3D3"3333"33""3333Df\99U""""""""""3\11U\88f""\11\11"\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11"""""""\11\11\11\11\11\11"\11\11\11\11""""\11\11\11"\11\11\11"""""\11\11\11""33333"DDDUfUUUw\88f3D3"""""333""3""3"\11\11\11\11\11\11\11\11\11"3D3U"3"""\11""3DUfª3"""\11\11\11\11\11\11"""D"\11\11\11\11\11\11""333\11\11\11\11"""""""""""\11\1133U3\11\11\11\11""3333""""DUD""3333DDfUUfDDDD"3"\11"""3""""3DDUUUUUUDfUUffD\11"D"\11""3f3"""\11\11\11\11\11\11\11"""3"\11\11\11\11\11\11\11"""""333"33333"""""""""3"\11Uªª\11\11"""DU\88\88\88\88\88\99\88U33333"""""\11""\11\11\11"\11\11\11""\11\11"""""""""""""3D33""""""\11"""""""333UwU\11"""DU""""""U\88fwD\11\11\11\11\11\11\11"\11"\11\11\11"33\11\11"\11"""3""""""\11\11\11\11\11\11\11"""\11"\11\11\11\11\11\11\11\11"""""\11\11""33333333DDfw\99wfff\88w333"\11""""""""""""\11\11\11\11""\11\11"33DU"D3""\11\11""3Df\99w""""\11\11\11"""3"3"\11\11\0\11\11"\11"""D"\11"\11""""""\11""""\11""3DD\11\11\11\11\11""""33333"UD"333333DffUfwD""3DfD"""3"""3"3DDUDUUUDD33DDfU"\11\11\11\11\113"f""\11"""\11\11\11\11\11"3\11\11"""""\11\11"""\11\11"33333333"""""""""333"\88ª\88""\11\11""U"w\99\99wfDD333""\11"""\11\11"\11\11\11\11"\11"""""""""""""""""3""""3""\11""\11\11\11""""""33DwU\11"\11"D3"""""3ffDUDD\11\11\11\11\11\11\11\11\11\11\11\11\11"33""""""""3"333"\11\11\11"""""""\11"\11\11\11\11\11""\11""""""\11""""333"3DDDf\99\88ffDUf\88f3"""""""""\11"""\11""\11\11\11"""""3"3DD33""\11""3Df\88\88""""""\11""""3D3\11\11\11\11"\11\11\11""3"\11\11\11\11\11\11"\11"\11\11\11\11\11""""3"\11\11\11\11\11""33""""3D3333D33"DDffUUff3"3U3"33""""""3"3DUDDUDDUD33DDfwfD3\11\11\11\11\11DD\11\11\11\11\11\11\11\11\11""""""""""\11\113"\11"""""3333"""\11""""""3DDDU\88U3""\11\11""\113\99\88DD33DD33"""""\11\11\11\11\11\11\11\11"""""3D3""""33""""\11\11\11""\11\11\11\11\11"\11"\11""""3333Df\88"\11\11"D3"3"3"3fDDDU"3""\11\11\11\11\11\11\11\11\11\11""""""""""""""3"""\11\11\11\11""""""""\11\11\0\11\11"3"""\11"""""33333333DU33DDUUDUDf\88f""""3\11"""""""""\11\11\11\11""33"33D333D"""33Df\88ª""""""\11\11"33D3D"\11\11\0\11\11\11"""""\11\11\11\11"""\11\11"33""\11"""""\11\11\11\11""""33"""3333DDDD3DDDUUUfUwUUD"""""""""""""33DDU333DfD33DDUfw\88fU\11"\11\11\11w"\11\11\11\11\11\11""""""""3""\11\11\11\11\11\11\11""3\11""""\11""\11""""""3DDD"3"""\11\11"\11""fU33D3"3""""\11\11"\11\11""\11\11\11\11""""3"33""3"D"""\11\11\11"\11\11\11\11\11\11\11"\11\11\11\11"""""""DDf\993333D3"""""DU333D3\11"\11"\11"\11\0\11\11\11\11"""\11\11"\11"""""""3"""""3\11\11""""""""\11\11\11\11\11"""\11\11""\11\11"33"""333DD3DD3DUDUDUUfwwD""3""""33"\11""\11\11\11\11"\11\113D3""""3"3"3333f»ª3\11"3DDUD33DD3"\11\11"\11\11""""\11\11"\11\11\11\11\11\11"\11\11"""""\11"\11\11\11"\11\11\11\11\11"""""""""33DDDDDDDDDDDDUff\88wDU"33"""""""\11""""3DD333"DD3"333DUUfwfUf"\11DU\11\11"\11"""3\11"""\11\113D3\11\11\11"""\11\11"3""""\11\11\11\11\11"""""33D3""333\11\11\11\11\11"UD333""333""""\11"\11"\11\11\11\11\11""""33"""3D3""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11"""""3UU\88f"U3D"""""3DD33333"\11\11\11\11\11"\11"\11\11"""""\11\11\11""\11""\113DD""3""D\11"""\11\11\11\11\11"\11\0\0\11\11\11\11\11""""""3D3"""3333DUDDUDUUfUDffw\88wDD3""""""\11""\11\11\11""\11\11"DD""""""""3333U»ÌwUw\88»»\99\88wffffffUD""3""3"""""\11\11\11\11\11"3\11"\11""""\11\11\11"\11\11\11\11"""""""""""33DDUUDDDDUDDUfff\88w3D3D"""\11""3"\11"""3UD333"3"333""33DDDU\88\99\88\11""U3""33""\11\11\11"\11\11"DU"""\11"\11""\113"""""""""\11"\11"""DD3""3"""\11"""\11U""""""""333""""\11\11\11\11"33""3""3D33333\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""333UUf\99fD"D3""""3fD3333"3""\11\11\11\11\11"UDD"\11\11\11\11\11\11\11\11\11"\11"\11\11U"""""D""""""\11\11\11""\11"D"\11""\11\11""""333""3DD3333DUU"DDUfUUfDw\99\88D"3"""\11"3\11"\11\11\11\11"\11\11\11\11"""\11""""333D3Dª»UD\99ª\99\88ª\88\99fU3D33DUwU"3333DD""""""\11\11\11D""\11""""\11"\11"\11\11"""""""""""""3DDDUUUUUfffUfffww3""""""\11\11""\11\11\11"""333"3DUf"3""""3333DUf\88ª3"33w""3D"\11\11\11\11"\11"DD"\11"""""""3"333""""\11\11"""3"33"""3""""""\11\113""\11\11\11\11"""3"""""\11\11\11\11\11""D""3"33DD3""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""""""33DD3f\88ªw""""33DfD3333""U\883\11\11\11\11\11"ff"3D\11\0\11\11\11\11\11\11""\11\11"""""\11"""""\11\11\11"3""\11\11fU""""\11\11""33""""3333333DD33UDDDDUUUf\99\99U"33""""""\11\11"\11\11\11""""33\11\11\11\11\11\11Df3D3D\88»\11""\11\11"3Uw\88\88D333""""3Uwf"\11\11\11\11"""""\11\11""\11\11\11"""\11""""\11"""33""""""""33DDUUffUUfwwffffwD"3""\11""\11\11\11\11\11""\11""333"DDD3""""""""3DDDUf\88w333Df""D3\11\11\11\11\11""""""""""""DDD"3"""""\11"\11"33DD""33""""\11\11\11"3"\11\11\11\11\11\11""""""""\11\11"\11"""\11wU""33DD3\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11""""33"3DDDDUf\99ª3"3333DwUD333"3\88ª\99D\11"\11\11\11\11"33""\11\11"\11\11\11""\11\11"\11""""\11\11"""\11\11""""3"\11\11\11U"""\11\11\11"3D"""3"""33333DD3D3DUDUUU\88\88wfU3D3"""""\11\11"\11\11\11\11\11""""\11""\11\11\11\11\11"3333U»3\0"\11\11"""""3ffD"33"\11\11""3U"\11\11\11\11\11\11""\11\11\11\11"""33UDUD3""\113D33""""""""333DDDUUfUfwwwUD3DD3"3\11\11\11\11"\11\11\11\11\11"\11"""3""3ff3"\11\11\11\11\11\11"""D3DUUf\88f33"DDD3"\11\11"\11""""""""""""DD33333"3"""\11"""33""""""""""3Uf3"\11\11\11\11\11\11\11\11\11"""""\11\11\11"""""Dwf3333""\11\11\11""\11\11\11\11\11""\11\11\11\11\11\11\11\11"""3"3""D3UfDDf\99\993"""""UUD33333D\88ª»\99f"\11\11\11\11"D3\11\11\11\11\11\11\11\11"\11\11""\11"\11\11"\11"""""3""""\11\11\11\11"""3\11\11\11""""""""""3"33DD3333"D3fUwwfUDUff""""3\11"""\11""\11\11"\11\11""\11"\11\11\11""\11""3"DÌD\0\11\0\11\11""""""3Ufw3\11"\11"""""\11"\11\11\11\11"3D\11\11\11\11"3D33ffD33"""33\11""""""""3333D3DUfUfUUfwUD"DD3D"\11\11""""\11\11\11"""""3""fDD"""\11\11\11"""\11"""3DDDUww33"DwD\11"\11"\11"""""""33""""f"3D33"3333D33"33\11"""""""\11""wD3\11\11\11\11\11\11\11\11\11\11\11\11\11""\11"""""""Uf\88U"D3""\11\11\11""\11\11\11\11"""\11"\11\11\11\11""""33"""3""3UUDDf\99ªf"3""3fDDD33333ªÌÌ\88D"\11\11\11\11"D33\11\11\113"3"\11\11\11\11\11""\11\11\11\11""""""""\11\11\11\11\11\11""\11\11\11"""""""3""""""""D333333fwwfUDD3DUUUU3"""\11\11""""\11\11\11"\11\11"""\11"U3"\11"""33ªf\0\11\0\11""\11\11"""""""DfD"""3"\11\11\11"\11\11""3U3\11"\11""DDDDDDDD333"\11\11\11"""\11\11\11"""3333DDDUUUfUf\88DUUD33""""33"33"33""33""UU3""\11\11\11\11\11""\11\11"""33UUfw\88D"3"\883""""""""""""33"""D"3"""""3333"33""""""""""""\11"3"\11"\11""\11\11\11\11\11\11\11"""""""3""33f3U333\11\11\11\11\11\11""\11\11\11\11"\11\11\11"\11\11\11\11""""33""3D"3DDDUUww»\99wU3"fwDU3333U»Ì»f3""\11\11\11\11\113DD3\11\113"3"\11\11\11\11\11""\11\11\11\11\11\11"\11\11\11"\11"\11\11\11\11"""""\11\11"\11\11""3"""""""333333"3fwU33D333D333D3""\11\11\11\11""\11\11\11\11\11\11\11"""""U"""""33U\88\11\11\11"\11"\11\11\11\11"\11""\11""3DDDD""""""3DU3DD"""""33UfffUDUD3"\11\11\11""\11""3"""333D3DDDUUUUfwwwwU3""\11\11\11\11"3DD33\1133DDU3DD""\11\11\11"\11""""\11"\11""33UDUw\88U"""DD""""""\11"""""3"33"""33333"33333D3D3""""3""\11\11\113f3"\11"\11"""""\11\11\11\11""""""""""DD3D33""\11\11\11\11\11\11\11""""\11\11\11""\11\11""""""""333"33D33fwww\99»ª\99wD3wD3D333Dw\99\88D"""\11\11\11\11\11"\11Uf""\11\11""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11"\11\11\11"""""\11\11\11""""33""""3"33333333fUD3""\11"33333DDD""\11\11"\11\11\11\11\11\11""\11\11"""\11\11"3""\11""3»"\11\11\0\11\11\11\11\11\11\11"\11"\11\11\11"""3fD"""""""DDD3D""""33UUUfwfUD3""\11\11\11""""\11""""333DDDDDDDUUw\88\88\88\99U3"\11\11\11\11""3"3"3"3D33UU3"\11\11\11"\11\11\11"\11"""\11\11""33DDDf\88w3""3D"""""""33"""""33""3""D""333"33"U3"""""33"\11"fwD""\11""""3"\11"\11"\11\11"""3"33DD3"33333"\11\11\11\11\11\11\11\11""\11"\11""""""""3"33"""""UDDD"UUw\99Ì»ª\88UDUfDDD33DUDfD3""""\11\11\11\11\11\11"D"\11\11\11\11""\11\11\11\11\11"\11\11\11\11\11\0\11"""""\11""3"3"33\11\11\11\11\11\11""""""33"3"""""3DUD3""""""""""333D""""\11"\11\11\11\11""\11\11\11\11"\11""""""3"3»\99\0\11\11\11\11"\11\11\11\11\11"""\11\11""""3U"3""""33"3UfffUUUUD3\11\0\11\11Uf3"""3"""3"\11\11\11\11"""33DDUDDDUUfww\88w\88D""\11\11""\11\11\11"""""DD"UUD"\11\11\11\11\11\11\11\11"\11"\11\11\11"""DD33Dfww3""D\88f""3333"3"""""""""""3""""33D"""3""""333DDUfUD3""\11"""""\11\11\11"""""""""33333333""""\11\11\11\11\11\11\11""3""""""""""33"""""333wfDDDDUwªÝ»ª\88DUfDDDD3DD3DD33""""\11\11\11\11\11\11\11"\11""\11\11"""\11\11\11\11\11\0\0\11\0\0\11"""3"""""""3"D3\11\11\11\11\11\11"""""""33""""DUUD3"""\11\11D3"3"""""3D3"""""\11\11\11"\11\11"\11\11\11\11"\11\11""3"3D\99Ý\11\0\11\11\11"\11\11\11\11\11""""""\11""33Uf"""D3333UwUDD3"33\11\11\11\11"\11UU3333"\11\11\11\11\11\11\11\11\11\11"333DDUDDDUUfw\88\99\99wD"""\11\11\11\11\11\11""3\11"3""UU""\11\11\11\11\11\11\11\11"3\11\11\11""""DDDDDUfwU\11U3\88f3DDDUD""333"""""""3"333"""3"D"""""3"\11ffUUD33"""""\11\11\11\11\11\11\11\11""""33"3333D333""""\11\11\11\11\11\0\11\11"""""""""""""3333"""""UfUDUDDf\88ª»ÌªwUUf3DD33DD""3"""\11\11""\11\11\11\11\11\11""""""3"\11""\11\11\11\11\11\11\11\11\11"""""""""\113DDU"\11\11\11\11\11\11\11"""""33"""3UUD3"\11"""""""""""""3DU"""""\11\11"3"""\11"\11"\11"\11\11""""w\99Ý\88\0""\11"\11"\11\11\113"\11\113\11"D""3DUw"""DDUDDfU3"\11\11\11\11\11\11\11\11\11\11"UD3D"\11\11\11\11\11\11\11\11\11"\11"""33DUUDD3Ufw\88\88ªª\88fD3\11\11\11\11\11\11\11\11""""\11"33"\11\11\11\11\11\11\11\11\11\11\11""""""\113U3DD3DDfw\11"3UfUUffUUDD3"\1133333"""""""""""3D""""""\11ffUDD333"""\11"\11\11\11""\11"\11\11"\11""""33DD""\11"""\11\11\11\11\11\11\11\113"D3""""""""""""3D333333DfUDUDDw\99w\99Ì\99\88\88wU33DD33"3""3""3UU"\11\11\11"""\11"""""""D3\11\11\11\11\11\11\11\11\11""""""\11""""3fD\11\11\11\11\11\11\11\11\11\11"""""""3UUD3""""""""""""\11\11""3"D3"""3"\11\11\11\11\11"\11\11"\11\11\11\11\11\11"""3\88ÌÝ3"""\11\11\11\11\11"""""""""""333wU""DUUfUUD3"""\11\11\11\11\11\11\11\11\11"""3\11\11\11\11\11\11\11\11\11\11"\11\11""""33D3333fww\99»ªwUD3\11\11\11\11\11\0\11\11"D33\11""""\11\11\11\11\11\11\11\11\11\11\11""""\11"""D3D33D3Df\88w"DD\88\88\99\88wwUD33""333"""\11"""""""""3"\11""""3ffDDD3""""\11""\11\11\11"""\11"\11"""33333D3""\11\11"\11\11\11\11\11\11\11"""3""3"3""\11"""""33333"""3"3DDUfDUw\99\99ªª\99\88wU3DD33D3"3""""""UD"\11\11"33"""""""\1133\11\11"""\11\11\11\11""\11"""\11""""33U"\0\11\11\11\11\11\11\11\11\11\11""""3UUD33""\11"\11\11""\11"""\11\11"""33UfDD"\11"\11""\11"\11\11\11\11\11\11\11\11"""""fªÝª\11\11"\11\11\11\11\11\11"3""\11\11\11""""""Dwf""3UUDU3""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""333333DUw\88»ªf3"\11\11\11\11\0\11\11\11\11\11""\11""\11\11\11\11\11\11\11\11\11\11\11\11"""""\11\11\11"""3D33D33Dfw\88\88D33wffU3fU3D3"33"""""""""""""""\11"""\11DUDUUD33""""33""\11\11""\11""""\11"""""""""\11"""\11\11\11\11\11\11\11\11\11\11"3""""\113"""""33333"3333DDDDUU3UU\88\88\88\99\99wU33D""33333""33""""\11"""33"""333\11333"""\11\11\11\11\11"\11""""""""""33\11\11""\11\11\11\11\11\11\11\11\11\11""3UD3"3""""\11\11\11\11""\11\11\11""\11"33DU\99\99D"3"\113"""\11\11\11\11\11\11\11"""""3\99ÝîD\11"\11\11\11\11\11"""""\11"\11\11"33"\11""3"""3DU\88w33\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""33""33DDU\99ª\88D"\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11"""\11\11\11\11\11\11\11\11""\11"\11\11"""3333DD3DDU\88w\99"\11D"""\0\11\11wfU33D3"""""""""\11"""\11\11\11"""UfDDD33"""""""3""\11\11\11"""""\11\11"\11"\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"\11"3"3U"\11""""""""33""3333D333UU3UU\88ªw\99fU3DDD33DD\11\11""33""\11"""""""3""333DDDDUf3""\11\11""\11""""""""""3fU""""\11\11\11\11\11\11\11\11\11\113fD"""""\11"\11\11\11\11\11\11\11\11\11"""\11\11"3DfwwUDD3\11\11""\11\11\11\11\11\11\11\11"\11"33"3ªÝÌ\11"\11"\11\11\11\11\11\11"3\11""\11""\11\11\11\11\11"""33DUUfU3""\11"\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11""""""3UUUw\88wD\11\11\11\11\11\11\11\11\11\11\0\0\0"\11"\11\11\11"""\11"\11""\11\11"\11\11\11""""33333D333DDf\88\99w""""""""33"3DD333""""""""\11"33"\11""DfUDDD3"""""\11""\11\11\11\11\11"\11"""""\11\11\11"""\11\11\11\11\11\113"\11\11\11""\1133"\11""\11"3D"\11\1133\11"3""333333""3333UDDDfª\99\88fD3DUDD3DU\11"3"3"\11\11"""3""""""3DD3""33UU33""\11"""""""""""""DD3"""\11"\11\11\11\11\11\11""3UD3\11\11"""\11\11"\11"\11\11\11\11\11""""\11\11""3wwf3DDUUD3\11""\11\11\11\11\11\11\11""""""UÝÿU\11""33"3"""""\11\11""""\11\11\11\11""""3DDUffU33\11""\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\0\0\11\0\11\11\11\11\11"""""3DDUffDU""\11\11\11\11\11\0\11\11\11\11\11\11\11\11\0\11\11\11"""\11""\11\11\11""""\11"""3D3DDDD33DDUUffw\11\11"""""\11\11\11\11"""DD3""3""""""""3"\113DUUD333333\11"""\11""3\11\11""""\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11""\11\11\113\11\11"""""\11\11"\11"\11\11\11\11\11"3"333""3"333DDDDUDU\88»ªw33"33DDDD"\11"""""""""D"""""3DDD3"""\11333D""""""""""""""""DD3""33""\11"\11"\113D33""\11\11"\11\11\11""3"\11\11\11\11\11\11""""""UUw\99\88DDUUUU"D"D"""""\11"""""""3\99ÿÌ\0""333\11\11""\11\11\11\11""\11"D""33\11""3DDUUffDDD333"3""\11\11""\11\11\11""\11\11\11\11\11\11\11\0\11\11\11\11\11\11"\11\11\11""""3UUUDUfUU"\11\11\11\11\11\11\11\11\11\0\0\0\11\11\11\11\11"""""""""\11\11"\11\11\11""3D33DD3333DUUfffwD\11\11"\11\11\11\11""""""DUDD33""3"3"""3DDUDDDD3333""\11"\11\11\11\113"\11"\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11D3\11\11\11\11\11\11\11\11\11""\11\11"\11\11\11"\11\11\11\11"3\11""3""""3333fUDUDDf\99ª\99D333333DD"""\11"\11"""""33""""333D33"""333DD"""33""""""""""3333"DU"\11\11\11\11""fU3"""3UU3"\11"""3\11\11\11""\11\11\11\11""UUDDff3"333D3DUD"\11""3"\11"""3""3wîÌ"\11\11""3""""""\11"33"3333"""\11"DDDUUUDDfU3333""""""""\11\11"\11\11\11\11\0\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3UUD33D"""\11\11\11\11\0\11\0\0\0\0\0\0""\11\11\11""\11\11\11\11""""\11""\11\11""DDDDD333"33DUfUUUf"\11\11\11\11"\11\11""\11"\113DD3DD3D33""""UUUDD333333""\11""\11\11\11\11"\11\11"3"\11"\11\11\11\11\0\11\11\11\11\11\11"\11\113\883\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11""\11\11\11\11\11\11\11"""\11\11""33DDffUUUf\88\99ªf3"""3DDf3""""""""3""3"""33"""33"""33333"""33"""""""""33DD33D3"\11\11\11\11\11Dwf33"333"D""""""\11""""\11\11\11"D33333333D3""333DD3"""3\11\0"DfwwUw\88\99w"\11"\11\11\11\11""\11""\11\11"D3"D333"""""3DfUDUUfU3"""3""""""\11\11\11\11\11\11\11\0\0\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3DDDDU333\11\11\11\11\0\11\0\0\11\0\0\11\0\11\0\0\11\11\11\11\11\11\11\11""\11"""\11"""3UUU3D"3"333UfUUfUff3\11\11\11\11""""""\113"\11""3"3D333"fDD3D3D3D3333""""\11\11\11"\11\11""U3"\11""\11\11"\11\11\11\11\11\11\11"33U"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11""""\11"3"3DDUffUUww\99\99\88DD3""3fwU33"""\11""3D33"3D"\11""""3"3333DDD3"""D""3"""3""""33""""3\11""""fw"""""""\11\0\11\11\11"\11"\11"\11\11\11\11\11\11333""3DD"33UD3"33D3DU33"""fwfªªww"\11\11\11\11"\11\11\11\11\11\11\11"\11\11"""""33D3"\113""3UUUfwwwUD""""""""""\11\11\11\11\11\11\11\11\11\11\0\0\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11""33333U"3"""\11\11\11\0\0\0\0\0\11\11\11\11\11\11\11\11"""""""""""""3DDD3Uwf3""""""DwUDD3DUUD\11\113""3D3"3"""""""""3"""fU3D3DDDDD33DD3"""""""\11"3fff3"""\11\11\11""\11\11\11""\11\11\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11"\11""3333DUUUUDDfwf\88wDD"\11"U\993""DDD"""3D3DUfD"""\11\11"""D"3U"3UD3""33"33"""3"33D3\11""33\11""\11\11Uf"\11\11""\11\11\11\11\11\11\11"""\11\11"\11\11""3""""D"DUwf333333"3DDDDwfUUw\88wfU\0\0\0\11"\11\11""\11\11\11\11\11\11\11\11\11\11\11"DU3"333\11""\11"DUUf\88wfD3"""""""3""\11\11\11\11\11\11\11\11\11\0\0\0\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11"\11"333"33"\11\11""\11\11\11\11\11\0\11\11\0\0\0\0\11\11\11\11\11"\11\11""""""""\113"""Dfff3""""ffU333"333DD3\11DfUUUDDD3"""""""3""\113f3333333333333""""\11\11\11\11"DDDDfU""\11""\11"""\11\11"\11""3U"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"\11"\11\11""""333"33DDDUDDDwDwfD3""DfD"\11""DU3DDD3"\11"\99\88"3"""""3"333DDDD3""3333333"""3D3\11\11\11"D"\11""3DD\11\11"\11\11\11\11\11\11\11\11\11\11"\11\11\11"\11"3"""\11"""33UUUU333D3"""""3DUUU\99fDDD\88\11\11\11\11\11\113"\11"\11\11\0\11"\11\11\11""DfD"\11D3"""""DUfw\99\88wD"""\11""""33"\11\11\11\11\11\11\11\11\11\0\0\11\11\11\11\11\0\0\0\11\0\11\11\11\11\11\11\11"""3DD3"""\11\11\11\11""\11\11\11\11\11\11\11\11\0\11\11\11\11"33\11\11""\11"""\11"\113"\11"33fw3"\11\11333""""""33DDD\11DDUUfwwD""""\113"""""3f3333D3333D33333""\11\11"\11\11"""\11""""\11"""""\11\11\11\11\11""""""\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11"\11\11"3\11"\11\11""D"3"""3DDD3U\99fUwU33"3D\11"""""""3"\11\11"""f\99f"""""""333"DUU33"""333"""""""3D\11""\11"\11\11\11Dw\883\11"\11\11\11\11\11\11\11\11\11""\11\11\11"""DD""""""""D3"3DU""D3"""3DUUDDD\88wD""3f\88\0\11"\11""\11"\11\11\11""""\11\11\11\11"""""3""""""Dffw\99wU3""\11\11\11""""""\11\11\11\11\11\11\11\11\0\11\11\11\11\0\11\11\11\0\11\11\11\11\0\11\11\11\11""\11"3D3"""\11\11\11\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11""""""""\11""""\113"\113"3ww3\11"D3\11""""3"""33DD"33DDDw\88U""\11\113D33"""D3D3"Df333DUU33"""\11"\11\11\11\11""\11\11"U"\11"\11\11\11\11\11\11\11\11""""\11\11\11"\11\11\11"\11\11\11\11\11\11"3""\11\11\11\11\11\11\11\11\11""\11"333""""33DUUfff3DU3"33\11""""""\11\11\11\11""""3DDD3DD3""333"3DD3""""""""33"""""""\11\11""3DDDwf3\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11"3\11"""\11\11"""33""D"3"3""""3DU3DDwwD\11\11"3f\99\0\11\11""\11\11\11"\11\11\11\11\11\11\11\11\11"""""D3"3"""DDUUw\88U3"""\11\11"""""""\11\11\11\11\11\11\11\0\11\11\0\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11"""3""3\11\11\11\11\11\11\11\11"\11"\11\11\0\11\11\11\11\11\11\11\11\11"""\11\11\11\11\11""\11\11"\11""\11\11\113U""3"\11""\11""3""""333"3333DUUfwfD3D3""33UD3""3DfDDDfw\88D"""""""""\11""\11"ff"\11\11\11\11\11\11\11\11\11\11D\11\11\11\113"\11\11\11"D"\11\11\11\11\11"3"\11\11\11\11\11\11\11\11\11\11\11\11\11"3D"3""\11"DUfwDD3"DU3UD\11\11"""""\11\11\11""3U3"""33DDD3333333DD3"3D"3""33"33"""""\11\11\11"UU3DU3"\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11""""\11""""""""\11"""D3"3UD333f\99D"\11"33f\99\11""\11\11\11\11\11\11""\11\11\11\11\11\11""\11""Dw3""""""33U\88U3""\11\11\11""""\11""""\11\11\11\11\11\11\11\11\0\11\11\11""\11"\0\11\11\11\11\11\11\11\11\11\11\11"""\1133""""""\11\11\11\11"\11\0\11\11\0\11\11\11\11\11\11\11"3"\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"""""333"\113333"""""33DUUUUUU3""3DfUDD3""UwUDDff\88\88U3"""""""\11\11\11\0U\99U3\11\11\11\11\11\11\11\11\11"3\11\11\113U"3"3"UUD\11\11\11\11\11\11"\11\11\11\0\11"\11\11\11\11\11\11""3"D""""U\88\99wU33"3fDU3"\11\11\11"""\11""""DD"3"""D"3"3333333D3D33D3"""""3"3"""3"\11\11\11\11"33Dw3""\11"""\11\11\11\0\11\11\11"3\11\11\11\11\11""""\11\11"\11\11\11\11\11\11""\113"\11""333"3UD"3fw3D""3"3\99f\11"\11\11""\11\11""\11\11\11"\11\11\11\11\11""33"\11"""""333fwD3"\11\11\11""""\11""""""""\11\11\11\11\11\11\11\11\11"\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\1133\11"""\11\11"\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11"""""\11\11\11\11\11\11\11""""\11\11\11"\11\11\11\11"\11\11""3""3""""""""""333DDDUUf3333UfUfwUDDDDD3Dff\88\99\88wU""3"\11""\11\113\99\88U\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"3\11"3"3DUU\11\11\11""""\11\11\11\11"""""""""3"3""""U\99\99ª\88f3"3wUUD""""""""""""3"""""""3D333D33DfD333"333""""33"""""3"\11\11\11"3"Uf"\11\11\11\11\11\11\11\11\11\0\11"\11\11\11\11\11\11\11\11\11\11""\11"\11\11\11"\11\11\11"\11\11\11\11""33"33""UDD\88\99333"""3wª\11"\11\11"\11\11\11""\11\11\11\11"\11\11"\11"""3""""""""33"DwU3"\11\11"\11"""\11""""333\11\11\11\11\11\11"\11\11\11\11\11\11\0\11\11"\11\11\11\11\11\11\11""\11"\11\11"\11"\11\11\11\11""\11\11\11\11\11"\11\0\11"\11\11\11\11""\11\11\11\11\11\11\11\11\11"""""\11\11"""\11\11\11""\11"""""\11"""""3""""3D3333DDDDDffDffffwfUUUD33Dffww\99\88wf3""\11\11\11\11\11"w\99\88D""\11\11\11\11\11\11\11\11\11\11\11"\11"\11\11""3DUUD"\11\11\11""\11\11\11\11\11\11"333"3"""""3"""fªªª\99\8833\88fUU"""""""""33""333"""""3UDDDUUUUDD"3333"D"""""333"""3""\11\11"DUU\11\11\11"\11\11\11\11\11\11\0\0"\11"\11\11\11\11\11"\11""\11\11"\11\11\11\11\11\11\11\11"\11\11""fD3\11"333DDDw\88"""""""fª"\11"\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11""33""""3"33"3"3U\88fD"\11\11\11\11"""""3D333"\11\11\11\11\11"\11\11\11\11\0\11\11\11\11\11\11\11U"\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""\11\11\11\11\11\11\11\0\11\11\0\11\0\113"\11\11\11\11\11\11\11\11\0\11"\11""\11\11"33"\11\11""\11""\11""\11\11\11""""""""""33333D3DDDDfw\88ffDD3DD3333Uwªª\99\88\88\88f3\11""""\11ww\99\99\99f\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\113\113D"UUUD3""""\11\11\11\11\11"3DD"\11"""""""""3U\99ª\99\88UUw\88w\88D"""""""333"333""3""""3fUDfwfD333333"333"""33"DUD"\11"""\1133U3\11"""\11\11\11\11\11\11\11\11\11""\11\11\11\11""\11"\11\11\11"\11\11\11\11\11\0\11\11\11"""""U33""3"UUD\88\883""""\1133Uª"\11"\11\11\11\11\11\11\11\11\11\11"""\11\11\11"""3""""333333""Dfwf3""\11""""3DDD3""""\11\11\11\11\11\11\11\11\11\11\11\0\11\0\11\11"U\11\11\11\11\11\0\11\11"""\11""\11""\11\11\11\11\11\0\0\0\11\0\0\0\11\11\11"3\113"\11\11\11\11\11\11"\11\11\11"\11\11"3\11\11\11\11\11"\11\11\11"""\11\11""\11""""""""3333333333DfUUffDD3DDDDUUw\99ª»»\99\88\88\88\993\1133"\11\11U\99\88\99\99w"\11\11"\11\11\11\11\11\11"\11\11\11\11\11\11""3""DDDfU"""\11\11\11\11\11\11\11""""""""3"333DDU\88\99\88wfU\88w\88D"3"""""""3"3"3""3"""""3UDDffffDU333"3"3333DD33333"3U3"3D3"\11"\11\11\11\11\11\11\11\11\11\11\11\11""\11\11"""""3\11""\11\11\11\11\11\11\11\11\11\11\11""3"3D33""3f\88\88\99\11\11\11\11\11\11"""\88»\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11"33""33333"333"3D"33""""3DUUDD3"\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11DD"""\11\11\11""\11\11""""\11\11\11"\11\11\11\0\0\11\11\0\0\0\0\11\0""\11\11"\11\11\11\11\11\11\11\11\11\11\11\11"""\11\11\11\11\11"\11\11\11\11\11"\11\11\11"""\11""""\11"""D""333333fDDDD33DDUUDDUf\88\88\99\99\88wff\88U\113UUDDDU\88\88\99ª\88U3\11\11"\11"\11\11\11\11\11\11\11\113"""\11"33D3U333\11\11\11\11\11""\11"""""""3""3"3DUf\88ªª\99U\88\88wwUD3""3333"33333"3"""""\11DDUDDUf\88fUDD333333D3333""U3"3""DU3\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""3\11""\11\11"\11\11\11\11\11\11\11"""""3"333"33wªf""""\11"""\11D\99Ìf\0\11\11\11\11\11\11\11\11\11\0\0\11"""""""""3"33DD33D3""\11""33D3"3DUffUD3"\11\11\11"\11\11\11\11\11"\11"\11\11\0\11\11\113""33""""""""33""3"\11\11\11\11\11\11\11\11\11\0\0\0\0\11\0\11\11\11\11\11\11\11"3\11"\11\11\11\11\11\11\11"\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11"\11\11""33"\11\11\11"""333333"DUD3333D3DDDDD3UUUffUfUf\88fUUUUDUDffUw\99\99wD3"\11"33\11\11"\11\11\11\11\11"\11""3D""DD3D\11\11\11\11\11"\11""\11""\11\11\11DD333"3DUwww\99\88ªwf\99wf333"33DDD33333333""""\11DDUDUUw\88\99wfDDDD3333"3DUUf\88D3DDUD""""""\11\11\11"\11\11\11"\11\11\11\11\11\11"\11"\11\11"DD3"\11\11\11\11\11\11\11\11\11""""33DD33D3Df\993\11\11\11D33"\11\113Uf\99f\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11""333DDUD3DD3"\11\11""DDD3DDfwwfUD33"""\11\11\11\11\11"\11\11\11\11\11\11""3"\11\11""""\11"3"3D3333D3""\11\11\11\11\11\11\11\11\0\11\0\11\11"\11\11\11\11"\11\11\11\11""\11\11\11\11\11\11"""\11\11\11""\11\11\11\11"\11\11\11"\11\11"\11"""\11\11\11\11"""U33"""DDD333333DD3D3DDD3DDfffffUfUDU3DDUffD3U\88\88wUUUfUD"DU"\11\11\11\11"\11\11\11"33""D"\11\11\11\11\11\11""\11\11"""\11""3D"3"3DUfffU\88ª\88Uw\8833D33333DDD33333"""""""""DDUUUUfwUfDDD33D33UUD3DDUUfUD"""\11"\11""\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11"U3""\11\11\11\11\11\11\11\11\11""333D3D"33UDUD333D3""\11\11"33wª"""\11\11\11\11\11\11\11\11\11\11\11\11\11\113"""3333DDfUDDD3""\11"33333fw\88ª\99wUDDD3""""\11\11\11"\11\11\11\11\11\11""3"\11"3""""""3""\11""""""\11\11\11\11\11\11\0\0\0\11"\11\0\11\11\11\11\11""\11""""\11\11\11\11\11\11\11\11"\11\11"""\11\11\11"\11\11\11""\11""\11""""\11""33"3"""""3D333333333333333DDUfUUDDD3UDDDDUUfDD3Dww\99wUUUUUDD"U3""\11\11\11\11\11""33""3"\11\11\11\11\11\11\11\11\11\11"\11\11"""33""DUUUwff\99»ªw\88\99"\11""3D3"DUUDD33333"33"""\11""3DDDfw\88UUUfwwffDUfU3333D3"\11\11\11""\11\11\11\11"\11\11"""""\11\11"\11\11\11""\11\11\11"3"\11""\11\11\11\11\11\11"\11"""333"\11"33wD3DDDDD3"""\11"33w»\88\11""\11\11\11\11\11\11\11\11\11\11\11"""33"""33D3UfUDU33"""333DDf\88\99\99ªªfUDfU33""\11\11\11\11\11\11"\11\11\11""""\11"3""""""""\11\11"""\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11"""""\11\11\11\11\11"3\11\11\11\11\11""\11\11"\11\11\11""\11""\11"\11\11\11\11\11""""\11\11"""""3333"333333333333UUUDDUUDD3D333DDDUU3DUwUUUDDDUUUDfD33\11\11\11\11"\11""3DD"3""\11\11\11\11\11"""""\11\11\11\11\11"33DDUfUffUDª»w\88\88w"3""3333DDUUDD333"3"""""""""333\88ª\99ª\99wwfUDD33333333"\11"\11""\11\11\11\11"""""""\11\11""\11\11\11\11\11\11\11"\11\11\11""""\11\11\11\11\11\11\11\11"3""3333"DDf\88"\11DU"""3"""""33wf"\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"33333"ffUUUD3"""3"DDfDDfwª\99UDDfUD3""\11\11\11\11\11\11\11\11\11\11"""""""333""""\11\11\11\11\11"""\11\11"\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11""""\11\11\11\11\11\11"\11\11\11\11\11""\11\11"\11\11"""\11\11\11"""\11"\11"3D\11""\11\11\11""3D""""3333333333DUUD3DDUUD3333"3DDDUDD33UUDD3DDUDDUDf3D33\11\11\11\11\11"3DD3DU\11\11\11\11\11\11""\11\11"\11\11\11\11\11\11"3DUUDUUUf\88\88ªª\99\99\99U""""3DDDDffUDD33D33DD3DDUfff\88\88wfUUDDUfDD33"""""""\11"\11\11"""\11\11\11"""3"\11"\11\11""\11\11\11\11\11\11"\11\11\11\11\11"\11\11\11\11\11\11"""""""3"""3"3Df\993\11"UD3U33"\11"""3UDf""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"33333"D\88fffDD"\11\11\113fUD""\11"Uw\99DDUww3333"\11\11\11"\11\11\11\11"""""3333"""3"\11\11\11""""\11\11\11\11\11\11\11\11\11\11""\11\0\11\11"""""\11""\113\11\11\11\11\11\11"\11\11\11\11\11\11\11""""\11\11""""\11\11\11"3DU3\11\11\11\11\11\11"\11""3D3""3""33"""3DUfU333DUUD3333D"333DD3333DUD33DDDDDUUUUUU3"\11\11\11\11"3333UD"\11"\11\11\11"\11\11\11""\11\11\11\11"""3DfUfUD33\88ªª»»\99D"33"""""DDUUUUDDffUUUUUUUfffwfU33D3DDD3333"""\11"\11\11\11"""""\11\11\11""""D"""\11\11"\11\11\11"\11\11"DD"\11\11\11\11\11\11\11\11\11\11\11\11"D"""""\11"33DDU\88\99DD\88\88wD"3"\11""""D\88\88U"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"333""33UffwfU3""""UU"\11\11""33D\99fUffwfU3"""3\11\11\11\11\11""33""3"D3"3""""\11\11\11\11\11\11\11\11""\11"\11\11\11""\11\11\11\11"""33"\11\11"\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"\11\11\11\11"""\11\11"3U3"\11\11\11\11\11\11\11\11\11""33""33"33""3UfUUD333DDDDD3333""333DD33"33DDDD33DDDDDUUUfD"\11\11\11\11""33DDD"\11\11""""\11\11"\11\11\11\11\11"3333ffwwffDDw»»ªw3""3"""333DUfDUfwwU3D333""333DDDD33UD3"""""\11\11\11\11\11\11\11\11\11\11\11"\11"\11"""""3"\11"\11\11\11\11\11\11"""3D"""3""\11\11\11""\11"""\11\11\11\11\11\11"DfU3DUwª\99w\99ªw3"\11\11\11\11""""U\99D\11\11\11"""\11\11\11\11\11\11\11\11\11\11\11"\1133"""33DDDDwfD"""DD"\11\11"""""DDwwUwDDfU33"3\11"\11""""33"""3"3"3""\11\11\11\11\11\11\11\11\11\11\11"""\11\11\1133""\11"""\11"3""\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11""\11\11\11\11"\11""33"\11"\11\11\11"\11\11\11"""""3""3"""333DUwfU3DDD3DDDDD"333333"333333D3DDUD333DDDDD3DUwU"\11\11\11\11\11"D3"3D3""3"""\11"\11\11\11""\11""333fwfUDUwwªª\99\99D""""""""3"DwwwfwfUD33333""""33333333D""""""3"""\11\11\11\11"\11\11\11"\11\11""""""""3"\11\11\11\11\11""3""\11\11\11\11\11\11\11\11\11\11\11"\11"\11\11\11\11"\11\11\113""3DD\88\99w\99ªªf""\11\11"""""3U\88"\11\11"\11"\11""""\11\11\11\11\11\11""33"""333DUUf\88UD33""\11\11"""""""33wfUwUUfD333333""33"33""""""""""\11\11\11\11""\11\11\11\11"\11"\11""""3D3""""""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11"\11"\11""333"\11"\11\11\11\11"\11""""3"""3"""33"3DwfUD333D3DDDDDD3"33"3"""""33DD3UfU333333DD3DUDDUU3\11\11\11\11\11333""DDD"D3""""\11\11\11"""""""DwUD3DUf\88\88\99ª\883""\11""""""Uw\99\88fUDDDDD3333333333333333""""""333"\11\11\11\11\11\11\11\11""\11""""\11"3"""\11\11\11\11""""""\11\11\11\11\11\11\11\11\11\11\11\11"""""""\11\11\11""""3Dw\88\99\88ª\99w3D3\11"3"""33\88f\11\11\11\11"""""3\11\11\11\11\11\11"\11""""""DDUffUUwU3D3"""\11\11"\11\11""3""w\99\88\88\88wfUDDDDUDD3"""3""""""\11\11\11\11\11\11\11\11\11"\11\11\11\11\11"\11\11""3""3D""\11"""\11"\11\11\11\11\11\0\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11"\11"""3"\11\11"\11\11\11\11"\11"3"\11""""33"""""3UffDDD33D33DDDDUD3"3"""333""""333"wf3""""3333DUDDDDD3\11\11\11\11\11"33"33DDD33"""\11\11\11\11""\11"\11"3UfDD3UUfff\99\88D""\11"\11""\11"UU\99ªwUUU33DD3DDD3333""""""3"3"""\11""3"\11\11\11\11"\11\11"\11"\11\11""""\11"""""\11"\11\113"""""""\11\11\11\11\113\11\11\11""""""\11\11"\11\11""""3Dfwª\99fwD\11\11""""""33U\99"\11\11\11\11""""\11"3\11\11\11\11\11\11""""33DDUfwf\88wwUDDD""\11"\11\11""""""33f\99\99\99\99wwwwDUU3UDU333"\11"D\11\11\11\11\11\11\0\0\11\11\1133\11\11\11"\11"3""""""33"\11\11\11\11\11"""\11\11\11\11\11\11"\11""\11\11\11\11\11"\11\11\11\11\1133D"\11\11\11\11\11\11\11\11\11\11\11"\11\11"""333""""3UwU3"DD3DD3D33DDUD3333""""3"""""""33D"3""333333D3DDDDDUU3\11\11"3"DD3"33U3D""\11"\11\11"\11\11\11\11""3UDU33DUUU\88\99D3"""\11\11\11\113D"Dª\88\88\88fD333D3D33"3D""""""3"""\11"\11\11"33\11\11\11\11\11\11\11\11\11"\11\11""""""""""\11\11\11"""""""\11\11\11\11\11\11\11\11""\11\11""""\11\11\11\11\11"""""\11"Df\88w"""\11""D\11\11""""D\99wD\11\11\11""\11\11\11""33\11\11\11"\1133"3DDUUfwUDfwwfU3D"""""\11"""3333DUf\88ª\99\99\99\99\88\88\88UDwwfD"3""""\11\11"\11\11\0\11\11\11"3D"\11"""\11\11""""""""\11\11\11\11\11\11"\11\11\113\11\11\113""\11\11\11\11"""""""""3D"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""333333Uwf33"3DDD3DUD33UD33""3"33"3""3""""3333D333333333D33333DfDDD3"DDfU"""3UUD"""\11\11\11\11\11\11\11""3D333""3Uw\99wUD""\11\11\11"DUD"3UwfffUDDDDD33D33"""""""D3""\11\11\11""""\11"""\11\11\11\11\11"\11""\11\11""\11\11\113"\11\11\11"""""""3"\11\11\11\11\11\11\11\11\11\11\11\11""\11""""""""""333w\88""\11"U3"""\11""""f\99""\11\11\11""\11"Uf"\11"\11"""3\883"3"DfwU3\11UwwwfUDD33""""""DD33DUfDU\88\88ª\99ª\99\99wUwwD33""""\11\11\11""\11\11\11\0\0\11""\11\11\11\113"""3""""""\11\11\11\11\11""""""""\11"3"\11"\11\11\11"3""\11D3""\11\11\0\11\11""\11\11\11\11""\11\11""\113""""DDDfwU33"33DDD333UDDU3""3333333"""33"""""3D33333333333333"""3wUDDD3D3"""""DUDff3""\11\11\11\11"""3333""\11\113U\88\99wD3"""DUUUDDDDDDDDDD33"3"333"""""""333""\11"\11\11""\11"\113\11\11"\11""\11\11\11"\11\11\11\11\11\11\11"3""\11\11\11""""\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""333D33Dww"""\11D3""""""""DfD\0\11\11\11\11\11""Uf"\11\11"\11""3\88U"3"3UwU"\11"Uw\88\88fUUDDDD333"DD33D3DUUUU\88\88\99ª\88wwww3"33""""\11\11\11\11\11\11\11\11\11\11"3\11"""""""""""""\11\11\11\11""""3""""""""""\11\11\11\11"\11\11""D"\11\11"\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11"D3333DUfwU"33""3DD3333DDDD3D3"""333""""3"3""""3DD3333"3333333"""""3UD"3UD""""""33DUwwD3""3"""333"""""\11\113D\88»w333DUUUD333333333"""3""333"""""""""""3"\11\11\11\11\11\11\11\11\11"\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""""3""\11\11\11\11\11\11\11"\11\11\11\11\11\11""\11"\11\11""""3D3"33DDfU"\11"""""""""""333fD\0"\11"""""""\11\11\11\11""U\99D"333ffD3"""Ufw\88\88wfUUDUUDDDDD3DDUDDUUUf\88\99\88\88fffUUD3"""""\11\11\11\11\11\11\11\11\11\11\11\11"33""3""\11""""""""3"\113"\11""""\11"3"""""\11\11""333\11\11\11""\11"\11"\11\11"\11\11\11\11\11\11\11\11\11\11"33DwwUD"33D333DDD33DDDD3""""""3333""33"3"""""33"3""3"3333"3""""\11"\11\11"""333"""""3DDf\99U3"""""""33""""\11\11""3U\88ªfDDDD3D3"""""3""""""""""3"""""""""3"""""\11\11\11"\11\11\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""""D3"\11\11\11\11\11\11"\11"\11\11\11\11\11\11\11\11\11\11""""\11"33333DU\993\11\11"\11\11\11\11""""""""D3wf\0\11\11"""""\11\11\11\11\11""U\99D33""fw3U3\11\11""DDUUw\88fU3UUDDDD33DUfUDfDf\88\88wffwfwUD3""""\11\11\11\11\11\0\11\11\11\0\11\11\11"""""""""\11\11"3"\11"""""3"3U3\11""\11"""3""\11\11\113D3""\11\11\11\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11"3UwwD"333"33D33D3D3DUD33"""3333333""D"3"""""""""3"333"33"""""""""""""333"""""333DfUUD3"""33333"""""""3DUwwUD"33DD33""""33333333""""""3"""\11"\11\11"""""""\11\11\11\11""UU\11\11\11\11\11\11"\11\11\11\11\11\11\11\11"33""""\11\11"\11\11\11\11\11"\11""\11\11\11\11\11\11\11\11""""""\11""3333U\88D"""\11\11\11""\11\11"""""3"Uw\883\11\11\11\11\11\11""\11\11\11""UªUDU3"DfD"\11""""""\11"3DUfffDDUfUUDDUUf"UffwwwwwwwfD3"3"\11\11\11\11\11\11\11\0\11\11\11\0\11\11""\11"3"""""""""3D"""3""3D3U\11"3""3333"""3U3"\11"\11"\11\11"\11\11\11""""\11\11\11\11\11\11\11\11\11""DfwU333333333333D3DDD""""3"""33""3""DD"""33""33""33"""33"""""""""""3""333""""33"3DfUD33"3DD"""""333""33DfwwDDD33D33333333UUDUUU333"3333""\11\11\11\11"""3"""""\11\11""Dwf""\11\11\11\11\11\11"\11\11"""333"""\11\11""\11"\11\11\11\11\113DD"\11"\11\11""3\11\11"""\11""""DDD\88U333\11\11\11\11\11\11\11"""""333U\99\993\11\11\11\11\11\11\11\11\11\11\11"fªwUU33DfU"\11"""\11\11"""3""3fwwwDUUUDDUffffUfwwfwfUUDD3""\11\11"""\11\11\11\0\11\11\11\0\0""\11\11"3"\11\11"""\11"""3"""3DDUUDDD""3""3"3""3DD"\11\11\11""\11"""""\11\11\11\11""\11\11\11\11\11"""Dww3333333333333333DUD""""33""""""33""D3""""""333"33"33"""3"""\11"""\11""""""""""""3333DU3"UDDU333""33333D33DDUfffUf"3DDDDDDDDDUffUwUUDDDU3D3"""""""333"""""""""DD"""\11""\11\11""""33""3\11"\11\11\11\11""\11\11\11\11""\11\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"3DUfU3D3"\11\11\11\11\11""""\11""33U\99ªf\0\11\11\11\11\11"\11\11\11\11\11w\88wwfDfDfU"\11\11\11"""\11""""""\11DUUfDUUDUUfwff\88fwfDD3DDDD3""\11\11"""\11\0\11\11\11\11\11\0\11\11""""3""\11"""""\11""3\113DDD33DD33""3\11""""3D33""\11""""\11"\11"\11\11\11\11\11\11"""\11\11"""3UwU3333"3333333333DDDD"""""""""""33333""""""""""3"\113"33"33""""""""""""33"3"""""33D33DUfUw\88\88DD3"""3333DDDD3DDUUfUUDDUUUDUUfDUUfwwUUfDUUDD"D3""D3333""3""3"""""""""""""3"\11\11\11\11"\11\11\113"\113"\11""\11\11\11\11\11""\11"""""\11\11\11\11\11\11\11\11\11\11\11\11""33DUf333""""\11\11\11\11\11\11\11\11"3"3U\99w\11"\11\11\11\11\11\11\11\11\11"wfDwwwf3Df""\11\11\11"""\11"""""\11\11"3ffUUUUff\88wwUDwU33"3DDD3""""3"\11\11\11\11\11\11\11\11\11\11\11""""3""""33"""333""33"""""DUD""D""""3D"\11\11"""\11""\11""\11""\11\11\11\11\11\11\11"""""Dff\1133""3"333333333DDUD""""33""""333""""""""""3""""""3"""3""""""\11\11\11"""33333""""D33333DDDUUfwU""3333DD3333"33DD3DUUUUUfffwwfwDfUwwfU3"3fffDUUD3DDD3U333"333"33"\11"""""\11\11"\11\11\11\11\11\11""\11"\11\11"""""\11"\11\11"""""""""\11\11\11""\11\11""\11\11\11"""33UfU"""""3\11"\11\11\11\11"""""33\88\99"\11"\11\11\11\11\11\11\11\113fD"DDUw\88UUU"\11""\11""""3"""\11"\11"UUffDUDUwfffUUD"D333D33""""""\11\11\11\11\11\11\11\11\11\11\11""3"D3"""""3""3"\113"3"\11""\11\11333U3"D""3D3\11\11""""""""""\11\11\11\11\11\11\11\11\11"\11"""3UU3"""""3"33333"""3DDD3"3""""3""""""""""3"""3""""3333""""""""\11""\11\11\11\11\11"333D33"3DDD33"""33DDDDU3"3DD33333"""33DUUD3DfffUUf\88\88UUw3DUffD\11\11\11UwwfUUUfUUDDDfUDDDD33DU3\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11"""3""""\113""3"""\11"""\11\11\11\11\11\11""""""""33DUw"""""""\11"\11\11\11\11"\11""""3\88f\11\11\11\11\11\11\11\11\11\113\99D3DD""3Uff""""\11\11\11"\11\11\11""""""3DffUfwfffUffDD"33"3D33"""""\11\11\0\11\0\11\11\11\11\11\11\11""""333\11""""""""""3""\11\11"\11\11"""\11"D3D"3D"\11\11\11""\11\11\11\11""\11\11\11\11\11\11\11\11\11"\11\11"""fU3\11"3"""""""33"3"3"3DD3\11""""3"\11"""""""""""""""""33333""""""3""""\11\11\11\11""""DDD33D333""""3U"""""3D""3D33333""\11\11"3DUUD3DUfwfUwwfU3UDDUffD\11""wwwUUUfwwDDD3DUDDDDDDD""\11\11\11\11\11\11\11\11\11\11\11\11\11""""3\11\11""D"""""""""""""""""""\11\11\11"3"\11"""3"3Ufw"""""""\11\11"\11\11\11"""""3DD\88D""\11\11\11\11\11\11\113\88DUfD"\11\113\99\883"3""D\11\11"\11"""\11\11"\11\11\113fwUUwUUU3UU3""D"3333""\11\11\11\11\0\11\11\11\11\11\11\11"\11""""""D3""333""\11\11"3"3"\11\11""\11\11"D""""33D3\11""\11"\11"""\11\11""\11\11\11\11\11"\11"\11""""3fD"\11"""""""""3""33333U3\11"""\11"3""""""""""""""""""3D3""3"3""\11\11\11\11""""\11"\11\11\11\11\11"""3DDDD3""3D3DD"\11\11"""3"33"33"3""""""3DDD3"DUUfwwwUDD"3DDUfU""""3Uffww\88\88\88fDDUUDDUDUD"\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""D""""3""3""""""""""""""""\11\11\11""\11\11\11"""""DU\88D"""3"""\11\11\11\11\11\11\11"\11\11"3UD\99""\11\11\11\11\11\11\0DwD3D3\11"\03wwD333"3\11\11\11""""\11\11\11"\11\11\11DffUUU"3D3""""33"33""""\11\11\0\0\11\11\11\11\11""\11\11""""\11"DfD33D3"""""3""""\11\11"3"\11"fD3DDUD"3"""\11\11"33""\11"\11\11""""\11\11""""3UU\11\11""\11\11"""\11"""3"33333U3\11"\11\11""3"""""""""""""333333D3333D33""\11\11""\11\11\11\11"\11\11\11\11\11"""""3DDD333D33""\11\11"""""""""33\113""\11\11"""33DDDUfw\88ªfD3"""\11\11""33"\11\11\11"\11"ww\88\99ª\99wDDUUUUUfD"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""3""""3"""""""""\11""""3""\11\11\11\11\11\11\11\11""""3""3D\88D""""UU"\11""\11\11\11\11\11\11\11""DUUf\11\11\11\11\11\11\11"f\8833U3""\11"U33""3D""\11""\11\11\11\11\11\11\11\11\11"DwfffD""""""""33"""3"\11\11\11\11\11\11\11\11\11\11\11"""""""""3UUw3"""3"3"""""""\11\11"3"\11"Dfw\88D"\11\11\11""\11\11\11\11\11"33\11\11\11\11\11\11"""""""3Dw"\11\11"\11\11\11""""3U""""3333U3\11\11\11""\11""""""""""3D333333"3""333333""\11\11"""""\11\11"\11\0\11\11\11"\11"""""DfDD333"3\11\11"""""""""3"\11""""\11"""3DD3DUUU\88wU""""\11\11\11\11\11\11""\11\11"\11"""f\88\88ª\99\88ffwfUUfD"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""3"3D3333""3"""""3"D3"""\11\11"\11\11\11\11\113"\11"""3"U\88f""\11"\11\11"\11\11\11\11"\11\11"\11\11""33ff""\11\11\11\11\113\99ª3"D"\11\11""U3"""""D"\11\11\11\11\11\11\11\11\11\11\11""UwUUwU"\11\11\11"3""33\11""3"\11\11\11\11\11"\11\11\11\11\11\113""\11""""\11"3UD\113DD3""""\11\11\113"\11"""3UwffD\11\11\11\11\11\11\11\11\11""\11""""\11\11\11\11""\11"""""3Uf\11\11\11"\11\11\11""""3"\11""""33DD3""""""""""\11"\11"""3"""33""""3"3333""3"""""\11\11"\11\11\11""""\11"\11\11"""""3333333"\11\11\11\11333"D3""""\11\11""""""3DD3UfUDfw"DD"""\11"DDDD""\11\11"""3DUUw\88fwffwwf"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""""33D3D33D3"333""33""D""""\11"\11\11\11\11\11\11\11"\11""""DwD"""\11\11"\11\11\11\11\11\11\11\11\11\11\11\11""DUff\11"\11\11\11\11fªwDDD\11"""\11DD""\11\11\11"""\113"\11\11\11"\11\11\11"\113fwwwU\11\11\11\11\11\11"""3\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11""""""""""33D3DU33""\11\11\11"33"""3DDUD"\0\0\0\11\11\11\11\11\11\11""\11"\11\11\11\11"\11\11\11\11\11\11""""3DUD\11\11\11\11\11\11"""""""""""33DU3"""\11\11""3"3""\11\11""3""""""3""\11"3333""3"\11""""\11\11\11\11\11\11""""\11\11"\11""33"""""D3"\11\11"\11\11"DDDUU3""\11"\11\11"""""DDDUfwfwfwU"D""""D\88f3DU3\11"\11\11""D33f\88wU3"\11"3"\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11"""3DU3DD33"3D3333333""33"3"""\11\11\11"\11\11\11""""3DU3\113""\11"\11\11\11\11\11\11\11\11\11\11\11"""3UU\88DUD33DwªU3D3\11"""""3"""\11"\11"\11"3""\11\11\11"\11""\11\11Uwwwf""\11\11\11\11\11"\11\11\11\11\11""\11\113\0\11\11\11\11\11\11\0\11\11\11""""""""""D3"D""3""""\11""""DDD""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11"3DfD"\11\11\11""\11"3""\11"""3""""DU"\11""\11\11\11""D""""""3"""\11"""3""""D3333"D""""""\11\11\11\11\11\11"""""\11\11\11\11""""3"\11"3"""\11\11\11"\113UUDD"""\11\11\11\11\11\11"3Dw\88\88\99\99\99wUwwwD"D3"3UfDD"\113D"\11"3"\11\11"fwwf3"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11""""DD333"3D333""""3"3333333""""\11\11\11\11\11\11""""3ff""\11"""\11\11\11\11\11\11"\11\11\11"\11""""3w\88U33UU\99\99DD3\11\11\11""""""3"""\11\11\11""\11\11""""""""\113ww\88U\11DU"\11\11"\11"\11\11\11\11\11\11"\11"\11\11\11\11\11\11\11\11\11\11\11""""\11"""""33\11"3""""\11""""33D"\11\11\11\11""\11""""\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11"""3DUD\11\11\11\11\11"\11"33"\11\11\11"""3"3"3D\11"""\11\11"""3D"""""3"""""""D""""3""33333"""\11\11\11\11\11\11\11\11\11"\11\11"\11\11\11"\11"""""\11""3"""\11\11"""DUU33D""\11\11""""3UªwU"UffUUwww""3UUU3"""""3U\11""""""DwfUD""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11""""DDD33"3333"""333333333"""""\11\11\11\11\11\11"\11"""DUUU"""\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11""33ªDDffU\88\99D33\11\11""\11""""""\11"""\11"\11\11\11\11"""33""\11"Uww3"w\88U\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""""""""""\11"3"3"""333D3\11\0\11\11\11\11""""\11"\11"\11"\11\11\0\0\11\11\11\11\11\11\11\11"\11""33DUU\11\0\11\11\11"\11\1133"""""""""33333"\11\11\11\11\11\11""""D33\11"3"""3""\11"\11""""3""333"3""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""3"\11\11\11""""""\11\11\11\11"""3Uf3D"\11\11\11""33Dw\88w3"DUDDUf\99f""U\88f"\11\11\11"\11\11UD"3""""3UfUD3""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""333DD3""3D3""3333"33"333"""3""\11\11\11\11\11""\11"3UU3D3\11\11"\11\11\11\11\11\11\11\11"\11\11\0\11\11"DDUffU3DDDf»D3""\11\11\11\11""""""\11"\11""""\11\11\11""3333""\113U33\11D\99w"\11\11\11\11"\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\113"33""""""3""\11"""""33DUD\11\0\0\11\11\11\11\11\11""\11""""""\11\11\11\0\11\0\0\11\11\11\11\11"\11"3Uf3"\11\11\11\11\11\11\113333"""\11""""""3DD"\11""""\11""""333""3"""""""3"\11""\1133""33""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11"\11\11\11\11\11"""""""\11\11""""DD\11"\11\11\11""33Dfw3"33DwDUUUU3"3\88w"\11"\11""""U3""\11\11"3UfUD""""""\11\11\11\11\11\11\11\11\11\11\11\11\11"\11""""3333""D33"33""33"""3"33""3"3"3"\11\11"\11\11"""""DD3333\11\11\11\11\11\11\11\11\0\11\11\11"33"DUDDD\883"333DªU"\11\11\11\11""\11"\113""""""""\11\11"""3DD""""""D33"3\88\883\11"\11\11\11\11\11""\11\11\0\0\11\11""\11\11\11\11\11\11""33D3"""""""3"\11""33DDDD"\11\0\11\11\11\11\11\11\11\11"""""""""\11\11\11\0\0\0\11\11\11\11\11\11\11"3UfD\11\11\11\11\11\11\11\11"33\11"""""""""""3D3"""\11\11\11\11\11""3333\11""""""\11"33"\11""""""3"""""""""33\11\11\11\11\11\11\11\11\11\11"""\11\11\11"\11\11\11\11\11\11\11\11"33"""""""\11"\11""""""DUf\88f""3""DD3""\11"DfwD""\11\11\11""33"\11\11\11""UwU33""\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11"3"3"""3DDD"""""3333333"3"""3333"""\11\11\11\11\11""""3Uf""333"\11\11\11\11\11\11\11\11""3UfUD3"33ww""3"3\99U\11\11\11\11\11\11\11\11"\11"""""""""""""""DfU3"3""3"\113w\88\88D"""\11\11\11\11\11\11\11\11\11\0\0\11\0\11\11\11\11\11\11\11\11""3D3\11""""""3""3"3DDUU3"\11\0\0\11\11\0\11\11\11\11"""33""""""\11\11\0\0\0\11\11\11\11\11"DfD3\11\11\11\11\11\11\11\11"33"\11""\11"\11"""""33D"\11\11""\11""\11""33"""""""""""""""""""3""""""3"""\11""\11\11\0\11"\11\11\11\11\11\11\11\11\11\11\11\03\11\11\11\11\11\11\11\11""D""""D"""""""\11\11"DUww\883"""3"""\11\11""f\99U3""""\11""""\11\11\11\11\11"Dw\883""\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11""""33"3DUfD3""33"3333333"""3"3""""\11\11\11\11\11\11"\11\11""UU3"""""3\11\11"\11\11"3DDDDDD33""3w\99""3"3\88U\0\11\11\11\11\11\11""\11"""""""""""""3"DUUU3""""""UUfU"\11""\113"\11\11\11\11\11\11\0\0\11\11"\11\11\11\11\11\11\11\11"3UD"""""3"3D"333DUU3\11"\11\11\11\0\0\11\0\11\11"""3DD33"""""\11\11\11\11\11\11\11\11\11"3fU\11\11\11\11\11\11\11\11\11D3\11"\11"\11\11\11\11"\11"""""D3\11\11\11"\11"""\11\11""""""""""""3""\11"""""3""""3"3"""\11\11\11\11\11\113D"\11\11\11\11\11\11\0\11\11\11\11\11""\11\11\11\11\11\11\11"3333"D\11"\11\11""\11\11"3DUDf\99w""""333""\11"3D333"""\11""3"\11\11\11\11\11"Df\88U""\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11"""""3333DDDD3"3"3"3D33333""33D33"3""\11\11"""\11\11\11""Df33"\11\11\113wwDU3D33D33D""""333\993"33Dff\0\11\11""\11\11"""\11"D""33"""""""3DD""""""3Ufw\88f\11\11""""Df"\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11"3UwU"3"""""3"3"Dff3\11\11\11\0\11\0\0\0\11\0\11\11"""333"333""3"""\11\11\11\0\0\11\113f"\11\11\11"\11\11"\11"D"\11"\11"\11\11\11\11\11"""3"33\11\11\11\11""""\11\11""""""""""""3"""""\11""""""3"3"""""""\11\11\11"3fD\11\11\11\11\11\11\11\11\11\11"\11\11""\11\0\11\11\11\11\11"33D33"""\11""\11"3"3DDwwwD"""\11""3""""""33"""""\11"3"\11\11\11""33wU""\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"""33DD33DD""33""33333333"3"""33333"""\11"\11\11\11""DU3"\11\11""\11"33"D33D333""3"""33Df"3DDUf\0\11D\11""\11\11\11\11\11\11"""\11"""\11"""3"33"3""33UfwfDU\11""""""fD\11\0\11\11\11\11\11\11\11\11\11""""""\11""DUD3U3"3Uwf\88UUwwU3"\11\11\0\11\0\11\11\11\0\11\11\11""3333"33DD33"\11\11\11\0\11\0\11\113D\11\11\11\11\11\11\11"333"\11\11\11\11\11\11\11\11"""333UUD""\11\11"""\11\11""""""""""\11"""\11""""\11""""""3"3""33""""\11\11"3D3\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"3D333"""""33""333U\88U3\11\11"\11""\11"""""\11"3""3"""\1133"\11\11\11\11""UU3"\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11"\11"33""DDDDDD3"""""3""3DD33"3""3D3333"""\11""\11\11\11"DU"\11\11\11\11""""3"""33D33"""""\113D3Df33DDU\11\0"3"\11\11\11\11\11\11"""\11"\11"D3"""33333"""33U33D"\11\113"\11\11\11"3D\0\11\0\11\11\11\11\0\11\11"\1133""""""DDDDUfDUfw\88\99\88wDDDD3\11\0\11\11\11\11\0\11\0\0\0\11\11\11""""33"3UU3"\11\11\11\0\0\0\11\1133\11\11\11\11\11"\113D3"\11\11\11\11\11\11\11\11\11\11"""33DD""\11\11\11"""""""""""""\11\11"\11""\11""""""""\11\11"3"33""3""""""""3""\11\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"3D3"33""""3""333DwwD""\11\11""\11\11""""\11"3333"""""""\11\11"\11\11"3U3""\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""33""D3"333D""""""""333"""3"D3DD333"""\11"""\11""33\11"""""""""""3333""""\11\11""333"Uª"33D\0\11\11D\11\11\11\11\11\11\11""""""33DD33"33"""3"3""""""""""\11\11""\11\11\11\11\11\11\11"\11\11\11\11\11""33""""3D333DUUDfw\99\88Dff""33"\11\11\11\11\11\11\11\11\11\11\11\11\11\11"333333D3""\11\11\11\0\11\11\11"D"\11\11\11\11""DU3"\11"\11"\11\11\11\11\11\11""""33D33""\11\11""""""""""""\11""""""""""""""\113"3"3""""3"""""""\11"33"""""\11\11\11\11\11\11\11""\11\11\11\11\11\11\11""3DD3"3""333""333DU\88U3\11"\11\11\11\11\11\11\11\11"\11\11"3U33""""\11\11"""\11\11"3UD3""\11\11\11\11\11\11\11\11\11\11\11\11\11""""333333333"3DD""""""""D333DDD3DDDD33""""""""33D"\11"""\11"\11""""""D3"3""\11"""""DD33»\88"3D\11\11\1133\11\11\11\11\11\11"3"""33DDD3"333"""""""""""""\11\11""""""\11\11\11\11\11\11\11""\11\11\11""3D3""""333DDUfffwf3"DD33333\11\0\11\11\11\11"\11\11\11\11\0\11\11\11"3""33333D3""\11"""3D"\0\11\11"DDD3""""\11\11\11\11\11\11\11\11"""3"33D3"\11\11"3""""""""""""""""\11"""\113"""3"3"\1133"""""""\11\11\11\11\11\11\11""3""3""\11\11\11\11\11\11\11"""\11\11\11\11\11""33DD33"""33"""3DDUwf3"\11\11\11\11\11\11\11"""\11\11\11"3D"33""\11\11"""\11\11\11\11UU3""\11\11\11\11\11\11"\11\11\11""""""""""33D33333DD""""""33333DDDDD333""""""""""\11"3D"\11\11"\11""""""\11\11"""""""3D""""3""3\88ªDDf\11\11\0\11"\11\11""\11"\11"""""3"DD3""3"""""""""333"""\11""33\11\11\11\11\11\11\11\11\11\11""\11"""""""""""3DDDDUUwf3"""""33""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11333333""""""""333D\11\11"D33""""""\11\11\11\11"\11\11\11\11\11""333DDD3\11\11\11""""""33""""\11"\11\11""\11\11\11\11"3"\1133"""""""3"""\11\11\11\11\11\11\11"\11\11"3\11\11\11"""""\11\11\11\11\11\11\11\0\11\11"\11\11"33UD3""3333""3DDUf\88f"\11\11\11\11\11\11\11\11"\11\11\11\11\11"3D33"\11\11\11""\11\11\11\11"DDD""\11\11\11\11\11\11"\11\11\11\11\11""""D333"33DD33""DD"""""333DDD3D3DD33""""3"3"""""3D\11\11\11"\11""\11\11\11\11\11"\11""\11"\11""3U"""D33"w\99\883w"\0\11\11\11\11\11"""""""""\11""3""""""""""""333""3"\11\11\11"\11\11\11\11\11\11\11\11\11\11\113"3"\11\11""""3"D""3DD3DDUff""""\11"""3\11\11\11\11\0\11\11\11\11\11\11\11\11\0\11\11""333"""""""""""3DD"DD3"\11\11"33""\11\11\11"\11\11"\11\11\11"\11""33DDD"\11"""\11"\11"3"""""""""D""""\11""""33"""""\11""""\11"\11\11\11\11\11\11\11"\11\11"\11\11\11""\11\11""\11\11\11\11\11\11\11\11\11\11"\11"D3DDD333333333DDfwwf3""\11\11\11\11\11\11\11\11\11\11\11\11\11"DD3"""\11\11\11\11\11\11"\113UD"""\11\11\11\11""\11\11"""""""""3""""""""\11"333""""3"3DUUDD3DDDDD3""3"""33333D"\11\11\11\11"\11\11\11\11\11\11"""""\11\11"\11\1133"3D3U\88fwffU\11\11\11\11\11\11\11\11"\11"\11\11\11"3\11""333"""""""""""3"""33"\11\11\11\11\11"\11\0\11"\11\11""""3D"\11\11"333"DD33UD3DUfU3\11"""""3"""\11\11\11"""\11\11\11\11\11\11\11\11\11""\11"""""""""""""3DffDD\11\11""""""\11"\11""\11\11\11\11\11\11\11\11"33"DDDD\11\11"""\11""\11\11""""\11\11\11""3"""""3"""""""3""""\11\11\11\11""\11\11\11\11\11"\11"\11"\11\11\11""\11"\11\11\11\11\11\11\0\11\11\11\11\11\11""DDD33333"333DDDDw\99f""""\11\11\11\11\11\11\11\11\11\11\11\11\1133D""\11\11\11\11\11\11\11"""3D""\11\11\11\11\11""\11\11\11\11""""""3"""""\11"""\11\11"""3""""""DUD3""3D33D333"33""3333D"\11"\11\11\11\11\11\11"""\11\11"\11\11"\11"""D"3DDUf\88\88"D\88f\0\11""\11\11\11\11"\113""""33"3"""""3"33""""""""""""\11\11\11\11\11\11\11\11\11"""""""3U"\11"""333"D3DU33DUfD"\11"\11"""""\11"\11""\11""\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11"\11"""3Dw\88D"3"""""3""""\11"""\11\11\11\11\113"333DDDD\11\11""\11"\11""\11""""\11\11\11""\11"""""""""""\11""33""""\11\11\11"\11"\11\11\11\11\11"33"\11\11\11""""\11\11\11"\11\11\11\11\11\11""""DDD3333333"3DDDDf\993\11"\11\11\11\11\11\11\11\11\0\0\11\11\11\11\11"33D"\11\11\11\11\11\11\11""""D""\11\11\11\11DD"\11\11\11"""""""""""""\11\11\11\11\11\11\11""""3""""DU3"""3333333""3333D3DD""\11\11\11\11\11\11\11\11\11\11\11\11"\11"""""3"DD3UDDf\88fDDww33""\11\11\11\11\11\11\0\11"3""333""""""""\11"""\11"""""""\11"\11\11\11\11\11\11\11\11\11\11""""33DD\11"33"3""3"UUD3Dff333"\11"""""3"\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11"3"\11\11\11"\11\11"""DD\88\883"""""""3"""""3"""""\11"\1133"33DDU3\11""\11\11\11""\11""\11"""\11"\11"""3"""""3\11\11\11"33"3"""\11\11\11"\11"\11\11\11\11\11\11\11\11"""\11""\11"\11\11\11\11\11\0\11\11\11"\11"""33DDD333""333DDDD\88f\11""\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11"333"\11\11\11\11\11\11\11"""33""\11\11\11\1133"\11\11\11"""""""""""""\11\11\11\11\11\11\11"""""3333"3""33""3333D333D3"333"""\11"\11\11"\11\11\11\11\11\11\11\11\11\11""""3fDDDDUUw\88fw\99\88"DD""\11"33"3333"3333"\11""\11"""""""""""""\11\11\11\11\11\11\11"\11\11\11\11\11""""""3"DUDD"333DfD""DUwfD33""""\11"""3"""\11\11\11\11\11""\11\11\11\11\11\11\11\11"""3\11\11\11\11"\11\11\11""3f\88\883"""""""""""""\11"\11\11"\11\11\11""""3DDDDD""\11\11\11"""""""\11""\11""""""""\11"3""""3"""""""\11"\11\11\11\11\11\11\11\11\11\11\11"\11""""\1133\11\11\11\11\11\0\11\11\11\11\11\11"""3DDD33""""333DUUff3""""\11\11\11\11\11\11\11\11\0\11\11\11\11\11"3D"\11\11\11\11\11\11\11\11\11\11"3""\11\11\11\11"\11\11\11\11\11""""""""""""""\11"""""""""3D33""""""""333333333DD"33""\11"\11\11\11\11\11\11\11\11\11"\11\11\11\11\11""""D\99U3DDUfwf\99\88ªf333"""""3"""3DD"D3""""D3"""""""\11""""""\11\11\11\11\11\11\11\11\11\11\11\11\11"\113""""DfUU3""3D3f33fwUD"""""\11\11\113"\113""\11\11\11\11\11\0"3"\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"\11\11""Dw\88\99UD""""\11"3""""""\11\11\11\11\11\11"D3"3"333U3""\11\11\11"""\11""""\11"\11""\11""\11""\11\11"3"""""""3"""""\11\11\11\11\11\11\11\11\11\11\11\11\11\113""D"\11\11\11\11\11\11\11\11\11\11"\11"""3U3DDD3""""33DDUUffU3""""""\11""\11\11\11\11\11\11\11\11\11"3D"\11\11\11\11\11\11\11"\11"D"\11\11\11\11\11\11\11\11\11\11\11\11"""""""""""""""""""""""""33"3""33333"333D3333D"3333"\11\11\11\11\11\11\11\11\11\11""\11\11\11""333fªU33DDf\99fw\99\99D33"""\11"""33"""33D"""\11"3D"""""""""""""\11\11\11\11\11\0\11\11\11\11\11\11\11\11"""3""D3fUwU333UDDDDw\99f3""3"""\11\11"\11"D"3"\11\11\11\11\11\11U""\11\11\11\0\11\11\11\11\11\11"\11\11\11\11""\11\11"DwUwU""\11\11\11\11""""""""\11\11\11"D"\11""""3""3DDUf"""\11\11\11""\11""""\11\11"\11""""""\11"3""""""""3"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0""3\11\11\11\11\11\11\11\11\11\11\11\11\11""333D33DD3""""33DDUUffUD"\11"3"""\11""\11\11\11"\11\11\0\11\11""""\11\11\11\11\11\11\11"""D"\11\11\11\11\11\11\11\11\11\11\11\11""""""3""3""""""\11\11"\11"""""33"""""333"333D33DD3DD3"3"\11\11\11\11\11\11\11\11\11\11"\11\11"""3""3f»wUUUUf\99UU\99\88U333"\11\11"""""333DDD""3"""""\11"\11"\11\11"\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3D"""""f\88fUUDfD"DU\88\99wUDD3"""\11D3"3D3"D\11\11\11\11\11\11\1133"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\113DUD3ff3"""\11\11\11""""\11""\11"\11\11\11"\11\11\11\11"3""3UDUD3"\11"\11\11"\11\11\11\11""\11\11\11"""""\11\11""""\11"""""""""""\11"""\11\11""\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11""3""""3D33""""33DDfffff"""33""\11\11"\11\11\11"3\11\11\11\11\11"3UU3\11\11\11\11\11"\11\11D3\11\11\11\11\11\11\11""\11"\11\11""3333333"""""3"""\11\1133"333"""3""333"D3D333D3333"""\11\11\11"\11\11\11\11\11\11""\11\11"\113"""\88ÌfDUff\88wff\99wD33"\11\11""""""""DDUD3"DD3""""\11"""\11\11"""\11\11\11\11\11\11\11\11\11"\11\11"\11\11\11"""3D""""UfUU33UDUfª\88wU3DDD3""\11\11D3"3D3DU"""\11\11\11\11"""\11\11\11\11\11\11\0\11\11\11\11\11\11""\11Uf3""DwUD""\11\11\11\11\11""""3""\11\11\11\11\11\11\11\11"\11\11""3DDUU\11\11\11\11\11\11\11\11\11\11\11\11\11"""""""\11\11\11""""""""""""""\11\11\11""""""\11\11\11\11\11\11\11\11\11""\11"""\11"""\11""""3"3D3333DD3"""3333U\88ww\883""333""""\11"""\11\11\11\11"\11\11"33\88f"\11\11""\11\113D"\11\11\11\11\11\11\11\11\11"\11"\113D3"3333""""""""\11\11""3""3"333""3""333333333""""33""\11\11"\11\11\11\11\11"""\11\11\11\11\11\11"U\99ªUUUUUw\99Uwª\883D3"\11""""""""D3DwU"3""""""\11"""""""\11\11\11\11\11\11\1133\11\11\11\11\11"""\11\11""3DD"""3UD"""fffwfUUfwD3333""""3D333DU3"\11\11\11\11\11"\11\11\11\11\0\0\11\11\11\11\11\11\11"\11\11"3U3\11""3DfwU""\11\11\11\11"\11"""""\11\11\11\11\11\11\11""""""3"DfwD\11\11\11\11\11\11\11\11\11"\11\11\11""""""\11\11"""""""""""""3""""\11\11""""\11\11\11\0\11\11\11\11\11""\11""""""\11""""""3"""""33D33"333DDffUwwU3""3D""""\11\11"3""\11\11""\11\11\11"Dfw"\11\11\11\11"3U""\11\11\11\0\11\11\11\11"\11\11""333D3D3"""""33"\11\11"""3""""3""333""333""3333"33D33"\11"\11\11""\11\11\11"""\11\11\11\11\113\99»\88DDUUUfwU\99\99f"33"""3"3D33"3DUf\99wD"""""""""\11""""\11\11\11\11\11\11\11""\11\11\11"\11\11""""""3DU""3333"333fwfUfDDUUD333""3"333DDDD"\11"\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11""DfU"\11\11\11""3wf3""\11\11\11\11"""""\11\11\11\11\11\11\11\11\11\11"""UfwfUf\88D"\11\11\11\11\11\11\11\11"""\11\11"""\11"""""""\11\11"""\11\11"""""""\113D3"\11\11\11\11\11\11\11\11\11""\11\11\11""\11\11\11\11\11"\11"\11"""""""DDD33DDUDUfU3DwD"""333"""""\11\11\11\11"\11\11\11"\11\11\11"3U3\11\11\11\11""fU"\11\11\11\11\11\11"\11""\11""333"33"""""DUU3"""""3"""""""3D3""333""333333"3"3"\11\11\11\11""\11\11\11"""\11\11\11\11\11\99fDDDUfUff»\88""3D3"""""3D333DUf\99f\88\88f"3"""\11\11\11\11""\11\11\11\11\11\11\11\11""\11\11\11""""""""""""""DD3""3Uf\88fUUUUUUUDD3333"\11"3""3D33""""\11\11"\11\11\0\11\0\11\11\11\11\11"\11"\11"3fw3\11\11\11\11\11"3Uw"""\11\11\11\11\11""""\11"\11\11\11\11\11\11\11\11"""UwffwwwwD\11\11\11\11\11\11\11"\11\11\11\11\11\11""\11"""""""\11""\11\11""\11"""3""""""\11\11\11\11\11\11\11\0\11\11\11"\11"""\11\11"\11\11\11\11""\11"""""""3DD3DDUfUfwf33fw\113""""""3""\11\11\11\11\11"\11"""\11\11\11\11"""\11\11""""U"\11\11\11\11\11\11\11\11"""333"""""33""""DD33D"3333""""3""""""""3333"3333""3D3\11"\11\11"\11\11\11\11\11\11\11\11\11"\11\113ªwUDDUUUfw\88»f"""3""""\11\11"DD33DUUw\99f\99ª»\99U3\11"""""\11"\11\11\11\11"\11"3""\11""\11\11""\11""""""333""3fwª\88wwfwU3DDDUD3""D33U\99\99wf""D3"33\11\11"\11\11\11\11\11\11\11\11\11\11"""""U\99\883\11\11\11\11\11""3fD""\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\113"f\88wfw\88wfD"\11\11"\11\11\11\11\11\11\11"\11\11"""""\11"""""\11\11\11\11""\11""33""\11"""\11\11\11"\11\0\11\11\11\11\11"\11"""\11\11"""""\11"""""""""33DUUUDfUUfffDUw3"""""333""\11\11\11\11\11"3\11\11\11\11\11\11\11\11\11""""""33D\11\11\11\11\11\11\11\11""3"33""""""""333""""3D33"33"""3"""""""3333"""3""333D"""""""\11\11\11\11\11\11\11\11\11\11\03\99wDDDUUUfwª\88D\11"3""\11""""""DDDUf\88fªª\99̪\99\99»\9933""\11\0\11"\11\11"\11\0\0\11\11""""""""""""D""3""DfwfUfw33fUD3"DDU3Dw\88ªª\99\99wUfD\0"UU3\113"\11\11\11""\11\11\11\11\11\11"""""U\88fD"\11\11\11\11\11\11\11"Df"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""3U\88ff\88\99ww3\11\11\11\11\11\11\11\11"\11\11\11\11\11\11""\11\11\11\11"3""\11\11\11\11\11"\11"""""""\11""\11\11\11"\11\0\11\11\11\11\11\11""""\11"\11\11""""""3""""""3"DUUfUUwUDDfwwwU\11"""""33""\11"\11\11\11\11\11"\11\0"""\11\11\11""""\11"33U3\11\11\11\11\11\11\11\11""""3"\11"""""3"33""333333333"""""""\11"3D3"""3"3333D3\11""\11"3"""\11\11\11\11\11\11\11\11\11\11\11w\99UDDDUDf\99ª\993\11\11\11""\11\11\11\11\11\11"\113DDUfw\88\88ª\88ÝÌ»»\99ªª\993"\11D\88ÝÌ»\99ªª\99\88f3D""""""\11""DU33Ufw\99wU33ffU3DD333"3UD3\88»ªwfwfUf\88\88w\88w"\11""\11"\0""\11\11\11\11\11\11""""Dww3"\11\11\11\11\0\11\11\11"3UfD"\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11""33f\88ww\88fU"""\11\11\11\11\11\11\11\11\11\11""\11\11\11\11"\11\11"""\11\11\11\11\11""""3\11"""\11\11"""\11""\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11"""""33"""""""3DUDffwwfUDDw\88fUD"""\11\11""""\11\11\11"\11"\11\11\11\11\11""\0\0\11\11"3""""33U\11\11\11\11\11\11\11\11\11"""""\11"\11333333"""""""33333""""""3DD33"""3""3333"3\11"""""""""\11"""""\11\11\11"\99ª33DUDD\88»Ì\88\11\11\11\11"\11""\11\11\11\11""33DUUf\88Ì\99UU\88ª\99\99\88\99ªª3UªÝîÝ»»»»ªªª\99w"""\11\11"fffUD33U\88\99wU33UwfUwfUDD3333U3ww\99wfUfUffw\99\99wD\11\11\11\11\11Df"\11\11\11\11\11"""3UwU"\0"\11\11\11\11\11\11\0\11\11"3Uw3\11\11\11\11\11\11\11\11\11\11\0\11\11\11"\11\11""""3"UfwfD3\11"\11\11\11\11\11\11\11\11\11\11"""\11\11\11\11"\11\11""\11\11\11\11"D333""\11\11"""""""""""\11\11\11\11\11"\11\11\11\11\11\11"\11"\11""""3""""""""3DDDUUU\88\88fU3UwDDfD"""\11\11\11""3"\11"\11\11\11\11\11\11\11""\11\0\11\11""33"\11""3D\11\11\11\11\11\11\11\11\11\11\11"""""3D3""""3""3""333"3""""""33DDD""""333333"""3""""""\11""\11"3"\11\11\11\0\88333DDUªÝªU\0\11\11""""""\11\11\11\11""333DfÌîÝ»\88Uwªª»ªÌîÝîÿÌ\88Uffwfff\88ªffUU\88UD\88\99\88U3"3DwUf3DDDDfww\88\88wD33333Dfw\88fUUUDDfffwUfUD3DDfw\883\11\11\11\113"3fUD""\11\11""\11\11\11\11\11\11\11""3DU"\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11"""""3DUDU3""\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11"\11\11\11"\11\11\11""3333""\11""\11"""""\11\11""\11\11\11\11\11\11"""\11\11"""\11"\11"""""3""""""3DUDDfDDfwD"U\88fDff33"\11\11\11"\11"""\11\11\11\11\11\11\11\11"\11\11\11\11\11""3""\11""3U"\11\11\11\11\11\11\11\11"\11\11\11\11"""""""33""""3""""""33""""3333""""""33D3""""3"""""""\11""\11\11\11\11\11\11\0fªf3333Dwª\99D\11\0\11\11\11"3"""\11""\11\11""""3fÝÝÌ»ÝÌ»ÌÝîÿÿîÝÌ\88wDD33UUUffw\88\99»ª»ÌÌÝÝÌ\99U\11Dwf"3D33D33U\88»»\99\88fDDDf\99ªfffUfUDDDfffUUUUUfwDUwwDfU3"DUfD\1133"3"\11\11\11\11\11\11\11\11\11"""3"\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11""""DDDU33""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11"\11\11\11\11"""""\11"""""\11"\11\11\11\11""\11\11\11\11\11\11""\11""\11\11""""\11\11""""3"""333UUUDDU3DUUDDDDDUU\11\11"\11""\11\11""\11\11\11\11\11\11\11\11"\11\11\11\11\11\11""3"\11\11\11"3\11\11\11\11\11\11\11\11\11\11\11\11\11\11"3"""""D3""""3""""""""""""""33""33"DD3""""""""""""""\11\11\11\11\11\11\11\11\113w\883""33Uª»f\0\11\11\11\11\11\11""\11"33"""""""3fÝÝÌÌÌÌÝÝ̪ªª\88wUDUD3"33D3DUD3D\88ª»Ì»\99\99\99\99ª»»ªD\11UD3D3UU\88\99wwfffª\99ª\88\88w\88UUfUDDD3DUDUD3D3D3"3"Uffww\88\99\99\99f3f\88UUU3\11\11\11\11\11\11\11\11\11"\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\113"333D333\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11"\11\11\11\11""\11"\11\11\11""\11"\11"""\11\11"\11\11\11\11\11\11\11"""""\11\11""\11\11\11\11"""""3D3"3DDDDUDUUDDDDD33DDf3""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"\11\11\11\11"""\11\11"33\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3"""3"3"""3""""33""""""""""""""33D3"33""3""""""""""""\11\11\11\11\0"w\99U33""3wª\993\0\11""\11\11\11""\11\11\11""3"\11"""DDÝÝ»»ªª»ª\88UUfD3""3DD3"333U3"UD3fwwwwfww\88\88\99\99\99ª\88\99\88w\99\88wwD"""3"3U3333DwUUUUD33333DD"3"""""""3"3UUf\99\88\88wf\88»ªfU""""\11"\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\113DUDUU3"""\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"\11\11\11\11\11""\11\11\11\11""""\11"""\11"\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11"""\11"""""333"33DDDDDUfUDDDDfUDDUf3"3""\11""\11\11\11\11\11\11\11\11\11\11\113""\11\11\0\11\11"""\11"D"\11\11\11\11\11\11\11\0\11\11\11\11\11"""\11"""3""""""3""""D3"""""""3""""3D3""3""\11\11"""3"""""3""""\11\11\11\0\88D333"Uªª3\11\11"""""\11\11\11\11"""33"""""3U\99ݪ»»ªªª\99wfwD3""333333"3"3UfUwUUfUDD3DDUDD3DDUDDDD3""\11"""""3"3DDDUUUDDD3"""33""3"\11""""33""33"DDUUUDUfwwwfUfffU\0\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11"3D3Uw3"3\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"\11\11\11\11\11""""""""\11\11""""\11\11\11\11\11\11"\11\11\0\11"\11\11\11\11\11\11\11"3\11"3"33DD3D3DDUUUDDDD333fU"\11\11"""\11\11\11\11\11\11""\11\11\11"3""\11\11\11\11"\11\11\11"3U3\11"\11\11\11\0\11\11\11\11\11\11"""\11"""333""""""\11"333""\11"""""3U""33D3"33\11""""""""3"""D3D3"\11\11\11\11f»U333"D\88»U\11\11""\11""\11\11\11\11\11"""33""3""33f»ªªªª\99\99\88\88w3""333""3D3"\113DUDUUUUUD""3333D3"""""3"""""""\11\11"""3333DUfU3D3"""""33""\11""\11""33"""""""3DD33333DUDDUUwwf33\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3DDDDD"\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11"\11\11\11\11"""\11\11\11\11"\11\11""\11"33""""""\11\11\11\11\11\11\11\11"""\11\11\11\11"\11\11\11\11\11""\11\11"""3333DD33DDDUUDUDD"33Uw"\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11\11"\11"\11""DD\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11"""3"3"33""""33""""""""3333"""""""3""333"""3"""""D3"\11"\113fª»3""""f\99w"\11\11\11\11\11\11\11\11\11\11\11""\11"3""""3333U\99»\88\99wwfUDD"""3""3""33""""D3D3DDD3""\11""""""""\11""""""""\11\11\11\11""""33""Uf33"""""""""""\11\11\11"""3""\11"\11"""""3333333"3DUDDDfwf\11\11\11\11\0\11\11\0\11\11\11\11\11\11\11\0\11\11"\11""DDDDD""\11""\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""\11\11\11\0\11"\11\11\11"\11\1133333""\11"\11\11\11\11\11\11\11\11"""""\11\11"\11\11\11\11\11\11\11\11\11\11333"333"33DUUUUDDD333DD"\11"\11\11""\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""33\11"\11\11\11\11\0\11\11\11\11\11\11\11\11""""D""""""D"""""3D"""33DUD333D3"333"33"""""""""\11\11\11\11""\11Dª»U3"3"3\99w"\11""\11\11\11""\11\11"\11\11"\11"""""\11""333wÝ\88\88w""3"D3""333""D33"\11\11""\11"3DD33""\11\11\11"""\11\11\11\11\11"\11"""3"\11\11\11"\11"""""33"D3""""""""""""\11\11\11""""""""""D""""\1133"3\11"33DDDDD3UD\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3UDffUf3""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\113\11\11\11\11\11""\11\11\11\11\11333"33""\11"\11\11\11\11"\11""\11\113"\11\11\11\11\11\11\11\11"\11\11\11\11\11""""""33333DDU3DDUD3DD"\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11""\11\11"\11\11\11\11\11\11"\11""""3D\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""D""33"33333"""""""3DD33"""""""3"3D""\1133""""""""\113"\11fªf3"3""w\993\11"""\11\11\11"\11"\11\11\11\11"""33""\113""333ª\88Df3"""3D33DU333DD"\11"\11\11"\11\11\11"D33""\11"3\11\11\11\11\11\11\11\11\11\11""""\11\11\11\11\11\11\11\11""3"333"""""3"""""\11\11"\11\11\11"\11""\11\11\11"""D"\11\11"\11""\03D\11"33UDD3U\88"\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11"3333DUf3""\11\11"\11\11"\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\0\11\11\11"\11""\11\11\11"""\11\11""33"333"\11"\11\11\11\11\11""""""\11\11\11\11\11\11\11\11""\11\11\11\11\11""""""""33"33UD3DUDD333"\11""\11\11\11\11"\11\11"\11\11\11\11"\11\11\11\11\11\11\0\0\11\11"""""3"3\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11"""""""333333"""""\11""""3D3""3"""33"""""""33"""33"3"3\113\88\99D"3"\11U\99w""3""""""\11""\11\11\11""\11\11""""""""3ff\883DD3"""3D333""3"3"\11\11\11\11\11\11""\11"""""\11\11""\11\0\11\11\11\11\11\11"""\11\11\11\11\11\11\11\11\113\11""""""3"""""""""""\11"\11\11""\11"""\11"""33"3\11\11"\11\11\11\11"3\11""3333Dw\99""D"\11\11\11\11\11\11\11\11\11\11\11\11\11\11"33"3UU33""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11"\11\11"\11"""""\11""33333""""""\11\11\11""""""""\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11"""33""""3D3DDDD333DD"\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11""\11\11"""D3\11\11\11\0\11\0\11\11\11\11\11\11\11\11"""""""""3D3"""3""""""""3""""""""""3D"""""3"""""3""3"f»\993""\11"\88\88D"""""""""\11\11\11\11"33\11"\11\11\11""\11\11""3\99ª\88UU3"3"33"\11"D3"3"""\11\11\11""\11\11\11\11"\11D\11"\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"\11\11\11\11\11\11\11\11""""""""33""""""""""\11""\11\11"\11\11\11\11\11""""""\11\11\11"""\11\11\11\11\11\11""33"3f\88f\11\113\11\11\11\11\11\11\11""\11"\11\11"""""DffD3"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""\11\11"""D333"""\11\11"""\11"""""\11\11""\11\11\11\11\11"\11\11\11\11\11\11\11"\11""""33""33DDUD3D333"D3\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\0"3"\11\11\11\11\11\11\11""\11\11\11""Dw\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11""""""3D"""\11"D""33"""""""""3"3"333DUD3""33"\11"3"""""3w»f\11"\11"f\99U""""""""3"\11\11\11\11\11"3\11"\11\11\11\11""3""3ª»ªf3""\11\11""""""3"""3"\11\11""\11\11\11\11\11"\11"\11\11\11\11\11\11\11\11\11\11\11"\11\11\11"\11\11\11\11\11\11\11\11\11\11\11""""""333""""""3"""\11"""""\11\11\11\11\11"\11\11"3""""""\11\11\11\11\11\11\11\11"33"3DU\88f3"\11\11\0\11\11\03U"""\11"\11""""Dw\88D""""""\11\11\11\11\11\11\11\11\0"\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11"\11""\11\11\11"3DD333""""\11""\11"33"3\11"3""\11\11\11\11""\11\11\11\11\11\11"\11""""333333DUfUDDD3"333\11\11""\11\11\11\11\11\11\0\11\11\11\11\11\113"\11\11\11\11\11\11\11\11\11\11\11\11\11"3DD\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""3"3"""""33"""""""""""""33D33DD3"\11"""""""""""\113fª\993\11\11"w\88U33D3"\11"""""\11\11\11\11\11\11"\11\11\11\11\11\11""\11"3DªÝ\99f3"\11\11\11\11\11"""""3""""""\11\11\11\11\11\11\11\11\11"\11\11\11\11"\11\11"\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"""UfU33"""""""""\11\11""\11\11"\11\11\11\11\11\11\11"\11\11""3\11\11\11\11\11\11\0\11\11""""3"3DffwDUUD3\11\0\11\88w"""\11"""""3Dw\88D"""""3"\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3UUD3D"3""\11\11"\11\11"""3""""\11\11\11\11\11\11"\11\11\11\11\11\11"""""33333DUUffUDDf3"DD3\11\11\11"\11\11\11\11"\11\11\11\11"\11\0\0"3"\11\11\11\11\11\11\11\11\11\11""""DD3\0\11\11\11\11\11\11\11\11\11\11\11\11""""33""33""33""""""""""\113"""DD33""""\11""""""""\11\11\11\11w»w3\11\11\11f\88f3""3D3\11\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""\11"D\99Ì»3""\11\11\11\11\11\11"""""3"\11"\11""\11\11\11"\11\11\11\11\11\11\11\11\11\11\11"33"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"3"DfUUD3""""""""\11\11\11\11\11"\11\11\11\11\11"\11\11\11\11"\11\11"\11\11\11\11\11\11\0\11\11\11"\11\11"3""DDUUfUffwwU\88\99w""""""""33UwD"33"""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11"\11\11\113DD3fUD3U""\11\11\11\11\11\11"\11"3"""3"\11\11\11\11\11\11\11\11"\11"""333333DDDDDUfwfU33D"DUD\11\11\11\11""\11\11"\11\0\11\11"\11\0\11\11"33\11\11\11\11\11\11"\11\11""33DDD\11\11\11\11\11\11\11\11\11\11\11""\11""""3333"""3"""""""""""""""333DD3""\11\11"""3""33"\11\11UªªD\11\11"U\99f3""""\11"""\11""\11\11""\11\11\11\11\11\11\11\11\11\11""3"""\88»»w\11"\11\11\11\11\11\11"\11"""""""\11"\11\11\11\11\11\11\11""\11"\11\11\113UUU""\11"\11\11\11\0\11"\11\11\11\11\11\11\11\11\11\11\11"UDUUUUUD3"\11"""""\11"\11\11\11"\11\11"\11\113"\113\11\11\11""\11\11\11\11\0\11\11\11""\11\11\11\11\11"\11"3DUD33DU\88\99ª\99\99\88UD""""""3DwUDD"""""\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11"\11"\11\11"D3DUD33D3"\11"\11\11\11\11\11""3"\11\11"3""""\11\11\11"""""""3333DDDDDUUUUwfD3DD3UD\11"\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11""""\11"""\11""\11\11""3DDDD\11\11\11\11\11\11\11\11\11\11\11""\11""""""3""""""""""\11"""\11"""333333""\11\11\11"\11""3"""333\99ªf\11\03w\99w3""""\11\11\11"""""""""\11\11\11\11\11\11\11"\11\11\11\11"""3U\99ªw3""\11\11\11\11\11\11\11\11""3""\11\11\11"\11\11\11\11\11\11""\11\11\11\11\113DD""\11\11\11\11\11\0\11\11\11\11\11"\11\11\11\11\11\11\11\11"w\88fUUDDUD3"\11\11\11""\11\11\11\11\11\11\11\11"\11"\11\11\11\11\11\11\11""\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11""3D3DDDUww\88\99ª\99\88UDUUD3"D33f"3""""""\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11""""\113DUUDUD333"3\11\11"\11\11"""3"\11""3D""\11\11\11\11"\11""""3"333DDUUDUDUUfwU3DU"UD"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3333"\11"\11""33"\11""\11\11\11\11\11\11\11\11\11\11""""""33"""""""""\11"\11"""33333""""\11\11\11"\11""""""""3wªw"\11\11\883"""\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"D3Dwª\883"\11""\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11"\11"""3333"\11\11\11\11\11\11\11\0\11"\11"\11\11\11\11\11\11\11""""wwUUDD3DD3"\11\11"""\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11""3"""\11\0\11\11\11\11""\11\11\11\11\11\11"""333DDUfffw\88\88fDUfUDUwfUD3""D3""""\11\11"\11"\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11"\11\11""\11"DDUD3D333333"\11\11\11\11\11""D"\11"""""""\11\11\11"\11"""3""3DDDDDUDfUDUUwf33UD3U3\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"3D33"\11\11\11\11\11\11\1133""\11\11\11\11\11\11\0\11\11\11\11\11\11""""""33"3""""\11\11"""3"3"3"""""\11\11\11\11\11\11\11\11""""33Dwªf"\113\88»f"""\11\11\11\11\11\11""\11"\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11"\11"D\88ª\88"""33\11\11\11\11\11\11\11\11\11\11\0\11\11"\11\11\11\11\11\11\11"""\11"UD3"\11\11\11\11\11\11\11\11\11\113"\11"\11"\11\11\11\11\11"\11"UwDUU3DDD3""\11"""\11\11\11\11\11\11""""""\11\11""\11""33"3\11""\11\11\11\11""""\11\11\11\11\11"""33DDUUUDUD3333DDDUUf\88U\11\113"""""\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"33DDD3333"3333"\11\11\11\11\11"3D"\11\11"""\11\11\11\11""\11"""333333DDDDUUDDUfwwUDDDUDD3\11\11\11\11\11\11\11\11""\11\11\11\11\11\11\11\11\11\11"\11"""3""\11\11\11\11\11""\11\11"3\11""\11\11\11\11\11\11\11\11\11\11\11"""""""3"3""""""""3""3D"33"\11\11\11\11\11\11\11\11\11\11\11\11"""3Dww3\0"w»w"\11"3"\11\11\11\11"\11"\11\11\11\11\11\11\11\11"\11"\11\11\11\11\11\11\11\11""\11"3\99»3\11"""3"\11"\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11""3DDD33\11\11\11\11\0\11\0\0\11\11\11"3"\11\11\11\11\11\11\11\11\11"3UU3DfD33D33"\11"""\11\11\11\11\11\11\11\11""""\11"\11"\11\11\11"""\11\11\11\11\11\11\11\11"""""\11\11\11\11\11""3DDUDUUDDDDDDDDUUfUDfD\11\11\113"\11"\11\11\11\11"\11"\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11""\11"UfUD33""3"""33""\11\11\11""3D"\11\11"""\11"\11\11"""""""33333DDDUUUD3Dw\99wUUDUD33D\11\11\11\11\11"\11"""\11\11"\11\11\11\11\11\11\11\11"\11"\11"""\11\11\11\11\11"""\11\11"3"""\11\11\0\11\11\11\11\11\11\11""33""33""""""""3"33"""\11"""""\11\11\11"\11"\11"\11"""3DDU\99"\11\88"\11\11"3"\11\11\11\11\11D"\11\11""\11\11\11\11"""""\11"\11\11\11\11\11\11\11"DªÝU""3"33""\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11"3DD3""\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11"\11\11\11DUfU33UD33"33"\11"""\11\11\11"\11\11\11\11""""\11""3\11\11\11"\11\11"\11""\11\11\11\11\11\11"""\11\11\11\11\11\11""33DDDDDDDDDDUUUUfUUwD"\11""\11\11"""\11"""\11\11\11\11\11"\11\11\11\11\0\11\11\11""\11"\11\11"\11DwfUUfU"D"""3D""\11\11\11""DD\11\11\11\11\11\11\11\11\11\11\11""""""33333DDUDUDUDUfUUwfDUD3DU""\11"""\11\11"\11\11\11"\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""\11\11\11"3"\11\11\11\11\11\11\11\11\11\11\11\11\11""""3"""3""""33"33"""\11"3"\11\11\11\11"\11\11"\11\11\11"""3DDfw"U\99\993\11\11"""\11\11\11\11\11"""""\11""\11"\11\11"""\11"""\11\11\11\11\11\0"wÝÌD""""3""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11UUD3"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"""\113UUU33D3""""3"""""""\11"\11\11\11\11"\113""\11\11\11\11"\11\11\11"\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11""""3DDDD3DDD33DUDUfUfw3\11\11"\11\11\11""\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11""\11\11\11\11fwUUD3DfD3DD"33""\11""DD\11\11\11"\11\11""\11""""33"3"3333DDDDUUfUUUUffwUUD33DD\11"\11""\11"""""""\11""""\11\11\11\11"""\11\11\11\11\11\11""\11\11\11\11\11\11"3\11"\11\11\11\11\11\11\11\11""\11"\11"""""""""""33""33"\11""3\11\11\11"33\11\11\11\11\11\11"""33Dw\99\99D\11\11\11\11\11\11"\11\11\11\11\11""\11"""""""\11\11\11\11""""""\11\11\11\0"ªÌ»D""""""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""DD3""\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""""3UUUD3DD3"""""""""""\11\113\11\11\11\11"33DDD3\11\11\0\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\0\0\11\11\11""""""33333DD33DDDDUUfD"""\11""""\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11fwwfUDD""33"DD33""""DD\11\11\11\11"\11""""\11""33333333333DDDDfUDUUUfffDD333D3"\11"\11\11\11"""\11"\11"\11"""\11\11\11\11\11""\11"\11\11\11\11\11\11\11\11\11\11\11\11\11"3\11\11\11\11\11\0\11\11\11\11\11""\11"\11""3""""3333"333"\11\11""\11\11\11"D3\11"""""""""Dwª\99̪U"\11\11"\11"\11\11\11\0\11\11\11\11""""""""\11\11"\11\11\11""\11\11\11\11\11\11\0"\99Ý»D\11"3"""""""\11\11\11\0\11\11\11\11"\11\11\11\11\11\11"3"""\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\03"3"3ffUf\88UD3DD3D3"3"""33"\11"\11\11""\11\11\11\11"3"\11"3"\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11"\11\11"3"333D333DUUUfUf"\11"""\11"\11\11\11\11""\11\11\11\11\11\11\11\0\11\11\11\0\11\11\11\11\11\11"\11\11"\11\11w\88wfUUU33""""\113DUDD333"\11\11\11\11""""""""33"3333333D33DDD33DDUUfffDD""D"\11\11"\11\11\11\11""""""\11\11"""""\11"\11""""\11\11\11\11\11\11\11\11\11\0\11\11\11"3\11\11\11\11\0\11"\11\11\11"""\11\11"""\11""""33""""""""""3"\11"3"""""""""""D\99ÌÌÝw3""""\11\11\11\11\11\11\11\11\11\11"\11\11"3"""\11\11\11\11\11\11\11\11\11\11\11\11\0\0\113ªîª""""""3""3"\11\11\11\11\11\11\11\11\11\11""\113"3""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11"\11\11"f\88wD3UffUwfU333"33"33D333""\11\11\11\11\11"\11\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11""33333D33"DUUUUDD"""\11""""""\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"w\88ffDUDD3"""""""\11"3DD3"""""""\11""""""""""""333DD3DD"U3333DUUUfD3"3"\11"\11\11\11\11\11\11\11"\11"\11\11"""""""""\11""\11\11\11\11\11\11\11\11\11\11\0\11\11\11""D\11\11\11\11\11\11\11\11\11\11"\11\11""\11""""3D33""""\11\11"""\11\11\11\11""\11""3"\11"3333UªÝÝ\99D"""""\11\11\11\11""\11\11\11\11""\11""""\11\11""\11\11\11\11\11\11\11\11\11\0\11D\99Ìݪ\11"""""33"""\11\11\11\11\11\11\11\11"\11""\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11""\11w\88\88ww\88wwfUffD333"""3333D3"""\11\11\11\11\11""\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11""3"33D333DDfUDwDD""""""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11"\11\11\11\11\113wwfUUDD33""""""""3"""\11\11\11""3"""""""""""3"3333333DDDD"3"33DDUwwU3333"\11\11\11""\11"""""""\113""""""""""""\11\11\11\11\11\11\11\11\11\0\11\11\11\11"3\11\11\11\11\11\11\11\11\11\11\11"""""""3D333""\11\11\11""""\113"\11\11\11"""\11\11\11"3333wÝÝ»f"""""""""\11\11\11\11\11\11\11\11\11\11\11""\11\11"""""\11\11\11\11\11\11\11\0"wªÌ̪3"\11"33""3"\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11f\99ww\88\88\88wffUDDD3""3"3"3DDD3""\11\11\11\11\11\11""\11\11""\11\11\11\0\11\11\11""\11\11\11\11\0\0\0\11\11\11\11\11\11\11\11\11\0\0\0\11\11\11\11\11\11\11\11"3333D333DUfDw\88U""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11"\11\11\11\113wffUUDD33333""""""3"""\11"3"""""""""3""""333333DDDDDDD3D"33DDfww"33D\11\11\11\11\11\11\11\11"""\11""""""3"\11""""""""\11\11\11\11\11\11\11\11\0\11\11\11\11\11""\11\11\11\11\11\11""\11\11\11\11""333"""""""\11\11""""""\11\11\11""\11""\11"""""33wÌ»\99U""""3"""\11""\11\11""\11\11\11\11\11""\11"\11"\11""""\11\11\11\11\11\11"ªÌ»»\993"""33""D3"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\113w\99\88\88\88\88\88\88wfUD"3"""""33DUfDD""\11\11\11\11\11\11\11\11""\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11\11"\11"\11\11"\11\11\0\0\11\0\11\0\0\0\11\11\11\11\11""33333DDDfDU\88DD3\11\11"\11\11\11\11"\11\11"\11\11\11\11\11\11\11\11\11\11\11\11"""\11\11\11\11\11\11"\88wfUDDDD33""""3"3"""""""\11\11\11\11""33"""""33"3"333DDDD33D3U3333DUDUDUDf"\11\11\11"\11\11\11\11"\11""3\11""""\11\11"""""""\11\11"\11\11\11\11"""\11\11\11\0\11\11""\11\11\11\11\11\11\11\11\11\11\11""""3""\11"""""""""""""\11"""""""33""333\99ÌwD"""""33"""""\11\11\11\11\11\11\11\11\11\11"""\11\11\11""3"\11\11\11\11\11\11\0fÌ»\88UU3"33""3DD33"\11\11\11\11\11\11\11\11"""\11\11\11\11\0\11\11\11\11\11\11\11""\11\11"""\11\11\11\11\11U\88w\88\88\99\88\88\88fUD33"""\11""333D3fU3"\11\11\11\11\11\11\11"""\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\0\0\0\0\0\0\0\11\11\0\0\11\11\11\11""3333D3DUfwff33\11"""\11"""\11\11"3\11\11\11"""\11\11\11\11\11\11\11"\11\11\11\0\11\11D\88fwUDD33"333"""""""\11""""\11"\11""""33DD33D333""3333D3DD33333"33UDUUUDfD\11\11\11\11\11""""\11"\11\11\11\11"\11\11\11"3""""""\11\113U"\11\11"""\11\11\11\11\11\11"""""\11\11\11\11\11\11\11""333""""""\11\11"\11\11""\11"\11""""""""3""3"D3U»»3""""""3""""""\11\11\11\11\11\11\11\11\11\11"\11""\11\11"""\11\11"\11"\11\11Dw\99\99fUfU"33UD3DD"\11\11\11\11\11\11\11\11\11\11"""""\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11"\11\11Uww\88»ªª\99ffUD3""\11\11\1133""333UU3"\11\11\11\11\11\11\11\11\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\0\0\11\11\11\0\0\11\11\0\0\11\11\11""""3333D3Dwwwf3""""\11""3""\11\11"\11"""""""\11\11\11\11\11""\11\03Uf\88wfDD33""33""""""""""""""\11""""""""3"3DD3D3""333333D33"33"33DUUUUUUf\11\11\11\11\11\11"""\11\11\11\11\11\11\11\11\11\11\11""""3U"\11\11"\11\11\11\11"3"""\11\11\11\11\11"33"""""""""""""""333"""\11""\11\11"""""""""3""""""3DU̪3\11""""33""""""\11\11\11\11"""""\11""""""\11\11"\11\11"\11\11"D\88»\99w\88fwD33"DDD3""\11\11\11\11"\11\11\11\11\11\11""""\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\113www\99»ª\88fUUU3""""""3""3333DD""\11\11\11\11""\11\11\11"\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\0\0\0\0\0\11\0\0\11\11\11\11\11\11\11\11\11""3333DDDUUw\99f"""\11\11\11\1133"\11\11\11\11"33"\11""""\11\113D"\0\113\88\99wfUfD3DD333""""""3"""""""""\11"\11"""""333333333333333333"3"333DDDDUwDfD\11\11""""""\11\11\11\11"\11\11\11\11""\11""\11"D"\11\11"\11\11\11\113""\11\11\11\11\11\11\11"\11\11333""""""""33333""""\11""""\11\11"""""333"\11""""""Uª»\88""3""33""""""\11\11\11""""""""""""""\11\11\11\11\11\11\113f\99ݪUDU3"""33DfD""\11\11\11\11\11\11"\11\11\11"""\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11"\11\11\11\11\11\11\11"""D\88\99ª\99\88wfUD3""""""""""3"333""\11\11\11"""\11\11\11\11"\11"3"\11\11"\11"\11\11\11\11\11\0\0\11\11\11\11\11\11\0\0\0\0\0\0\11\0\0\0\11\0\11\0\11\11\11\11""DD3DDDUDUf\99\99U""\11\11\11\113D3"\11\11\11"""""""3"""Uwfff\88ª\99\88fDUfUD3D3""""33"""3"""""""\11\11""""\11"""3D333DD333333333D3333DDDDDUfw\88f"""""""""\11"\11"\11"\11\11"""\11"\11"3"\11\11\11\11\11\11\11"\11\0\11\11\11""\11\11\11\11\11\113D"""""""""""3""""""""\11\11\11""""""33""\11"""33D\99ÌÌD\11"""""""""""""""""""""\11"\11"""\11"\11\11\11\11\11\11\11UÌÌݪ3D"\11"""3DUD"\11"\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11""""\11\11\11\11\11\11""3\11D\88\99\99\88wUUD3333""3"""""33D"\11\11"\11\11"3"""\11\11"3""3"\11"\11""\11\11\11\11\11\11\11\11\11\11\11\11\0\0\0\11\11\0\11\11\11\0\11\0\0\11\11\11\11"""D33DUDDUDUfU3"""\11"\11"D3"""\11"""""""3Dwwww\88\99\99\99w\88\88wfUU3D333""""33"""""""""""\11""\11""\11"""333DDD3333333333DUDD333DDDUfw\99ªf"\11\11\11"\11\11"""\11\11\11\11\11\11""""\11""D3\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11"""3D33"33"""""3"""""""""\11\11"\11"""3"""""""""3fÌÝ»3"""33""3""3""""""""33""""\11"\11""\11\11\11\11\11"fÌÌ\99\99ª3"\11\11\11""3333\11\11\11\11\11"\0\11\11\11\11\11\11\11\11\11"\11"\11\11\11\11\11"\11\11\11\11\11\11\11""\11\11\11\11\0\11"3"\11\11\88\88\88wffUDD333333D3""3DD3D3""\11\11"\11\11\11""\11\11"3"""\11""\11\11\11\0\0\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11"\11\11\0\11\11\11\11\11\11\11""""333DUUUDfw\88"""""\11\11"3""3""""33""3Ufww\88\99ª\88\99\99\88wwwffDD3"3"33333"""""\11""""\11"\11\11\11\11""""""33""3333333DDD3DDDU3""3DDfUUfw\99\88wD3""\11"\11"""\11\11\11"""333"""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3"3"""""\11"""""""""""\11""""""""\11""\11\11\11DfwÝÝ\88"3"""""333"""""3"""33"3"""\113"\11\11\11\11\11\113w»Ý»\99\88\99D"D\11\11"""D""\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\0\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11"w\88w\88wfUDDDDD33DDDDDDUUDDD""\11\11"\11\11\11\11""\11""""""3""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"\11\11\0\11\11\11\11\11\11\11\11\11"""3DDDDUUff\88w3""\11\11\11"33"""\11""""""3UwDf\88\99\99\99\99\99\99\88wfUUUD33333333""""""""""\11\11\11"\11\11"""""""333"""D33"33333DDDU""""DDUUfw\88wfwwwU\11"\11\11""""""3DD3"3""3"""\11\11\11\11\11\11\11\11\11\11\0\0\0\11\11\11\11\11\11\11\11\11\11\11\11"D3""3""3"""""""\11"""\11""3""""\11""""3\88Ì»ªªw3"33"33""""3"""33"3"""""""3DD\11\11\11\11\11D\88Ìî»\88w\99wD3D""""3D3""\11\11\11\11\11\11\11\11"\11""\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11"\11\11\11\11\11\11""\11\113\88\99wfw\88fUUfDD333DDDDDD3DUD"""\11"\11\11"\11""\11"\11""""D3""\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11333DDUUUU\88\88w3""\11\11\11"33D3""""\11"""3ffff\88\88\88\99\88\88\88wwffUDDD33333D3""""""""""\11\11\11"""3"\11""""33""\11"\11"333333"3U33""""3D3DffffwwwwwU\11"""""""""UU3""""""""\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11D33""3"""""""3"""""""""\11\11\11"""\11"D\99Ý̪\88U""33"3333""3D""D""3"3DDU33UfUDUwf\99ÌÌ»\88fDf\99fDDU"\11""333"\11\11\11\0\11\11\11\11\11\11"\11"""\11\11\11\11\11""\11\11\11\11\11\11\0\11"\11""\11\11""\11""\11\11"U\88\88\88wff\88\88wwUDDDUUDDD33D3DD333"""\11\11\11\11D"\11\11"3D3"\11""\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11"\11\11\11\11\11\11\0\11\0\11\11\11\11\11\11\11"33D3UU3Uw\99\88f"""\11\11"33DUD"""\11\11""Df\88\99Uw\88wwwwwwffUUUUDDD333""""""""""""\11\11""\11"""""""""""3\11\11"\113""33"333""""3"333DUfffffUffU"\11\11"""""""DD33"""""""\11\11\11\11\0\0\11\11\0\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11"""""""""""""3"33"\11""\11\11\11\11"33U\99Ìî\88333"""""33"3"""""3"333"f\99wDUffff\88\88\99ÌÌ»»ª\88Uff\99wfDD""""3D3"\11\11\11\11\11\11\11\11"\11\11\11\11"""\11\11\11\11\11""\11\11\11\11"\11\11\11\11""\11\11\113"3"\11\11"Uw\88wwwUffwwUDUUUUUU3DDDUDD3333333\11\113U3\11\11\11""U3\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\0\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11"3DUDfUfDf\88U3\11"\11"""33DUU""\11"Uw\88\99w\88\99\88wwfwffwffUUDDDDD33D3"""""""""""\11""\11\11\11""""""\11""""3\11\11""""333"3""""3"""33UUUUUwf3Uwf3"\11\11"""""""3333"3""""\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0"33"""""""""33"""33"\11\11"DffªÝîîf\11""""""""3333"""""33333fw\88fUUDUUUUf\88ªª\88\99ªª\88\88»\88\88wU3"\11\11""""\11\11\11\11\11\11\11\11\11\11\11\11\11\113"\113\11\11\11""""\11\11\11\11\11\11\11"\11\11"\11"""\11\11\11\11Uw\88ww\88D""3fwfffUfUDDDDUUUD33333"""D3"3\11\11\11""""""\11\11\11\11\11\11\11\11"\11"\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\0\0\11\11\11\11"""3UDUfD3UD\11""\11\11\11""33DDD""Df\88\88\88w\88\88\99\88\88wfffUUUUDDD3DD3333""""""""""3"\11""""3"""""""""""""""""""33"""""33"333DDUUfDDDDDUD""""""3333""""3333""""\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\0"""3"3"""D33"\11"3UU3DUwff»îÝÝw\11""333""333333"""""""\11"wwwUfUD333UUww»wª»»ÌÌÌ\99\88wfU\11\11\11\11"3"\11\11\11\11\11\11\11"\11\11\11\11""""\11""\11\11\11\11\11"\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11"UwwUUD""\113fwfwfUffUUDDDD3D3""D3""33""\11\11\11"3"\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11""3DUUDfw33\11\11\1133""""""33"\11Dwwww\88\99\99\88wwwfUDDDDDD3D33f3333333""""""""\11\11\11\11""3"\11""""333333D3"""""33D3""""""""3DDUfUDDD3DfD"""D3"3"333""33333D3"""\11\0\0\11\11\11\0\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0DU"33333333"\11\11\11""3DUUªÝîîÝ»f"""3D33333333333"3""3Dfw\88wfD333333DUw»»ÌÌÌîÌ\99w\88fD3"""33\11\11\11\11\11\11\11\11"\11\11\11\11\11\11"""""\11\11\11\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\113fwD3""33"UwffffwwfUfUD33DD"3DDDD""\11"""\11"3""\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\0\0\0\11\11\11\11\11\11\11\11\11\11\11\0\11\11\0\0\11\11\11"3333D33w\11""\11\11\11"3""\11"\11\11\11\11\11"Dw\88ww\88w\88\88fwUUDDDDD33"3DfD333D33""""""""\11\11""\11"""""3"333"33333D33"3"""""\11\11"""""33DDUUDDU3D3fUD""3333""""""33"3"33""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11"\11\11\11"\11fD3""3"3""""\11\11\11\11\11"3ÌÝÝÝÝÝ»\883""DD3"3"33"3""""\11DfUw\99ffUD"3333333D\99ÌÌÌÌÝÌ\99\88\88f3"\11\11\11"3"\11\11\11\11\0\11\11\11\11"\11\11\11\11"\11\11""\11\11"""""""\11\11""\11\11\11\11\0\11\11\11\11"\11\11\11\11UwUD3"\113UffffffwfUUUD33DU33"UD3"\11\11\11"3"""D"""\11\11\11"\11\11"\11\11\11""\11\11\11\11\11\0\11\11\11\11"\11\11\11\11\11\11\0\11\11"\11\11\11\11"3333DD33D\11"3\11\11"\11""\11D"\11\11\11Dw\88\88ª\99\99ª\99wwwwfUDDDDD33"3DDDDUDD333"""""""\11""\11""\11"""3"3"""33""""""""""""""\11""\11"33DDDDUUUDDD33UfU""3U""""33"3333""""""\11\0\11\11\0\11\11\0\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""UU33""\11""\11\11"\11\11"Dff»ÿÝÝÌÌ\99w\99wDDw33""""3"w"3Ufww\88wDUUUD"3333"3"D\88»ÌÌÝÝÌ\99»\993""\11\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11"\11\11""""\11\11\11"""\11""\11"\11\11\11\11\11\0\11\11\11\11"\11\11""\11UffUD"3UffffUffUUffU3DDUDDDUD3\11\11\11\11"""333"""\11\11\11\11\11"\11\11"\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11""333DUf"\11\11"\11\11\11\11\11\11\11\11"""3f\99ªªªªªª\99wfUwUDDDDDD3"D33"333D3333""""""""\11\11"3\11\1133""""""""""3""""""""333""""""33333UUDUUDDD33DDD""33"3""D3"""""\11""\11""\11\0\11\0\0\0\11\0\0\0\11\0\0\11\11\11"\11\11\11"\11\11\11\11\11\11\11\11\11""\11\11"Uf"""\11"3fUfwª»ÝÌîÿÿÝÌÌ»UUUwUDf33\11Uf\88w"fw\88wfUUD3UDUU3"D333333U»»ÌÝÌ̪\99\88D\11""\11\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""\11\11"\11"""3"""""\11\11\11\11\11\11\11\11\11\11\11""3U3fUD"3UUUffUUUUfUDDDUUDD333D"\11\11\11"""""33"\11"\11\11\11\11\11"\11"\11\11\11"""\11\11\11\0\11\11\11"\11\11\11\11\11\11\11"""""\11\11\11""3333DU"""3""\11\11"\11\11\11\11"f\88\99\99\99\88\88\88\99\99\99wfUUUDDDDD33333333333333""""""\11\11\11\11""3"\11"D"\11"""""""""""""""""""""3"""""333DUUUDUDDDDD33DU3""D333333"""\11""\11""""\11\11\11\11\11\0\0\11\0\0\11\11\0\11\11\11\11\11"\11"""\11\11\11\11""\11\11\11\11\11\11\88wDw\88ª»»»ÝîîîîÿÝ\99w\99ª\88\88UUUffw\88f\88w\88wwUfUUDUD3""DDDD3D3"""33Dw»ÌÌ̪»\88w3\11\11\11\11\11\11\11"\11""\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11"""""3"\11\11\11\11\11\11\11\11\11\11\11\11"3DD\11UUDDD3UfDUD"UUUUUUfD333DD""\11\11\11""3"""3""""""\11"""\11\11\11\11\11\11\11\11\11\0\11\11\11\11"\11\11"\11\11"\11""\11"\11\11\11\11\11\11"3DDU\8833\113"\11"\11\11\11\11\11\11Dww\88wUfwwwf\99\88UUUfDDDD3""333"""33"3"""""""""\11\11\11""\11\11""""""""""""""""""""""""333"\11""33"DUUDDDUUDD3DDD3DfU"UU""""""""""\11""\11"\11\11\11\11\11\11\0\0\0\11\11\11\11\11\11\11\11\11\11\11""""""""""\11\11\11\11\0\0Dw\99»»ÌîÝîÌÝÌÌÝîÿ»wffUffwf3UfUUf\88\99fffUUUDD333"""33DD3D33""333\88»Ì»»\99ªwU"\0\11\11\11\11\11\11\11"""""\11\11\11"3""""\11\11\11\11"""\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\0\0"UDD"UUDfD3"33""\11\11UfUUUD3"3D3D"\11""""33""""""""""""""""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3""\11\11"\11\11\11\11""D3DUUf3"""\11\11\11\11\11\11\11\11DwwfDUD3DfffwUUUUUD333""333""""3""""""""""\11\11\11"""\11"\11""""""""""""""""333""""D33"""3333DUDUDD3UUUDDDU333D3"\1133\11""\11\11\11""\11\11"\11\11"\11\11\11\11"\11\11\0\11\11\11\11"""\11\11"\11""\11\11"\11"\113"\11\11\11\11\11\11\0wwwÌ»Ý\99ÌÌÝ»îîîݪffUUDDfw"fffDDUfU3DUDD3D3""""""3"DD3DD""""3fª»»ª\88ªf3"\0\11\11\11\11\11\11\11""D3""\11"DD"""""\11\11\11\11\11\11\11\11\11\11"\11"\11\11\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11UfD"3Ufff"3"\11\11\11\0\0"UfUUD""3D33"\11\11""333"""""""""""""""""\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11""\11"3""""\11\11"\11"33DUf3"\113\11""\11\11\11\11\11DfwfUD33UffUDDDUUUD333""33"""""""""""3"""\11\11\11""""\11"""""\11\11\11""""""""""333""33D3""""""3DDDDDDDUUUfUUUUD"D"3"\11\11\11"\11\11\11\11""""""\11""""\11"""\11\11\11""\11\11\11\11\11\11\11\11\11"\11\11""\11"""\11\11"3"\11\0Dwf\99\99»Ì»ÝÝîÝݪ\99wfUDDD33Ufw\88UDDDfD333DD3"""""""""3U333D3""""3\99»»\99\88\88f"\11\0\11\11\11\11"\11\11"\11"DD""\11DU""\11"""\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11"\11\11\0\11\11\11"\11\11\11\11\0DfUDDDDfw33""\11\11\11\11\11Ufwwf""DU""""\11""33333""""""33"""33"3"\11\11\11\11\11"\0\11\11\11"\11\11\11"\11"\11"""""""\11"\11\11"""DUfD""""3""\11""\113U\88wfffw\99\99wUDDDDUUD33"""3"3"""\11\11"""""""""\11\11\11""""""""""""""""33"""3"3333"333""""""3333DUDUDDUUUUUUfD3UD"\11\11\11"\11\11\11"\11\113""\11""\11\11"3""3"\11"\11\11\11\0\11\11\11\11\11\0\11""3"""\11"""\11\11""\11"DU\99ªÝîÌÝîÝîÌ\99ff\88fD3333DD3Dfw\88fUDUD3333"""""\11"3"\11"\11DU"3D3"""\11"D\99ª\99\88\88w"\11\11\11\11\11\11\11\11\11\11\11\11"3U3\113D""\11\11"""\11\11\11\11\11\11\11\11\11"\11\11\11\0\11\11\11\11\11\11\0\0\11\11\11\11\11\11\11\113fUUfD3DUwwD\11\11\11\0\11"DUwwwU"3DD"\11""3"D33333""\11"333333333""\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"""\113"""""3"\11\11\11"""UwU\113"3"D"3"333Df\88w\99\99ªª\99\88wUUUDDD333""33""""""""""3"\11"""\11\11\11"\11""""""""""""33"33""3"""3D333"""""""3"33DDUUUUUDUUffwwUwU\11\11\11\11\11"\11\11\11\11\11\11"\11\11\11\11\11\11\11"""D"\11"\11\11\11\11\11\11\11\11\11\11\11\113UD"\11\11\11"D"\11\11"""DfUUwª»»ÿݪ\88UD33D3"""""3DUUD\99\88fUUU3DD"""\11"""""\11\11"DDw333""\11\11\11\113U\99wfU\99U\11\0\11\11\11\11\11\11\11\11\11\11\1133DDDU3"\11\11\11"""\11\11\11\11\11"\11\11"\11\0\11\11\11\11\11"\11\11\11\11\0\11\11\11\11\0\11"3fUf3UD33Dwf\11\11\11\11\11"UD3DUU33U3"""D3D3DD333"""\1133D333333"3"\11"\11\11\11\11\11\11\11\11\11\11\11\11""""""""""3"""""""3UwDDD333"\11\11\11\11\11"Dfww\88ªª»ª\99fUDD33333"33"""""""""""""""""\11\11\11\11\11""3"""333""""""33""33333D"3"""""""""3333DDDUUUUUUffw\88\88\99D""\11\11\11\11\11\11\11"\11\11""\11\11\11\11\11\11"333DD\11\0\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11"\11""""""""DD3"w»ÝÝÌ»fD3""""""""\11\11""3DDD\88fwffDDD33"\11""""\0"DwwwwwwD"DUDD333wwwfwU"\11\0\11\11\11\11\11\11\11\11\11\11""3DfU3"\11\11""\11"\11\11\11\11\11"\11\11\11\11\11\0\0\11\11\11\11\11""\11\11\11\0\11\11\11\113DffDDD3""3Uw"\11\11""333""3333UD33DDUDDff3"333"""3DUD33333""""\11\11\11\11\11\11"\11\11"""""""D"""""33"3"\11\11\11"DUff\88D333\11\11\11\11\11"fww\88w\88ª»Ì\88D33333333"33"""""\11\11"\11"""\11"3""""\11\11""DU3"33DD3"""\113333""3""3DD3""""33"""""333DDUffUUUUfUf\99\99\88\11"""\11\11\11\11\11\11"\11"\11\11\11\11\11"\11\11"33""\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""33D""D»ÝÝÌ\993""\11\11\11\11\11\11\11"\11\11\11\11\11\1133"fwUUUUD333""""3"3fwffUUUDDwwUDDUw\88ffffwfD\11\0\0\0\11"3\11\0\11\11\11\11"3DD333"\11""""""\11\11\11\11\11\11\11\11\11\11\11\0\0\11\11\11"\11\11\11\11\11\11\11\11\11\113wUwUDD"""Dw3\0\11\11\11\11\11\11""3"3"""DDDD3Uwwf3333D33""DDD3"33"3""""\11\11\11\11\11\11"""""""""3\11"""3""""3""""33fwwD""""\11\11\11\11"ffffwªª\99wD"333333"3""""""""\11\11"\11\11\11\11\11\11""""\11\11\11\11"33"33"3D3""""DD33333333D3D""""""""""""D33DUUUUUfUfw\88\88f\99U"""\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11"""""\11\0\11\11\0\11\11\11\11\0\0\11\0\0\11\11\0\11\11\11\11\11\11\11""33""U»Ý»\88U"\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""DD3DDUUDDDDDDDDDDDDDUD33DD3D3""33DwUD3\88w\11\0\0\0\11""\11\11\11\11\11\11"3D3"""""3"""""\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11""\11\11"\11\11\11\11\11\11\11\11UwwfUD3""\11DD\11\11\11\11\11\11\11\11\11\11"\11\11\11\113333DUwwffU"""33333D3"33"""""""\11\11\11\11\11\11\11"3""""""""""""33"33""\11"\113UD333"""""\11\11\11Dwfff\99\99fD"333333""""""\11\11"""\11\11"\11\11\11"\11\11\11\11\11\11\11\11""\11""""\1133D333"3333"""""33333"3""""""""33333DDDUUUUfffwfUwf"\11"\11\11\11\11"\11\11"\11"\11\11\11\11\11\11\11"\11\11\11\11"\11\0\11\11\0\0\11\0\11\11\11\11\0\0\0\11\11\11\11\11\11\11\11"""""fªÌ\99f"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""D3"33UwU33""\11"""33D33""3"""""""3DUw33fªD"\0\0\11"\11\11\11\11\11\11\11\11""3"""""3"\11"\11\11\11""\11\11\11\11\11\11\11"""\11\11\11\11\11"""\11\0""\11\11\11"UwwU3"""\11\11D"\11\11\11\11\0\11\11\11\11\11\11\11\11\11"33DUffffwDUD3"33333""D33""""""\11\11"\11\11"\11\113""\11\11""\11\11\11""""33"33""3""Uw3\1133333""\11\11\11wfDD3ffD33"3""3"""""""\11""\11\11\11"\11\11\11\11"\11\11\11\11\11\11\11\11"\11\11"""""333333D3"33""""""333"""""""333"3DDDDDDUUUUffffDw\99U\11"D""""\11\11"\11\11\11\11\11\11\11"\11"\11\11"\11\11\11"\11\11\0\0\0\0\0\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\113UU»ÌªUD"\11\11\11\11\11\11\11\11\11\0\0\11\11\11\0\0\0\0\11\11\11\11\11\11"D""D333\11"\11\11\11"3\11\11"""""""""""""\11""3Dw\88f»w"\11\0\11\11\11"\11\11\11\11\11\11"\11\11""""\11"""\11"\11\11\11""\11\11"\11"33D3"\11\11\11\11\11""\11\11\11\11"\11\11\11"ffU3"""\11\11""\11\11\11\11\0\0\0\11""""\113D"DD3""""3DUDD"3D333""D"\11"""""\11\11\11\11\11\11\11\11\11"""""""3"""""3333333"""33fD33D""""""\11"UfDDDfUD"""""""""\11\11"\11\11\11\11\11\11\11\11\11\11\11"3""\11\11\11\11\11\11"\11\11\11\11""""3U3333333""33333"33""""""""33""3DD3DD3DDUDDUfw\88f\883\11\113"""""\11\11\11\11"\11\11""\11"""\11"\11\11\11\11\11\11\11\0\11\0\0\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11"UwªÝÌ\99wD"\11"3"""\11\11\11\11\11\0\0\11\11\0\0\0\0\11\0\0\0\0\11\11\1133DD""\11\11"\11\11""\11\11\11\11"""""\11\11"\11\11"\11\11"33Dw\99»w3\11\0\0\11\11\11\11\11\0\11\11\11\11\11\11"""""""\11\11\11\11\11\11""\11\11"\11"3333"\11\11\11"3"\11""\11\11\11\11\11\11\11DfD""""\11\11\11"\11\0\11\11\11\11\11\11\11""\11\11""\11""\11\11\11"""3D3D33D33"""33\11\11"""""\11\11\11\11\11\11\11"3""""""33"""\11"33333"33"3Uwf""""\11\11"\11D"\11ffDDDwD"""""""""\11"\11"\11\11\11\11\11\11"""""3D"\11\11\11\11\11\11\11\11"\11\11\11\11""""3"3"333333333333333"""""""3"3"3DDDD3DDDUDD3UwwU\99D\11\11\11\11\11""\11\11\11\11\11\11""\11\11\11\11""""\11\11\11\11\11"\11\11\11\0\0\0\0\0\0\0\11\11""\11\11"\11\11\11\88ª»\99\99\99\88\88f3\11\113""""\11\11\11\11\0\0\0\11\11\11\11\11\0\11\0\0"\11\11\11"DDD"""\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11"""\11\11\11\11""DUUU\99w\11\0\0\11\11\11\0\11\0\0\11\11\11\11""""""""""\11\11\11"\11""\11"""""\11\11\11\11\11""33\11\11\11\11\11\11\11\11\11\11DfD"""\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11""33\11\11""3"DUU3D33"333""""""""\11\11"\11\11\11\11\11\11\113"""""\11"33"""\11"333"3D333DU\88U\11\11\11\11"\11\11"UD\88wfDUf3\11\11\11\11\11\11"\11\11\11\11\11\11\11\11""""\113""3"\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11"""""333333D3DD333333333"""""333333DD3D3333DDDDDUffUw\11\11\11\11\11\11\11""\11\11"\11\11"""\11""\1133"\11\11\11\11\11\11\11\11\11\0\0\11\11\11\11\11\11\11\11\11\11\11\11"wÌ»\88w\88wfff3"\11"""\11\11"\11\11\11\11\11\11\11\0\11\11\11\11\0\11\0\11\11\11\11\11"333""\11\11\11\11\11\11\11\11\11\11""""\11\11"\11"\11\11\11\11\11\11\11"33DU\99f\11\0\0\0\11\11\11\11\11\11\0\11\11"\11\11\11\11""\11"\11\11\11""\11"\11"""""\11\11\11\11\11\11"""\11\11\11\11\11\11\11\11\11\11\113U33"""\11\11\11\11"\11\11\11\11\11\11""\11\11\0\11\11"""3\11\11\11\11""3UfDUD3""333"3"\11\11"""\11\11\11\11\11\11\11\11\11"3"""\11\11"333"""""333DU3"DD3Df3""\11\11\11\11"U\88\99wfUff3"\11\11\11\11\11\11\11\11\11\11\11\11\11"""""33D3\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11""\11"""""""\11\11\113DUDD33"333"D3""333333UDDD33333DDDDDUUf\99"\11\11\11"\11\11\11\11\11\11\11\11\11\11"33\11"""3\11"\11\11\11\11\11\11\11\0\0\0\11\11\11\11\11\0\11\11"\11"D\88̪\88wffwUD"""\11\11""\11""3"\11\11\11\11\0\0\11\11\11\11\11\11\0\11"\11\11\11"\11""\11""\11\11\0\11\11\11\11\11\11\11""""""\11\113"\11\11\11\11\11"""33f\99"\0\0\0\11\11\11\0\11\11\11\0\11\11\11\11\11\11\11"\11\11"""\11"""\11"\11""""\11\11\11""\11"\11\11\11""\11\11\11"\11\11\11DUD"""\11\11\11\11\11\11"\11\11\11\11\11"33\11\11\11\11"""""\11\11\11\11"\11\11\11\11Uff333DDU33"\11\11"""\11""\11\11\11\11""3""\11"\11""333"""""3D3D33DD3DfU33"\11\11\11DUwwwwffw3"\11\11\11\11\11\11\11\11\11\11\11""""""3D"3"\11\11\11\11\11\0\11\11\11\11\0\11\11\11\11\11\11\11"\11"""""""""""""DUDD"33"3"33"33""3DDD3333333DDUfffUfw\99\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3"3""""\11\11\11\11\11\11\11\11\11\11\0\11\11\0\11\0\0D\99»»\99»ªwwwUfDDU3""\11"""\11\11\11""\11\11\11\11\11\0\11\11""\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11""""""""""D\11\11\11\11\11\11\11\11"DD\99D\0\0\0\0\0\11\0\0\11\11\11\11\11\11\11\11\11\11\11""\11\11""\11"3"""\11\11"3"\11\11"\11\11\11\11\11\11""""\11\11"\11\113UD3""""\11\11\11\11\11"\11""\11\11\113U\11\11\11""""\11""\11\11"\11\11\11\11"U\88UD33DUU33\11\11\11"""\11"\11\11\11\11\11"""\11\11"""\11\11"33""3333D333DDDUUfDDD\11"\113\99\88\88wfU"fD\11\11\11\11\11\11\11\11\11\11""\11"""3"3""""""\11\11\11\11\11\0\11\11\0\11\11\0\11\11\11\11""""""""""""""""3UD333"3"33"333"3UUD333333DD33UªwUfw\88f\11\11\11\11\11\11\11\11"\11\11\11\11\11""\1133"""3"\11\11\11\11\11\11\0\0\0\11\11\11\11"U\99ªwf\88wUUwUD"3DD3""\11\11\11"""""""\11\11\11\11\11\11""""\11\11""\11\11"\11\11\113\11\11\11\11\11\11\11\11\11\11""\11""""""3"""\11\11\11\11\11\11"\11\11\11"3Uw3\0\0\11\11\11\11\11\11\11\0\11\11\0\11\11\11\11\11"""\11"\11\11\113"""\11\11\11\11"""\11\11\11\11\11\11\11\11\11"\11\11\11\11"\113UUD3""""\11\11\11\11""""\11\11\11\11"U\11\11""""""\11\11\11\11\11\11\11"3"UUUDDDDUD3"\11\11"\11"3"3"\11\11\11"""""""""3"""33333D33D33DDUDD3"3"\11\11"wfUUUDD3w"\11\11\11\11\11\11"\11""""""33"3"""""3\11\11\11\11\11\0\11\11\0\0\11\0\0"\11\11\11"""""\11""33""""""3DDD333"33333333UUDD33D333D33DwUffww\99"""""\11\11\11\113D\11\11"\11"""""""\11\11\11\0\11\11\11\11\11\0\11\11\11\11"DªªfDDD3Dff3""33"333\11\11\11\11\11\11"\11"\11\11\11\11"\11\11"""""""\11\11\11\11\11\11\11\11"""\11\11\11\11\11\11\11"""3D33"33"""""\11\11\11\11\11\11\11\11\11"DwD\0\0\11\11\11\11\0\11\0\11\11\11\0\11\11\11""\11\11\11"\11"\11"""3D""""\11\11\11""""\11\11\11\11\11\11\11\11\11\11"\11\113UD""""\113"\11\11\113""\11\11\11\11\11\11\11\11\11\11"""\11\11\11\11"""\1133"3"3UD3""D333""""33"""\11\11"""""""\11""333"""333333DUDDDUUDUfD\11"UwfUUUDDD3f\11\11\11\11\11""""""""""333"""\113U3\11\11\0\11\11\11\11\11\11\11\0\11\11\11\11"""""\11\11\11"""""\11\11"""3DD333""3"33333DUDDDD3D333D333UDfw\88\99D\11\11\11\11\11\11\11\11\1133\11\11\11\11""3"\11\11\11\11\11\11\11\11\11"\11\11\11\11""3w»w33D3DwU3"3""""""3"\11\11\11\11\11\11""\11\11\11\11\11\11"""""""""\11\11"\11\11\11\11\11"""\11\11\11\11\11\11""""3"D33"""3""\11\11\11\11\11\11\11\11\11""UD\0\0\0\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11""""""\11UUf3\11"\11\11\11\11""""3f3\11\11\11\11\11\11"\11\11\1133""""\11\113\11\11\11\11""\11\0\11\11\11\11\11\11\11\11\11\11"\11"\11"\11""""3"""\11\113\11\11\11\0"U3""3ffD3""""""3"3"""""3D"3""""33333DUDw\88fUU\8833\88\88ffUUUDDDDDD\11\11\11\11""3"""""33""3"""\11"DU"\11\11\11\11\11\11\11\11\11\11\11\11""""""\11"""3""""""""""3D3"333"3D3333DUUDD3D333"3333DDUw\88\88w\11"\11\11\11\11\11\11\11\11"\11\11"33"""\11\11\11\11\11\11\11\11\11"\11"""3Dw»\99"""3DUfD""3"""""""\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11"\11""\11"3""\11\11\11\11\11"""3""3""\11\113"\11"33DD3"DD""D"\11\11\11\11\11\11\11\11"3D3\0\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11Df3\11\11\11\11\11\11\11"""\11\11\11\11\11"\11"""\11\11\11"D""\11""\11\11\11\11\11\11\113\11\11\11\11\11\11\11\11\11\11\11\11"\11"\11\11""""""3""\11\11\11\11\11\11\11\11"3"Dw\99\99wD33""""3"""3""""DD""""""""D3D33Dww\88w\88Df\88fUUfUUDUDD3DU\11"""3"333"""3"3D""3""DD3"\11\11\11\11\11\11\11\11"\11"3""\11\11""""\11\11""""""""""3"3D333"DD33D3DDUUUD333D33D33"UDUff\99U\11\11\11\11\11\11\11\11\11\113""""3"\11""""\11\11\11\11\11"\11\11\11\11"Dªª3\11""DUUU3"33""333\11""\11\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11""""\11\11""""3""""3""\11\11""3"3"3333DD333D3\11\11\11\11\11\11\11""""\11\0\0\0\11\11\0\11\11\11\11\11""\11\11\11\11\11\11\11\11"""""\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11"\11""""3\11\11"33""""\11\11\11\11\11\11\11D3\11\11\11\11\11\11\11\11\11\11\11\11""\11""\11"""""3"""\11\11\11\11\11\11\113w\99ª\88ª\99\99w3""3""""""3""""33""""3"""DD3DDUDD\99ªª\99\99U3DUUDUUDD33ff""""333""""3"3""333fff""\11\11\11\11\11\0\11\11\11\0""""\11""""""\11"""\11""""""\1133"UDD3333DDDD3DUUUUD3DDD3""""UUUU\88f\11\11\11\11\11\11\11\11\11\11\113D"""""\11\11\11\11\11\11\11\11\11\11""""\11\88ªU"""3fUDDD333""3U3""\11\11\11\11"3"\11"\11\11\11\11\11\11\11\11\11\11\11\11\11""""\11\11\11"""""""D33"""""33"33333D33"3""\11\11\11\11\11\11""33\0\0\11\11\0\11\11\11\11""\11"""\11\11\11\11\11\11"""""""\11\11\11\11"\11\0\11\11\11\11""\11\113"\11"""3"\11\11\11\11\11U3"""""\11\11\11\11\11\11"""\11""\11\11\11\11\11\11""\11\11\11"""\11"""3DDf3"3""33Uw\99\99\99\88w\88\99\88\88U3"""33D"""33"""3"""""""3DDDDDDfUD\99ª\88UDUUUDfUDD"3\88\99U3"""3D"""3"""""3333D33""\11\11"\11\11\11\11\11\11\11\11"\11\11\0\11"""""""""\11"""""""D"\11"D33333DDDUfwfUUffDUD3""3"3DwUwf""\11\11\11\11\11\11\11\11\11"\11""""""\11"\11\11\11\11\11""""3DUªª3"""DfDUUD3""""""""""\11\11"""\11\11\11\11\11\11\11\11"\11""\11\11\11"""""""""""""3DDD33"""""""""3""33"""\11\11\11\11\11\11""""D"\0\11\11\11\0\11\11"\11"\11\11\11\11"\11\11\11\11\11\11\11\11"""""""\11\11\0\0\0\11\11\11"\11\11\11"\11\11"\11""""\11\11\11\11\113U""""""\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11"\11\11"\11\11"""""3333f\88wffUf\88\99\88fDDUUfffw\88D33""""3333""""333""3"3333DDD3Dfff3f\88UUUfwwfU3Ufªª\99fD3D3U3""3"""3"3D33"""3"""\11"\11\0\11\11\11\11\11\11\11\11\11\11\11\11""""\11\113\11"\11\11"""""\11\11""3333DDUDf\88\99\88fUUfwfUD""""DDUfUw""""\11\11\11\11\11\11\11\11\11\11""3"""\11\11\11\11"\11""33"D\99»\883"DUfUDDD3"3"""""""\11\11\11\11\11""\11\11\11\11\11\11\11""""""\11"""""""3""""33DDUDDUUD333"3""""""33""\11\11\11\11\11\11\11\11""33\0\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""\11\11\11\11\11\11\11\11\11\11""\11\11"3"""""\11\11\11\11\11\1133""""3"\11"\11"\11\0\11\11\0\11"\11""\11\11\11""\11\11\11""""""3DUU\88ª»ª»»ª\88f3"\11"3UD33DUD"3333""33"3"""3333"""33333D"DUUff\11UwfffwwfDDU\88\99\99wwwf3DDDD"""""3"3333"""33"\11"\11\11\11\11\11\11\11\11\0\11\11\11"\11\11""""\11\11""\11\11"""""\11\11\11\11""3"33UUDf\88\88wfUDUwwfUD3""3DUffww""""\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11""DU3\11\11\88D33wfUD""""""D3"3""\11\11\11\11\11""""\11"""""""""""\11\11"333333"""33DUUUU3DDUDDD3"3"3""""""3\11\11\11\11\11\11\11\11\11"3"\0\0\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11\11\11\11""\11\11""""3333"\11\11"\11\11\11\11DD""3"3U""\11""\11\11\11\11\11""\11\11\11\11\11\11\11\11\11\11"""""33DDUw\88»»ª\99UD""\11""""D3""33"3"33""333"3""3333333333333DDDUUf3"U\99\88\88wwwffwwwwfffwwUDDUU""""3"""33"3333""""\11\11\11\11\11\11\0\0\11\11\11\11\11\11""""""\11"\11\11\11"\11"""\11\11\11"""DDD\11Df\88\88fUUUDwwwwfUD3"3DDUw\88f3""\11\11\11\11\11\0\11\11\11"\11\11\11\11""""\113"D3""\11D\99ªUDDUwU33"3"""\11"3"3"""\11\11\11"\11\11\11""\11"""""""""3"\11""""3DDDD3DDDDD"33\11\11\11""3""333D3""3""\11\11\11\11\11\11\11\11"""3\0\11\11\11\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\113\11\11""""33\11""DUUUD33\11\11\11\11\11\11\113DD""""3U33"\11\11\11\11\11""\11"\11\11\11\11\11\11\11\11\11"3DDDDDDUUDww\99ª\88D3"""\11""\11"D""3""3333"""33333""""3333""""""3DDDUU"\11"\11\99ª\88\99fUUfwfUffDUwwwwff"""3333"""3D3""3""""\11\11\11\11\11\11\11\11\11"\11\11\11\11""""\11\11\11\11\11\11"\11\11\11\11\11\11\11"""3UD3"U\88wUfUUf\88w\88wffUDDDDDf\99ª\88"""\11\11\11\11\11\11\0\11\11\11\11\11\11""3"\11"3""""3fªªf3DfUUD3"""""\11\11\11""3"\11\11\11\11\11\11\11\11\11"\11\11""""""""\11\11\11"""""""""3""3333"""\11\11\11"""""333"""33"""""\11\11\11"\11\11\1133\11\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11"\11\11\11\11\11""\113"""3"\11\11"3DfUD3""\11\11"\11\113DDD3"""UUDD""\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\1133Dfww\88wfUfUUfUD3""\11"\11"""\113D"3"""333DD333333""""33D3333"""""33DU"\11"\11\11f\99\88wfffffDUU3DUUw\99\99\88D333333""""3D333"""""\11\11\11\0\11"\11"\11"\11\11\11\11"""\11\11\11""\11\11"\11\11\11\11\11\11\11\11""333fU3"Dwf\88\88\88wfffwfUUDDUU\88ª\99U"""\11\11\11\11\0\0\11\11\11\11\11\11"\11"""UU\11"DU\99ª\99fDU\88fD3D""\11""\11\11\11\113"\11"""\11\11""\11\11"""\11\11\11"""""""\11\11"3"3"""\11"""""333""\11\11\11\11\11\11""""""""3""""\11\113""\11\11"\11"\113\11\11\11\11\11\11"""""""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11""\113D3\11\11\11\11\11"3"\11\11"\11\11\11\11\11\11333D3""3D""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"3DU3UfwfUfUD3D3""\11\11"""\11"\11\11\113D3"3"33DD33333D"""""3DDD3""3""""3DU33"\11\11\113\99\99w\99\88fUUDD3DDUUw\99\99\99w33""""""333DD""""3""\11\11\11\11""\11"\11\11\11\11\113\11\11\11\11""\11""\11"3\11\11\11"\11\11"""3fwU\11"\11"33w\88wffffffUffUUfw\88\883"""\11\11\11\11\11\11\11\11\11""""\11\11\11D\99ªÌ»ªª\88fUDf\88DDD3"33""""""33"""""3""\11"""\11"\11"\11\11"""""""""3""\11"""""""333""\11\11\11\11\11\11"""""3""""""\11\11""3"\11\11"""3"3\0\11\11\11""""""3""\11""\11"\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11""3"\11\11\11\11\11\11\11\11""\11D33\11\11\11\11"3D3"""\11\11"""\11"\11\11\11\11\11\11"\11\0\11\11\11\11""\11\11\1133DD33UDD3"""33\11\11\11"\11"""""\11\11\11D333"DDDD33DDD""""33DDDD33"""\11"DDUD3\11\113"D\88fffUDDDD3DDUfffw\88\88f3U"""""333333"""3""\11\11\11\11\11"\11"\11""\11\11\11\11\11""""\11\11D"\11\11\11\11\11"\11\11\11\113ffD"\113\11"3"U\88fwwwfUffUwUDwwfww\11"\11"\11\11\11\0\11\11\11\11""\11\11\03f\99\99\88wfffUUfwfU3333"""3"""""3""""""""3""""\11""""\11"\11"33"""33D33"""""""""""3"\11\11\11\11""\11"""3""""\11\11"\11""\11"\11"""33DD\0\11\11"3\11\11""3D"\11\11""""\11\11\11\11\11\11\11\11\11\11\11\11""3"""""\11"\11"\11\11\11\11\11"""\1133\11\0\11\11\11\113DD3""\11\11""""\11\11\11"""""\11\11\11\11\11\11"\11\11\11\11\11\11\1133"33"\11\11\11\1133\11\11\11"\11"\11\11\11"\11\11\113DDDDDUDUDDUUD33"3DUDUUDD3"\11\11\11\113UUU3\113UDfDUfUD33333DDfffff\99\99DU""""3"3D3D"""""3"""\11\11\11\11\11"3\11""33\11\11\1133\11\11"3D""\11\11\11"\11\11"Uwf3"\11\11\11""3""fwfwwwfUUUffUfwfw\993"""\11\11\11\0\11\11D"""\11\0"\99»\88wwfw\88\88\88wwfD333"3""""""""\11"""""""""3"3""\11""\11"\11""""3""""DDD""""""\11"\11"""3""\11\11\11\11\11\11"""3"3"""""""""\11""""3DD3\11\11\11\11"""\11\11"3\11\11\11""\11\11\11\11\11"\11"\11\11\11\11\0\11""3""""\11\11\11\11\11\11\11\11"\11\11"3"\11\11\11\11\11\11\11\11"D33""""""""""333"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11"\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11""DD3\11"UD33UUUDD3DUf3UfUDD3"\11"\11""3UD3"\88\88ffUUfUD333DDUffwwww\99\88\88wD3""""333D""3"""3"\11\11\11\11"\11Uf3Dff"\11"""3"""""3"\11"""\11Dw\88D""\11\11""3D3D3UwwfUwffffwfwffU\99D""""\11"\11\11\11\113\11\11"UªªwU3DfwfUDDDD3""3""""\11""""""""""""""""\11\11"3""\11\11\11\11\11\11""33""33D33"""""""\11"3"""\11\11\11\11\11\11\11"""""3DD"\11"""\11\11""""33DDD\11\11\11\11\11\11\11\11\11"\11\11\11""\11\11"\11\11\11""\11\11\11\11\11\11\11\11"""\11\11"""\11"""\11""\11"3"\11\11"\11\11\11\11\11\11\11""33"3D""\11"3"33D"\11\11""\11\11\11\11"\11\11\11\11\11"\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11"\11\11"D3"\0UUffDDD3"\11DwfffUD"""""3DD3"ª\88wfffUUUUD3DUDUUwfww\88\88ffU""3""""3"""33"3"""""\11\11DwwfUf""\11"\11"""\11""""""\11"3wf3"3""""""D"UD""wwfDwwww\88wwwff\88\88"""3""\11\11\11\11"\11\11f\99ªfD333DDUDD3333""33"""\11"""\11\11""3"""""""\11\11\11\11""""\11\11\11\11\11""3"\11""3D333""333"\11\11"3"""\11\11\11\11\11\11""\11"33"D3"""""""""3DDDUwD""\11\113333Df"3""\11\11\11\11\11\11""\11\11"\11\11""\11\11\11\11""""""""\11"3""""""\11\11\11"\11\11\11\11\11\11"333"3"\11\11"""\11"\11\11\11\11"""\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11""\11UDUUDU3\11"\11UfUffUD""\113""D\88f\88ªªwfUUUUUUUDUUUfwfww\88\88w\88ffU33"\11""""33""3"""""3Dff33U"""""\11\11\11\11\11\11"""""3UUU3\11""""""3"D333""3Uwww\88w\88wffffUU\88D3"""""\11\11\11\11\113\88ªwD3"""333D3333""333"3"\11"\11""\11\11""""""""\11\11\11\11\11\11""""\11\11"\11""3"""""""""3"""3"\11\11""3"\11\11\11"""""""""33"33"3""\11"\11"3DDfwwffD3\11DUUff\88\88DU3\11\11"\11\11""\11\11""\11\11\11\11\11\11\11\11\11"""""""\113fU""""""\11\11\11\11\11\11\11\11\11\11"3""\11""""""\11"""3""\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\0\11\11\11\11\11\11\0\11"\11\11\0\11\11\11\11\11\11\11\11\11""3DDD3DU"\11\11"w\88\88\88wwU333"3U\99\99f\88\99ªwfUUUffD3DDUDUfwwwffwwUw\88\88wU3"""""\11""3"33"DUUU3\1133\11"""\11"\11\11\11\11"3"33Uf333"""\11\11\11\11"\113"33"""DUUw\88wwffwffUUD3"33""""\11"""\88»\88DD3"""""33333333""D3"""""\11\11\11"""""""""""\11\11\11\11"""\11\11\11\11\11"""\11\11"""\11"\11"\11\11\11\11\11\11\11""""""\11\11""""""""33"\11"D""D3"""\11"DDDw\88UfwfwDUfDw\99\99UU3D"""\11"\11\11\11\11\11"""\11""\11\11\11"""""""33ff3"""""""\11\11\11\11\0\11\11\11"""DUD3""""\11"""33"\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\0\11\0\11\0\0\0\11\11\11\11\11\11\11\11\11\11\11\0\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""DUUfffUfUDfffUDDfw\88\88w\88\88\88wfU\88\88\88\99wUwfDUUUDDDDUUfffffwUUwwwUUUU3"333"""""3fwDU3\11""\11\11"""3D"""""\113U\883\11"3""\11\11\11\11\11\11\113"\1133""3""ff\88w\88wffffDwD"""\11""\11""""\11\88UD3""""""333"""3"""3333"""\11\11\1133D3""\11""""\11\11\11\11\11"\11\11\11""""""\11"""\11"""""\11\11"\11\11\11\11\11"\11""\11""\11"\11""""33"""D"""3""""3DDUw\88UUUUUUDDUw\99\99wwUUw3"""\11\11\11\11"""""""\11\11"\11""""""33U3\11""""3"\11"\11\11\11\11\11\11\11""Df\88U3""\11"""3""333\11\11\11\11\11\11\11\11\0\11\0\11\11\0\11\11\0\0\11\0\0\0\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\113"3fUfUfUD3"""""""""3DDUUffUfwfDwwwffwwUUUUUUfUUfffUUf\88\88wUUffww3""""""""3U3\113""\11"\11\11D3Uwf"""33DUw3"""""\11\11\11\11"\11\11"3333""3333UD\88w\88fffUffw"33"\11""""""3\88DU""\11\11""\11"""3"333""33""""\11\11\11\1133"3D"""""""\11\11\0"D""""""""\11"""""\113"\11\11\11\11\11\11\11\11\11\11\11"""\11"\11\11\11""""3"33""3""""""""3DDDU\88333DDDDUUfwwfw\88wfww3""\11\11\11"\11""""""\11"""""""333DD"""3"""""\11\11"\11\11\11"""3wU\11\11\11\11\11""""33"3"\11""\11\11\11\11\11\11\11\11\0\11\11\11\0\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\113"DfUD3333"3"""""""""3DDDDDUUfUUU33UffDUfwffUfUUffwwUf\88wwfUUfw\88w\88\88\88\88\88D3\11\11"33D"\11\11\1133fwffwfUUDUD3ff"""""3\11"\11\11\113"33333"3"3D3DDw\88wfffwf\88D3"""33D"\11"wÌ\99U\11"\11"\11\11\11\11""""333"3""""""\11\11\11\11"3""3"""""""\11\11\11"DU3""\11"\11\11\11""""""""\11\11\11\11\11\11\11\11\11\11\11""\11"\11\11\11\11"""\11"33333""3""""""3D3DDU"""""3DDUUffwfw\99\88fw\883"""""""3""33""\11\11"3"33"""3DD"\11""\11""""""\11\11""3"""\11\11\11\11"\11\11\11\11""D3"\113D3\11""\11\0\11\11\11\11\0\11\0\0\0\11\11\0\11\11\0\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11"\11"U3""""3""\11""\11\11"""""333DUfUUUUD3"3f33D33wwffwUfD\11\11"Ufffwfwwfw\88\99\88\88\99\88\99\99\88wfUw\99f"3w\88\99\99wUDf\88fD3333DD""""3D""""""3"""3""3333"33DUwww\88wwww"33333D"3\88Ì»fD\11""\11"\11\11\11""3"333"""""""D\11\11\11\0"D"""3"\11"3"\11\11\11\11"D\11"3"\11\11\11"""""""\11""\11\11"\11"\11\11\11\11\11\11\11\11"""""\11"""""33333""33"""333DDDDf3""""33DDUUUUfUf\88\88\88w\993"""\11\11"""3DDD"""\11"""3333D3"""\11\11\11\11\11""""""\11"""""\11\11\11\11\11"\11\11\11""""""33U"""\11\11\11\11\11\11\11\11\0\0\0\11\11\0\11\11\11\0\0\11\11\11\11\11\11\11\11\0\11\11\11\11\11""\11"3"\11\11\11"\11"DD3"""""""\11\11\11\11\11\11\11"""""3DDUffDD33""3""3333f\88w\88fD"\11\11\11\11\11"Ufwwwfw\88\88\88w\88\99\88\88wffDDf\88ª\99ª»ª\88fU3DDwfDfUUwf"""3D"D33"""33"""3""""33333D3D\99\88\88\99w\88U"33""\113\88Ì»\88DUU"""\11\11"\11""33"33"""""""3\11\11\11\113D\11""""\11""""""\11"3\11\11""""\11\11"\11""\11\11\11\11\11\11""\113""""""""""""""""\11"""""D3""3""""33DDDDDU3""""3333DDUUfffwff\88»\99f3\11"\11""3"DDUD"""""""33"3""\11""\11\11""""""""""""\11\11\11\11\11\11\11"\11\11\11""""33"\11"3""\11\11\11\11\0\0\11\11\11\0\11\11\11\0\11\11\11\11\0\0\11\11\11\11\11\0\11\11\11\11\11\11\11""\11\113"\11\11\11\11\113D3"""33""""""\11\11\11\11\11\11\11\11"3Uw\88\88f3"3""""""33333D\99w"""\11\11\11\11\11\11"33wf\88\88\88fw\88\88\99\88wwffDfw\88\88w\99\99ffDUUUfffwUDfwD"3""3DD3""3D3D3"""""""33"333333w\88\99\88\88U3D3D33\88Ì»w33fD3\11\11\11"""""\11"33"""""""\11"\11\11\11\113D"""3"\11\11\11"\11""""\11\11\11\11\11\11"\11\11\11\11""\11\11\11\11\11\11"""3"3""""\11\11""33"""""""""3D""33"""""3D3DDDD3D3"""""3"33DDDUfw\88w\88\88\99Ì\883""33D3DD3""""""3""""""""\11""""\11"""""""""\11\11\11\11"\11\11\11\11\11\11\11\11"""33"\11""""\11\11\11\11\11"\11\0\11\11\11\0\11\11\11\11\11\11\0\11\11\11\11\11\0\11\11\11\11\0\11\11"\11"3"""\11""UU"""33""""""""\11\11\11\11\11\11\11\11\11""3\88\88\88w3""""""333"33Dwf"\11"\11\11\11\11\11""\11\11"w\88\99\99w\88\88\88\99\99\88DDUUww\99wwwDDD3DDUw\88fffDffD\11""3DUUDUUUDDf3"""3"""3"""D3333\11\99»\8833DfDfªÌª33Df3"\11\11333""""""3"""333f"\11"""\11"3333"3""""""""3"\11\11\11\11\11\11\11\11\11\11\11\11\113\11\11\11\11""""""3""\11\11\11"33333""""""""D3"""""""33DDDDDUU\11\11D3D3D"""""""3DUfww\88\88\88ªª\88"33333""3D""""""""""""""\11"""\11\11"""""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3"\11\11\113""""\11\11\11\11\11\11\11\0\11\11\11\11\11\0\0\0\0\11\11\11\11\11\11\11\11\11\0\11"\11\11""\11\11"\11"UwD"\11\11\11"33"""""""\11\11\11\11\11"\11\11\11\113U3"DwU""""""33""DfUw"\11""\11\11\11\11\11\11\11\11\11"3fwfUUDDDUf3DDw\88\88wfU""DD3"DUUfDUDDUfUUDDfwUUDDDDDDD"3""33"3""33""3"D33\99ª»\88U3"DwÌ»ffUD3"\11"\11U3\113UDD33D3\11\11""3333""\11\11\11"""3333"DD""""3D"\11\11\11\11\0\11\11\11\11\113"3"\11\11"\11"""""\11"3"\11"DD3333""""""""D3"""""""""DDDUDDD\11\11"3""33"""3U3"33DDDUwwww\99\88\883"""""3U3""""3"33"""""\11"\11"\11""""3"\11"\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3"""""\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\0\0\0\11\11\11\11\11\0\11\11\0\11\11\11\11""""\113fUDDD"""""33"""""\11\11"\11\11\11\11\11""""UU""3Uf3"33333"3333\88D""\11"\11""""\11\11\11"""3U"UU"3""UDwUw\88U"D3""3D333DDD3UDUwwU"DUDfUDD333"D3333DDDDD3333"3"D"33U\88ª\8833\88»»fUD333DD"""\11\11\11""""""DDUD""""""3"\11\11"""""\11\11""3""3"""3\11\11\11\11\11\11\11\11"""3"\11\11\11\11"\11\11\11"\11\11""""""3DD33"\11\11333"\113D"\11\11\11"""""3UDUUDU"\11"3"""3""""DD"""333DDfw\88w\88\99ww""""33"""3fw3D3""""""""""""3""""\11\11""\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11"""\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\0\11\0\11\11\11\11\11\11\11\11\11\11\11\11"\11"3Uf3"3DUD33D3""33"\11\11\11\11\11\11\11\11\11\11\11\11"DUf"\11"3fD3""333""33UwD\11\11""""\11"\11"""\11\11"333D"3"\11"Uf3"fD"33"DDUD33"33D3UUU3"333"3DDDD33"D33333"3DD33333""""3D3Dwª»»Ì»wUUD3"3Uf3"""\11\11\11\11"""""\11\11"""""3"""""33"""\11\11""""\11\11\11""33""\11\11\11""\11""""\11\11\11""\11\11\11\11\11\11\11""\11"\11\113DDD"""33""\11"D""\11\11\11""""33DUDUD3""3""""""3""\11\11""""33DDUwww\88\99wwU""33""3DDUU3"3"""""""""""""""""\11\11"\11\11\11\11\11\11\11"\11\11\11\11"""\11\11\11\0"3"\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\113wfU3""33333"""""3""\11\11"\11\11\11\11\11\11\11\11\11"3333"\11\11UD3"333"""3D\88UD\11\11\11\11\11""3""\11\11\11"\113333333333"""33D33"333""""333Uf3""333""3D3333"D3"33"3333"333""3"33333\88\99ªÝÝ\88D33333""33"""\11\11"\11""""\11\11\11D""\11\11\11\11\11"""U3\11"""\11""""\11"""\11\11"""\11\11\11""""\11"\11\11\11\11"\11\11"\11\11\11\11\11\11"\11"\11\11""3333"33"\11\11""3""\11\11""""3"DUfDfD"""3"\11""""3""""\11""""DDUfffw\88fffw3D333D333D3"""""""3""""""\11\11"33"\11\11"\11\11\11\11\11"""\11\11\11""""\11\11\0\113"\11\11\0\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11UfUD3""33"""""""3""\11\11\11"\11\11\11""\11\11""\11"""""""\11U3333333""D\88\88\113\11\11\11\11"\11\11\11\11"\11\11"""3"""33D""\11"3"DUD""""3"""""33DD""""""""3333D3"3D"DDDDD3"33""333"3D33""f»ÌÝ\99wD3D33""""\11"""""""""\11\11\11""""\11\11"""""\11\11\11\11"3""\11"""\11"\11\11\11""""\11\11\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11"333DDD333"""33"\11\11\0\11""3333UUfUU\11""D3\11"""""""""""""333DDUUU\88\88ww\88\99fD33""333UU"3""\11""""3"""\11333"""""\11\11"\11\11"3"\11\11\11"""33\11\1133""\11\11\11\11""""\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\0\11\11\11\11\11""ffD3""33""""""""""""""\11\11\11"""\11\11"\11\11""\11\11\11"""3f"3""""""3D\99D"\11\11\11"\11""\11"\11\11\11"\11\11""\11\11\11\113D"\11"3UfD3DU3""3"\11"""33UD""""""""33""""DD333DDU3"3"""333"333"3"D»Ì»\88wUDD3""""33"""\11\11\11"\11""\11""33""\11""""""\11\11"3"""""""""\11\11"""3""\11\11""\11"\11\11\11\0\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11""333D"D3"D"\11""D"\11\11\11\11\11""33DDUffU3""33""""33"3"3"3""""33DDUUUwwfUww3\11\11\1133DDfwf3DD3UfU"\11"""33"""\11\11\11\11\11\11\11"""""\11\11\11""3DD"\11"U"""\11\11\11\11\11"3"\11""""\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0DfUD3333"""""""""\11\11"\11\11\11\11\11\11""\11\11\11\11""\1133""""""UD\11""""""33ff\11\11\11\11"3"""\11""\11\11"3"""33"3UDDDUD33"DD3D3\11\11"""""33DU3"""""3"3""""D3DD33DD3"""3333""3"3"3"U»ªfUDDDD333""""\11""\11"\11""""\11""""\11\11""""""""""\11"""""""""""\11\11\11\11\11\11""\11"""\11\11\11\11\0\0\11\11\11\11\11\11\11\11\11\0\11\11\11"""333D333""""""3"\11\11\11\11\11""33DDDf\88D3""""""""D3""33"""3""""3DDDUffwwUU"""""3D333DwwwfDUD3"\11"33\11\11\11\11\11\11\11\11\11\11\11\11\11""\11"\11\11"D33D3"\1133""\11\11\11\11\11\11\11\11""33"\11\11\11"\11\11\11\11\11\11\11\11\11\11""\11"""\11ffUDD3"""\11\11\11\11\11"\11"\11\11\11\11\11\11\11\11\11\11\11"""\11"""\113D""""""w"""""""""Dw"\11\11"\11"""3"\11"3""DD3D33DD3"""""""333333""""\11"\11"3DDD\11"""""3""""""UD333D3D"3333"""""3""DDw»\883DD3DDDDD""\11\11""3""\11""\11\11""\11"\11\11\11"""""""""""""""""""""""""\11""\11\11\11"""""\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11"3"3"33"""""3"\11\11\11\11\11\11"""33DUU\99D"""3\11\113"""3"3""3"""33"3333DUUUwwff3\11\11\11"""3D""""""""\11\11\11"""\11""\11\11\11\11\0\11\11\11\11\11\11"\11\11\11\11\11\11\113\11\11\11\11\11"""D3\11\11\11\11\11\11\11"3"3""\11"""\11\11""\11\11\11\11\11\11\11\11"\11""ffD333""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11"\11\1133""33\11""""\11DU\11""""""""Df\0"""\113UDDUD"""3D"D3"3"\11\11\11""""""""3""3DD""\11"""33U\11"""""""""""\113DDD333D33"""""""33""33\99ªU33DDD3UfUU"""\11""\11""\11"\11""3\11\11\11\11""\11\11\11""""""""""""""""\11"""""""\11\11\11\11\11"""\11"\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11""\11"3"""""""3"""""\11\11\11\11\11\11\11\11"3DDUwD"""""""333""\11"33D33""D"3333DUUfDUDD\11\11\11\11"""\11"""""\11"""""""\11\11""""\11\11\11\0\0\11\11\11\11\11\11\0\11\11\11\11\11"\11\11\11\11\11\11\11\11"""\11"\11\11\11\11"""""\11"""""\11\11\11\11\11\11\11\11""\11\11\11\11UfU333"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11"\11\11\11\11\11"3"3DD3"""""\11\88D""""\11\11\11\113Uf33333D"\113UUD3""3DD""\11\11"\11\11""\11"""""""33"D"\11\11\11\11"3U3""""""""""\11"\11DD3333333"""33""33"\11"U\99\88D3"DDDDDDUDD3"\11\11\11\11\11\11"""\113"\11\11\11\11\11\11\11\11"\11\11\11"""""""\11"\11"""\11"3"""""3""\11\11"\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3\11\11\11\11"""""3DD"""\11\11"\11\0\11\11\11\11\11"3DUw3\11"""""""""3""333D33333"3"33DUUUwfUD3\11"\11\11"""\11"""""\11\11\11""""\11\11"""\11\11\0\11\11\11\11\11\11\0\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11""""33"""""""\11\11\11"""\11\11"\11\11\113wfUD33"""\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11"\11\11\11\11\11\11"\11"""3D333"""\11\88U"""\11\11\113DUUDfDDDD"\11"UUfw\88wUUD"\11\11\11"\11\11"""""""\11\11""3""D3\11\11\11\1133UD""""""\11""\11\11\11DD333DD3"""""""""3""U\99ªf"3""33DDUD3"33""\11\11\11\11\11"""3"\11\11"\11\11"\11"""""\11"""3"""""""D""3D3""""\11""\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11""""""\11\11"3"3UfwD"3\11""\11\11\11\11\11\11\11\11""3Uw\883""""""DUD"""3"""""3333"33D333DDDUU""""\11\11\11\11""\11""\11\11\11\11\11\11\11\11"\11""\11\11\11\11\11\11\11\11\11\0\0\11\11\0\11\11\0\0\11\11\11\0\11\11\11""3"\11\11\11"""""\11"3"""""""\11""\11""""""\11"""f\88UD333""\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11"""\11\11"""""3\11"3""""""\11\0wf3"""3DDD3D33D33"""U3DfD3""\11\11\11\11\11"\11"""""\11\11\11"""\11"""""3""""3DD""""""\11""\11\11\11"U333D33""""3""""33D\99ªw3"3DDD"33DD""D3"""\11\11"\11""3""\11\11""\11\11\11\11\11""""333""""""3"3"""\11"3"""\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11""""3D""3""""3333"DUfU""""\11\11\11\11\11\11"\11\113DDUDD""""""DUD"""3"333""3"333DD3D33DUDDffUD\11\11\11\11"\11\11"\11\11\11\11\11\11\11\11\11\11\11"\11"""\11\11\11\11\11\11\0\0\11\11\11\11\0\11\11\11\11\0\11\11\11""\11\11\11\11\11\11"33""""3""""""""""""""""""""DwffU33""\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11""""\11"33""""DD3"3"""\11\11\11ª\88UDD333"""""""3D3"3D3D3\11\11"\11\11\11\11\11\11"\11\11\11\11"\11"""""\11\11\11\11""""D3\11"3UD"""\11"\11\11\11"\11"DUUD3""3"""""""""Uw\99\99fU"""33"33DDD33""""""""""""""\11\11"\11\11""\11\11\11"""333"""""3D3"""\11"""""""\11"\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11""33"""3""3""""""3DDDD"\11\11\11\11\11\11\11\11"""Dw\99D\11\11"""3DD3"\11""""""33"""\11\11"33"3"33DDD3ffD3"\11\11\11\11\11"\11\11\11\11\11\11\11\11"\11\11\11\11"\11"\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\113\11\11\11\11\11\11"\11\11"\11\11""\11\11\11""3"3"""33"""""3""""""3UwD"3"33""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\113UUD3UfwwD333"\11\11\99UD3"""""D""333UD"""3""\11"3"\11\11\11\11\11"""\11\11\11\11\11\11""\11\11"\11\11\11""\11"3DUDDU3\11""\11\11\11"""DDUD3"""""""33"""3f\99\99f3"""""""3"DD3D333"""""""""""D3"""\11"\11\11\11\11\11""""""3""""333"""\11"""""""\11\11\11""\11\11\11\11\11\11\11\0\11"\11\11\11"333""3333""""""""""""\11\11\11\11"\11\11"3"3D\99ªf\11\11\11""333""""""\11"""""\11""""""""""""3DDDD3DD3\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11""\11\11\11""\11""""\11"\11\11\11"3DDDU3333""""33""""33Dff33""33"""""\11\11\11\11\11\11\11\11\11"""\11\11""\11\11\11\11\11"DUwUfwf3DUUD33UwwUD3""33""33333DU33"""\11\11"3D"\11\11\11\11\11""""\11"\11\11"\11""\11\11\11\11"\11"\11\11""33UfU""""""\11""DD3fU"\11""33""""Dfw\88wU3""""\11"""""3DDD3DD"3"""33""""DD\11"""\11\11\11\11"""""""""""""3"3"""""""""""\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11"3333"""""\11\11333"""""""\11\11\11\11\11\11"3\113DDf\99ªªD\11\11\11"3D""333""""\11""""""""\11"""""""""3D3DD"D3"\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"""\11""\11"\11\11"\11\11\11\11\11"D3UUD3"""33333""""33fwD333"3""""""""\11\11\11\11\11\11"""\11\11\11""\11\11\11\11\11"3DU\88\99fUD33333DDDUD33""""""""333333"3""\11\0"DD"\11"\11\11\11"""""""\11\11\11\11\11\11\11\11"\11\11"\11\11\11"""33DUD""""""33"DDUU"""""D""U\88\88wU3"""""\11""""""3DD33""D3""3"3""""33""\11\11\11\11\11\11\11""\11"\11""33"""""3""""""""""\11\11""\11"\11\11\11\11\11\11\11\11\11\11\11\11\11"3""""\11\11\11\11"33\11\11\11"""\11"\11\11\11\11\11\11\11\113"3Dw\99ªªf"\11\11\11"D33"33"""""""""\11\11\11\11""3"\11"""""\11"""3"DD3D3""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3""""""\11\11\11\11333"3""""3333""""333Dww33333333""\11\11""\11\11"\11\11\11""""\11\11\11\11""\11\11""3DDfwD"UU"\11\11""""33\11""""""""""33333333"\11\11"33\11\11\11\11\11\11""""333"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11""33DDD3"33""3UDDDD""3"Dw\88\88DD3""""""\11\11"\11""3DD33D""3U3"D3"\11\11\11\1133"""\11\11\11\11\11\11\11\11"\11"""""\11"""""""""""""\11""\113"\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11"""""\11\0\11\11"""""""\11\11"\11"\11\11\11\11\11\11\11\1133Dffª»wD\11\11\11\1133"3"3"""""""\11\11\11\11\11\11\11\11\11""\11\11"\11"""""33"UDDD3"\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11"""\11""\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11"33"333""\11\11Df"""\11""""333"""""33U\88w33333"33"\11\11\11\11""""""\11"""""\11\11\11\11\11"\11""333DDUDDD"\11""""\11\11\11\11\11\11"""""3"33"""3D"33"\11\113"\11\11"\11\11"\11"""""""""\11\11\11\11\11\11\11"\11"\11\11""""""""333DDD""33UUD""33"3UwwU333"""\11""\11\11\11\11""33DD33D33UU3"""\11\11\11\11"D3""\11\11\11""\11\11\11"\11"""\11"\11\11"""33"""""""""\11\11""\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\1133"\11\0\11\11\11""\11""""""\11\11\11\11\11\11\11\0\11\11\11\11"Uwf\99»ªw\11\11\11""""""""33"""\11"\11\11\11\11\11\11\11\11"""\11\11\11"\11\11\11\11\11\11"3333DD"\0\11\11\11"\11\11\11\11\11\11\11\11\11\11\11"\11\11\11""\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11"""33333""Df3\11"""333DD3"""333U\88\88UD33"3333""\11\11\11""""""""""3"\11""\11"\11\11\11""3333DUD\11\11\11\11\11""\11\11\11\11\11\11\11""""333"""3333333"\11""\11\11\11\11\11\11\11"\11\11""33""\11\11\11\11\11\11\11""\11\11\11""\11""""""33333DD""DD333DDUw\88fU""""""""""""\11\11"""DD3DDD33DD3"\11\11""\11\11"3"""\11\11\11"\11\11\11\11"\11"""""\11""""""""""""""\11\11\11\11\11\11\11"3"\11\11\11\11\11\11\11"\11\11\11\11"3\11\11\11\11\11\11\11\11""""\11\11"\11"\11\11\0\11\0\0\11\11\11\11\11"f\99\99»ª\993\11"3"D3"\11""""""\11\11\11\11\11\11\11\11\11\11\11\11"\11"\11\11\11\11\11\11\11\11""\11""3UDD\11\11\11\11"3""\11\11"\11\11""""""\11"3"3"\11"\11\11""""\11\11\11\11\11\11\11"\11""""""""\11\11""D""3DDD3D3"33D\88\99\88U33"333DD3"\11\11""""""""""""3"""\11\11\11\11""""3D3DUDD""\11\11\11\11\11\11\11\11\11\0\11\11"""""""""3"3"33"3""\11\11\11\11\11\11\11"\11"\11\11"333"\11"\11\11\11\11\11\11"\11\11\11""\11""""""33""33DU3333"33"Uww33""""""\11"\11\11"\11\11\11\11""3D333DD"33"3"""3"\11\113""""\11\11\11\11\11"\11"""""\11""\11\11\11\11\11\11""""""""\11\11\11\11\11\11""""\11\11\11\11\11\11\11"\11\11""""\11\11\11\11\0\11\11\11"""""\11"\11\11\11\11\11\11\11\11\11\11\11"3"DU\99ªª\88"\11\11"33""""""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11"\11\11"\11\11"33D"3D\11"33""""""""""""""D"""3""\11\11\11"\11\11\11""\11\11\11"\11\11\11"""\11\11\11\11\11\11\11\113333D3333UUDfª\99f33D33333"33""""""""\11""""""3\11"\11\11\11\11\11""""33DDDw3\11\0\11\11\11\11\11\11\11\11""\11\11"3"""""""33""""33D3D\11\11\11\11\11"\11\11\11\11\11\113"\11\11"""\11\11\11""\11\11\11""\11\11"33""\11""""333UDDD33"3U\99f3D3"""""\11\11\11\11"\11\11\11\11\11"DD3333D3""D3"\11""\11\11\11"\11"""\11\11\11\11\11\11\11""\11""""\11\11"\11"""""""""\11\11"\11\11\11\11\11"3"\11\11\11\11\11\11\11\11\11\11""UD333"\11\11\11\11"\11\11\11\11"\11""\11\11\11\11\11\11\11\11\11\11"3DUw\99ªª\88D\11"\11\11""""""""\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11""UDDDD"3"\11\11""\11"3""""333D""3""3"\11""""""\11\11\11\11"\11\11\11"\11"\11\11\11\0\11\11\11\11\11"D33D3""3Df\99wUDDDD3333333"""""""3""""""3""""\11\11\11"\11""""33DUUD"\11\11\11\11\0\11\11\11\11\11""\11\11"""D3"3333""3D3"\113D\11\11\11\11\11\11\11\11\11\11\11\11"""\11\11""\11\11"""""\113""""""\11""""""""3DDUf3"\11D\88w3"""3D"\11"\11\11\11""\11"\11\11\113D333333""333"\11\113\11\11\11""""\11"\11\11\11\113""\11"""""\11\11\11"\11"\11"""""""\11\11\11\113\11""3"\11\11\11\11\11\11\11\11\11""D3UDDD"""\11\11"\11\11\11"""\11""\11\11\11\11\11\11\11\11\11\1133wªÌ»ªD"DD\11\11\11""\11""""\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""3DDD"\11\11""""""33"""""3333""\11""3D33""\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11""3""3Uw3UDDD33333333""""""""33"""""\11"\11"""\11""""""33DwU33\11\11\11\11\11\11\11"\11"""D\11\11"\11"3"3""""33DU""""\11\11\11\11\11\11\11\11\11\11"\11""""\11"\11""\11\11"\11""""""\11"""""""""""33DDUD""f\88D3"""""D""\11\11\11\11\11"\11\11\11\113333333""""33"\11\11"\11\11\11""""""\11\11\11\11"\11\11\11\11\11\11\11""\11"\11\11\11\11\11\11""\11"\11"""\11\11\11"""D\11\11\11\11\11\11\11\11\11"3UUDD33"""""""\11\11\11\11""\11""\11\11\11\11\11\11\11\11\0"3f\99\88\99\99D\11\11"3D"\11\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11""3DD3\11""3""""""333""""""3"""333U3"\11""\11\11\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11"3fwDD""333D3"33""""\11""""""""\11""\11\11\11"3""\11\11""""33DwU"3"\0\11"\11\11\11\11\11\113"DD\11\11""""3""3"3""3D3D"\11\11\0\11\11\11\11\11"\11\11\11\11\11"\11"""\11\11\11\11\11"""""3\11\11""\11\11""""\11""""3DDf33ww3""""""3D""\11\11\11"\11\11\11\11\113333333"""""3""\11""\11\11\11\11\11\11""\11""\11"\11\11\11\11\11""""\11\11\11\0\11"\11\11\11\11\11\11"\11\11\11\11\11\11\11""3\11\11\0\0\11\11\11\11"33333333"""\11"""\11\11\11\11"""""\11\11\11\11\11\11\11\11\11\11""3UUf"\0\11\11\11"3U"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11"\11\11\11\11\11"""\11\11\11"""33DUD3U33"""""""""333"""""DUUD3""""\11\11\11"3""\11\11\11\11\11\11\0\0\11\11\11\11\11\11\11\11\11\11\11\11"3fU"\11\11\11"3"333DD3""\11""""""3""\11\11"\11\11\11"3\11""\11""""""DfD\11\11"3\0\11\11\11\11\11\11\11\113"33""""33"3"3"3"33DU"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11""\11\11\11"""3D33"""""\11\11\11""""\11"3"33DUDUfD""3"""3"33"""\11\11\11\11\11\11\11"""3333""""""3""""\11\11\11\11\11\11"\11"""""\11\11\11\11\11"\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3U"\11\0\11\11\11\11\113D""\11"3""3""""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""3DU3\0\11\11\11\11333Uf"\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11"""""\11\11"""""\11\11"""3333D3DD33""""""""333""""DUD333""""""""3""\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"3fD""\11\11\11\11""UD"3D"""""""33""3\11\11\11\11\11""3\11"""""3"""Uf\11\0\0\11D"\0\11"\11\11\11\11"3D333\11"33DD"""333"3333\11"\11\11\11\11\11\11\11\11\11\11\11\11""\11""""""""""D""\11\11"""\11\11"\11""""""D"3DDwf3333"""""3333""3"\11\11\11\11"3"3"D3"""3""""\11\11"\11""""""\11\11"""\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3\11\0\0\0\0\11\11""D"""\11""33"""""\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11""333D3\11\11\0\11\11\11"33DDfD"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""""\11"\11""\11\11"\11""""""3""33333"D"""33"3""wUUD3D3\11\11\11"""\11""3\11\11""""\11\11\11\11\11\11"\11\11\11\11\11\11\11"\11\11Dwf"""\11\11\11\11\11"3D3333""""""33"33"\11\11\11"""""\11""""3""ff\11\0\11\11UU"""\11\11\11\11"""""D"""3UD3333""3""3"\11""\11\11\0\11\11\11\11\11\11\11""""\11"""3"""""""\11\11"""\11"\11\11"\11"""""""33D\88f333"\11"""""3""33"3"\11\11\11"""""33""""""""\11"""\11\11""\11"\11\113""\11"\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""\11\0\11\0\11\11"""\11\11\11"""\11\11"""\11\11"\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"3333"\11\0\11\11\0\11""3333DfwD\11\11\11\11\0\0\0\11\11\11\11\11""\11\11\11\11\11""\11\11\11""\11\11\11\11""\11\11\11\11\11\11\11"\11"""D3"D33UUU33DDUwfD3DD\11\11\11""\11\11\11\11""\11""""""\11\11\11"""""""\11\11"""DwU"""\11\11\11\11\11""""33"3333"""33"33"""\11\11\11"""""""\11"3Df\0\0\11\11"3"3D\11\11\11\11"""""3U""333333"""333"""\11"\11\11\0\11\11\11\11\11\11\11"3""\11"""3"\11\11"""""\11"\11\11"""\11\11\11"""\11\11"3"3f\99D""""\11\11""""""""UD\11\11\11\11"3"""""3"\11\11\11"""""""\11\11\11"""""\11"""\11\11\11\11\11"""3"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"33"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""\11\11"""""\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""D"D"\0\11\11\11\11\11""3333DDUUwU"\11"UfD"\11\11\11\11\113\11\11\11""\11""\11""""\11\11""3"\11"\11\11\11\11""\11""3DDUDDfUf3""DDD3\11\11\11\11""""\11\11\11"\11\11\11"3"""3"""""\11""""""3"3U\88U33\11\11\11\11\11\11\11\11\11\11D"33U333"""""DD"""""""\11\11"""\11\11"DUD\11\0\11"""""\11\11"\11\11""3""\11DD"""3""33"""D33\11\11"3""\11\11\11\11\11\11\0\0"3D"\11\11""""\11\11\11\11\11""\11""""""\11\11\11\11\11\11"3""3U\88\88D"""\11"""""""""""D3"\11\1133""""33"\11""\11"""""\11\11"""3"\11\11\11""\11"""""\11"33""""\11\11\11\11"\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""\11\11\11\11"3""\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3D\11\0\11\11\11\11\11""""333DUUUDUwwwfw\88wwfUUw\88UDUD3\11\11\11\11""""\11\11\1133\11\11\11\11\11\11\11"\11\11""3"DUDUU3UDD"DUfwfDD\11"\11\11"\11\11\11\11\11""""""""""\11\11"""""333"3w\88UD3""\11\11\11\11\11\11\11\11"""D3333"3333DU"3"\11\11"\11\11\11\11\11"\11"3DDU"\11\11\11\11"""""\11"""\11"3"""DD333""""3"33""\11\11"""\11\11\11\11\11\11\11\11\11333"\11\11"3""\11\11\11\11\11""\11"\11\11"""\11"\11\11\11"""\11\11UfwUD"333""\11\11""\11""""333""DD"""""3\11\11\11\11\11\11""3"\11"""""3\11\11\11\11"3"""""""""""\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\1133"\11\11\11\11\11\11\11\11\11\11\0\0\11\0\11\11\11\11\11\11\11\11\11\11\11\11""""""\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11"3D"\0\0\11\11\11\11"3"""""333DDD33DDUU33"33333DUfwf3UwU\11\11"\11\03fU""\11\11\11\11\11\11\11\11\11""333D3DUUUUD333DUfwwU\11\11\11\11\11\11\11\11\11""""""""\11""\113"""3D3"Df\88fU33"""\11\11\11\11\11\11\11\11\11\113DU3""33DDD333"""""\11\11\11\11\11"33DD"\11\11\11\11\0\11\11"""\11\11\11\11"""33DDDU3"""""""3""""""""\11\11\11\11\0\11\11\11"33"\11\11""""\11""\11\11"\11\11\11\11\11\11\11\11\11\11\11\11""""\11\11Dwf3UD"3D3\11\11\11"\11\11""""33"3"D3"""""3"\11"\11\11\11\11"""\11"""""""\11\11\11\11""""""""""""33"""\11\11\11\11\11\11\11\11\11"\11\11"""\11\11\11\11\11\11\11\11\11\11\11\0\11\11\0\11\11""""\11\11\11\11\11""\11D3"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"3D3\0\11\11\11\11""""""\11\11""""33"3""333"""\11\11"""""DD\88\88\99\88\88fDUwª\99\99\88\11"\11\11\11\11"\11"\11"33DDDD"DUD"33333"DDDUwf3"\11\11\11\11\11"""""""\11\11\11"\11"3"33DD"UD\88fUDD3"""\11\11\11\11\11\11\11\11\11\11\11\11DD3"3DD3D"D"3""\11\11\11\11\11"\113"DU\11\11\11\0\11\11\11\11"""""""\11\11\11"""33DD""""""33"33""""\11\11\11\0\11\11\0\0\11333\11\11\11""""\11"""""""\11\11\11\11\11\11\11\11"\11""3DDDffD33U3333""\11""""""33""UDD3""3""33"\11\11\11\11\11""""3""3"""\11\11""3"\11"""\11"""""3"""""\11"\11\11\11\11\11"\11\11\11""\11\11\11\11\11\11\11\11\11\11\0\0\11\11\11\11\11\11""3"\11\11\11\11""""33\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""3\11\11\0\11\11\11"\11"\11\11\11\11\11\11\11"""""""""\11"\11""\11\11\11"\11\11""DUDfUUw\88wDwww\88UDDUfffw\88\88U3""3333UD""\11\11\11"""33DUUf3\11\11"\11"Uwf"""""""""\1133""DD3ffU\99fD3"33"""\11\11\11\11\11\11\11\11\11\0"UDD3DU3U33D33"\11\11\11\11\11\11\11"\11DU"\11\11\11\11\11\11\11\11"33"""3"\11\11"33"D33""3"""""3""""""\11\11\11\11\11\11\11\11"3"\11\11"""""""""3D"""\11"\11\11"3D"\11"""3UfwfD3""U333""\11\11""\11""""""3UD3"""""3D3""\11""""333"""""""""""""""""""""""3"33""\11\11\11\11\11"\11\11"\11\11"\11\11\11"\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11"3"\11\11\11"33333"\11\11\11\11\0\11\0\11\11\11\11\11\11\11"\11\11\11""3\11\11\11\11\11\11""\11"\11\11\11\11\11\11\11\11\11"""\11\11\11\11\11"""""\11\11\11\11\1133Dff3333"\11DffUDDfUDf\88UD3DUUfU3D3fU\11\11\11\11\11\11\11""3DDU3UU"\11\11"Uff3\11\11"33"""""D3"UfUUwU\88\99UD333"""\11\11\11\11\11\11\11\11\11\11\11"333DU33UD33D"\11\11""\11\11\11\11\113U\11\11\11\0\11\0\11\11\11"""""""3"\11\11"3333333""""""""33"""\11\11\11\11\11\11\11""\11\11\11"""\11""""""3D""33\11\11"3D33""3DfUDDUD3""DDDD3"\11\11\11\11"\11"""3"3D3""""33DD33"""3"3DD3""\11\11""\11\11"""3"""""""3""""DU3""\11\11\0\11\11"\11\11""\11""\11"3"\11\11\11\0\11\11\11\11\11\11\11\11\11"3D"\11\11""333D"\11\0\0\11\11\11\11\11\11\11\11\11\11\11"""\11\11""3\11\11\11\11\11\11""""\11\11\11\11\11\11\11\11\11"""\11"\11\11\11""\11\11\11\11\11\11\11""DDUw3"33"""ffUU33D333U3""\11"3DUw\99»ª\88D"\11\11\11\11\11\11"3DD3"U3\11\11\11Dw3D33fD"333"\113f\88w\99\88\88UUD\88\88U33"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11""\11\0DUUDD3""""\11\11\11\11\11"3\11\11\11\11\11\11\11\11\11\11"""""3"\11\11\11\11"DD3333"""3""333"33\11\11\11\11\11\11\11"3"\11\11\11"""\11""\11"""3D"""""3DD3"33DDDUfUD3U33"DUDUDD""\11\11"\11"""""3D33333"DDD3""""3"DDDD3""""""""3333"""""3"33"3U3""""33""""\11""\11\11"\11"3"\11\11\11\11\11\11\11\11\11\11\11\11\11"3D""3"3"3D3"\11\11""\11\11\11\11\11\11\11\11\11"""""""3U3\11\11""""""\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\113\11\11\11\11""DDUf""3D33""fUU3"333"33\11\11\11\11\11\11\113Uw\99\88\99\99\88U"\11\11\11""33DDDfD333UDDDfwU33D3D3\11ffw\88\88\99\88\88wff\88U""\11\11"\11\11\11""\11\11\11\11\11\11\11"""\11\11\11\11\113fUD"33""\11\11\11\11\11"D3\11\11\11\11\11\11\11\11\11\11"\11\11""""\11\11\11\11"D3DDDD"""3""3333"\11\11\11\11"\11\11U33"\11"""""\11\11""""3U"3"33DD3"3""33DUUD3"D33DDU"DU33"\11\11\11\11\11""""3D3333333DD33"3"33DUUD3"333"3"""3D"""3"""D"3"""""""""""""\11\11\11\11""\11\11\11\11\11"""""\0\11\11\11"\11"""DD"""3""3DD""\11\11""\11\11\11\11\11\11\11"""""""""UD\11\11"3"""""\11\11\11"\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11D3\11""""DUUU3\1133UU"\113fD333333"D\11\11\11\11\11\11\11"3Dfww\99wwwwU"\11\113"3DDDUffUU3UUffDUDUf3UffDDUUUfUUDDDUf3"\113\11\11\11""\11\11"\11\11\11\11\11\11\11\11\11"\11\11\113fU3333""\11"\11\11"D"\11\11\11\0\11\11\11\11\11""\11\11\11\11"""\11\11\11\1133DUUU3"""""""""\11\11\11\11\11\11\11"U33"3"""\11\11"""""""D3"33DD3""3""33DDDD"""33D3UD3DfDDD""\11"\11"\11"UD"33333D33D3DD""3DDUD3333D"D3""33""3D3""""3""3\11"""""\11\11\11\11\11\11\11"\11\11\11\11"\11\11\11""\11\11\0\11\11\11"""""3D\11"3"""33D33"\11\11\11""\11\11\11\11"\11"""333""3DUDUfDDUfDDDDD3"\11\11"""33""""""\11\113f"""3"DwUf""3UfD3\113UD333333"D"\11\11\11\11\11\11\11"3DUf\88ffffww\88wU"33DDUUff\99\99\99wU333UUffDDUDDDUDD333333DDD3DD"\11\11"\11\11\11"\11\11\11\11\11\11\11\11""\11\0"DfDD33""\11""\11"D3\11\11\11\0\11\11\11\11\11""\11\11\11\11\11"3"\11\11\11"3DUD3D3"""""""\11\11\11\11\11"\11\11\113D\11"3""""\11"""\11"3"3333DD3"""""33DDD3D3""""""3DDU"DDD3\11"\11\11\11"3UU333333"33Df3D33UDDD33""33"3D"3"""""3D3""""\11"""\11""\11""\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11"\11\11\11\11\11"""""3D\11"3""""33D33""\11"\11\11""\113"""33333"33Dwww\88\88\99f3UD33"D"D3333333D3DDUDDwU"""3UfUD"""3"""""DDD333333D3\11\11\11\11\11\11\11\11"3Dw\88fUfwwffff\88wD33D3"U\88UUU""3333333333DDDDD33""3"3"333""D3""\11\11\11\11\11\11\11\11\11"3DDD3"3DD333""\11\11""3D3\11"\11\11\11\11\11\11\11""\11\11\11\11\11\11"\11"\11\11"3333"3""\11\11\11"\11""\11\11\11\11\11\11\11\11\033"""\11""""""\11"""333DD3"""""3333333"""""""""333DDDD"""\11\11\113DU3"3D333"3DUUUD3UUDD33""""3DDD"3""""\11""3""""""3"\11\11""\11\11\11"\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11""\11"\11\11"""3"DD"3"\11""33"DD3""""""""""""""33DD"3""3fwwff33D3\11\0\11\11\11\11\0\11"""33""33DDDDDDDDUUUDfD\0\11"""""""UDD33DDDD"\0\11\11\11\11\11\11\11""3U\99fDUUUfffUUffwfD33ffUD"""""333333"3333D33"""""""""3"\11\11"3"\11\11\11\11"\11\11\11\11""DUDD""\11DD33""\11\11""3DU""\11\11\11\11\11\11\11\11"\11\11""\11\11\11\11\11\11\11\11""""\11\11"""""\11\11"""\11\11\11\11\11\11\11\11\11"""\11\11""\11"3"\11""333""""""\11""""""3"""DD3"""""3DD"3"3333\11\11\113D3D33fD"33DDUDUUDUDDD"""3"3333""""""""\11"""""""""\11\11\11\11\11""""\11\11\11\11\0\11\11\11\11\11\11\11\11\11\113"""\11\11"""""3U"\11""""33""DD3""""\11\11\11\11\11"""""33D33"""3U\88wf\11\11\11"""\11\11\11\11\11\11\11"\11\11"""33"333\11"\11"\11""3UDfffUD"3D"fUUDw\99fDU3\11\11\11\11\11\11\11\11\11""DU\99D3DD33333333Uf\99\99fU3"\11\11""""33333""""""33"""""""\11\11\11\11\11\11\11\11D3"\11\11\11\11\11\11\11"\11"33U"\11""3D3""\11\11""3Df"""\11\11\11\11\11\11"""\11\11""\11\11\11\11\11\11\11\11"""\11\11""""""\11"""\11\11\11\0\11\11\11""3"""\11"""\11""\11\11"333""\113"""""""333333U33"3""""D"UU"D3333UUDDDD33U"\11D33DUDUUfDDDD3""3333D"\11""3"""""""""""""\11\11\11\11\11\11\11""""\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11"3"""3U"\11\11"3""""3"33""""3"\11\11\11\11""\11"33Uf""""""Uw\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"""33333"\11""\11""""\113"3"\0\11"DD3wwww\88UUD33""\11\11\11\11\11""\11\11"Dwf"3"""""\11\11\11""3DUD33"\11\11\11\11\11\11"""""""""""""""\11"""\11\11\11\11\11\11\11\11\11\11U3""\11\11\11\11\11\11\11\1133UD""3\11"3"""\11\11"3Df""""\11"\11""""""\11"\11\11\11\0\11\11\11\11\11\11"\11\11\11\11\11""3""33\11""\11\11\11\11\11"\113D3"""""\11""""33333""""""""""DDDD3DD"3"D""""3Dffff\88\88UDUwwwDDDDD"\1133D3UUfDDDDD"\11"3333333"""3"""\11"\11"""""3\11\11\11\11\11\11\11\11""""\11\11""""\11\11\11\11\11\11\11\11\11\11\11\11\11"3"""""3"\11\11""""""""3"""""3"\11\11\11\11\11"\11\11"3U\88D"\11"""Uf3\11\11\11\11\11\11\11\1133"\11\11\11\11\11""\11""""""\11\11\11"""\11"3\11""\11\0\11\11\11\0\11"Dw\99wUU\88DD3""\11""""""\11"3Dw""""\11\11\11\11\11\11\11"""33"""\11\11\11\11\11"""""""""\11"""""\11""""\11\11\11\11\11\11\11\11\11\11""""\11""\11\11"""\11"DDD"3""3"\11"\11\11\11"DU3"""""""""""\11\11\11"\11\11\0\11\11""""\11\11\11"\11\11\11"""""""""\11\11\11""""\11"33\11""""3333333"3""""""""""D333DD3333""3"""DDDDDUwU3Uw\88ffwDUU"3DD3DfUUUDD33""""""333"3"33""\11""""\11"\11\11"3\11\11"\11\11\11\11""""\11\11"""""\11""\11\11\11\11\11\11\11"\11"33""""3\11\11\11\11\11\11"""""\11""""\11""\11\11\11\11\11\11\11""3Ufw3\11"""\113D\11\11\11\11\11\11\11"3D3\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11"\0\0\11\11\11""3DUwww\88\88wUD33333""""""3Uf"""\11\11\11\11\11\11\11\11\11\11\11""""\11\11\11\11\11""33333"""\11"""\11\11\11\11\11""\11"\11\11\0\11\11\11\11\11""""""\11\11"3""3D333"""3""3333DUfw""""3""""""\11\11"\11\11\11\11\11\11"""\11\11\11\11\11\11"""""\11""""""\11\11""""\11\11\11""\11"""333"33""33""""""""33333"DDD3""""""33DDUDDUfwf\88wwUDDfD3DDDDUffUUD3"""""""333D3"""3""""""\11\11\11\11\11\11\11""\11\11\11\11\11\11\11\11"\11\11\11"""""\11\11\11\11\11\11\11"""""""""""""\11""33D"""""\11"\11\11\11""\11\11\11\11\11\11\11\11""3fff"\11\11\11"""\11\11\11\11\11\11\11""33\11\11\11\11\11"\11\11\11\11\11\11\0\11\11\11\11\11\11\11""\11\11\0\11\11\11\11\11\11""""3fUDD333\11\113333""3333DDUf""\11\11"\11\11"\11\11\11\11\11\11\11\11"""\11\11\11\11\11""3333"\11"\11"""\11"\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11D"3"\11\11\11"3"333""33"3DUDUUD3"3f\99D""""""""""\11\11\11\11\11\11\11\11\11\11\11\11"3\11\11""""""""""""""\113"""""\11\11\1133\11"\11\11""""33333"""""333""3333DDD3"333""""33DDDD3wwwDDD3DDDD3DDDDUUffU""3\11""""3"""3"""3"""\11\11\11"""\11\11\1133\11\11"\11\11\11\11\11\11\11\11\11"""""""\11\11\11\11\11\11"33DD"\11\11"""""\11\11"33"33"\11"\11\11\11\11\11"""\11\11\11\11\11\11""3DDfUw""""3\11\11\11\11\11\11\11\11\11"""\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\113\11\11\11\11\11\11\11\11\0\113"\11\0\0\0\11\11\0\11"D3DDDDw\88\88\88f3""""\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3"3""""\11"\11\11"\11"\11\11\11\11"\11\11"\11\11\11\11\11\11\11\11D\11""""""""33"""""3DDUf3"333U\88f"""333"""""\11\11"\11\11\11\11\11\11\11"""3\11\11"\11\11""""""3"""\11\11\11""""\11\11\11\113"\11"\11\11""""""33"""""33"""""D333D333D33"""3333D3Dw\88fD3D333DDUUDDDfUUDD""""""\1133""""""""""""\11"""\11\11"\11""\11"\11""\11\11\11\11"\11\11"\11""""""\11\11\11""\1133D3""\11\11"""\11"""D"\11\11"33\11\11\11\11\11\11\11\11"\11\11\11\11\11""D33DD3Uf"""3"\11\11\11\11\11\11\11\11\11"""\11\11"\11"\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\113"\11\11\11\11\11\11\11\11\11\0\11\11\0\0\11\11\11\11\11\11\033"3""f\99\99\99\883""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3\11""3""\11""\11\11\11"\11\11\11\11\11\11\11\11\11\11"\0\11\11\11\0"3\11""\11"3"3"333D3DUD""DfDDDUfwUD\11\11"3"""""\11\11""\11\11\11\11\11\11\11\11""3"\11"""\11"\11""""3"\11"\11""\11"\11\11\0\11\11"3"""""""""33"33""""""""""DD333DU3333"""333"33U\88wU333"3D3DDDUUUfffUD""""""""3"""""\11\11""33"""""\11\11""\11\11\11\11"""""""\11""""""3""""""""\11"DD3\11\11\11\11\11\11\11\11\113"3""\11\11\11"""\11\11\0\11\11"\11\11\0\11\11\11\11"3D3DD"3Uf"""3\11\0\0\11\11\11\11\11\11"""""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""\11\11\11\11"\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11""""3U\88ª\99\88D3"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""""""\11""\11\11\11"\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11U3""""""""D3Dfw\88wUUDDDUUf\88UD3U3""3"""""""""""\11\11\11\11\11\11"""\11\11\11\11"""""""""\11\11\11\11\11\11\11\11\11\11\11\11\11""""""""""""D"""""""""3333UfDDUDD3333""3"""""3fwfD333"3333D3Df\88fUfUD""3""""3""""""\11\11""333""""\11""\11"""\1133"""""\11"""""""""""""""""""\11\11\11\11\11"\11\11""""\11\11\11\11\11\11\11\11"3\11\11\0\11\11\11\11\0\0\11\11\11""UDD33"DUD""\11\11\11\0\11\11\11\11\11\11""3"""33\11""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11"\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11""333f\99\99\99wD""""\11\11\11\11\11\0\11\11\11\11\11\11\11\11""""\11\11"""\11\11"\11\0\11D""\11\11\11\11""\11\11\11\11\11\11\11\11\11\11DU33333DfUfwUD33""\11\11""""3"33U3"""""""""\11"3"\11\11\11\11\11\11\11\11\11""\11\11\11\11\11\11""""""\11"\11""\11\11"""\11\11"UU33"""""\11"""""3""""""DDDDUD33"333D3""3"""""\11Dw\88U3"3333"33333Dw\88fUU"\11""""""""""3\11"\11\11""333"""3"\11""\11\11\11"\11""""""\11"""\11\113"\11"3""""""""\11\11\11\11""\11\11\1133""\11\11\0\11\11\11\11\11\11\113\11\11\11\11\11\0\11\0\11\11\11""D33""3DUfDDD\11\11\0\11\11\11\11\11\11\11\11""333"\11"\11\11"""\1133"\11\11\11\11\11\11"""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11""\11\11""33w\99\99ª\99U"3""\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11\11\0\11\11"\113\88w3\11\11\11""""""\11\11\11\11\11\11\11\11D3"DDDUwffD""\11\11\11""\11\11"\11"""3DU3"3\11\11"3"3"""""\11\11\11\11\11\11\11\11\11\11"""\11\11\11\11\11""""""""\11"\11""3"\11\11""3wU""\11"""""333"3"""3"3U3333333333333"""""""\11UwwD3""333333333Dfw\88U3"\11"3"""""""""\11""\11\11"333"""D3"\11\11"\11\11\11""""""\11\11"""\11""""""""""\11\11""""""""\11""""""\11\11\0\11\11\11""\11\11\11\0\11\11\11\0\0\0\11\11\11\11""3U33"33DwfDfU\0\11\11\11\11\11\11\11\11\11"""3"\11""""""\11\11D"\11\11\11\11\11\11\11""""\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11"\11\11\11\11\11"""3U\99\88wf""""\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11""3"\11"UUw\88\99ªªªª\99f3\11\11\11""""\11\11\11\0\11\11\11\113U3DUDUD33D"\11\11"\11\11"\11\11"\11\11""33U3""\11\11\11\11"""""""\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\0\11\11"""""""""\11\11"""\11\11"\11"\11"D3""33"333""""""""33333""333""""3"""""\11"\113w\88f3"""3"3333333D\88\88wf""""""""""""""""\11\11\11\11""3"""3"\11\11\11""""3"""""""""""\11\11\11"""\11""""\11"\11\11\0"\11\11"\11"3"\11""\11\11\11\11\11\11\11\11\11\11\11\0\11\0\11\0\0\0\0\11\11\11\11"3D3333DDUwwf\883\0\0\0\11\11""\11\11\11"3""""""""\11"\11""\11\11\11\11\11\11\11"""\11\11\11\0\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11"33DwU"\11"""\11\11\11\11\11\11\11\11\11\11\11\0\11"Dw\99ª\99\99\99ª»ªªªª\99\88w\99\99\88D""""\11\0\0"DDDUUDDfDDD3"""3D3\11\11\11\11\11\11\11""\11\11\11"3DU3"""""\11"""\11""\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11""\11\11"""\11""""\11\11\11\11\11\11\11\11""""""3"""33"""3"3""D33"333""""""3"""""\11DfwU"333"33D333DDUw\88\88f3\11""""""\11\11\11"""\11"\11\11\11""33"""""""""\11""""""""""""""\11\11"\11\11\11""3""""\11\11\113"\11\11\11"3\11\113"\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\0\0\11\11\11"""3D""33UfUfw\883\11\11\11\11"""\11\11\11"""""""""3""""\11\11\11\11\11\11\11\11\11\11\11\0\0\0\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""333"UD"""\11\11\11\11\11\0\11\11\11\11\11\113w\99\99\88\88\88wwwwwwwwffffw\99\99D""\11\11"DwwwffUUU3""3""""3""\11\11\11\11\11\11\11\11"\11\11\11\11"3f3""""\11"\11"\11""\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\0\0\11""\11\11"\11\11\11"3"\11\11""""3"\11""""""""""""""""DDUDUD3333"333"""""""""""""Dwf""3333DDU"3DD3UwwwfU\11"""""3""""""\11""\11\11\11"""""3"""""""""""""""""""""\11\11\11\11\11\11""3"\11\11\11\11\11\11""\11"33"""3"\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11""3D"3D33Uf\88wf3D\0\11\11\11\11\11\11\11\11"333""""""""""\11\11\11\11\11\11\11\11\11\0\0\0\0\0\11\0\11\0\11\11\11\11\11\11\0\11\11\11\11\11\11\11""\11\11\11\11\11\0\11\0\11\11"""33333D\11\11"\11\11\11\11\11\11\11\0\0\11\11f\99wffffUUUDfUfwwfffff\99w\11"3DfDDD3"33333""3""""""""\11\11\11\11\11\11\11\11"\11\11\11""DU3"\11""""3"""""\11\0\0\11\11\0\0\11\11\0\11\0\0\11\11\11\11"""\11\11"\11\11\11\11""\11""""3"""""""""""\11""""""3ffDD3"3"33333""""""""""""3Dww3333DUDDUD333DUw\88wfUD"3""""\11\1133"3"3"\11\11\11\11\11"33""""""""""""""""\11""""""\11\11\11\11\11\11\11""\11\11\11\11\11""""33""""DU3\0\11"\11\11\11\11\11\11\11\11\11"""\11\11\11\11\11\11\11\11"3D33333DUffffwD\0\11\11\11\11\11\11""""3""D3"""""\11\11\11\11\11\11\11\11\11\11\0\0\11\0\0\11\0\0\0\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11"3333"\113U\11"\11\11\11\11\11\11""33DwfUDDUUUDDDDUUUfffffw\88ªfUff3""""""3""""\11"""""\11""""\11\11\11\11\11\11\11\11\11\11\11""3DD"\11\11""3"""33"\11\0\0\0\0\11\0\0\0\0\11\11\0\11\11\11\0\11"""\11\11\11\11\11\11\11"\11"3""33""""""""""""""""""UU333"3""333UU""""""""\11\11"UwfD3333"DUUfU33DDUwwUDDUU"""\11"""\1133""3D"\11\11"\11"""33""""""""""""33\11""""\11\11\11"\11"\11\11\11\11\11\11\11\11"""\11\11\11\11\11\11\11DUUf33"\11\11\11\11\11\11\11\11""""""\11\11\11\11\11\11\11"3DDDD3"3DUfwf"\11\0\11\11\11\11\11\11\11\11"""""33\11\11"""\11\11\11\11\11"""\11\11\0\0\0\0\0\11\0\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\0\11\11\11\11\11""3D3""3wD\11\11\11\11\11\11\0"w\88\88\88\88D333D3DDD333DDDffffww\99\88DD3"""\11"""33""\11"\11\11\11\11\11\11"""\11\11\11\11\11\11\11\11"\11\0\11\11""DU3"\11\11"3\11""33\11\11\0\11\0\11\11\11\11\0\0\0\11\11\11\11\11\11\11\11""\11\11\11\11\11""""""""33""""""""""""""""""DD3"333333"3fwU"""""""""3fww"3"""3"3UfU"33DwwwfDDDUU"""""""""3"3""""\11""""333""""""""33"""\11""\11\113"\11\11\113\11\11\11"\11"""""""\11\11\11\11\11\11"DD3"""3\11\11\11\11\11""""\11\11\11\11"\11\11\11\11\11\11\11"DDDD"3"DDDwf\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11""\11\11\11"""\11""\11\11\11\11\0\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11"3D"\11\113wDw"333D""wwwwwU333333333"33DDDUfffUfwD""""""\11\11""""""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\0\11\11\11"33D""\11""\11"""""\11\11\11\11\11\11\11\0\0\0\0\11\11\11\11\11\11\11\11""\11\11\11\11"\11"33"\113333"""""""""""""""""""3D"333333"3ffU"""""""""Dw\88fD""33"33"DU3"3DwwwwDDDDUU"\11\11"""""""""3"3"""""""3""""""""""3""3""\11\11"33\11\11\11\11""""\11"""\11\11\11\11\11\11\11\11\11\11"\11\11\11\0\11\11"""""""\11\11\11\11\0\11\11""\11\11\11\11\11"3DDUD""3DDww"\11\11\11\11\11\11\11\11\11\11"\11\11\11""\11\11\11\11""3"""3""\11"""\11\11\11\11"\11\11\11\11\11\11\0\0\11\11\11"\11\11\11\11\11"""\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\113UUUffUUw\88wfffUUD"3"""3333333333DUUUUUffffD""\11\11\11\11"33""""\11\11\11\11\11\11\11"\11"\11\11\11\11\11\11\11\11\0\11\11\11"""U""""\11\11\11\11\11""\11\11\11\11\11\11\11\11\0\11\0\0\11\11\0\11\11"\11\11\11\11\11\11"""333"\1133D"\11\11"\11\11\11""""""""""""33""""333""3UUD"""""""""3w\88U"""333"3U"DU3D3UwwwU33UDD3D\11D3""\11\11"""""""\11""""""3"3""""\11"33"""""\11"""""""\11""""""3""\11\11\11\11\11\11\11"\11\11\11"\11\11\0\11\11\11"33""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"DUfDD33DDU\88"\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\0\11""3"""""""""\11"\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11""\11\11\11"""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0DU33Ufw\99\99\99wUDDDD333"""3""""33333DDDDUUUDUDDU3\11\11\11\11\1133D3DUU3"\11\11\11\11""\11\11\11\11"\11"\11\11\11\11\11\0\11\11"fU""""\11\11\11"""\11\11\11\11\11\11\11\0\0\11\11\11\11\11\11\11\11\11"\11\11\11"\1133333"""3333"3"\11"""""""\11""\11""""33"""3"33"3DD3""""3""333\88\88U"3333D333UUD3D3UwwUD"DDDD"DDDU\11""""""""""\11"333""""""""33"33"3""\11""\11\11\11\11""3""""""\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\0\11"\11"33""\11\11\11\11\11\11\11\11\11\11"\11\11\11\11"3UfUDDDDDDD3"\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11""""\11"3"""""\11\11\11\11\11\11\11\0\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11UU"3fUD\88fUfU333""33"3"""""""""""33DDDDDD3DDUUU3"\11\11\11"3"D33DDD3"\11\11\11\11""""""""\11\11\0\11\11\11"DwD"""\11\11""\11"\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11"\11"\11\11"f"\11"""\11""33DU"\11\11"""\11""\11"""""""3"""""""3"3D3""""""""333\88w3"333"3""3DUD3UfwwwU33DDDDDDDUU"\11"""""""\11\11"3""33""""""""333""""\11\11\11\11"\11\11""""3""""\11\11\11\11\11\11\11\11\11\11\11""\11"""""33"33""""\11\11\0\0\11\11\11\11\11\11\11\11\11\11\11"3UDDDDD3DUD""""""\11"\11\11\11\11\11\11\11\11\11\11""33\11"3""\11\11\11\11\11\11\11\11\11\11\0\0\0\11\0\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\03wU""DDfwUUUU3""""""""""""""\11"""3"3DDD33333DD33DUUD"3D"\11\11\11\11"""DUD"3f\88\88wUU"\0\11\11\0\11DD\11"fwU3"""\11\11\11"""\11\11\11\0\11\11\0\11\11\11\11"""""\11"\11\11\11"3U\11\11"\11\11\11"3"33UD\11""\11""""""""3"""""""""""33D33"""""""3333\88w3"""3333""333DfwwwUU3"33DUDDDDfUD"3"""""""""""""""""""""""""""\11\11\11\11\11"""\11""""""""\11\11\11\11\11\11\11"\11\11\11""\11"3""""33DD3"\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11"3D3D33D3f"\11"""""""\11\11\11\11\11\11\11\0\11\113"\11"\11""\11"\11"\11"\11\11"\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\0\0\11\11\113"\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"ffU3"UwDUUUD33\11\11"""""""\11""\11""""\11""DD333""33333"3D33DUDD3\11\11\11\11\11\11"3DU3UUfffwUUUU3\11"wUDwf3UD"\11\11\11\11\11"""\11\11\11\11\11\11\0\11\11\11\11\11""D"\11\11\11\11"3""\11""\11"3D3\11"DD""""\11\11""\11""33""""""""""""333"""""""33333\88U3"""3333"""DDww\88wUD""33DDDDDDUUUUwD3"""""""""\11"""33""""""\11"\11""3\11\11\11\11""\11\11"""\113DD\113"\11\11\11"""""\11D3"""""\11"3"3"3"\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3333333f"\11"""33""\11\11\11\11\11"\11\11"UD\11\11""""""3"\11\11"\11\11\11\11"\11\11\11\11\11\11\11\11\0\11\11\11\11\11\0\0\0"D"\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11DwwUDUfD"""\11\11\11\11\11\11\11"""3""\11\11"""""""\11"""333""""""3"""3"\11\113"33"\11\11\11\11\11\11"DD33333wDDUff\88U\88w\88\88f3\11UD\11\11\11\11\11"""\11\11\11\11\11\0\0\0\11\11\11\11\11\11\11""""\11""\11\11"\11"""3"""\1133"""""\11\11"""""""""""""""3""33333"""""3"33f\88U33"""3"33""3wwwwfD3\11""3333D33DUUUfD3""3D3""3"\11"""""""""""""\11\11\11"\11\11\11\11\11\11\11\11"\11"33""3D""\11"\11""""""""""""""""""33"3""\11\11\11\11\11\11\11\0\11\0\11\11\11\11"""""""3Uf3\11""3"3""\11\11\11\11"""\11"33"\11\11\11\11\11"""""\11\11\11"\11\113U3"\11\11"\11\11\11\11\11\11\0\0\0\0"DU3"33""""\11\11\11\11\11DUU"f\88\88wwfUD3"\11\11\11\11\11\11\11\11\11\11""""\11\11\11"""\11"3""""3"3"""""""""\11\11"\11\11\11"3""""\11\11\11\0\1133"""""3UDUUffw\99\99ªwUU"\1133\11""\11\11""\11\11\11\11\11\11\0\0\11\11\11\11\11\11\11\11"3\11\11"\11\11\11"\11\11"\11""""\11"3""3"""\11""""""""""""\11""""3"3333"""""""3Dww333"3""333""Dfw\88\88U3"\11""3333D3"DUUDDfD333DDD33"\11\11"""""""""""\11"\11\11"\11"\11\11\11\11\11\11\11""""3""\11"3"""33"""3"3""33"""""""""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11"33""\11\11""UU\11\11"33""""\11\0\11\11"""\11\11"\11\11\11\11""3D3"""\11"""\11\11\11"\11\11\11\11\11\11\0\0\11\11\11\11\0\11\0\0DUD333""\11\11\11"3UDUfUw\88\99wwUUD33"\11\11\11\11\11\11\11\11\11\11\11"""""""""""""""""""""""\11""""\11\11\11\11\11\11\11\11"\11"""\11\11\11\11\11"""\11"\11""33DDUU\88\99\99\99wDD"\11""\11\11\11\11\11\11\11\11\11\11\0\0\0\11\11\11\11\11\11\11\11\11\11""\11""\11\11\11"""\11\11""""\11"\1133\11\11\11\11""""3"\11"\11""""""""33D33"""3"""33fwU"3""33333333w\88\88\88wUD"""""3333333DDU3U3D3DDD3D33"\11\11""""""\11\11\11""\11""""\11\11\11\11\11\11\11\1133"3333"""33""D3"3""3""""33"""33""33\11\0\11\11\11\11\0\11\11\11\11\11\11\11"33D3"\11""3fDU3"DD""\11"\11\0\11\11""\11\11"\11\11\11"D"DfD3""""""\11\11\11\11\11\11\11\11\11\11\0\0\11\11\11\11\11\11\0\0"3""\11""\11\11\11\11"DffUUDf\88\88fUUDD3""\11\11\11\11\11\11\11\11\11\11"\11""""\11\11"""\11\11"\11\11"""""""""""""\11\11\11\11\11\11\11\11\11"""\11\11\11\11"\11"""\11\11\11\11""""33Uwwww\88f3D"\11"3\11\11\11\11\11\11\11\0\11\0\0\11""\11\11\11\11\11\11""\11\11\11""\11\11\11\11""""\113""33UDD\11\113\11\11"""""""""3""""""3333""""""""3Df\88D"3""3"3333"3\88w\88wU""""""33"333"333DUUU3D3DDDDU3"""\11"\11\11"\11\11\11"""""""\11\11\11\11\11\11\11\11\11"3333DD3""33333""\11""""3"""""""""3"\11"\11\11\11\11\11\11\0\11\11\11\11\11\11\11"333D"\11\11"DUfUD""3D"\11"\11\0\11\11\11"\11\11\11\11\11\113UUDwD""3"""\11\11"\11\11"\11\11\11\11\11\0\0\0\11\11""\11\11\11\11"\11\11\11\11"\11"33DDUUD33UUfUDDDD3""\11\11\11\11"\11\11\11\11\11\11"""\11\11\11\11\11"D3\11\11\11""""""""""""""\11\11\11\11\11\11\11\11\11\11\11"""\11\11\11\11\0\11\11\11\11"\11\11"""""DUfDffffUD\11\11""\11\11\11\11\11\11\11\11\0\0\11\11\11\11\11\11\11\11\11"""""\11\11"\11\11\11""""""3DUfUD3\11\11""\11"""""""""D3"""""3333"""""""""UwU""3""""3333DU\88\88wf3"""""""DDD333333DDUDDD333UDfD3"\11\11\11\11\11"\11\11\11\11"33"""\11\11\11\11\11\11\11"\11"""33""3""33333"""""333"""3""\11""""\11\11\11\0\11\11\11\11\11\11\11"\11\11\11\11"33\11""\11"\11DwfD""33"""3"\11\11\11\11\11\11\11"""\113UUDU"""3""""\11"\11""\11\11\11\11\11\11\0\11\11\11\11\11\11\11\113"\0"\11\11\11\113wUUDDD33"DUDDDDDD""\11\11\11\11\11\11\11\11\11\11\11\11"""\11\11\11\11\11\11"U3\11\11\11"""""""3""""""\11\11\11""""\11\11"3"""\11\11\11\11\11\0\0\11\11\11\11\11"""""33DUffUw\88U\11""\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11"\11\11""\11""""\11"\11\11\11"\11"3ffUfDD\11\11""3"\11""""""""\1133"""""3333"""""""""DD3""3"""3"33"U\88\88\88wU3\11""""""3D333333DDDDUD""33DUDDD3"""\11\11\11\11\11\11\11""""""""\11\11""\11\11\11"""""""""""3"33"""""""""""""""""""\11\11\11\11\11\11\11\11\11"\11"\11\11\11\1133D3"""""3ffD33"""33"3"\11\11\11"\11"""\11\11DfU3\11"""3"""""\11\11"\11\11\11\11\11\11\11\11\11\0\11\11\0\11\11\11"\113w\88fUfwwUDDDD3"""DUDDDD33""\11\11\11\11\11\11\11\11\11\11\11"""\11\11\11\11\11\11""3"\11\11\11""3""333""""\11\11\11\11\11""\11"\11\11"33""\11\11\11\11\0\11\11\0\11\11\11\11"""\11"D3UUUUwf\88"\11"\11\11\11\11\11\11\11\0\11\11\11\11\11\11\0\11\11"\11""""\11""""""""3DDUUf3"3"\113D3"\11\11"""""""""3\11"""""333D""3""""DD""""""""3""33f\99\99w\88f3"""""""DUDDD""33D33D33333DUD33D"""\11"\11\11\11\11\11\11""\11"33""""""\11"33"""""\11"""""33"""33""""""""""""\11\11\11\11\11\11\11\11\11\11\11"""\11\11\11\11"DDD3""""3D3D"3333333"\11\11\11\11\11"""3"\11"D3D""\11""""\11"3""\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\0U\99ª\99\88ffwDD3333""3DD333333""""\11\11\11\11\11\11\11\11\11\11"\11""\11""\11\11\11\11"""\11""3""3D33""\11\11\11\11"\11""""\11\11\11"\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"33ff333UU\11\11"\11\11\11\11\11\11\11\0\0\11\11\11\11\0\11\11\11\11\11\11"""""3D33333333333\11"3DDD3"""\11"""\11""""""\11\11\11"""3"""""""\113D3""""""""""""3f\99\99\99wfU"""3"""33DDDD3"3333DD33"3DD333UD33"""\11\11\11\11\11\11\11"\11""3"""""\11""3"""""""""""33"3""""""""""\11\11\11\11\11\11"""\11\11\11\11\11\11\11\11""\11\11\11\1133DD33""3Df""\11D333333"\11"\11\11""""\11""\11\11\11Uf3"D3\11""D"3""\11\11""\11\11\11\11\11\11\11\11\11\11\11\0\11"w\99\88ffD3DD333"3""D3DDD333333""\11"\11\11\11\11\11\11\11\11\11""\11""""\11\11\11\11""""""3333333""\11\11\11"""333"\11\11\11"\11\11"""\11\11\11\0\11\11\11\11\11\11\113"\11\11"""U3""3f""\11\11""\11\0\0\11\11\11\0\11\11\11\11\11\11\11\11\11\11"3"""3U3"""3"3"3"33""3UU3""\11\11"""""""""""\11"""""""""""\11"fD"""""\11""\11"""3U\88\99\99\99wfDDD3D33"33"DDDDD33333D33333D3"33UD3D3"\11\11\11\11\11\11\11\11"""3""""\11\11"\11\11\11""""""""""333"""3"""\11"\11\11\11\11\11\11\11"\11"""\11\11\11\11""\11\11\11\0\11\11\113DUD3D3"3UU3""D33"3"3""\11"\11\11""""\11""\11""DUDD3UUUUUU33333""\11"""\11\11\11\11\11\113w\88\88wUDDD3"3333"3"""3D3DD"33""""\11\11\11\11\11\11\11\11\11"\11"""""\11\11\11\11\11\11\11""3"""33"33""\11\11\11\11""""3"""\11\11""\11\11"""\113\11\11\11\11\0\11\11\11\11\11\11\11\11\11"33\11""ff\11\11"\11\11\11\0\11\11\0\11\11\0\11\11\11\0\0\11\11\11\11"3DDDD3"""""""""3DU""33DD3"\11\11"\11""\11"""""\11"\11""\11""""""""3f3"""""\11"\11\11""33w\88\99\99\88fU"""333DD"3"3DDD333""3DD3DDD33D33DUDUD"""\11\11\11\11\11\11\11\11"""""""""""\11"""""""3"33DD3"""""""\11\11\11\11""""\11""\11\11\11\11\11\11\11\11\11\11\11\0\0\11""3UUU33DDDDD""""""""""\11\11"\11\11"""\11\11\11""\11\11\11\11\11fUUfUUUDUUDD3DD3DDDD33D33DfU33DDDDD33333333"3"333D33D3"""""\11\11\11\11\11\11\11\11\11\11\11\11"\11"\11""\11"""""33""3""3"""\11"""\11"3"""\11\11\11\11\11\11\11""""\11"\11\11\11\11\11\11\11\11\11\11\11\0\11""3\11\11""DD\11""\11\11\11\11"\11\11\11\11\11\11\0\0\11\11""\11"""33"""\11\11"""""""33""3"DD3""\11\11\11""""""""""\11\11"""""\11\11"\11DD3""""""\11\11\11""""U\88\88\88wf"3"33D3D3D33""3333"""333DDUU3D33333DUDDDDD"\11"\11"\11\11\11""""""""""""\11"""""""3"3DD3""""""\11\11\11\11\11\11\11\11\11\11\11\11""\11"\11\11\11\11\11\11\11\11\0\11"33DwwD"33DfDD"""""""""\11\11\11"\11\11\11""\11\11\11\11\11\11\11""ff3DDDDDD3333D33DD3UUUDDDDDD333DD3333333D33"33333DD3333"""\11\11\11\11\11\11\11\11\0\11"""\11"\11\11"3"\11""\11\11"""333"333"""\11\11\11"3"""\11\11\11\11\11\11\11\11\11""\11\11"\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11""3DD\11""\11"""\11\11\11\11\11\11\11\0\11\11""3"\11""""""\11\11"""""\11\11\11\11\11\113"""""""\11""""""""""\11\11\11""""""\11\11\11f3"""""""""""""33w\99\88fU33333D333333"3333333"3333UUfD3D333333D333Df""\11\11\11\11\11""3D"\11"\11"\11"\11\11"\11""""""33333"""""\11""\11\11\11\11\11\11\11\11\11\11""\11"\11"\11\11\11\11\11\11\11"33"3\88f3""3"DD"\113"\11"""3""\11\11\11\11\11\11\11\11\11"\11\113UfUUffUUUD3333333D3"3"DUUUDDDDD333DUDUDUD"333333"3"333DD3"3""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""33\11\11\11\11""\11\11"""""333""""\11"333""\11\11\11""""\11\11\11"\11\11\11"\11\11\0\0\0\0\11\11\11"\11\11""\11\11"""333D"\11\11""\11\0\11\11\11\11\11\11\11"""\11\11""\11\11\11\11\11\11"""\11\11\11\11\11\11\11\11\11"3""3""""""D3""""""\11\11"\11\11\11"\11\11"\11"w3\11\11"\11\11""333""""f\88\88fDf3D333"333D33"3""333333"33UUUDDDDDD"3""""""DDD\11\11\11\11\11"\11""""\11"\11\11\11\11\11"""""""333"""3""""\11""\11\11\11\11\11\11\11\11\11\11"""\11\11\11\11\11\11\11\11""33333fU3""3UUD3\11""""\11""""\11\11\11\11DDD""DUff\88\88fDDDDDDD33"33333333DDUUDDD3333D3DUUffUD3"""33"3333D333"3""""\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11"3"\11\11\11\11\11\11\11""""""333"\11""3333""\11\11\11""\11\11"\11\11\11\11\11\0\11"\11\0\11\0\11\11\11\11""\11\11""\11"""3DD3D"\11""\11\0\0\11\11\11\11\11\11\11\11"\11\11\11\11\11\11"""\11\11"""\11\11\11\11\11\11\11\11\11"""\11""""""3D""""\11\11"\11\11"\11\11\11"\11"\113U3\11"""""""""""3Dw\99wDDDD"33D3333D3D333""3""33"3DUUDUDDD33"\11\11"\11"\11"3UU3\11\11\11\11\11\11\11\11"""""\11"""\11\11\11\11""""""""33"""\11"""\11\11\11\11\11\11\11\11\11\11"""""\11\11\11\11\11\11\11\1133333f"\113"3Df"\11"\11\11\11\11\11\11"""\11\11\11\113DDUUDUUfUDDDDDDDDD3D3DD333D3DUUUUDDD333DDDUfwfUD3""D33D33333333"3"3""""\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11""\11"\11\11"""\11""""""D33"\11\11"33D3"""\11"""\11""\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11"\11\11""\11"\11"33D3DD\11"\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11""""""""""\11\11\11\11\11\11\11""\11\11\11""3""\11\1133""""\11"\11\11""\11\11\11\11\11\11Uf"\11\11\11\11\11""""""\113f\99\99UDD3DD"D3333333D333""33"333DUDDDUUU3333"\11"""""33UU3\11\11\11\11\11\11\113D""""""\11\11\11\11\11\11""""333""""""\11""\11"\11\11\11"""\11\11\11\11""\11\11"\11\11\11\11\11""3333f3\11"33Dff3"\11"\11\11\11\11"""3"\11\11DU333DDDUDD333333DD33"3D333D3DUUDDDDDDUUUUUUDDUD"333D3DD333UUD3333333""""\11\11\11\11\11\11\11\11\11\0\11\11\11\11"""\11\11\11\11"\11"\11""""""""""""""3333"""3""""""3"\11\11\11\11"\11\0"\11\11"3\11\11\0"\11\11"\11\11""""33UU3\11\11""\11\11\11\11\11""\11\11\11\11\11\11\0\11\11""""""\11""\11\11\11\11"\11"""\11\11\11"333\11\11\11"D""D""""\11\11"\11\11\11\11\113ww\11\11\11"\11\11"""\11""D\88\99\99wDD3D3D33D3333333D""""3"3"33UDDDDUU33DDDD""""""33DDff\11\11""""33"D""""\11\11\11\11\11\11"""\11"""""""\11\11\11"""\11\11\11\11\11""\11"\11"""""""\11\11\11\11\11\11"3DDUw"\1133DUU3DDDUDU""DDUfD3333333""3DD3"""33DDD333DD3DDDDUUDDDDDDUUDD333333DDD33333DDDUUU3"333"3""""\11\11\11\11\11\11\11\11\0\11\11\11\1133"\11\11"\11"D"\11\11\11""""""""""""""333""3""3"""33"\11\11\11\11\11\11\11"3"33"\0\11\11"""""""""3DUD3\11""""\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11""""""\11"\11\11\11\11""""\11\11\0\11\11"333"\11""3\11"3"\11""\11"\11\11\11\11\11D\88f""\11\11\11\11""\11""3wªª\88UDDDD3DDDD3333""3333""""""3DD33DDDDU"3D3DD"""""333DDUf3U3"""""""""\11"\11\11\11\11\11\11"""""\11\11\11\11\11\11\11\11\11""\11"\11\11\11\11\11""\11""""\11\11\11\11\11\11\11\11\11"3DUDwf"""D3UDDwD333UUU33333"""""\11""""3D3""333DDD333D33DDDDDDDDD33D3DDD33333DDD33"33"DUUfUD""33"3"""""\11\11""\11\11\11\11\11\11\11\11D3\11\11""\11DwU""\11\11"""3"3333""""3333""3"""\11"3"""\11\11\11\11\11"\1133""""\11\11"\11\11""""""33DDU"""""\11\11\11\11\1133\11\11\11\11\11""\11\11""""""""\11\11\11\11\11\11\11\11\11\11\11\11""3333""""\11\11""\11\11\11\11\11\11\11\11\11\11Uf"""\11\11\11"""""3D\88ª\88\88UUDDDDDDDD"33333"33"3"\11""3D""DDDDD33DU3""D33"3333"3D3DUUUU\11\11\11\11"3""\11"\11\11"\11"\11""\11\11\11\11\11\11\11\11\11\11\11\11""""""\11\11\11""""""\11\11\11\11\11\0\11\11\11\11""3DDw\883""33DwfU"\11\11"""3""""""\11"""""""DD3DD3"""3DDD33DD333333D3333333D33333D"3DDD3"3"3DDUfDD3"3333"""""\11""\11\11\11\11\11\11\11\11""""""""3fU""\11\11"\11"""3"""""3"DD3"""D"\11\11\11""""""\11\11\11\11\11"\11\11\11""\11\11\11"\11\11"""\11"""DD33"3""\11\11\11\11\11\11\11\11\11\11\11\11"""""""""""""\11\11\11\11\11\11\11\11\11"\11\11"DU""3""""\11\11\11\11\11\11\11\11\11\11\11\11"DfD"""""""""""""w\99wwfUUD33"33D33"33333333""33UfUUwfUU3"333UD"33"33"3"333D3D3DDUUwwDU""""\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""\11"""\11""\11\11\11\11\11\11\11\11\11\11\11\11\11"3DUwU""""3DUw\11\11\11""""\11\11"\11\11\11\11\11"""""33DD"33""""333DDDDD3D3"33DD33333333333DD33DDD333DUDUfUfD"3333"""""""\11\11\11\11\11\11\11\11"33\11\11""\11"""3""\11"3"\11\11\11"\11""\11""3DDD3"33\11\11\11""\11"""\11\11\11\11\11\11""\11\11""\11\11\11\11\11\11"""""""DDDDU"3"\11\11\11\11\11\11\11\11\11\11\11"""\11""3"\11""""\11""\11\11"\11\11\11\11\11\11\11\11"D"\11\11"""\11\11\11\11\11\11"\11\11\11\11\11\11Dww"""""""""""""\11f\99wfffUD333333D3""3333333""UfffwfUD3""33"33DD3"33UD3D""3UDDDDDDffUww3\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11""""""""""""""\11\11\11\11\11\11\11\11\11\11"DDff3"\11\11\11333DU"\11\11\11\11\11\11\11"\11\11\11\11"""""333"33"33333DDDDDDDDD3D33DUD3""33D3DDDDD33333D"3333UUf\88f3333333D"""""\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11"3"\11\11\11\11\11""\11\11\11\11\11"3""""3D33\11""\11\11"3""3"\11\11\11\11\11"\11\11"""""\11\11\11\11\11\11"""""""DDDDD3DD""\11\11"\11\11\11\11\11\11\11""\11""3""\11\11"""\11\11\11\11""\11\11\11\11\11\11\11\11"\11""""""\11\11\11\11\11\11\11\11\11\11\11"UUD333""""""""""\11wªfffUUDDD33333"""3""33"""3UfUDDD3""""3"""""33""333DUf3""DD33UUUD33DUD\11""""\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\113""""""\11""""3"33"\11\11\11\11\11\11\11"3DDD3\11"\11"""DUU3\11\11\11\11\11\11"""""\11"""""3333333D3333DUD3D3DD3DDDDUU3"3"3DDDDDDDDD3333"""3333DD3UD3333"3D33""\11\11\11\11\11\11""\11"""\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11"""""\11"D3"3""\113""33D3\11"\11\11\0\11\11\11\11\113"""\11\11\11\11\11\11\11\11\11""""3DUDDDDD3""""\11\11\11\11\11\11\11\11\11\11"3"""\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11"""\11\11\11\11\11\11\11\11\0\11\11UD3333333""""""""3\88\99\88wwfUDDDDDD33D"33"""33D3UfU333333""""""""""3"""3DDUfD3D"333D33333D3ff"\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""D3""33D333""\11\11\11\11\11\11\11"3DD"\11\11"""33D3"\11\11\11\11\11\11\11\11"33"""3""3DDUD3"333DD3DfUDDDDDDDDDDDDfU33DU333DD3D33D3D3333333333"3333DDD33""""""\11\11"\11\11\11\11"\11""\11\11\11\11\0\11\11\11\11\11""\11\11"\11"""""\11\11"33D""""333"3D"""\11\0\11\0\11\11\11""\11"\11\11"\11\11\11\11\11\11\11\11"""3DD"33UU3""3""\11\11\11\11\0\11\11\0""""""\11\1133"\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""\11\11"\11\11\11\11\11\11\11\11\0\113UU333333333"""""3w\99\99\88wffUUUDD3DD3U"3"""333DDUUD333333"""""""""""3"D33DDf3\11"\113"3D333333D3Df\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11"\11""fU3333"""\11"\11\11\11\11\11\11\11"3UUD"\11""""UD""\11\11""\11\11\11\11""3"3"333DDDDw\88\88D3DDDDDw\88fDDDDUUUwwfUwfDUUD3333DD33DDUDUU333333D333""33DD\11"3""D3"\11\11\11\11\11\11\11\11""\11\11\0\0\11\11\11\11\11\11\11""\11\11\11\11"""""\11\11\1133"""\11"""""\11DD\11\11\11"\0\11\11\11\11""\11\11"""\11\11\11\11\11\11\11\11\11"""3333"UDU"""33"\11\11\11\11\11\11\11\11\11\11"\11""\1133""\11\11"\11\11\11\11\11\11\11"\11""\11""""""\11\11\11\11\11\11\11\0"\88fDD33333333333D3f\99ª\88wwffUUUUUDD3DDD33"""\11"DDUD333333""""""""""""""33D3DDU3""UwUD3333333D3DfwDD3"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""\11""3D33""""""""\11\11\11\11\11\11\11\1133DU3"""""ww"\11"""""\11"""33""""3DUfUU"3"fwDUUUfwD\88wUUUUf\88\99DDDwwUU3"""33333DD3DDU3D3"333333D33333UD"333UU3\11\11\11\11\11\11\11\113D"\11"\11\11\11\11\11\11\11"\11\11"\11\11\11"""""""3U3""\11"""\11\11\11\11"D"\11\11\0\0\0\11\11\11""\11\11\11\11"\11\11"\11\11\11\11\11\11\11\11"""333UfDD\11\11"""\11\11\11\11\11\11\11\11\11\11\11\11""\11"33"\11\11"\11\11\11\11\11\11\11\11\11""\11"""""\11\11\11\11\11\11\11\11\03\88ªfUDDDUDDDDDDDDU\99ª\88UfffffUDUUUDD3Df3""""""Dff3333333"3"3""""""""""""3DDDDDwfUD333333333333"3Dwwwf\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11"""""\11"""""\11"""\11\11"\11\11\11\11\11\11\0\11"33DD""""3\88w3\11"3"3"\11""""D3"""""333"3\11\11\11\11fUffwfDD\88fUDUUf\99\99w"Df3"UfD""""3DDD3333D3"33333D33D3DDDDDD"3DDU3\11\11\11\11\11\11\11"33\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""D3DD3"\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11"\11\11\11"\11\11\11\11\11\11\11\11\11""3DDfDD3\11\11\11"\11\11\11\11\11""""\11\11"""""D33\11\11"D\11\11\11\11\11\11"""""\11\11"""\11\11\11\11\11\11\11\0\0Uªª\99wwwwwwUfUUUUfwªª\88""fUUUU33DUUUDDUDD3"""3DfU333""3"3""""""""""""""""3UD3""33"3"333333333333DDfff\88D\0\11\11\11\11\11\11\11\11\11\11\11\11\11""""""\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11"\11\0\11\113DD3333f\99\99""333"""33"33D3"3"\11"""\11\11\11\11\11\11\113fDUU"\11w\88fDUUff\99\88\99f\88U"3UfD""3fU3D""D33UU333333D333333U3""DDDD3"\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""3D"3"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\0\11\11\11""""3DD3D3\11\11"\11\11\11\11\11\11""3\11\11"\11\11\11"DD3D"\113\11\11\11\11\11"""""""""\11\11\11\0\11\11\11\11\0\0\0Uªª\99ªªª\99w\88fwwfww\99ª»ªU\11\11UUDUDDDDDDUUUUDD33""3UUD"""""""3"""""""""""""""33D33"33"3"3333333"33D3DDUUUfUfwD\0\11\11\11\11\11\11\11\11\11\11""\11""""\11"""\11"\11\11\11\11"\11\11"""\11\11"\0\11\11"DU"\11Df»»wU33333"3D3""33D33""\11"""\11\11"\11"\11\11\113"fD3UwfUUUfw\99\99\88fwf"\11DfU3"wfD33D3fD33DD3333"3333333DD"33DUD""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11""""D"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11"\11\11\11\11\11\11""""DDDD33D"\11"\11\11\11\11\11\11\11\11""""\11\11\11\113fUD""3""\11\11""""3"""3D\11\11\11\11\11\11\11\11\0\0\11\88fw\99ªÌ»ª\99\99\99\99ªª»ªª\99U\11\1133DU3DDD3DDDUUf3D3333DU3""""""""""""""""\11""""""33D3333333"3333333"33333DDUUfUffUww"\11\11\11"\11\11\11\11\11"""""""\11\11\11\11\11\11\11\11""""""""""\11\0\11"3DU""\99ÌÌ»\8833DDD33333D33D3333""""\11"\11\11\11\11\11\11"3UUfUDDDD33"DwwD33\11\11"DDD"DUD"33UDDU3"3""""\11"33333""3333D3"\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\0\11\11\11\11\11\11\11\11\11\11\11"3"3""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11"\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""3D3DU333""\11\11\0\11\0\11\0\11""3""\11\11\11"3DUD""3""\11\11\11\11""\11""333\11\11\11"\11\11\11\0\113\88»\99"Df\88ª»»»»»»\99fUw\88f"\11\11D333DD333DDDDDUDDD333DD""3""""""""""""""""""""""3D3"3"""3"""33333""3"333333DDUUUUfUwwDffU3\11\11\11\11\11\11""\11\11\11"\11\11\11\11""""3"""33"3\11\0\11""ffDU\99wª»wDDDUUDDD3333DD333DD"""\11\11\11\0"\11"3DDDD3D3D33333ww\11"\11\11\11"3Df3"3333DD3D""33"""""3DD33333333333"""\11""\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""\11"3"3""\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""33D"D"""3\11\11\11\11\11\0\11\0\11\11"33""\11\11\11"""3D"D3D"""""""\11""\11\11\11\11\11\11\11\11\11\03\88ª\99ªªwDU\88ª»»»ªªU"""3f\11"\113UD3DDDDUUUUUUfDUfD333DD33"""""\11\11""33"""""""""""33333"333""""33333"""3333333DDUUUfUUUfwfww"\11\11\11\11"\11\11\11\11\11""\11\11"""""""""\11"\113"\0\0\11"\88Ì\88wfDwªÌ\88UUDDDUDDD3DDD3D3D33U3"\11\113DD"""\1133DDDD3""33fwwwD""""3Uw33333333DD"""3"""""""3D333"3333""""\11\11\11\11\11\11\11"""\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11"33"""\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11"\11\11\11\11\11\11\11\0\11\11\11\11\11"\11\11"""\11\11\11\11""""Dw"\11\11\11\11\11\11\11\0\0\11\11\11\11\11\11""""\11\11\11"\11DUD333"3D3""\11""3\11\11\11\11\11\11\11\11\11\0D\99ªªª\99wDUUf\88\99\99\88UDDU"3U""\11"UUDUUDffwffwwffffU33DDD33"""""\11"""""""""""""""""3333"""""""3""33""""3"3333333DDDUDDUD33Dff"\11\11\11\11""\11\11\11""\11"""\11"\11"\11\11"\11\11\11\113\11\11\11U\88ÌÌ»\88DDwªªwUwUffDDUUUUDUDDDDD3D"\11""\11\11""\11"""""333""3"3f\88\88U3"""""UwD333333DDD3"3D3"""""3D"333D3""""""\11\11\11\11\11\11\11\11\11\11"\11"\11\11\11\11\11\11\11\11""\11\11"\11"DD33"""\11\11\11\11\11\11\11\11\11""\11\11\11""""\11\11\11"""\11\11\11\11\0\11\11\11\11\11\11\11\11\113\11\11""3D33DUUw3\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""\11\11\11"33""3"\11"""\11\11\11\11\11\11\11\11\11""\11\11\11\11\11U»»»ªw3Df3DDUD3"\1133"D3D3\11\11"UUDDUDUfffw\88wwwffD3DD333""""""""\11""""""""""""""33"""""""3""33333""3"3"333333333DDDD3333DDfU\11\11\11\11"\11\11\11""\11"""\11"3""""\11\11""3"\11\11fªªªÌ\99DD3UUfwffww\88fDDDUDDUfwwfwUUD\11"""3"\11"""3""33""""3DU\99w3333"""DUfD33""333D3333""""333333""""""\11\11\11\11\11\11\11"\11\11\11"""\11"""""\11\11\11\11\11\11"""""DD3D3"""""""\11\11\11\11""\11\11"""""\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11"""3DDDDDUw3\11\11\0\11\11\11\11\11"\11\11\11\11\11\11"""\11"""""""""""\11\11\11\11\11\11\11\11\11\11"""\11\11\0\11"f»»ªw3\11Dww"D333"""\11"D33DD\11\11UUU"\11\11DUUffw\88wwwffUUUD"33""\11"""""""""""""""""""D33"""""""33"333D""3""""33"3333"33333333333UwD\11\11\11\11"\11\11""\11\11"\11"""""\11\11\11""DD"\11D»»\99\99»f3D3""\11\11"\11\11"Df\88f3UD3U3\11\0\11D3D""""""""""""""""""33DU\88ªfD33"""333D3DUD33333""""\11""3""3D3"""""\11""\11""\11"""\11\11\11""""""\11\11\11\11"\11\11\11""""3DUU3D333"""""""\11""""\11"""""\11\11"\11\11\11\11\113""\11\0\11\11\11\11\11\11\11"\11\11""33DUUUww"\11\11\0\11\11\11\11""\11\11\0\11\11\11\11""""""""""3"""\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11D\99\99ªª\99D\0\0Dfww3"3"""3"""""3DD""DD\11\11\11""DD33f\88wwwfUfUUDD3""\11"\11""""""""""""""""3D33"""""""""""""3"""""""""""""""""""""""3DDDfwf"""\11\11\11""\11"\11\11""""""\11\11""DD3"fª\99w\88\88\88D3"333"""""D33DfDffD"\11\11\11\11\11\11\11\11""""""3""""""""333UDDDUf33D33"3"DfUfD333"3""\11""""""3333""""""""""\11"""""\11"3333"D333333"""""""DDUU3333333"""""""""\11\11"""\11"\11\11"\11\11\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11"""33Dfff"\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11""""""""33""\11\11\11"\11\11\11"""\11\11\11\11\11\11"\88»Ì\99\88w3\0\11""3UU"""""""\11\11\11""3U3\11\113\11\11\11"""""\11DwwwwfffffDD3"""""\11""""""""""""""3D3"""""""""""""""3"""""""""""""""""""""""33333Uwf3"\11\11\11\11"""\11"\11\11"\11""\11""3DD3Uw\88ffwfDD"3"333""3""333""\11"\11\11\0\11\11\11\11\11\11"""""""33"\11\11""\11\11"333D3D33DD"D33UfU\88\99fDD33"33"""""""""33""""""""""""""""""D333"\11"3"3333"""""""3UffD"\11""3D3""""""""\11"""3"""""\11\11\11\11\0\11\113"\11\11\11\11\11\11\11\11\11\11\11"""33Dff3"\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11D333"333"""\11""\11"""""""""\11\11\11U»Ì»3\113\11\0\0\11"33D"""3D3"\11\11"""33D"""\11"""""3""DwwwwwfUwwDD3""""""""""""""""""""3D33""""""\11\11"""""3"""3""\11"""""""\11"\11"\11"\11""""3333DD\88D\11\11\11\11\11\11"""\11\11"\11"\11\11\11"3DDUUUfwUfffD333333""333333333"\11\11\11\11\11\11\11\11\11"3""\11"""""""\11\11"\11"""""DD3"""33"33D33DDw3D""""3"33333""""""""""""333"33"3""3"""\11""""""33"3"""\11"3DUwf"\11""""3333""""""""""""""""\11\11\11\11\11\11\1133"\11\11\11\11\11\11\11\11\11\11""""3DfU33\11\11\11\11\11\11\11""\11\11\11\11\11"\11\11"3UD33DD3""""""\11"""""\11""\11\11\113\88»»\88"\11\11\11\11\11\11\11"3"\11""U3"\11\11""333DD3"""""33"""3fUwwfwwwwUD33""""""""""""""""\11"""DD333""""""""""""3"333""""\11"""\11\11\11\11\11"""""""""""333\88\99D\11\11\11\11\11"""""\11"\11"""3DUUUwwUUUfffU33333D3333D333""3"""\11"\11\11"\11\11""D""""""""""\11"\11\11"""""DU""""3""""\11"DDUf"""""3333DD3333"""""333"3"3DUUUDDD33""""\11""""333""""""3Ufff""""""3"333333""""""""""""\11\11\11"\11\11\11\113"\11\11\11\11"\11\11\11\11""""""3fD""\11\11\11\11\11\11"""\11\11\11\11\11"\11"3"3DDDD3D3"3"""""""\11\11\11"\11\11\11\11Uª»U3\11\11\11\11\11\11\11\11"\11"\11\11\11""\11\11"\11"3333UU3"""""33"3UUUDwfwwwwfDD33"""""\11""""""""""\11"3DD3D"3""""""""33"""3"3"""""\11""""\11\11\11"""\11"""""""""3D\99\88"\11\11\11\11\11"""\11\11\11\11""3333DUwwfUUff3UD33333D33D3D3""""""\11\11\0\11\11""\11\11\11\11\11\11""3333""""\11"""""""\11\11"""33\11"""""DUUw3D3"33DD3DD333""33""3"\11"3"UwU33""""3D"""""""""333"3"33DffU""""33"3333333333"""""""""\11\11\0\11\11\11\11\11""\11\11\11\11\11\11\11\11\11"""\11""DU"333""""""""\11\11\11\11\11\11\113333DDUDUU3""33"""\11\11\11\11""\11\11\113\99\88f"\11\11\11\11\11\11\11\0\11\11"""\11\11\11\11\11""""3"333Df3"3"33"3UfDD333DfwwffD3"""""""""3"""""""\113DDD3333"""""""3"33333""""3"""\11\11\11\11\11\11\11"\11\11"\11""\11"""""3UU\99\88\11\11\11\11\11\11\11\11\11\11\11"""3""3DDDffUUffUD"333D33D333333"""""\11\11\11\11\11\11\11\11\11"\11\11"""""33D3""\11""\11"""""\11"""""""""""33DUUD3333333333333"333333""33U\88w3"\11"""""33"""\11\11""""""333DDffU"""""33"333"333333""""""33"\11\11\11\11\11\11\11"3"\11\11\11\11\11\11\11\11\11"\11\11"33D""3D3""333"\11\11\11\11\11\11\11\11""33""3UUD"\11"""""\11\11\11\11\11\11\11\11\11"U»\99"""\11""\11\11\11\11\11"""\11\0\0\0\11\11\11\11"""33DDDwU"33333UUDDD33DD"DwwDD3"""""""""3"3"""\11\113DDDD3"3""""""\11"""""3UD""33"""""\11\11\11\11\11\11\11\11\11"\11"\11"""\11\11\113DUU\99\88"\11\11\11\11""\11\11\11\11\113"""33DUfUUUUUUUU33DDD3D3333""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""3"33"\11\11\11\11""""""\11\11\11"""""""33""33UfD3DDDDDD333DDDD3D333D33UUffD"\11\11\11""""3DD""""""\11\11"3333DUfU33"33"""""33333333"""""""33""\11\11\11\11\11\11\11"""\11\11\11\11\11\11\11\11\11\11""333"""33""3"""\11\11\11\11\11\11\11\11""""""3Uw3\11\11\11\11""\11\11\11\11\11\11\11\11\11D\88\99\99Df3"\11\11\11"\11\11""3""\11\0\0\0\0\0\11\11\11"""3DUDff33333UUD3DD3DUD"3DfU33""""""""3""""""\11DUU333""""""""""""""""DD3"""""3"\11"\11"\11\11\11\11\11\11"\11\11"\11""""""DDUffU\11\11\11\11""\11\11\11\11"\11\11\113333DUfUUUUDDDDD3DD3DD333"""\11\11\11\11\11\0\11"\11\11""\11\11\11\11\11\11"\11\11""""\11\11\11"""""\11\11"\11\11\11""""""3333333DDUUDUD33333DU333"UfDDDDD3D3\11\11\11"\11\11\11""""3""""\11\11\11"DD33DDw\99D"D333"33"33333333"""333""333""\11\11\11\11""\11\11\11\11\11\11\11\11\11\0\11\11\11\11""3D3""""33""""\11\11\11\11\11"\11\11\11\11\11""3"Dw3\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11U\99\99D\0UU3\11\11\11"\11\11\1133D"\11\0\11\0\0\0\0\11\11"""3DUDDfD33DDfU33DDDfU3"33UD3""""""""3"""3""""DDD""3"""""""""""\11"3"""33D""""""\11\11\11\11\11\11\11\11\11\11\11"""""""3"333DffU"\0\11\11\11\11\11"\11\11\11""\11""333DUfUUDDD3DDDDDUD33"3""""\11\11"\11\11\11""\11"\11"\11\11\11\11\11""\11\11"\11\11\11"\11\11"""\11\11\11\11""\11"\11"\11"""33""33333wwUDD333"33""""33333"3D333"""\11\11"""""""""\11\11\11""3D33DUwU""Df33333"""333333333"""""33"3""""\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11"3DUD""""33"""\11\11\11\11\11\11""\11\11\11\11\11"333UD\11\11\11\11\11\11\11\11\11\11\11\11\11"U\88\99w\11\11\11DU""\11\11""""33""\11\11\0\11\11\0\11\11"""3DUfDfU33DUfD333DDf3""3"DU"""""3333333"""""3UD3"""3"""""\11\11""\11"""3"""\113D""""""\11\11\11""\11"\11"\11"""""""""3"3DDUDffD\11\11\11\11\11\11\11\11\11\113""3DDDUUfUUU3"DDD3DDUD3333""\11\11\11\11""\11\11"""\11\11\11"\11\11\11""""\11"\11\11\11\11\11""""\11"\11"""\11\11\11"""""33333"3D\88»wUDD333""""""""""""33"DDD3"\11\11\11"""""""3\11\11""""333UwU3""3UfD333"3""333333333333"3"33""""""\11\11\11\11\11\11\0\11\11\11\11\11\11\11\11"\11"DU3\11"""""""\11\11\11\11\11\11""\11\11\11\11\11\11"33DD3\11\11\11\11""\11\11\11\11\11\11"wªªw"\11\11\113D"\11""""3D33"\11"\11\11\11\11\11\11"""3DUffwD3DfUDDDDDfww"""""DU3"""333""33"3"""3D33"""""""""\11\11"\11"\11\11"33""""\113"\11\11"""\11\11\11"\11\11\11\11""""""""""DD333DDDUfww\0\11\11\11\11\11\11"""""33UffUffUUU"DD333D3DDD3""""""33"DD"""\11"\11""\11\11\11""\11""""\11\11\11\11\11\11\11\11\11""\11"\11\11\11\11\11"\11\113"33333D33DwUDDDD33""3"""""3""333DD33""""""""""3"""""""""DwD"""3D33"""3"33D""333"33333"""D3"3"""\11\11\11\11"\11\11\0\11\11\11\11\11\11\11\11"\11"3U\11\113""""""\11\11\0\11\11\11""\11\11\11\11\11\11\11"33"U3\11"\11\11\11\11\11\11\11\11\11""fªª3\11\11\11\113D"\11""3"UD3"\11\11\11\11\11\11\11\11""3DDU\88\88\99\88wfUUUUffUf\88U"""3UfU33"""33"33"""""\11D3""""""""\11"\11\11"\11"""\11"3333"""\11""\11\11"""""""\11\11\11\11\11"""3""3333DD333DUfDfw\11\11\11\11\11\11"D""""3DUUUUUUU333DD"3DUDD3""""""\11\11\11\11\1133""""\11\11\11\11\11\11\11"""""""\11\11\11"\11\11\11\11\11"\11\11\11\11\11\11\11\11\11""""D333""""\11"DDUUU3"\11"\11"""""""""333D3"""""\11""""3"""""33"\113U"""""3ffD33D3D3DD3333"3333333"3333""\11""\11\11\11\11"\11\11\11\11\11\11\11\11"""""D""3""3""\11\11\11\11\11\11\11""\11\11\11\11\11\11\11\11"3333""\11\11""""\11\11\11""f\88w3\11""\11\11UD""""3UU3"""\11\11"\11\11"""3DUw\88ww\88ª\88\88wwwfUfwf"\11""3wwDD3"""33"""3"""""D3"""""""\11\11\11\11"\11\11""""""33"3"""\11\11""\11\11"""""\11\11\11\11\11\11""3D3""33DDDD33UUfUff"""""\113""""3D33DDUfUD333"3UUUD3"33333""\11\11""\11"""3""\11\11\11\11\11\11"""""""""""""""\11""\11\11\11\11\11\11\11""\11""3D33"""""""""3D"""\11\11\11"3"""\11"""3D3D3\11""\11\11""\11"33""""""""33D""""""33\88fD3333DD33333"3D"33D3333"""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""3""""\11""3"\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\113"\11"""\11"""\11\11\11""3wwD""""""3f3\11\11\11\11DUD3"""""""33DDUfwwfff\88ª\99wUUUUwwD""""3fwfDD""3333333""""3U3"\11""\11\11\11\11"""""\11\11\11""""DDD333"\11\11\11\11\11\11\11""""\11""\11"\11\11""3333333DDDDDDDDUU\88w\11""\11\11"\11"""""DD3DUUD33"3D3DUUD333D3""""""""\11""""3""\11\11"\11""""\11\11""""""""""""""\11"""""""""33DD"""""""\11"""33""""""""""\11\11""3DDDD3""\11""""\11"3""""""""""""""3333""33"DD3UUfUD33333"333D3D33D""""\11\11\11\11\11\11\11\11\11\11\11\11"\11""D3D3"\11\11""""""\11"""\11"\11\11\11\11\11\11\11\11\11\11\11"\11\11\11"""""\11\11\11\11"UªU\11"""""\11\11fD"\11\11"UUD33""""33DUUfwUUfwUU\88ªfUDDDDww3"""""fwfDD333333333""3"DU333"\11\11\11\11""\11"\11\11"\11\11""""""DD33"\11\11\11\0""\11""\113"\11"\11""\11"""""33"3D3DD3D3DDDf\88D\11\11\11\11\11\113"\11"3"D33DUUD3333"DUUDD3"33""""""\11"\11\11""""""\11\11\11\11""33"""""""3"""""3"""""""""33DDD33"3"""""\11"\11""""""""""""""""33DD333"\11\11"""\11""""""333""""\11"""\11\11"33""33D3""33DDDDD33333"333"3333""\11\11\11\11\11\11\11\11\11\11\11\11\11"""33DfU3""""""\11"""\11\11\11\11\11\11"\11\11\11\11\11\11\11\11"\11""""\11\11"\11\11"U\99»D\11"""""""DU3\11\113UUD3333""33DDfw\88fDDfww\88wD3DfDDfU"33"""DwwUDD333333333""3DD33"""\11""\11\11\11\11"\11\11\11"""""\11"\11\1133\11\11"\11\11\11"3\11\11"\11\11\11"""""""""""3"""333D3D333Dfwf3\11\11\11\11\11""\11"3"333DDD333""DU3DD333"""""\11\11\11\11\11\11""""""""\11\11"3333"3"""33""""""""""""\11\11"333UDDD3""\11""\11\11\11\11\11""\11"""""""""""3D3"33"3""\11\11""""""3\11"DD3"""""\11"""""""3DUU3"""""333DDDD3""3333""3333""\11\11\11"""""\11\11\11\11\11"\11"3Dfff"""\11""""3"\11\11\11\11\11\11\11"\11\11\11\11\11\11\11"""""""\11\11\11\0D\88»\883\11""""""""wD""DUDUD3D33D33DDUffwff\88\99wfDDDD3DUUD\11""3"""fwwfDDDD33333"""DUD""3"\11\11""\11\11"\11""\11""""\11""\11\11\11"\11\11\11\11"\11\11\11\113\11"\11\11"""""""""""""3333D"3"3333DUUUf3\11"\11\11\11\11\11"""33D3333""""33DD3333""""\11"\11""""3D""""""\11""3333""3""DD33"3""""""""""""33"3UD3"""""\11\11\11""""""""\11""""""333""333"3""\11""""""\11"""D33"""\11\11""\11\11"""""3D3"""""3"D3DDDD"3""3""D3D3"""\11\11\11\11"""""\11\11\11\11""""3UDDU3"\11"33"""\11\11\11\11\11\11\11"\11\11\11\11\11\11"""""3"\11\11\11\11\11UÝ»w"\11"""""""\11UU""UD3DD3333DDDDUDDf\99ª\99wUUDDDDDD33Uw""""333DffwfUUUD3333"""fD"""""\11\11"\11\11\11"\11\11\11\11"\11\11"\11\11""""""\11\11\11\11"\11\11\113"\11""\11\11\11"""""""""3333"D33333"""DDDUU\11\11\11\11\11""""3fD"33"""""3"3DUDDD333DU3""""33""\11""""\11\11""3D333""3"""33""3"""\11""\11\11\11""""""3fD3""\11"\11"\11""""""""""\11""""""""""""33D3""\11\11\11"""""3"""""""\11"\11\11\11\11"""\11""3""""""333333UD33"333D33"""""\11\11\11\11"""\11""\11\11\11"""3DDDDD3""333"\11\11"\11\11\11\11""\11\11\11\11\11""""3"""""\11\11"\99ÝÌw"\11"""""""\11\11w33fD""""3DD3DUUUDf\88\99fD33DDDD333DDUU33"3""\11DDfUUUUUDD33"""Dw3""\11"\11\11"\11\11\11\11\11\11\11\11\11\11\11\11"\11\11"""""""""\11\11"\11\11\11D"\11""\11\11\11"""""""""3""""D"33"""3333UUf"\11\11\11""""3D33"33""""""33D3DD3"33"\11""""\11\11"\11"""\11"\11"""33"333""""""33"3""""\11"\11\11\11\11\11""""""UD3"\11\11\11"""""""""""""""33""\11"3""""333D3""\11""""""""""""\11""""""""""\11""""""""3333333D3"3"333D3333""""\11\11\11"\11\11\11"""""""DDUUDUU3""3"\11""""\11\11\11\11"\11\0\11\0\11"""""33"""\11\11U»ÝÝ»D\11""""""""\11"wUwf3""""3DDDDUUf\88wU3""333333"3UU333333333"UDffUDUDDD33"3Uf3""""\11"""\11\11\11\11\11\11\11\11\11\11\11\11\11""""""\11"3\11\11\11\11"\11\113"\11\11\11\11\11""""""""""""""""""""""""""3DUwf333"333DD333"""3"3""33DDD3""""""\11"""""\11""3"\11\11"""3D33DD3"""""""""""""\11""\11\11\11\11""""""3DD3"""\11""""3""3""""\11"3UD"\11"D"""""3""33"3"\11"""""""33"\11\11""""""""""""\11\11"\11""3333333DD333"D3D3"33333"""\11"""\11\11""""""D3DDDDU333"\11"\11\11\11\11\11\11\11\11"\11\0\11\11\11\11"""""3"""""wÌÝÝ»\99wD""""""""\11UD\88wD33"""3DDDDU\88\88D3"""""\11""""DU""33333333D3UUffUUDDDD33DfD3""""""""\11"\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""\11\11"\11\11\11\11""\11\113\11\11\11""\11""""""""""""""\11""3""""""3""33U\88\88\88\99\99w3Uf333""""""33DDDDD33"""""""3""""3DDD"\11\11\11""3DDff3"""""""""""\11"\11\11"\11\11\11\11\11""\11"""UU33"""3"""""""""""""33\11\11"33\11"""""""3D33"\11\11"""\11\11\11"""\11\11\11\11\11\11\11\11\11"\11""""""""""""""333DD3""3DD3D33333"""""""""\11\11"""3""""DD3fU\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11"""\11"""""DfÌÝ»ª\99\99\99U3"""""""3UffU3""""""3DfwwU"""""\11\11\11\11\11"3UU\11\11"3333DDDD3DfUwfUU3333UUU33"""3"3"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11""\0\11\11\11""\11\113"\11\11""\11\11\11"""""""3"""""3"""""3"33"333Uw\99»ªwffD3"3"""""3"3DDDD33"""\11\11"""""""\11DUU3\11\11\11\11\11""3333"""""""""""\11\11\11\11\11"""\11\11""\11""3"UfUD"\11"33""""""\11\11\11\11""""\11"\11"""""\11\11""3"3D3D"\11""""\11\11\11\11\11""\11\11\11"\11""\11\11"""""\11"\11"""D3""333D3"3DDD3333D3"33"\11""""""""\1133"""""33"U3\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""""3"D3\88Ì̪\99\99\88\88wfU"""""""DffD3"""""3ww\88fD"\11""""""\11\11\11"DUD"\11"""D33DD3D3fffwwwU"3UwfD"3"""3"33""\11"\11\11\11\11\11\11\11\11\11\11""""""\11\11\11\11\11\11\11"3""\11\11""""\11\11\11\11\11""""""""""""""3"""3""33333DUf\88\88\99wwU"33"""""33"D333"3""""\11"""\11""""D3"\11\11\11"""3""""""3"3""""""""""\11\11"""""""""3"33DDD\11\11\11""3""""\11\11"\11\11"""""\11""\11\11""\11"3""""DDD3\11\11"\11"\11"\11"""""\11\11\11\11""""\11\11\11"\11""\11"3"3U333"3D3"333333333D33""""""""""3"\11"\11\11\11"""D3DU""""\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11""""""33DDwÌ»\88w\99\99ªwUwU"""3"33wwD33333"D\88U"\11"""""""""""""UUD3"\11""3DDDDU33UffwfUUwUwfD33"D""""33""\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""\11\11\11\11\11\11\11"\11""\11\11\11"""\11\11\11\11""""""3"""""""3"\11"""3"333DDDUUUU\88ª\99D"33""""3"333DD33D3""""""\11"""33"\11"""""3"""""3"33333""""""\11""33D"""333333333D3""""""3""""\11\11\11\11"\11\11""""\11\11\11\11\11\11""""""33333\11\11\11\11\11\11\11"\11"""\11"\11\11\11"\11\11"\11"""\11"""D33D3"33"3D"333DUU3"""33""""\11\11""""33""""""""33DU3"""\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11"""""333Dwª\99\88\99\99\99ª\99\99\99U"333333ffDDDD3Uf\99w""\11\11""""\11""""""3fUDD3""""3DUDUUD3wfwwUUffUDD333333"33"""""\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11\11\11\11"3"3""\11\11\11"""""\11\11\11"""""""""\11\11"3"""""333333333333DUww"3"""""""3DDD333""3"""""\11"""""\11"""""""""""""3"""3"""333DUwwfw\88wwUDDDUUUDDDDD3""3"""D3"3\11""\11\11"""33\11"\11"\11\11"""""""333D"""\11\11\11""""\11"""\11"\11\11\11"""\11"3""""""DDD3""""3D3""DD33UDD333"3"33"\11"3DD3""""""""""3Uf"3""\11\11\11\11\11\11\11\11\11\11""\11\11\11\11""""33Df\88\99\88\99\99ª\99ªª\99\99\88D333333f\88UDUfU\99\99UU\11"""""""""""""3UDDDDDD"""3333DUUUUwfwwU33"3D333333333""""""\11\11\11"\11\11\11\11\11\11\11\11\11""\11\11\11\11\11\11\11"D3"""\11\11\11\11\11""""\11\11"""""""""\11"\11""""""""""3333""33DDUU3333"""""33"3"""""3"""""\11"\11"""\11"3"""""3"""""""""3"3333DDUUUfffwUwwwfUDD3333DDDDD"""""D3\11"3""3\11""3"\11"""\11\11\11"\11""""3DD3""""\11\11"""\11"3""\11\11\11"\11\11"\11""\11"""""DD"\11"3"""U3"3UUUUwfUfUD33D"""3DUUD""""""\11\11\11""333DUD"\11\11\11\11\11\11"\11\11\11\11""\11\11"""""33DUÌ\88\88\99\99\99\99\99\88ªª\88fD"333DDwwfU\88ªªU"\11"""""""\11""""""3wfD3DDDD333"333UUUUUUDD3"""DUD33D3333333"""""""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\113""""""""\11\11\11\11\11\11""\11"""""\11"\11\11"3333"""""33""""3"33UUD3333""""""""""""\11""""""""""""\11"3""\11"""""""""3D33""333"3333DDUUUUUUfwU3DUDDUfDUUD""\11\11""3\11\11\11\11\11\113""""\11\11"3\11\11\11""""333DDD33""""""""""""""\11\11\11\11\11\11\11\11""""""DU3""3""\11UD"3DDUUUDDDDDUffUUUUUU3""""""\11\11\11"""""333D"\11"\11\11\11\11\11\11\11\11\11"\11\11\11"\11\11"""3Df\88fw\88w\99\99\88\88ªªª\99UU33DD33wf\88ª\99w3\11\11\11"""""\11""""\11\11"U\88wfwfD3UUDDDDUUDfUDDfwUD3"3DUD""3333333""""""""""\11"\11\11\11\11"""\11""\11\11\11""""3""""\11"""""""\11"""\11\11"""3""\11\11"3D3"""\11"""""""3333UUU333""""\11\11"\11""\11\11\11\11\11""""""""""\11""333"33D33"3DUffUD333"""""""333DDUUUDDDD33DD3UD3DD"\11\11\11\11\11\11\11\11""\11\11\11\11""\11\11"\11"""\11\11\11""33DDUDD333""""""3"""""\11\11\11\11\11\11\11\11\11"""""3D"""3""\11UwDDD3DDD3DDDDDUDDDDU33""""""\11\11\11"""""""333D3\11\11\11\11\11\11""\11\11\11""""\11\11\11"33Dw\99ffww\88\99\99\88\99\99ª»ªwD33333f\99»\99D333"\11\11""""\11\11"""\11\11"w\88U33DfwfDUDUDDUUUUUUffUD3"33D33"33D333""""""""3""\11\11\11\11\11\11"\11"\11"\11\11\11""""\11"""3"""""\11""""""""""""""""\11"\113D"""""3"""""33DDD3D"333"""\11\11\11\11\11\11\11\11"\11\11\11"3"""""""""""33UDDDD333Dffwf3D""""""\11""""""333DDD""3"""\11\11\11"""\11\11\11\11\11\11\11"\11\11\11"""3"\11\11"""""""\11""""3DDDDDD333"""""""""3""\11\11\11"\11\11\11"\11"""""D3"3"3"\11fffU3333DUU3D3DD3DDDD""""""""\11"\11""""""""3333D3"\11\11\11\11\11\11\11\11""\11\11\11\11""333\88\99Ufff\88\88\88\88\88\88\99\88\88wfU333DUªÌ\8833333""\11""""""""""3\99f""3DDUUf\88UDDDDUUUDDwwwUU33"333D33333333333""""""""\11\11\11\11\11\11\11\11"\11\11\11""""\11"\11"3"""""""""""33"3"""""""\11"\11\11DD""""""""""3DDD3"D"""3""\11\11\11\11\11\11\11"""""\11""""\11"""""""33"""3DD333DUU33UD3""""""3""""""3333"""""3"""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""\11\11"\11"""""""""""33DDDDUD333""""""""3"""\11\11\11\11\11\11\11"""""333"3""Dwwww333333333333DDDD3""""""""""""\11\11"""""""33DDD"\11\11\11\11\11\11\11""\11\11\11""""3D\88wDUfffw\88\88\88\88\88\88\88fwwD33f\99Ì»f33D33""\11\11""""\11""""U\99f"333DUUUDf\88w3DDUwww\88\88\88fUDDDD33333"333"""""""""3""""""\11\11\11\11\11\11"""""\11""\11\11""""3"""""""""""""\11\11"""\11\11"""\11"D3"""3"3"33DDDUfD3""""\11\11\11"\11\11\11\11"""\11\11\11"\11"\11"\11\11\11\11""3""""""3U333DfDUD3""""""""\11"""""""""""""3DD33\11\11\11"\11\11\11\11\11\11\11\11"\11"\11"""""\11\11""""3D"\11"\11\11""33DDDDDDUDDD3333D3D"3333\11"\11"\11"\11""""3""""33fwwUUf"3D3333DDDDDUDD333"""""\11"3""""""""""3"33333D33\11"\11\11"\11\11"\11""""3fwD3UffUUfwwwwwwfUUw3D\99»ªfDDDD333""""""""""""DwD"3333DUUUDUf\99\88\88wwffUU\88wfD33DD333DD3D33"""""""""3"""\11\11\11\11\11\11"\11\11"""\11\11\11\11"""""""33""\11\11"""""""\11""""\11\11\11\11\11""33""""333333DDDDUU3""""\11\11\11\11\0\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11"3""""""3UUDD3DUUU3""""\11\11\11""""3"""333""""33"33"\11\11\113\11\11\11\11\11\11""\11\11\11\11\11\11"\11\11""D3D33"\11\11"\11\113"33DDDDUUUUUfffw\88wffUDDU3\11\11\11\11"\11"""""""""""UfwfUfD3"33333DUUUU3DUUD""3""""""33333""33DDUDDD333D3\11"\11\11""\11"""333wU33DDUUUUfwwwwfw\88\88ffU»\99fUDUDDD33"""""""""""33D"""""33DUDDDUffw\88UDDDUfwfDD3333333DD3333"""""""333"""""\11\11\11\11\11\11\11""\11\11\11\11\11\11"""333D"3\11"\11""""""""\11"\11\11"\11\11\11\11\11"3"""\11"3""333333UDDD\11\11\11\11""\11\0\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\113U3""""DDUU33UD3"\1133""\11\11""\11""""333333"""3""""3"\11\11""\0\11\11\11\11"""\11\11"\11""""""333""\11\11\11\11\11"3""33333DDUUUffwfwwUUfwUDD""\11\11\11\11""""""""""3"ffwUfUfDD3"333UUU33DDDD"33333333DUDDD3DDDDDDDDD3""""\11"\11\11\11\11""""3"D\88D"33DDDUUUfwwwfU\88ª»wf\99UDDDDDDD333""\11"""""""3D3""""""33DDUDUUUfw\88fDUUffwfUDD333"3DD3333""""""3333""""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""3D3"33""\11"""""\11"""\11\11\11"\11\11\11\11"\11\11\11\11"""3""3D333D33"\11\11\11""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"33D3""DDDDD3DD""D3D"""""""""""""""3DD"3333"""3\11\1133\11\11\11\11\11\11"\11"3"\11\11""\11\11"""""\11\11"\11"\11"D"333"DUD3DUUwwwwU\88ffwfwfUUD3\11"\11\11"""""3""""""UUwUDwUDDDDDDUD3D3DDDfD33"3DDUUUUUD3333DDDDDD333Df3\11""\11\11\11""""33w\883"DDD3DDDUDUUUffU\88»Ìª\99DDUUDDDDD33""""3""3""UD"\11\11\11\11""33DDD3DUUDDfwUDUffffUUUD"D3DDDDDD3"3"""3333333""""\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11\11""""3"D33"\11\11"""""""\11\11\11\11"\11\11\11\11"\11\11\11\11\11\11"33"33D3D3DU3\11\11\11"\11\11\0\11\11\0\11\11\11\11\11\11\11\11"""\11\11\11\11\11\11"DUU3"3D33DDD"3DUUD""33"""\11\11""""""333D""""33"""""3"\11\11\11\11\11\11\11\11"""\11""\11\11\11"""\11\11\11""\11\11"3""""""D333DUwwfUUfDDUwwwwfUU3""""\11"33""""3""3f\88f3UwfUUfwwfUUUUDUUUD"33"D3D3DD3""33"DDD3DU333DU3\11""\11\11""33333ww33DDDD3DDDDDDUUUfUwÌ̪UUUUUUUDDD33"""""33"3U3\11"\11\11\11\11\11"3DDDU3DDDDUUwDDDUw\88ffUDD333D3DDDD33"33DDD333333"""\11\11\11\11\11\11\11\11\11\11\11\11"\11"\11""""D"D3"""\11\11\11\11"""\11""\11\11\11"\11\11"\11\11\11\11\11\11"""3""333333Uw"\11\11\11\11\11\11\11\11\11\11\11\11\11\11""""""\11\11\11\11\11\11\11DwwU"3D3DUD33"Uw3D33""\11\11\11"\11"""\11"""""""3""""3"3""\11\11\11\11\11\11\11"\11\11"\11\11\11\11\11\11\11\11\11"""\11\11""\11\11""\11"""""""""3UfUUDDUUUUUUwwffffD\11"\11"""333"""333D\88\88UDwfffff\88wUDD3"3DD33"""333D"""""333DU3333DD333U3"""\11\11\11"33DDf3"33DDDD3DDDDDUUDUw\99»\99fUUUUUUUUUDD33""""""3UU"\11\11\11\11\11\11\11"""33UUDD33UUUfUDDU\88fffUDD33DDUDD3DD3D3DDDD333"""""\11\11\11\11\11\11\11\11\11\0\11\11"""33""333D3"""\11\11\11"""""""\11"\11"\11"\11\11\11\11\11\11\11\11"""""33"DDUUf3\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""\11\11\11\11\11\11"""3UUfwDDD3"3UDDDD3""""""\11\11\11"""\11\11\11\11\11\11"""3""333"\11\11\11\11\11\11\11""""\11\11\11\11"\11\11\11""""""\11"\11\11"\11""""""""""3DUUUUDUfffUfw\88wfwfDU""33"""""33333"Uwf3DwUw\88wwfffD"""""""3"""D"3U3"""333DUD33333333DD3\11"\11\11\11"33"f\88D"3DDDDUDDDDDUUUDwª\99wUDDUUUUUUUUUDDD3"""""UU3""\11\11\11\11\11\11"""3DDDD3D3DDUUU\99wDw\88fDDD3333D3DD3DD3DD3DDD3333""""\11"\11\11\11\11\11\11\11\11\11\11""""""3DD3D3"\11""\11""\11"""""\11"""""\11\11\11\11\11\11\11\11\11\11\11""""33"UUfU""\11\11"\11\0\11\11\11\11\11\11\11\11\11\11"""3"\11\11\11\11\11\11\11"""DDDfwDDD3DUDD3D33"""""\11"3D3"\11\11\11\11\11\11\11\11\11"""""""\11\11\11\11\11\11""""\11\11\11\11""\11\11"""\11"""""""\11\11"""""\11\11"""DDUUDDDUUUUUDDffwwUDDUDD3"""""3333Dw\88\88UUUwww\88\88wf3""""""""""3"""3DD3333333"3DD33333D3U3\11\11\11""3333\88\993"DDDDDDDDDDDUUUwª\88U3DUUUUUUfUUUUDDD333"33wf"3""\11\11\11\11\11""""3DDDDD3D3UUUfDf\88wwwDDD"33DDDD33DDUDDDDD3333""""\11\11\11\11\11\11\11\11\11\11\11\11"\11""""3"3"""""""\11"""\11\11""""\11"""\11\11\11\11\11\11\11\11\11\11""""""33DDD33U3"\11\11\11\11\11\11\11\11\11\0\11\11\11\11"""3"\11\11\11\11\11\11\11"""""3UwU33DDD33Uf33""""3\11"""\11"\11\11\11""\11\11\11"""\11\11\11"3"\11\11\11\11\11"""\11\11\11\11\11"3"\11"""\113"""\11\11\11\11\11"""""\11\11\11""3DDD""33333D333Uwww\88fDDf3"""3333D33fwwfUDDw\88\99\99f3""""""33""""""""3""33"33333"D3333D3UU"\11\11\11\11"33"3\88\99"333DDDD33DDUUUU\88\99U""3DUUUUffUUUUUDDD33"3UwU"""""\11\11""""""3DDDDDD33DDUUD3fwUwwUD333DUDD33DDUUDDDDD333""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\1133DD3""3""\11""""""\11""33"\11\11"\11\11\11\11\11\11\11\11\11"\11"""""33DD3D"3""\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""D3"\11\11\11\11\11\11\11"3""33UD33DUD33fwD3"3D33"""""\11\11\11\11""\11"\11"\11"\11"\11\11"""3\11\11\11"\11""\11\11\11\11"33\11"\11""D3""\11\11\11\11"""""""\11"""3UD3"""""""""3"Dffwffwwww3"""33"3DDf\99ª\88wffUUfwU3"3"""""333"3""3"""""333333"3DD3"3UfUU"\11\11"""33"D\99\9933D3DDDD33DDDUf\88\99f333"DDUUUUUUUUUUDDDD3"DfD3"3""""""\11"""""333DD3333DDDUDU\88wUwf33333DDD3D3DUUDDDDDD33"""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""33""""\11\11\11\11""\11\11\11"\11\11"3"\11\11\11\11\11\11\11\11\11\11\11\11\11"""""333UU33"3"\11\11\11\11\11\11\11\11\11\11\0\11\11\11""""D3\11\11\11\11\11\11\11\11"""""3333DDD3UDUU33D3D\11"""D"\11\11"\11"3"\11\11\11\11\11\11"3D"\11""""\11""\11\11\11""\11\11\11""""""33"""\11"\11\11\11"""""""\11\113D33"\11\11\11"\11""""33DffUUUf\99\88wU"""3"DD3w\99ªª\99wwD""""DD3"""""""D"3"""33""3D3333333D3UfwwfUwU3\11"D""3"w»\8833D3DDD3DDDDUfwªªD3333"DDDUUUUUUUUDDDD33Dw33333"3""""""""""333D3333DDDDUf\88wfDwU3""3U"3333DDDUDDD3333""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11""\11\11"\11"\11\11"\11\11\11\11"\11"""""\11\11\11\11\11\11\11\11\11\11\11""""""33333""3""\11\11\11\11\11\11\11""\11\11\11""""3""\11\11""\11\11\11\11""""""33DDDD3DDD""333"\11"\11\11""""333\11\11\11\11\11\11""""3"\11\11"""""3"33\11\11""""""\11""3""""\11"""\11""3""""""D3""\11\11\11\11"""""""3DUfUUfwfw\99\99f"33333Uw\88w\88fUDw"""333333""""""D"3""\113"""33"3""33UfffDD"3UDD333D""D\99ªw333DDDDD3DDDUUf»Ìf"3333DDDDUUUUUUUUUUDDDff3"33""3"""""""\11""""333D33DDDUUfw\88fUwfUUUDDD3""3DUDDD3D3D""3""""\11\11\11\11\11\11\11\11\0\11\11\0\11\11\11\11\11\11\11\11""\11\11\11"\11\11\11\11\11\11\11\11"""""\11"\11\11\11"\11\11\11"""""""""3"3DD""3""\11\11\11\11\11\11\11\11\11""\11"\11"\11\11"\11""""\11\11\11\11\11"""""""3DDD33DUf33""3"\11"\1133"""33""""\11\11\11\11"""\11\11\11\11\11""\11"3""""""""3""""""333""""""\11""""""3"3"""\11\11\11\11""""""""3DUUUUfwfU\99\99\883333Dfw3DUfUDfU"333"3"333D333333"""33""33333D3DUU333DUDf3333UD"3f\99\99f3333DDDDDDDDfUU\99wUU33333DDDDUUUUUUUUUUDUwU""""""3"33"""""""""""3333DDUUDUwfUfUwwUUUUD3D"3DUUDD33D33"""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11"\11"\11\11\11\11\11\11\11""\11\11\11""""""\11\11\11""""""""""33DD""3""""\11\11\11\11\11\11"\11\11\11\11\11\11\11\11"\11"""\11\11\11\11""\11\11"\11\11"""33333DUfDD33"""""33"""33""3""\11\11\11""""\11\11\11\11\11\11\11\11\11"""3\11"""""""""33""""\11"\11"\11""\11"\11""3""""\11\11\11"33\11\11"""""3DUffUUfw\88\99\99\99f333wf33UUUDD33333"""3UD3D3D3"D3"""33"3D33DDDUU33DfwfDUD333DUUf\99\88\88\88D33D3DDDDDDDUUUww33U33333DDDDUUUUUUUUUUf\88D33""3"""333"""\11\11\11\11\11\11"""333DUfwUfD"\11UUfUDUUU3"D"UfUDD33333"3""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\0\11\11\11\11"""\11\11"\11\11\11"\11\11"""\11"""\11"3""3"""""""""""""3DU3""""\11"\11\11\11\11\11\11\11\11"\11\11"\11\11\11\11\11""""\11\11\11\11""\11\11"\11\11"""3DUD33DDUDUDD3D"3"\11\11""""333""\11""\11"\11\11\11\11"\11\11\11\11\11\11""3"""3""""""""333"\11""\11\11\11"\11\11"\11\11\11"333""\11""""\11"\11\11""33DfUfUUUUUf\88\99\88\88DUwfUwwUUD333"""33333DD"33333D"""""3DD333333fDDfwU3DU3D3Dfwfw\99\88\88\99U33D3DDDDDDDUDfwfU3"UDD33DDDDDUUUUUUUUf\88\88D333""D""333"""\11\11\11\11\11\11""""3UDUffUfw3""\11UfUUDUD33DUfUDD333D3""""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""\11""\11\11"3""""\11"""\11""\11\11""""""""""3""33"DU3"D3""3"\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""\11""\11\11\11\11\11\11"""3UDD3DDUffwf33"DD3\11\11\11"""3D3""\11\11\11\11\11\11\11\11""\11\11\11\11\11\11""3"\113U333D"333333""3"\11\11"3"\11\11\11\11\11"3"3"""\11\11"\11"\11\11""""33DUUfUUUfffw\99\88\99wUUDDU\99fD333""""3"333"33"3D3""""""33DD333333ffwU333UU3UUwwU\88\88ª\99ªf333D33DDDDDfUfªD3D33DUDDDDDDDDUUUUUUDwªwDD3333"33"333"""\11\11\11\11""\11""3DfUUUfwf3\11\11\03UDUfDD3DDDUUUD3"3333""""""\11""\11\11\11\11\11\11\11\11\11\11\11\11"3""\11"""""\11""""""""""\11\11\11\11\11\11\11""3""""""""33"33Dfw\88fD3DD\11\11\11\11\11\11\11\11\11\11\11\11"\11"\11\11"""\11\11\11\11\11\11\11\11\11\11\11\11""3DUD3DUDwfUffD33"3"\11\11"""""3""\11\11\113\11"\11\11""""\11\11\11\11"3"""DUD""DU""D3D""""""""3D\11\11""""3""""""\11\11\11\11\11\11"""""333UUUfUUw\99\99\99\99\99\99wDDDwwwwU3""3D3U3"3333333333"""""33DDD3333DwUfU33"UfUUffwUfw\99wwfD33D3DDDDDDfUU\88ª333333UfDDD33DDDDUUUU\99ªUDDDD33""D"""33"\11\11\11\11\11\11\11\11""3DDfUUUfU"\11\11\11\11DUDfD3DDDDUUUUD33333"33"""\11"\11\11\11\11\11"\11\11\11\11\11\11\11"3"""""""\11""""\11"\11\11""""\11"\11\11\11\11""3"""""""""3DDUUw\88wUUfw\88f\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11\11\11\11"\11\11\11\11"33DD33DDUDDD33333"\11"\11\11"""""3""\11""\11\11\11\11""3"\11\0\11\113""""3DDU"3U3"33333DDD3""\11\11\11\11"""""""\11""""\11\11\11\11\11\11""""33"3DDUwff\99ª\99w\88\88wU3DffUUUfUUwUDD33D3333333333"""3"DDDD33DDUUUfD"3"3fUfwwwww\99\88U"""3DD3DDDDDUUU3w\99w333D33"DÌUffDDUUUDDw\99\883DDDD333""3"""33"\11\11\11\11\11"\11""333UfUUfU"\0\11\11\11"fUUD3""DDDDDDDD33333"3""""""""""\11\11"3"\11\11"33""""""""""3\11\11\11\11\11\11""\11\11""\11\11\11"""333"""""333fwwwwUDUDUfwwU"\11\11\11\11\11\11\0\11\11\11"""\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11"3"3DD333UDDDDD"333\11\11""""""\11"""""\11\11""""""\11\0\0\11\11\11""""""DD33UD33DDU3DDU""\11\11"\11"\11""""""\113"\11\11\11"\11"\11"""""""333DUffw\99\88fDDfU33DUfUffU\88f33333333DUD333""3"""3"DDDUUDDDD3UD""33"UUUffwww\88w3"3333DDDDDDDDUUU3\88\883""3333"3\99fwDDDUUUUª\99UDDDDDDDD333"3"3"""\11\11\11""\11""333DUffww"\0\11\11"3DwfU"3DD3DDD"3D333333"3"""""\11\11\11""""""""3""""""""""""3"\11\11\11\11\11\11\11"""3\11\11\11\11\11"""3""""333"DfwwfD3DDUUDDUfD\11\11\11\11\11\0\11\11""\11""\11\11\11\11\11\11\11\11"""\11\11\11\11\11"""DDDDUUDUDDD33"""""\11\11\11\11"\11\11\11\11"\11""""\11""\11\11\11\11\11\11\11"3"""33DD"DU""UDDUUUDD3"\11""\1133"""3"""3""""""\11""""""3"333Ufwwªªf3DDDUUUffUDDDUDw3D3333""3D333333""""3DUffwffUUfU3"""3D3UDDfwwwww"333333333DUDUUUUUfw3""3333"3"fªUDDUUDf»\8833DDDDDDDD3333"""3"""""3"""3DDDDUwwf3""33""UUDD\11DUDD"3DDDDD33333"""""\11""""\11\11""\11"""""""""3"""3"\113\11\11"\11\11\11\11"\11"\11"\11\11"\11""33"33""3333UUfD33UDDDUUff\88"\0\11\11\0\11"\11\11""3\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11"\11"3D333DUUDD333D""""""\11"\11\11\11\11"\11"\11\11\113"\11""\11\11\11\11\11\11\11""3"\1133333DD""3DDDUUff3""""\11\11""""3"""3""""\11\11\11\11\11"\11""""3D3Uf\88\88ª\99wDDDDUUUwwUD3DDDUwD3D333333DD3333"3""3DUwf3D33D"\11\11""3333DUDUwwwff""333DD33DDDUffUUffU\11\11"""3"""""D\99\88DDDwª»f33DDDDDDDDD33"""""333""33""33D33DwfD"""\11"""UDUU33UDDD"33DDD333"33""""\11"""\11\11\11"""""""""""""\11\11""""3"\11\11\11\11\11\11"\11\11\11\11\11\11"\11"333333"33D333UUD"3DUUUUfw\88w"\11\11\11\11\11\11\11\11""DfUDD\11"\11\11\11\11\11\11\11\11""""""DD33DUDDD3333"\11""""""\11\11\11\11\11""\11"""3\11""""\11\0\11\11\11""\11""3"3"3D3"3"DD3DDUfU""""\11"""""3DD"D3""\11"\11\11\11\11\11\11""D3DDDUww\99ª\88fDDDDUffUUUDD3DUUwwUfwD3"333DUfD3"3333DUUfDUU33"""33"333DDDUUffww"33"3333DDDDDUfDUfU3\11"\11"""33"""""\99ªw\88ªÌwD3DDDDDDDDDDD33"""33D333DD3333DDDU\99f"\11"\11\11\11\11\11"fUwf3DDDD33D3DDDDDDD3""""""3""\11"""""""""3"\113\11\11\11"""\113\11\11\11\11\11\11\11"\11\11\11\11""\11\11"333"3"""33333DUfD33DUfUfw\88\99D\11\11\11\11\11\11\11\11\11"3DfUD3""\11\11\11\11\11""\11\11\11"""3"33DDDD3333D3"""3"3"\11\11\11\11\11\11\11"\11""3""""""\11\11\11\11""\11"33""""33""33UD33DU3333""""""3DUU3D33"\11\11\11\11\11"\11"""3DUDDDffw\99\8833UDDffffDDDDDDUUffwfffDDD"DDD3D3"33DDUfwU3Df3""""3""3"333DUDUwwwU"33333DDDDDDDfD"Uf\11""\11""3""""3""D̪»ÌªU333D3DDDDDDDD3D3333""33DDDDDDDDUUf\88wU""\11\11\11\11\11\11\11DffUD33D""DDDDD3DDDDD3""""""""""3"""""""""\11\11\11\11"""\03""\11\11\11\11\11\11""""\11\11\11\113"""\11""""33333DDUD33DUUfUw\88w3\11\11\11\11\11\11\11\11\11\11"33"""\11"3"\11"\11""\11\11\11\11"""""33"33"33"DD"""3""""\11\11\11\11\11\11\11"\11\11\11\11"""""\11\11\11\11"""\1133""""3"""D3UUD3DD"""""""""""DUf"3D33"\11"\11\11\11"\11"""3DDDDUff\88wD3DUUUffUDUDDUUDDDDwfUUUD33DD333333DDUUfUfDDDUD"\11"""""""3"DfUDUUD3"3""3DDDDDDDDDfDDU\11\11\11\11""""""3""DU\88\99\99wfDDDDD33DDDDDDDD3D333""333DDDDDUUDUUDf"D"\11\11\11\11\11\11\11\11DUDDUDD333333333DD3DUD""""""""""""""3"\11\11\11\11\11"""""""\11\11\11"""""\11\11"\11\11\11\11""""\11\11\11""333333DD3U333DUfwww\88""\11"\11\11\11\11\11\11\11""3"""""""\11\11\11\11\11\11\11\11\11\11"""""3""33""DDUD""D33""3\11\11\11\11""""\11""""""\11"\11\11\11\11"3"""""""3D"""3UUD"DU"\11"""3"D3333UUUUD3"""\11\11"""""\11"33UDDDUf\88w33DUDUfwDDUUDDDD3D33wUDDfD"3DD3D333DUUUD3wwUDDD3\11""D3""3D33ffD""\11""""3DfUUUDDDDUUwf3\11\11\11\11\11""""""33f\99\99wDDD3DDDDD33DDDDDD3D3D33"""333DUDDfUUD33"33"\11\11\11\11\11\11\11\113D33DUD33333333""DDDDD""""""""""""3D3"\11\11\11\11"3"\11\11""""""\11""""""\11\11"\11"""""""\11"""3""33D3333333Uwwwwfff""\11\11\11\11\11\11\11\11""3D""""33\11"\11\11\11\11\11\11\11\11""333"""3"3DDDU""DU33"3"\11""""""\11"""\11\11"D""\11\11\11""\11"""""""""""3DUDDD"""""""""U3D3333"DD\11\11\11""""""""D33DDUDUw\88\88333DDDUfDDDUUD333"DUwU3DUf333DDDUDDDDDUD3fwDD3"""""3D33DD"3UwD"""""""33UUUDDDDDDfwf\11\11"\11\11""""""""Uw\88\99\99\99U33DDDDD3D33DDUDD333D""""3333UDDUUff3"\1133U"\11\11\11\11\11\11\0"D"33UUDD"3D3333333UUDD"""""""""""3UD"\11"\11"""\11"""""\11\11"\11"""""\11\11""\11\11"""\11"\11\11"\11\11"3333DD33U33DDfwwwfDDU\11"\11\11\11\11\11\11\11\11"3""""""3"""\11\11\11\11\11\11"\11"""3""3U33D3"33"DDDDfU"""""""""""""""U3""\11""""\11\11"""""""""333D3DDDU3"""""3UD3"D3DUD""""""""3""DD33DDUUU\99\88D"3DDDUfD3D33D33"3"UfU33DUfUDUUffDDUUUfffUD33D3""333"33DUUUUfD\11""""""33DDDDD3DDUwwD\11\11"\11\11"\11""""""w\99fww\99\88fDDfwD33D3DDDDDDD3333"""3333DD33UUfU3"33DD\0\11\11"\11\11"3D\11\11\11DUDDD3D333"333"UUDD"3"333"""3"UU3"\11\11""""""\11"""\11"\11"""""\11\11""\11\11""""\11\11\11\11\11\11\11"3333DD3D3333UfwffDDfD"""""\11\11\11\11""3""""""""\11\11\11\11\11\11\11\11\11\11"""3333333""33"DD3Dfff33""33""3"""3333"""\11\11\11"""3"\11""3"""""3"33DD\88\88D3""3DD333DD3D"\11\11""""3U33"33"33DUUU\88\993"33DDUUD333D33333DD\88wD3DDDfUUUUfUUfUUUD3"3"3""""""\11"DDUfwwfU3""""""""DDDDD333DDww3\11"\11\11\11\11\11"""""3w\99\88\88\99\99\99\99\88\88\99fD3DD3DDDDDDDD3333"""3333D333DUD33"33D3\11\11\11\11\11"3D"\11"3DDDDDD"333333333UUU3"""""3"3\11DU3"\11""3""""""""\11"""\11"\11""\11\11\11\11\11""""\11\11\11\11\11\11\11""3333DD333"33UfUUD33f""33D3\11\11\11"""""""""33\11\11\11\11\11\11\11\11\11"""""3"3333"3333Uf3DDDDD333"3""""""""""""\11\11\11\11\11\11\11\11""\11"33"""33"33U3D333"""UD3D3U3"33"\11\11""\11\11"3D3\11"""3DUDw\99\88U"333DDUD3D333333"3D\88UD3U33UfUfff\99w\88U33333""""\11"""\11"3UUUU\88ffUD""""""333UDDDDDD3Dff""\11\11\11"\11\11\11""""Dw\88\99\99\88fUDD\88\88fw3DDDDDDDDDD333333""33DDDDDDDU""3""DD3\11"""\11\11\11"\11\11"UfUDD3D3"""3333D33DUU3"""3333""U33""33"""\11\11"3"""\11""""""""\11"""3""\11\11\11\11\11\11\11\11"33"UDD"""333DDDDD33UD3D333"\11\11\11""""""""33\11\11\11\11\11\11\11\11\11\11\11""""33D333DDD3UU3DUDD3333D"33"""""""""\11\11\11"\11\11""\11\11\11""""3"""3"33DD33U3\11"3DD"3UU3333"\11""""3U33""3333DUf\99ª\993""3333DUD3333""3"33fUD33"DDUUUfffwfU"33"3"""\11"""\11""\113ffffwwD"\11\11\11"""333D333333DDfU\11"\11\11\11"\11\11"""\11"3ww\88wfUDDDw\99D3Uf3D3DDUDDDD33""""""33DDDDDUU3""3UD3\11\0\11""\11"""\11\11"3UUUD333"""3"33333D3U3"333333\11\11"3"333"""""\11""\11""\11\11"""\11\11\11\11\11\11"3"3"""\11\11\11\11\11"\11""3D333"333333DDD333f"3D33"\11\11\11""""""""""3\11\11\11\11\11\11\11\11\11\11"3"""33333D3DUDDDUD333D333333"\11"""""\11"\11\11\11\11\11\11\11\11\11\11\11\11""\11"""""""3"33Uf""""D33333UUD3"""\11\11"3""""3333DDD\88\99\99\99fUfD"3"3D3""""""3"3D33333DD3UUDf\88\88wwfDDD333"""3D"\11""""UUUfUD3\11"\11\11""""333"3333DDDUU\11\11\11""""\11""\11\113DfwfUUDUUDDfwUUUwUDDDDDDDDD33""""""3DDDDUUU""33U"\11\11\11\11\11\11\11\11"3\11\11333UUD33""\11""""3D333DUUUDD"""""\11"3""""""""""\11""\11""""3""\11\11\11\11\11""""""""\11\11\11\11\11\11\11""3""D3"333333D3333Uw33""""\11\11\113""3""3""3"\11\11\11\11\11"\11\11\11\11\11""""""3333333DUUD3"3DD"""33"""""\11"\11\11"\11\11"\11\11\11\11\11\11""""""3"""""D333wwf""""3"33"33333""\11\1133""""3333DDD\88\99\88\99\88fww3"""33""""""33"3DD333333DUUUfw\88\88fDDD3"3"""333"D3"33UUUfD3""\11\11\11\11""3""3"33DDDUD"3""\11"""\11\11\11"3DffUD"""""3333DDUUfwUDDUDD3D33"""""33DDUDDU3\11"33U\11\11\11"\11\11\11\11\11"\11"\11DUUDDD"""""""""3DD3333Uffw33"\11\11""3"""\11""""""\11""\11\11\11"""\11\11"\11\11\11\11""""""""""""\11\11""""3"D3"33333D3333Dw\883"""\11""\11"33"3\11""""33"\11\11\11"\11\11\11\11\11"\11""""""3D3"D33UUD"""3333333""""""\11\11"\11\11\11\11\11"\11\11\11\11"""""\11"""3U3D33fUfwD"""3"""""3"""\11"\11\11"3"""""3"333Dw\88\88\88wffwf"\11\11"""""""""""3D33333333DUDUUUfw\88f"3333""3DD""3""DfUUff"""\11\11""""""333"33DUfU3"333""""""""DwfD"""""3""333333DUwU3DD33333""""""333DU3""\11""3U3\11\11\11\11\11\11\11\11\11"\11"DUDDD3"""3\11""3DD333333"333DffUDD3D33""""\113""\11"\11\11\11"\11"\11\11""\11\11\11""""3""""""""\11\11""""33"""3D33333"33Uwf""""\11"3"33D33""3""""""\11\11\11\11\11\11\11"\11\11\11\11"""""3""33DDD3"3333333D3"""\11\11\11\11\11\11"\11""\11\11\11\11\11\11""""\11"""\11"D333"3fff3"3UU3"""3""\11\11\11\11""\11"\11""3"33333Df\99\99\88ffwwUD"\11\11""""""""""3333"333333DUDUUUw\88w\99D33D333D3"""""3DDDU33"\11\11\113""""3D33""3DUffD"""333333""3UUfD""""""""3333333DDwD3D3333333"""""333DD"\11""3"DD\11\11\11\11\11\11\11"\11\11\11\11"DUD333333""""33DD""3333333"33DffD"33\11""\11""""\11\11\11\11\11\11\11"""\11\11"""""""33""""""""""""333""3DD33D3"""D\88U""""\11""3"333"3333"""""\11\11\11\11\11\11\11\11\11\11\11\11\11"""33"3DUUDDU3DUD3D333"""""\11\11"\11\11""""\11\11"3"""3"""""""33""D""3UU"3DfwD\11""3"""\11\11\11"\11\11\11\11"""333333UU\88ª\99\99www\88f"""""""""""""333D333333333DUUfffUDfDDUDDDDD"""""3D3UU3""\11"\11"3\11"""D333333UUf3333DD333"333fU3""""""""""""33"33DDfD3333DD3333""3333DD\11"""33DD\11\11\11\11\11\11"\11\11\11\11\11\03DD"33"D3"3"3""3UD"333"33"333D3UfD"3""\11\11""""\11\11\11\11""""3"\11\11"""""3"""3"3"\11\11""\11"""33333333D3333"D3fU3"""\1133""""3D3333""""\11""\11\11\11\11\11\11\11\11\11\11""""3333DDDD3DUUUU3""""\11\11"\11"\11"\11\11\11""""\113""33""""""""333"3D3""3DD3UUwf3""3"\113"\11\11\11\11\11\11""""33333DUUwªªª\88\88\88fU3""""""""""3D3"3DD3333333DDDUUUUDDDffDDDDD33""""3DDUU333"\11"""""""""3D333DDDUDD3D3"3D3"3DffD3"333333""""3""333DUU33333333""333D3333"""3D3UD\11\11\11\11\11\11\11\11\0\0\11\11\11\11DDDD3"\11"33""""3UU3"333D"3333DDDDffD"\11\11\11"""\11\11"""\11\11"\11"""""""""""""""""""""\11\11""3D3333333DD3333DUU"""""D3""""3UU33""""""\11\11\11\11\11\11\11\11\11\11""\11"""""33DD33DUDDUUD"3"""""""""\11\11\11"""\11""3D"""\1133"\11""3""333333"3DDDUwfUD""\11\11"""\11\11\11\11\11\11""""3333DUUU\88\99\99\88wfUD3""""\11"""""3D333DD3333333D3DDUDDDDD3ff3DD333"""""DDDDDD3"\11"""""""3"""333UU3333DDD3DDD3"Dff"D333D3DD3"""33"3333DfDD33333"3333333"3\11""3333DD\11\0\11\11\11\11\11\11"\11\11\11\11\03D3D3"\11\11\11\11""""\113fUDD3333333""3DDUUfU"""""\11\113ffU"\11"""""""""""""""""""""33"\11\113"33"3333D333DDDD33"""""33"3""3UUD333""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11""33D3D33DfDDD333"3""""""\11\11\11\11\11"\11""""33""\11\113"\11"D"""3"3333333DUDw\88U333""\11\11\11\11"3"\11\11""""333DDUwfw\99w\88fUfD"""\11\11"3"""""D3"3f33333333DDD3D3333UU3fU3UUD""""""3UDD""3"\11""""""\1133333"UUDD"""3D33UD33D3UU"3333333DD"""""""""3DUUD33333333333333""""33""3f\11\11\11\11\11\11\11\11\11"\11\11\11\1133\11""\11\11\11\11\11""\11""""3DDU3333"33D333DDDDUDD3""fwwU3D"\11""""\11"""""""\11"""""3""""\11""""3""33DD33DDf3\113D""""""""3333DUD333"""""\11\11\11\11\11\11\11\11\11\11\11\11\11"\11""33333333UUUDD333"\11""""\11\11""\11\11"\11\11\11\11"\1133"\11"\11"\11""""3""333"33ffUfffwU""""\11\11\11\11\1133\11\11"""33"3DUUf\99\88ªwwwUD3""""\11""\11"""""DDUfUUD"333D333DD3"33DDUDfffDUD""""33DDD""""""""""""""3"DUUU3""3""3333DDDDDwU3""33""33D"""""""3"33DDDDD3333333DD3DD"\11"D33333U"\11\11\11\11\11""""\11\11\11\11"3\11\11"\11\11\11\11\11\11"""""""3"DD3"""""333333DDDfwwDUffUD3333""""\11"""""""""\11"""3""""""\11\11""""333D33D3""\11\11\11\11\11""""""333DDDUUD33"""""\11\11\11\11\11\11\11\11\11\11\11\11"""""""333333DUfU3333"3""\11\11\11\11\11\11\11\11\11\11""\11\11\11333\11\11\11"\11\11"""""""33""333UwffU3\11\11"\11"\11\11""\11\11\11"""3333DDUfw3wfD333"""\11\11\11\11"\11"U3\11"DUfDUwD3""3D3333D333333DUfww3DDD"33DU333"\11"\11\11\11"\11""3"""""DDDD3"""""3333""3UwfU""""3"33333"""""""3"33DfUDDD3333"DDDD3"""DD33"3f3\11\11\11\11\11\11"""""\11"""\11\11\11"\11\11\11\11\11\11"""""""3"D3D"\11""""""3333DDUf\88wfDDDDDD3D3"""\11\11\11\11\11""""\11"""""\11\11\11"\11\11\11""""333DDD3\11\11"\11"""\11""""""""33UfUUD3"3"""""\11\11\11\11\11\11\11\11\11\11\11\11\11"""33"3D33333UUUD3"""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3""""\11"""""""""""33"33UfwwwDD33"\11\11\11""\11\11""""""3DUDffD\88\88UD33""\11\11""\11""D33\113DUUUUU"33333"333"3333333DDwffU333333D33"\11"\11\11\11\11\11"\11"D"3"333UD3D3"33"3""3""3ffUD""""""""3D33"""""""33DUwUUUDD3333D3DD3"333"""3DU"\11\11\11\11\11\11\11\11"\11"""""""\11""\11\11\11\11\11"""3"""""""D3\11\11"""\11"""3"33DUfwUU33D3DD3""\11\11\11\11\11""""""""3\11\11"\11\11\11\11\11\11\11\11""\11"33DDD3""""""\11\11\11"""""3""3DD333"""""""""\11\11\11\11\11\11\11\11\11\11\11\11\11"3"""33"33333UUfDDD"\11\11""\11\11\11\11\11\11"\11""\11\11\11\1133""""""""""""""""""3DD3DDDf3"DwU3\11\11\11\11\11"""""""3DUUUDw\88wDD3""\11\11"\11\11"3D33D33UDDDDD"33"3""3"3333333333DUDDUU3"333333"\11\11\11\11\11\11\11\11"""3"333"DUDDDD""3D33D"3UUUU33"""33"333"""""""""333UUDUUfD3DD333UD3"333""33DU"\11\11\11\11\11\11\11\11\11\11\11\11\11"3""""\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\1133\11\11"\11\11\11\11"""""3DwwUDDD33333333\11\11\11\11\11\11\11"""\11\11\11""""\11\11\11\11\11\11\11""3""""33D3""""""""\11""""""33DD33""""""333"""\11\11\11\11\11\11"\11\11\11\11\11""""""3333"3"DUUUDD""\11\11\11\11\11\11\11\11""\11"\11\11\11\11\11"""\11""\11""""""""""""3D"33D3333"3"3"\11\11\113"""""""3DDUfff\99ªw3"3"""\11\11\11"33D33D"DD3D333""3333"3"""33333333DDDDDUU3DD33333"\11\11\11\11\11\11\11"""333""33DDD3UD33U33UUDUDDD3"3""3""""""""""""""""33DDDUUfDDD33"DDD333""333DfD"\11\11\11\11\11\11\11\11\11\11\11\11"""""\11\11\11\11\11\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\11\11\11\11\11"""""3DDUUD333"3333333"\11\11\11\11\11"\11\11"\11\11\11\11"""\11\11\11\11\11\11\11"""\113"3""33D3"""\11\11"333""33D3333""""""""33"""\11\11\11\11\11\11\11\11\11\11\11""\11""DD"33"3""3UfD33\11"\11\11\11\11\11\11\11\11""""\11\11\11\11"""\11"3"\11\11"\11"""""""33UD""3UD3D""D3\11\11\11\11"33\11"3""3DDUfww\88\99wU"3""""\11"D3333D3"3D"3D3""""333"3""""33333DDD333DDUwfUDD333\11\11\11\11\11\11\11\11\11""""3"33"DDD3D333UU3UDDDDD3333""""33""33"""""3""3333DDUDDffUDDDD"D3""""3333UU3\11\11\11\11""\11\11\11\11\11\11""33""\11\11\11\11"\11\11\11\11""\11""\11\11\11"\11\11\11\11\11""\11""33UUfDDUUDD333"3333Df3\11\11\11""\11""""""\11\11""\11\11\11\11""""\11"33333DD"DDD3""\11"DD33333"""3"33"3"""""""""\11\11\11\11\11\11\11\11\11\11"""\11"33D3"""""3UDD33"""\11\11\11\11\11\11\11"""\11\11\11\11\11"""\11\11"\11"\11\11""""3"3D33"""""3Uf333"""\11\11""""""""3DDUUffw\88\88ªf""""""""D"3""333"3333""""33"""""""333"33DD3""333Uw\88\88\99f333""\11\11\11\11\11"33"\11""333D3DDUD333DUUDDD333"33"333"33"3"""""""D33"3D33DDDDUUUUDD3DDD""""""33UD3D\11\11\11\11\11\11\11\11\11\11"""D33""\11\11\11\11"\11\11\11\11""\11\11\11"\11""\11\11\11"""\11\11\11"33DfUUfUDDD3""""DDDUD"\11\11"\11"333"3""""3"""333"\11""333333DD3333"""DDD33D33"""333333"3"""3""""\11\11\11\11\11\11\11\11\11\11"\11\11\11\11"3D3"""""33DD3D3""\11\11\11"\11\11"""\11\11"\11\11\11""\11\11\11\11\11\11""""""3U\88f3"""333DD"D3"""""333"""3DDUUDUffww\88ª\883""""""3""3D"""3"3333""33"D3"""33""""3"3DD3"33"33Uwwfw\99UD"""\11\11\11"""33"\11""3"3D3UffDDDfDDDD3"3"3333"33"33""""""33""33D3DDDDDUDUUUUDDDDUD""""3"3DUf"3"\11\11\11\11\11\0\11\11\11"""3""3\113\11\11\11\11"\11\11\11\11"\11\11""\113\11\11\11\11\11\11\11\11"""""3fUUUDDDDD""""33D"3f""""33DD3"""\11"33"""333""""333"""D3D3D33UDD3""33"D33333"""""""""33""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"\11"3"""""333D333D""\11\11\11"\11"""""\11\11"3"\11\11\11\11\11\11\11""""""33UDD3""3DDUUUfD""""3DDU33"DDDUUDUfwUw\88ªªwD3"\1133"""33""""3"3333333"33""3""""D333D33"""""""Dffffwww3""""\11\11\11"\11\11""""33D333UUDUUUUD3D33"""3333"3"33"3"""3"3"3333DDDUDDUUDUUDDDDUfD""""\11"3DDw33"""\11\11\11\11\11\11\11""33""D"3f\11\11\11"\11""\11"\11"\11\11\0""\11\11\11\11\11\11\11"\11""\11DwffDUDDDDD"333"3"D\88\88D"33"""33""""\11\11\11\11""33\11""""33"3"333333DDD33333DDD333""""\11""""""3"33""""\11\11\11\11"\11\11\11\11\11\11\11\11\11""3""""3DU3"3"""""\11\11"""""3""3"\11\11\11\11\11\11"\11\11"3"33333"3333D3DUUU33""\11"3DffD"3DDDDDDUUUwfU\88»\88U3"""3"""333""3"\11""3""3"DD""""""""33DD333"""3"""3DUUfw\88wf3333\11""\11\11\11\11""""33DDDDD33wfDD333"""3"3333333DD3"\11"333"33DUDDUD3UUDUUDDDUDUUD3""""""3Dw3"U""\11\11\11\11\11\11\11"\11"33"D33DD\11\11\11"\11"\11\11\11\11\11\11\11\11"\11\11\11\11\11\11"\11\11""3UD"3DD33"3"3""""DUwfUfU33""\11""\11\11""\11\11\11\11\11\113"\11""\11"""33"3""3"3D33D3D333"33""""""""\11\11"""3"""D3"\11"\11\11\11"\11\11\11"\11\11\11\11\11\11""""""""DU""""""""\11""""""""""\11\11\11\11\11"\11\11\11"3333""""DD333D3333""\11"""""ffD"3DDD3DDUfUDUw\88ª\88f""""D3"""3""D3"""""""3D333"""""""""3DD""""""""""DDDDfwwww3"33\11"\11\11\11\11""""3DDDDDUUDUfU3333""3D"333DD3DD3D3D333333333DfD3DDDDDfDDDDUDD33"""""""3Df\1133"""\11\11\11"""\11\11"3"3D"DU"\11"33\11\11"\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11\113wUD"\11"3D3""3""3DwwUU3"3UD\11"""""\11\11\11\11\11\11\11\11\11\11""\11\11\11\11"""""""33"3333333D333D3""""""""\11""\11""""""3""\11\113\11\11"\11\11\11\11\11\11\11\11\11\11\11""""""""33""3"""\11\11\11"3"""\11"\11\11"\11\11\11"\11"""""3"D"""3DD333D333D33\11\11\11\11"\113Uw33DDDDDDUfwfDU\88ªªUU""33""""3"Dwf""""""3DDD3"""""""3"""D""\11\11"""""""3DDUUDw\88w\883"3"""\11"""33DDD3DD3DUU33"D"33333333"""D3""""3D3"33333D33D3DD3DDUDDUDDUD3""333""3"""Uf\11""\113"""3""\11\11"33D3"DU3\11\0\11"33DDD\11\0\11\11"""\11\11\11\11""\11"ff"""""""33"3UUw\88w3"\11""3DU\11""""\11\11\11\11\11\11\11\11""\11\11"\11\11""""""3"33""33333"3DD3"3"3"""""""\11\11"\11""""33""""""""\11\11\11\11\11\11\11\11"\11\11\11\11\11"\11"""""3D3""""""\11""3""""""\11\11\11"33"3"""""DD"""3U3DD3DD3""D"\11\11\11\11\11"DDUUDDDDDDDUUfffwªÌ»f"3DD"\11"\11"3wªw3""\11"33333"""""""""\11333"\113D"""""""DD3DDDDfwwfDD""\11\11"""333D"33"D3UU33""3U3"""""""""""""""333""333333333D33DDDDUDUDDD"33333""3"\11\11\11UD""""33"""3""3D3DD""U3"\11"""\11\11\11\11\11\11\11\11""""\11\11""""D\88U3""""\11\11\11\11DwwwU"\11"\11""""33U3""\11"""\11\11\11\11\11\11\11\11""""\11""\11\11"""33"333"""333""""""3""""""""\11"""""3"""""""""\11"\11\11\11\11\11\11\11\11\11\11"\11"""3""""DD"""""""3""""""3"\11\11\11"\11\11"3"""33"3"3"DD3D33DDD""3"\11"\11\11\11"""33DDUDDDDDDUff\88\88\88\88""33\11"""\11wwwD3"\11"33"""""""""""\11"33"\11\11"""\11\11""333D3333DUff\88wf3\11\11\11\11""3""3"D333D3DD""33"3"""""""\11\11""\11"""""3"33"33D3DU33DDD3UUDUDDD"3D33"3"33"\11\11\11"w3"\11""33"\11"D"""3333"UU3\11\11""\11\11\11\11\0\11\11\11\11""33""""3wwD""""""\11\11"\11\113D"33"""""""333D\11"\11"\11\11\11\11\11\11\11"""""\11\11\11\11\11"\11\11"3"33333""""33D3"""""""""""\11""""""3"""3"3"""""\11\11\11\11\11\11\11\11\11\11\11\11""\11""\11"""DD"33"""""""33\11\11\11\11\11\11\11"\11"""3D333"33"ff33DD3D3"DU"""\11\11"\11""3333DD33D3DUf\88ªwUw\88ªw3"\11\11""""\88ª\88\99"\11"""""33"""""""""3"""\11\11"D"""""333333"3DUUUfwf3"\11\11\11\11"33""3DDDD333D3"UD3D3""33"\11""""\11""""""3"3"DDD3""U3"33DDfUDDD33DD33"3"""""\11\11"Uf\11\11\11"33"\11""\11\11"333"\11Df33\0\11"\11\11\11\11\0\11"\11"""""""""DwD"\11"""\11\11\11""\11\11\11"3""3""""""""33""\11\11\11\11\11\11\11"""""\11""\11"""""""""""3"3U"""33333"3"3""""""\11""""""33"""3"""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""""D3333333""\11"""\11"\11\11""""""""D333333"3UD"333DU3"DDU3"\11""""""3"33D33UUUfUDDUUfwª\99""\11"""\99ªªªwwU\11""""\11"3""\11\11"""""D""\11\11"\113D""""333D""""3DDUUUfD"3"""""D333"33DDDDDD33U3UwU""33"""\11\11\11"\11""""""""3333333"""3UDUUDD3333"333DD""333""3wU"""3""\11""\11\11""33333UU3"\11\11""\11"\11""\11\11""""""3DU33"""\11\11""\11\11\11\11\11"\11"""33"""""\11\11"33\11\11\11\11\11\11""\11\11\11"""""""""""""""""3""""""""3333"""3"""\11"""""""333"""""""""\11\11\11\11\11\11\11\11\11\11\11\11\11"""""""33D3333"3D3""D3""\11\11"""3"""3DDDDDD3""3fD"333DUU3"DUf3"\11"""""3"""33Uw\88fUD3"DDUD\88ªD"\11""U\88\99U3UUU\11""\11"""\11"\11\11\11""""3""\11\11\11\11\11"""""333333"\11"""3DDDffD3UU3""\1133DD"3D33333"DDDU33U"33"""""""\11""""\11""3333DDDUD3D33DDDDDD3D""3"33U3"333"\1133\88""3"""\11"""DDDUDUU3ffU3"\11"\11\11"\11"3"\11""""\11\11UfD3""3"\11"""\11\11\11"\11"\11\11\11"33"\1133"\11\11\11""3"\11\11\11\11"\11\11\11\11""""""""""""\11"""333"""33""33""33"""\11""\11"\11"33""333"""\11""""\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11""3""\11"DD33"333333"\11\11""""33D33333333D3"""3U333333UUDD3333""""33"3333DfwfwUD3""U3DUU»f\11Uf3\88w3"3fDUD\11\11\11\11""\11\11"\11\11\11"\11""\11""\11\11"\11\11"""33D"33""\11\11\11""33DDffU3D3""""3UDDD3"3"""3333"33DD33""""""\11""""""""33333D3DD"3DDDDDUDDD3333"33"3"333"\11"3wf\11""""""""3DD33"""fUUUD\11\11\11\11\11\11"UD""""\11\11UwD""""""""""\11"""""\11\11""3D"""33""\11"""3\11\11\11""\11\11\11""""""""""""\11\11""""""""""3"""3"""3D"3"""""""3D3""3"""\11\11"\11\11\11""\11\11\11\11\11\11\11\11\11\11"\11\11""""""\11"DD3"""333"""\11"""3"3UD"""3333DDD333U3"333"DUDD\88fD"U333DUDDUUfUUDDDDD3""3D33D\88»\99\99»\88f3\11""DUDDD""\11""\11"""\11"\11"""\11\11"""""\11"""33""33\11""\11\11\11""3DDUUfDD333""3D333D333\11""D33"U3"3DDDUU3"""\11"""""3333"3333DU333"33DUUD333DD""333DD33""""Uª\11\11"3333333""333"DUffU3U\11\11\11\11\11\11""\11\11\11\113DfU"\11""33"3""""""""3"\11"""""\11""3"""\11\11\11"D""""\11\11\11\11""\11\11""""""""\11"""""""""""3"3"""""3D"""""""33D3"""""""""\11\11\11""""\11\11\11\0\11\11\11\11""\11""3""\11\113DD3""3333"\11"""""33"fwU""3333DD333"UU"""3"Uffww\99\99\99wwUfUUUffD3333DDD33"3D3"33Dw»»ÝÌf"""""DU"UD""\11"""""""\11"3\11\11\11\11\11\113"\11"""33"3D""\11""\11\11\113"3DUUDfU3"\11\11"D3""""""\11"3"333"D333DDDUwww3""\11""""D3""3D3"3DD33D333333D33DDfU333DDUDD3""3D\883\113DD333"3"333DDDUfUfUD3\11"\11\11\11\11\0\0\0"UUD3"\11\11""33333333"""""33"\11"""\11\11"33"\11\11\11\11"33""\11\11\11"\11""\11""\11\11"""\11"\11\11"3"""""""""3"3"33DU3D3\113""""""""""""""""""\11"""""\11\11\11\11\11\11\11""\11"""""""3DD3"33"""""""""""""3w"""33D33333"3Uf3""3UwwUUfUfwfUDDfDDDUD33333DD3DD333333DDfÌÝU""3"""3DD3w"""""""""""3"\11\11\11\11\11\11\11\11""""""""3"\11\11"""\11\11\11""33DDw\88w""3"333"""""\11""33""3""DD""3DDD3D3""\11\11""""""3""333DD333""333333UUU\88\99U333DDD3\11"3DUf3DDD3""333"33D3"fDUUUU3""\11\11\0\11"DUfD"\11\11\11\11\11\11\11"\11"""""""""""""""33"\11\11"33"\11\11\11\11""D3"\11\11"""""""""""""\11\11"3"\11"3"""""""3""""333333D3"33""33"""""3""""""""DD3""\11\11\11\11\11\11\11"3"""""\11"DD3333"""3"""""""""""UD3""33"333"33UD""D\88wUUUUDUUUD"UwD""""3D33"3""""""3D"333U»Ýª"D3"3"3D3UwDUff""""""33"\11\11\11\11\11\11\11\11"\11\11""\11""3""\11\11"\11\11\11\11\11\11"3UUf\88\88D"\113D3""""""\11\11\11\11""""""33333D33333"""\11\11"\11""""""""3D3DD33""""3""3w\88wªfDDDDD33"""DDªD333D3"""3"""33\11DfDDDDUD"\11\11""DU3\11\11\11\11\11\11"""\11\11\11"\11\11\11""3""""""\11""3D"\11"33"\11\11\11\11\11"3D"\11\11"""""""""\11\11"\11\11"""""""3"""""""3""""D3D3"DU3"""3""""""3"""""33DUUDD3""\11\11\11\11\11\11\113D""""""3D3"""\11""""3DDD"""""""3"""3333333""D3"3ffUUUUDD3D33DDD3"3""""3""3"""""""""3333\88ÝîU3D3""3f3U\88U3DfD33""3U3""\11\11\11\11\11\11\11\11\11""33""""\11""\11"\11\11"\11""33UDfffUDDUD33"""""\11\11"""33D333"3"""33"3"33""""\11""""""""3DUDD333"3D333Dwª»w3DUD"33\11"3D3ªw\11"33\11\11"""3""""\11\11wDDD33D""\11U3\11\0\0\11\11\0\11\11\0"""\11\11\11\11\11\11\11\11\11"3\11""""""\11""3"""""\11\11\11\11\11"3U33""""33""""\11\11\113\11"\11""""3""""""""""""""33"3333""333""""3333333DfwwfDDD3""\11\11\11\11\11\11\1133"""""3"""""\11\11""\11"UDD""3"""3333"33"333"3DD3DDwU3DD33333D""3D""3"""33""""""""""""333D\88Ýݪ\11"DD333UU\88"3DUU33""Df"\11"\11\11\11\11\11\11\11\11\11\11"""\11"""\11\11""""\11\11\11\11""3DUUfffwww\88U33""""\11\11\113""333333DU"3UD3D"""3"""""""\11""""""3D3333"Uw333"f»\99\99f33DD"""""DDwª\0"3"\11\11"3"""3"\11\11\11\11fD33DD3"\11wD\0\11\11\11\11\0\11\11\033"\11"\11\11\11\11\11\11\11"""""""""""\11\11""""\11\11\11\11\11\11"3DU""\11""""3"""\11\11\11"""""3"""333""3"\11\11"""3"3D33D33333D3"""33DDDDUU\88\88\88f3\11""UD"\11\11\11\11\11""\11""3DDDD""""""""\11""""""33""333"""""333D33Dw\99\99\88wDDD3333DD3""33"""""""3""\11""""3""""33Df\99ÌÝ»»U"3"DDD3\883""DDU3\11"Uf"\11\11\11\11\11\11\11\11\11""\11"3"""""\11\11\11\11\11"D\113"\11\11"DDUfUUUfwwwf"3"\11\11"\11"""""DDDDDDD333DDD""3"""""""""\11"""""3D33"""\113333""fwDDU3"""\11"""DUfª\11\11""\11\11""333"""\11"\11DUDDDDD3Df"\0\11\11\11\11\11\11\11\11\1133"""\11\11\11\11\11\11"\11\11\11"\11""""\0\11""3"\11\11\11\11\0\11\11\11"3D3"""3""333""\11\11\11""""""""""""33"""""""""""3"3D33D33""333UUUf\88\99\99f3"\11\11"3\11"3""\11\11\11"""3""3DfD3""\11\113D""""""""3"33"3"""33"33""33\11D\99\99wUDDDD3D3fD"""3""""""""""\11\11\11\11"""""""3U\88»Ì̪»ª»U"33UD"3w""3DfD33fD\11\11\11\11\11\11\11\11\11\11\11"\11""""3""\11\11\11\11\11\11\11"33""""UUUfUUUfffwfDD""\11\11\11"\11""3DDDUD3D3333DD3333"""""\11""33""""333333"""""""33333"""\11\11\11\11"Df\88\99"\11\11"\11""333\11\11\11\11"\11\11"UDDUfU3DD\11\11\11\11\11\11\11\0\11\11\11"\11\11\11"\11\11\11\11\11\11\11"""\11"\11""\11\11\0\0\11""\11\11\11\11\11\11\11\11\11"3U3""33"333""\11\11\11"""""""""""""D3"""3"33U3"33"3D33D3D3DD33Uf\88»Ì\883\11""\11""\11"""""""\11""""""D3DD3D"333""""""3D"""""333333"333D3""3wwDD3DD3DD33D3""""3""""\11""\11""\11\11"\11"""""33ªÌÌ»\99ª»ªD"333DD\11w"""DUf3D3U"\11\11\11\11\11\11\11\11\11"""""""""\11\11\11\11""\11\11D"DDD"3DDDUDDDDUUUwUD3""\11\11"\11\11"333"3DD33D333DDDD"""\11"33""3"\11"\11\11"33333""""""""""DD""D"\11\11""3DwªD\0\11\11\11""\11\11\11\11\11\11\11"\11\11\11\113UUffUU3\11\11\11\11\0\11\11\0\11\11\11"""\11\11\11\11\11\11\11\11\11""""\11\11\11""\11\11\11\11""""\11\11\11\11\11\11\11""3U3333D"333""""\11"""""""""3"""333""3333U33"""3DDDDDDUDfw\99\99Ì\99U"\11\11""""\11"\11"""""\11\11"""3DDDDDDU3"3D3"""\11"""""""""""33"33333DD"3fwUDD"3D33"3"DDD3"""3""\11\11\11\11\11\11"\11\11\11\11\11\11"""3Dfªªªª\99ª»f\1133"33""f""3DfUD""3""\11\11\11\11\11\11\11\11""""3""\11\11"\11\11\11"3\11""3D"3"33DDDDDDUffffDD\11"\11\11"\11\11""""""""""3333333DDD333UD33DU""\11"\11""33"""""\11\11\11"D3""\113DD""\11"3Dwª\88\0\11\11\11\11\11\11\11\0\11\11\11\11\11\11\11"DUU\88fwUU"\11\11\11\11\11\11\11"\11\11\11\11\11\11\11\11"\11\11\11\11\11\11\11""""""\11"\11\11\11\11\11\11""""\11\11\11\11\11"""DUD3"33"""333D"""""""""333"""33""333D3D3"33"3DUffw\88\99»Ì»\88D\11\0\0\11\11\11\11""""""""""""\11"""DfUDD33D3""""""\1133""333""""3D""333333"w\99wDD333333"3"D3"D3"""""\11\11\11\11\11\11\11\11\11\11"\11\11\11"33DUf\88\99\99\99D"\883\11"3"3""DD3"DUwD"\11"\11\11\11\11""\11\11\11"""""3"""\11\11\11\11\11"D"\11""3""3"33DDDDDDD3DUwU""""\11\11\11"""""""""""333333DDDDDD33D3D"""\11\11"""""3""""\11\11\11"3U"DDDff3""""3f\99»"\11\11\11\11"\11\11\11\11\11\11\0\0\11"ffD\1133\11\11\11\11\11\11\11\11\11\11""\11\11\11\11\11"33"\11\11\11\11\11\11\11\11\11""D"\11\11\11\11\11\11\11\11""\11""\11\11\11""""3UU3333333333DD33"3333"33"33"3D3D3Dfw\99wfUUDDfw\99\99ª»\99ffD3\11\0\0\0"\11\11\11\11""""""""3"""""""DwfU33D33"""""""""3""3"""""3D3D333"33D\99wUDDD33"333"""3""3D3""\11""\11\11\11\11\11\11\11"\11""""3DUUffw\99fD\11\11U\883"33"""U"33Dw3""\11\11\11\11\11\11\11\11\11\11"""33"""\11"\11\11\11\11\11"\11""\11\11\11"\11"""3333D333DDUfU"""""\11"""""\11"\11"3"""33"333fUU33"""""D"\11\11"\11"""3"\11\11\11\11\11\11\11\11""""UD"3"33"3Uf\99U\0\11\11\0"\11\11\11\11\11\11\0D\88UD3\11\11\113\11\11\0\11\11\0\11\11"""""\11\11\11\11"3D3"\11\11\11\11\11\11"\11\11""D\11"\11\11"\11\11\11\11""\11""\11\113"333DwDD333DUDDDDfD333D333DUDDUUD3DUwffD3\99\99»ª\99\99\88wwD\0"""\11\11\11\11\0\11\11\11\11\11\11\11""""""""33"""""\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0
\ No newline at end of file
diff --git a/tests/simple.c b/tests/simple.c
new file mode 100644 (file)
index 0000000..4789377
--- /dev/null
@@ -0,0 +1,39 @@
+#include <gtk/gtk.h>
+#include <gdk/gdkprivate.h>
+
+
+void
+hello ()
+{
+  g_print ("hello world\n");
+}
+
+int
+main (int argc, char *argv[])
+{
+  GtkWidget *window;
+  GtkWidget *button;
+
+  gdk_progclass = g_strdup ("XTerm");
+  gtk_init (&argc, &argv);
+
+  window = gtk_widget_new (gtk_window_get_type (),
+                          "GtkObject::user_data", NULL,
+                          "GtkWindow::type", GTK_WINDOW_TOPLEVEL,
+                          "GtkWindow::title", "hello world",
+                          "GtkWindow::allow_grow", FALSE,
+                          "GtkWindow::allow_shrink", FALSE,
+                          "GtkContainer::border_width", 10,
+                          NULL);
+  button = gtk_widget_new (gtk_button_get_type (),
+                          "GtkButton::label", "hello world",
+                          "GtkObject::signal::clicked", hello, NULL,
+                          "GtkWidget::parent", window,
+                          "GtkWidget::visible", TRUE,
+                          NULL);
+  gtk_widget_show (window);
+
+  gtk_main ();
+
+  return 0;
+}
diff --git a/tests/test.xpm b/tests/test.xpm
new file mode 100644 (file)
index 0000000..9b0d2ef
--- /dev/null
@@ -0,0 +1,92 @@
+/* XPM */
+static char *openfile[] = {
+/* width height num_colors chars_per_pixel */
+"    20    19       66            2",
+/* colors */
+".. c None",
+".# c #000000",
+".a c #dfdfdf",
+".b c #7f7f7f",
+".c c #006f6f",
+".d c #00efef",
+".e c #009f9f",
+".f c #004040",
+".g c #00bfbf",
+".h c #ff0000",
+".i c #ffffff",
+".j c #7f0000",
+".k c #007070",
+".l c #00ffff",
+".m c #00a0a0",
+".n c #004f4f",
+".o c #00cfcf",
+".p c #8f8f8f",
+".q c #6f6f6f",
+".r c #a0a0a0",
+".s c #7f7f00",
+".t c #007f7f",
+".u c #5f5f5f",
+".v c #707070",
+".w c #00f0f0",
+".x c #009090",
+".y c #ffff00",
+".z c #0000ff",
+".A c #00afaf",
+".B c #00d0d0",
+".C c #00dfdf",
+".D c #005f5f",
+".E c #00b0b0",
+".F c #001010",
+".G c #00c0c0",
+".H c #000f0f",
+".I c #00007f",
+".J c #005050",
+".K c #002f2f",
+".L c #dfcfcf",
+".M c #dfd0d0",
+".N c #006060",
+".O c #00e0e0",
+".P c #00ff00",
+".Q c #002020",
+".R c #dfc0c0",
+".S c #008080",
+".T c #001f1f",
+".U c #003f3f",
+".V c #007f00",
+".W c #00000f",
+".X c #000010",
+".Y c #00001f",
+".Z c #000020",
+".0 c #00002f",
+".1 c #000030",
+".2 c #00003f",
+".3 c #000040",
+".4 c #00004f",
+".5 c #000050",
+".6 c #00005f",
+".7 c #000060",
+".8 c #00006f",
+".9 c #000070",
+"#. c #7f7f80",
+"## c #9f9f9f",
+/* pixels */
+"........................................",
+"........................................",
+"........................................",
+".......................#.#.#............",
+".....................#.......#...#......",
+"...............................#.#......",
+".......#.#.#.................#.#.#......",
+".....#.y.i.y.#.#.#.#.#.#.#..............",
+".....#.i.y.i.y.i.y.i.y.i.#..............",
+".....#.y.i.y.i.y.i.y.i.y.#..............",
+".....#.i.y.i.y.#.#.#.#.#.#.#.#.#.#.#....",
+".....#.y.i.y.#.s.s.s.s.s.s.s.s.s.#......",
+".....#.i.y.#.s.s.s.s.s.s.s.s.s.#........",
+".....#.y.#.s.s.s.s.s.s.s.s.s.#..........",
+".....#.#.s.s.s.s.s.s.s.s.s.#............",
+".....#.#.#.#.#.#.#.#.#.#.#..............",
+"........................................",
+"........................................",
+"........................................"
+};
diff --git a/tests/testgtk.c b/tests/testgtk.c
new file mode 100644 (file)
index 0000000..b1d698a
--- /dev/null
@@ -0,0 +1,3110 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include "gtk.h"
+#include "../gdk/gdk.h"
+#include "../gdk/gdkx.h"
+
+
+void
+destroy_window (GtkWidget  *widget,
+               GtkWidget **window)
+{
+  *window = NULL;
+}
+
+void
+button_window (GtkWidget *widget,
+              GtkWidget *button)
+{
+  if (!GTK_WIDGET_VISIBLE (button))
+    gtk_widget_show (button);
+  else
+    gtk_widget_hide (button);
+}
+
+void
+create_buttons ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *box1;
+  GtkWidget *box2;
+  GtkWidget *table;
+  GtkWidget *button[10];
+  GtkWidget *separator;
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "buttons");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+      box1 = gtk_vbox_new (FALSE, 0);
+      gtk_container_add (GTK_CONTAINER (window), box1);
+      gtk_widget_show (box1);
+
+
+      table = gtk_table_new (3, 3, FALSE);
+      gtk_table_set_row_spacings (GTK_TABLE (table), 5);
+      gtk_table_set_col_spacings (GTK_TABLE (table), 5);
+      gtk_container_border_width (GTK_CONTAINER (table), 10);
+      gtk_box_pack_start (GTK_BOX (box1), table, TRUE, TRUE, 0);
+      gtk_widget_show (table);
+
+
+      button[0] = gtk_button_new_with_label ("button1");
+      button[1] = gtk_button_new_with_label ("button2");
+      button[2] = gtk_button_new_with_label ("button3");
+      button[3] = gtk_button_new_with_label ("button4");
+      button[4] = gtk_button_new_with_label ("button5");
+      button[5] = gtk_button_new_with_label ("button6");
+      button[6] = gtk_button_new_with_label ("button7");
+      button[7] = gtk_button_new_with_label ("button8");
+      button[8] = gtk_button_new_with_label ("button9");
+
+      gtk_signal_connect (GTK_OBJECT (button[0]), "clicked",
+                         (GtkSignalFunc) button_window,
+                         button[1]);
+
+      gtk_table_attach (GTK_TABLE (table), button[0], 0, 1, 0, 1,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+      gtk_widget_show (button[0]);
+
+      gtk_signal_connect (GTK_OBJECT (button[1]), "clicked",
+                         (GtkSignalFunc) button_window,
+                         button[2]);
+
+      gtk_table_attach (GTK_TABLE (table), button[1], 1, 2, 1, 2,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+      gtk_widget_show (button[1]);
+
+      gtk_signal_connect (GTK_OBJECT (button[2]), "clicked",
+                         (GtkSignalFunc) button_window,
+                         button[3]);
+      gtk_table_attach (GTK_TABLE (table), button[2], 2, 3, 2, 3,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+      gtk_widget_show (button[2]);
+
+      gtk_signal_connect (GTK_OBJECT (button[3]), "clicked",
+                         (GtkSignalFunc) button_window,
+                         button[4]);
+      gtk_table_attach (GTK_TABLE (table), button[3], 0, 1, 2, 3,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+      gtk_widget_show (button[3]);
+
+      gtk_signal_connect (GTK_OBJECT (button[4]), "clicked",
+                         (GtkSignalFunc) button_window,
+                         button[5]);
+      gtk_table_attach (GTK_TABLE (table), button[4], 2, 3, 0, 1,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+      gtk_widget_show (button[4]);
+
+      gtk_signal_connect (GTK_OBJECT (button[5]), "clicked",
+                         (GtkSignalFunc) button_window,
+                         button[6]);
+      gtk_table_attach (GTK_TABLE (table), button[5], 1, 2, 2, 3,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+      gtk_widget_show (button[5]);
+
+      gtk_signal_connect (GTK_OBJECT (button[6]), "clicked",
+                         (GtkSignalFunc) button_window,
+                         button[7]);
+      gtk_table_attach (GTK_TABLE (table), button[6], 1, 2, 0, 1,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+      gtk_widget_show (button[6]);
+
+      gtk_signal_connect (GTK_OBJECT (button[7]), "clicked",
+                         (GtkSignalFunc) button_window,
+                         button[8]);
+      gtk_table_attach (GTK_TABLE (table), button[7], 2, 3, 1, 2,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+      gtk_widget_show (button[7]);
+
+      gtk_signal_connect (GTK_OBJECT (button[8]), "clicked",
+                         (GtkSignalFunc) button_window,
+                         button[0]);
+      gtk_table_attach (GTK_TABLE (table), button[8], 0, 1, 1, 2,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+      gtk_widget_show (button[8]);
+
+
+      separator = gtk_hseparator_new ();
+      gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
+      gtk_widget_show (separator);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button[9] = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button[9]), "clicked",
+                                (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+      gtk_box_pack_start (GTK_BOX (box2), button[9], TRUE, TRUE, 0);
+      GTK_WIDGET_SET_FLAGS (button[9], GTK_CAN_DEFAULT);
+      gtk_widget_grab_default (button[9]);
+      gtk_widget_show (button[9]);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+void
+create_toggle_buttons ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *box1;
+  GtkWidget *box2;
+  GtkWidget *button;
+  GtkWidget *separator;
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "toggle buttons");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+
+      box1 = gtk_vbox_new (FALSE, 0);
+      gtk_container_add (GTK_CONTAINER (window), box1);
+      gtk_widget_show (box1);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_toggle_button_new_with_label ("button1");
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+      button = gtk_toggle_button_new_with_label ("button2");
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+      button = gtk_toggle_button_new_with_label ("button3");
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+
+      separator = gtk_hseparator_new ();
+      gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
+      gtk_widget_show (separator);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+void
+create_check_buttons ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *box1;
+  GtkWidget *box2;
+  GtkWidget *button;
+  GtkWidget *separator;
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "check buttons");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+
+      box1 = gtk_vbox_new (FALSE, 0);
+      gtk_container_add (GTK_CONTAINER (window), box1);
+      gtk_widget_show (box1);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_check_button_new_with_label ("button1");
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+      button = gtk_check_button_new_with_label ("button2");
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+      button = gtk_check_button_new_with_label ("button3");
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+
+      separator = gtk_hseparator_new ();
+      gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
+      gtk_widget_show (separator);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+void
+create_radio_buttons ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *box1;
+  GtkWidget *box2;
+  GtkWidget *button;
+  GtkWidget *separator;
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "radio buttons");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+
+      box1 = gtk_vbox_new (FALSE, 0);
+      gtk_container_add (GTK_CONTAINER (window), box1);
+      gtk_widget_show (box1);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_radio_button_new_with_label (NULL, "button1");
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+      button = gtk_radio_button_new_with_label (
+                gtk_radio_button_group (GTK_RADIO_BUTTON (button)),
+                "button2");
+      gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (button), TRUE);
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+      button = gtk_radio_button_new_with_label (
+                 gtk_radio_button_group (GTK_RADIO_BUTTON (button)),
+                "button3");
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+
+      separator = gtk_hseparator_new ();
+      gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
+      gtk_widget_show (separator);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+void
+bbox_widget_destroy (GtkWidget* widget, GtkWidget* todestroy)
+{
+}
+
+void
+create_bbox_window (gint  horizontal,
+                   char* title, 
+                   gint  pos, 
+                   gint  spacing,
+                   gint  child_w, 
+                   gint  child_h, 
+                   gint  layout)
+{
+  GtkWidget* window;
+  GtkWidget* box1;
+  GtkWidget* bbox;
+  GtkWidget* button;
+       
+  /* create a new window */
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_title (GTK_WINDOW (window), title);
+
+  gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                     (GtkSignalFunc) bbox_widget_destroy, window);
+  gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                     (GtkSignalFunc) bbox_widget_destroy, window);
+  
+  if (horizontal)
+  {
+    gtk_widget_set_usize (window, 550, 60);
+    gtk_widget_set_uposition (window, 150, pos);
+    box1 = gtk_vbox_new (FALSE, 0);
+  }
+  else
+  {
+    gtk_widget_set_usize (window, 150, 400);
+    gtk_widget_set_uposition (window, pos, 200);
+    box1 = gtk_vbox_new (FALSE, 0);
+  }
+  
+  gtk_container_add (GTK_CONTAINER (window), box1);
+  gtk_widget_show (box1);
+  
+  if (horizontal)
+    bbox = gtk_hbutton_box_new();
+  else
+    bbox = gtk_vbutton_box_new();
+  gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), layout);
+  gtk_button_box_set_spacing (GTK_BUTTON_BOX (bbox), spacing);
+  gtk_button_box_set_child_size (GTK_BUTTON_BOX (bbox), child_w, child_h);
+  gtk_widget_show (bbox);
+  
+  gtk_container_border_width (GTK_CONTAINER(box1), 25);
+  gtk_box_pack_start (GTK_BOX (box1), bbox, TRUE, TRUE, 0);
+  
+  button = gtk_button_new_with_label ("OK");
+  gtk_container_add (GTK_CONTAINER(bbox), button);
+
+  gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                     (GtkSignalFunc) bbox_widget_destroy, window);
+
+  gtk_widget_show (button);
+  
+  button = gtk_button_new_with_label ("Cancel");
+  gtk_container_add (GTK_CONTAINER(bbox), button);
+  gtk_widget_show (button);
+  
+  button = gtk_button_new_with_label ("Help");
+  gtk_container_add (GTK_CONTAINER(bbox), button);
+  gtk_widget_show (button);
+  
+  gtk_widget_show (window);
+}
+
+void
+test_hbbox ()
+{
+  create_bbox_window (TRUE, "Spread", 50, 40, 85, 28, GTK_BUTTONBOX_SPREAD);
+  create_bbox_window (TRUE, "Edge", 200, 40, 85, 25, GTK_BUTTONBOX_EDGE);
+  create_bbox_window (TRUE, "Start", 350, 40, 85, 25, GTK_BUTTONBOX_START);
+  create_bbox_window (TRUE, "End", 500, 15, 30, 25, GTK_BUTTONBOX_END);
+}
+
+void
+test_vbbox ()
+{
+  create_bbox_window (FALSE, "Spread", 50, 40, 85, 25, GTK_BUTTONBOX_SPREAD);
+  create_bbox_window (FALSE, "Edge", 250, 40, 85, 28, GTK_BUTTONBOX_EDGE);
+  create_bbox_window (FALSE, "Start", 450, 40, 85, 25, GTK_BUTTONBOX_START);
+  create_bbox_window (FALSE, "End", 650, 15, 30, 25, GTK_BUTTONBOX_END);
+} 
+
+void
+create_button_box ()
+{
+  static GtkWidget* window = NULL;
+  GtkWidget* bbox;
+  GtkWidget* button;
+       
+  if (!window)
+  {
+    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+    gtk_window_set_title (GTK_WINDOW (window),
+                         "Button Box Test");
+    
+    gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                       (GtkSignalFunc) destroy_window, &window);
+    gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                       (GtkSignalFunc) destroy_window, &window);
+    
+    gtk_container_border_width (GTK_CONTAINER (window), 20);
+    
+    /* 
+     *these 15 lines are a nice and easy example for GtkHButtonBox 
+     */
+    bbox = gtk_hbutton_box_new ();
+    gtk_container_add (GTK_CONTAINER (window), bbox);
+    gtk_widget_show (bbox);
+    
+    button = gtk_button_new_with_label ("Horizontal");
+    gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                       (GtkSignalFunc) test_hbbox, 0);
+    gtk_container_add (GTK_CONTAINER (bbox), button);
+    gtk_widget_show (button);
+    
+    button = gtk_button_new_with_label ("Vertical");
+    gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                       (GtkSignalFunc) test_vbbox, 0);
+    gtk_container_add (GTK_CONTAINER (bbox), button);
+    gtk_widget_show (button);
+  }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+
+void
+reparent_label (GtkWidget *widget,
+               GtkWidget *new_parent)
+{
+  GtkWidget *label;
+
+  label = gtk_object_get_user_data (GTK_OBJECT (widget));
+
+  gtk_widget_reparent (label, new_parent);
+}
+
+void
+create_reparent ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *box1;
+  GtkWidget *box2;
+  GtkWidget *box3;
+  GtkWidget *frame;
+  GtkWidget *button;
+  GtkWidget *label;
+  GtkWidget *separator;
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "buttons");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+
+      box1 = gtk_vbox_new (FALSE, 0);
+      gtk_container_add (GTK_CONTAINER (window), box1);
+      gtk_widget_show (box1);
+
+
+      box2 = gtk_hbox_new (FALSE, 5);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      label = gtk_label_new ("Hello World");
+
+      frame = gtk_frame_new ("Frame 1");
+      gtk_box_pack_start (GTK_BOX (box2), frame, TRUE, TRUE, 0);
+      gtk_widget_show (frame);
+
+      box3 = gtk_vbox_new (FALSE, 5);
+      gtk_container_border_width (GTK_CONTAINER (box3), 5);
+      gtk_container_add (GTK_CONTAINER (frame), box3);
+      gtk_widget_show (box3);
+
+      button = gtk_button_new_with_label ("switch");
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         (GtkSignalFunc) reparent_label,
+                         box3);
+      gtk_object_set_user_data (GTK_OBJECT (button), label);
+      gtk_box_pack_start (GTK_BOX (box3), button, FALSE, TRUE, 0);
+      gtk_widget_show (button);
+
+      gtk_box_pack_start (GTK_BOX (box3), label, FALSE, TRUE, 0);
+      gtk_widget_show (label);
+
+
+      frame = gtk_frame_new ("Frame 2");
+      gtk_box_pack_start (GTK_BOX (box2), frame, TRUE, TRUE, 0);
+      gtk_widget_show (frame);
+
+      box3 = gtk_vbox_new (FALSE, 5);
+      gtk_container_border_width (GTK_CONTAINER (box3), 5);
+      gtk_container_add (GTK_CONTAINER (frame), box3);
+      gtk_widget_show (box3);
+
+      button = gtk_button_new_with_label ("switch");
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         (GtkSignalFunc) reparent_label,
+                         box3);
+      gtk_object_set_user_data (GTK_OBJECT (button), label);
+      gtk_box_pack_start (GTK_BOX (box3), button, FALSE, TRUE, 0);
+      gtk_widget_show (button);
+
+
+      separator = gtk_hseparator_new ();
+      gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
+      gtk_widget_show (separator);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+void
+create_pixmap ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *box1;
+  GtkWidget *box2;
+  GtkWidget *box3;
+  GtkWidget *button;
+  GtkWidget *label;
+  GtkWidget *separator;
+  GtkWidget *pixmapwid;
+  GdkPixmap *pixmap;
+  GdkBitmap *mask;
+  GtkStyle *style;
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                          (GtkSignalFunc) destroy_window,
+                          &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                          (GtkSignalFunc) destroy_window,
+                          &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "pixmap");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+      gtk_widget_realize(window);
+
+      box1 = gtk_vbox_new (FALSE, 0);
+      gtk_container_add (GTK_CONTAINER (window), box1);
+      gtk_widget_show (box1);
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
+      gtk_widget_show (box2);
+
+      button = gtk_button_new ();
+      gtk_box_pack_start (GTK_BOX (box2), button, FALSE, FALSE, 0);
+      gtk_widget_show (button);
+
+      style=gtk_widget_get_style(button);
+
+      pixmap = gdk_pixmap_create_from_xpm (window->window, &mask, 
+                                          &style->bg[GTK_STATE_NORMAL],
+                                          "test.xpm");
+      pixmapwid = gtk_pixmap_new (pixmap, mask);
+
+      label = gtk_label_new ("Pixmap\ntest");
+      box3 = gtk_hbox_new (FALSE, 0);
+      gtk_container_border_width (GTK_CONTAINER (box3), 2);
+      gtk_container_add (GTK_CONTAINER (box3), pixmapwid);
+      gtk_container_add (GTK_CONTAINER (box3), label);
+      gtk_container_add (GTK_CONTAINER (button), box3);
+      gtk_widget_show (pixmapwid);
+      gtk_widget_show (label);
+      gtk_widget_show (box3);
+
+      separator = gtk_hseparator_new ();
+      gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
+      gtk_widget_show (separator);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                 (GtkSignalFunc) gtk_widget_destroy,
+                                 GTK_OBJECT (window));
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+void
+create_tooltips ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *box1;
+  GtkWidget *box2;
+  GtkWidget *button;
+  GtkWidget *separator;
+  GtkTooltips *tooltips;
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                          (GtkSignalFunc) destroy_window,
+                          &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                          (GtkSignalFunc) destroy_window,
+                          &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "tooltips");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+      tooltips=gtk_tooltips_new();
+
+      box1 = gtk_vbox_new (FALSE, 0);
+      gtk_container_add (GTK_CONTAINER (window), box1);
+      gtk_widget_show (box1);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_toggle_button_new_with_label ("button1");
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+      gtk_tooltips_set_tips(tooltips,button,"This is button 1");
+
+      button = gtk_toggle_button_new_with_label ("button2");
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+      gtk_tooltips_set_tips(tooltips,button,"This is button 2");
+
+      button = gtk_toggle_button_new_with_label ("button3");
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+      gtk_tooltips_set_tips (tooltips, button, "This is button 3. This is also a really long tooltip which probably won't fit on a single line and will therefore need to be wrapped. Hopefully the wrapping will work correctly.");
+
+      separator = gtk_hseparator_new ();
+      gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
+      gtk_widget_show (separator);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                 (GtkSignalFunc) gtk_widget_destroy,
+                                 GTK_OBJECT (window));
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+
+      gtk_tooltips_set_tips (tooltips, button, "Push this button to close window");
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+GtkWidget*
+create_menu (int depth)
+{
+  GtkWidget *menu;
+  GtkWidget *submenu;
+  GtkWidget *menuitem;
+  GSList *group;
+  char buf[32];
+  int i, j;
+
+  if (depth < 1)
+    return NULL;
+
+  menu = gtk_menu_new ();
+  submenu = NULL;
+  group = NULL;
+
+  for (i = 0, j = 1; i < 5; i++, j++)
+    {
+      sprintf (buf, "item %2d - %d", depth, j);
+      menuitem = gtk_radio_menu_item_new_with_label (group, buf);
+      group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem));
+      gtk_menu_append (GTK_MENU (menu), menuitem);
+      gtk_widget_show (menuitem);
+
+      if (depth > 0)
+       {
+         if (!submenu)
+           submenu = create_menu (depth - 1);
+         gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
+       }
+    }
+
+  return menu;
+}
+
+void
+create_menus ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *box1;
+  GtkWidget *box2;
+  GtkWidget *button;
+  GtkWidget *menu;
+  GtkWidget *menubar;
+  GtkWidget *menuitem;
+  GtkWidget *optionmenu;
+  GtkWidget *separator;
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "menus");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+
+      box1 = gtk_vbox_new (FALSE, 0);
+      gtk_container_add (GTK_CONTAINER (window), box1);
+      gtk_widget_show (box1);
+
+
+      menubar = gtk_menu_bar_new ();
+      gtk_box_pack_start (GTK_BOX (box1), menubar, FALSE, TRUE, 0);
+      gtk_widget_show (menubar);
+
+      menu = create_menu (2);
+
+      menuitem = gtk_menu_item_new_with_label ("test\nline2");
+      gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
+      gtk_menu_bar_append (GTK_MENU_BAR (menubar), menuitem);
+      gtk_widget_show (menuitem);
+
+      menuitem = gtk_menu_item_new_with_label ("foo");
+      gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
+      gtk_menu_bar_append (GTK_MENU_BAR (menubar), menuitem);
+      gtk_widget_show (menuitem);
+
+      menuitem = gtk_menu_item_new_with_label ("bar");
+      gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
+      gtk_menu_item_right_justify (GTK_MENU_ITEM (menuitem));
+      gtk_menu_bar_append (GTK_MENU_BAR (menubar), menuitem);
+      gtk_widget_show (menuitem);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      optionmenu = gtk_option_menu_new ();
+      gtk_option_menu_set_menu (GTK_OPTION_MENU (optionmenu), create_menu (1));
+      gtk_option_menu_set_history (GTK_OPTION_MENU (optionmenu), 4);
+      gtk_box_pack_start (GTK_BOX (box2), optionmenu, TRUE, TRUE, 0);
+      gtk_widget_show (optionmenu);
+
+
+      separator = gtk_hseparator_new ();
+      gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
+      gtk_widget_show (separator);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+void
+create_scrolled_windows ()
+{
+  static GtkWidget *window;
+  GtkWidget *scrolled_window;
+  GtkWidget *table;
+  GtkWidget *button;
+  char buffer[32];
+  int i, j;
+
+  if (!window)
+    {
+      window = gtk_dialog_new ();
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "dialog");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+
+      scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+      gtk_container_border_width (GTK_CONTAINER (scrolled_window), 10);
+      gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
+                                     GTK_POLICY_AUTOMATIC,
+                                     GTK_POLICY_AUTOMATIC);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
+                         scrolled_window, TRUE, TRUE, 0);
+      gtk_widget_show (scrolled_window);
+
+      table = gtk_table_new (20, 20, FALSE);
+      gtk_table_set_row_spacings (GTK_TABLE (table), 10);
+      gtk_table_set_col_spacings (GTK_TABLE (table), 10);
+      gtk_container_add (GTK_CONTAINER (scrolled_window), table);
+      gtk_widget_show (table);
+
+      for (i = 0; i < 20; i++)
+       for (j = 0; j < 20; j++)
+         {
+           sprintf (buffer, "button (%d,%d)\n", i, j);
+           button = gtk_toggle_button_new_with_label (buffer);
+           gtk_table_attach_defaults (GTK_TABLE (table), button,
+                                      i, i+1, j, j+1);
+           gtk_widget_show (button);
+         }
+
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
+                         button, TRUE, TRUE, 0);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+void
+create_entry ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *box1;
+  GtkWidget *box2;
+  GtkWidget *entry;
+  GtkWidget *button;
+  GtkWidget *separator;
+
+  /*  if (!window) */
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "entry");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+
+      box1 = gtk_vbox_new (FALSE, 0);
+      gtk_container_add (GTK_CONTAINER (window), box1);
+      gtk_widget_show (box1);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      entry = gtk_entry_new ();
+      /* gtk_widget_set_usize (entry, 0, 25); */
+      gtk_entry_set_text (GTK_ENTRY (entry), "hello world");
+      gtk_box_pack_start (GTK_BOX (box2), entry, TRUE, TRUE, 0);
+      gtk_widget_show (entry);
+
+
+      separator = gtk_hseparator_new ();
+      gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
+      gtk_widget_show (separator);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  /*  else
+    gtk_widget_destroy (window); */
+}
+
+void
+list_add (GtkWidget *widget,
+         GtkWidget *list)
+{
+  static int i = 1;
+  gchar buffer[64];
+  GtkWidget *list_item;
+
+  sprintf (buffer, "added item %d", i++);
+  list_item = gtk_list_item_new_with_label (buffer);
+  gtk_widget_show (list_item);
+  gtk_container_add (GTK_CONTAINER (list), list_item);
+}
+
+void
+list_remove (GtkWidget *widget,
+            GtkWidget *list)
+{
+  GList *tmp_list;
+  GList *clear_list;
+
+  tmp_list = GTK_LIST (list)->selection;
+  clear_list = NULL;
+
+  while (tmp_list)
+    {
+      clear_list = g_list_prepend (clear_list, tmp_list->data);
+      tmp_list = tmp_list->next;
+    }
+
+  clear_list = g_list_reverse (clear_list);
+
+  gtk_list_remove_items (GTK_LIST (list), clear_list);
+
+  tmp_list = clear_list;
+
+  while (tmp_list)
+    {
+      gtk_widget_destroy (GTK_WIDGET (tmp_list->data));
+      tmp_list = tmp_list->next;
+    }
+
+  g_list_free (clear_list);
+}
+
+void
+create_list ()
+{
+  static GtkWidget *window = NULL;
+  static char *list_items[] =
+  {
+    "hello",
+    "world",
+    "blah",
+    "foo",
+    "bar",
+    "argh",
+    "spencer",
+    "is a",
+    "wussy",
+    "programmer",
+  };
+  static int nlist_items = sizeof (list_items) / sizeof (list_items[0]);
+
+  GtkWidget *box1;
+  GtkWidget *box2;
+  GtkWidget *scrolled_win;
+  GtkWidget *list;
+  GtkWidget *list_item;
+  GtkWidget *button;
+  GtkWidget *separator;
+  int i;
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "list");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+
+      box1 = gtk_vbox_new (FALSE, 0);
+      gtk_container_add (GTK_CONTAINER (window), box1);
+      gtk_widget_show (box1);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      scrolled_win = gtk_scrolled_window_new (NULL, NULL);
+      gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
+                                     GTK_POLICY_AUTOMATIC, 
+                                     GTK_POLICY_AUTOMATIC);
+      gtk_box_pack_start (GTK_BOX (box2), scrolled_win, TRUE, TRUE, 0);
+      gtk_widget_show (scrolled_win);
+
+      list = gtk_list_new ();
+      gtk_list_set_selection_mode (GTK_LIST (list), GTK_SELECTION_MULTIPLE);
+      gtk_list_set_selection_mode (GTK_LIST (list), GTK_SELECTION_BROWSE);
+      gtk_container_add (GTK_CONTAINER (scrolled_win), list);
+      gtk_widget_show (list);
+
+      for (i = 0; i < nlist_items; i++)
+       {
+         list_item = gtk_list_item_new_with_label (list_items[i]);
+         gtk_container_add (GTK_CONTAINER (list), list_item);
+         gtk_widget_show (list_item);
+       }
+
+      button = gtk_button_new_with_label ("add");
+      GTK_WIDGET_UNSET_FLAGS (button, GTK_CAN_FOCUS);
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         (GtkSignalFunc) list_add,
+                         list);
+      gtk_box_pack_start (GTK_BOX (box2), button, FALSE, TRUE, 0);
+      gtk_widget_show (button);
+
+      button = gtk_button_new_with_label ("remove");
+      GTK_WIDGET_UNSET_FLAGS (button, GTK_CAN_FOCUS);
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         (GtkSignalFunc) list_remove,
+                         list);
+      gtk_box_pack_start (GTK_BOX (box2), button, FALSE, TRUE, 0);
+      gtk_widget_show (button);
+
+
+      separator = gtk_hseparator_new ();
+      gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
+      gtk_widget_show (separator);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+void
+color_selection_ok (GtkWidget               *w,
+                    GtkColorSelectionDialog *cs)
+{
+  GtkColorSelection *colorsel;
+  gdouble color[4];
+
+  colorsel=GTK_COLOR_SELECTION(cs->colorsel);
+
+  gtk_color_selection_get_color(colorsel,color);
+  gtk_color_selection_set_color(colorsel,color);
+}
+
+void
+color_selection_changed (GtkWidget *w,
+                         GtkColorSelectionDialog *cs)
+{
+  GtkColorSelection *colorsel;
+  gdouble color[4];
+
+  colorsel=GTK_COLOR_SELECTION(cs->colorsel);
+  gtk_color_selection_get_color(colorsel,color);
+}
+
+void
+create_color_selection ()
+{
+  static GtkWidget *window = NULL;
+
+  if (!window)
+    {
+      gtk_preview_set_install_cmap (TRUE);
+      gtk_widget_push_visual (gtk_preview_get_visual ());
+      gtk_widget_push_colormap (gtk_preview_get_cmap ());
+
+      window = gtk_color_selection_dialog_new ("color selection dialog");
+
+      gtk_color_selection_set_opacity (
+        GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (window)->colorsel),
+       TRUE);
+
+      gtk_color_selection_set_update_policy(
+        GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG (window)->colorsel),
+       GTK_UPDATE_CONTINUOUS);
+
+      gtk_window_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                          (GtkSignalFunc) destroy_window,
+                          &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                          (GtkSignalFunc) destroy_window,
+                          &window);
+
+      gtk_signal_connect (
+       GTK_OBJECT (GTK_COLOR_SELECTION_DIALOG (window)->colorsel),
+       "color_changed",
+       (GtkSignalFunc) color_selection_changed,
+       window);
+
+      gtk_signal_connect (
+       GTK_OBJECT (GTK_COLOR_SELECTION_DIALOG (window)->ok_button),
+       "clicked",
+       (GtkSignalFunc) color_selection_ok,
+       window);
+
+      gtk_signal_connect_object (
+        GTK_OBJECT (GTK_COLOR_SELECTION_DIALOG (window)->cancel_button),
+       "clicked",
+       (GtkSignalFunc) gtk_widget_destroy,
+       GTK_OBJECT (window));
+
+      gtk_widget_pop_colormap ();
+      gtk_widget_pop_visual ();
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+
+void
+file_selection_ok (GtkWidget        *w,
+                  GtkFileSelection *fs)
+{
+  g_print ("%s\n", gtk_file_selection_get_filename (GTK_FILE_SELECTION (fs)));
+}
+
+void
+create_file_selection ()
+{
+  static GtkWidget *window = NULL;
+
+  if (!window)
+    {
+      window = gtk_file_selection_new ("file selection dialog");
+      gtk_window_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (window)->ok_button),
+                         "clicked", (GtkSignalFunc) file_selection_ok,
+                         window);
+      gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION (window)->cancel_button),
+                                "clicked", (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+
+/*
+ * GtkDialog
+ */
+static GtkWidget *dialog_window = NULL;
+
+void
+label_toggle (GtkWidget  *widget,
+             GtkWidget **label)
+{
+  if (!(*label))
+    {
+      *label = gtk_label_new ("Dialog Test");
+      gtk_misc_set_padding (GTK_MISC (*label), 10, 10);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->vbox), 
+                         *label, TRUE, TRUE, 0);
+      gtk_widget_show (*label);
+    }
+  else
+    {
+      gtk_widget_destroy (*label);
+      *label = NULL;
+    }
+}
+
+void
+create_dialog ()
+{
+  static GtkWidget *label;
+  GtkWidget *button;
+
+  if (!dialog_window)
+    {
+      dialog_window = gtk_dialog_new ();
+
+      gtk_signal_connect (GTK_OBJECT (dialog_window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &dialog_window);
+      gtk_signal_connect (GTK_OBJECT (dialog_window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &dialog_window);
+
+      gtk_window_set_title (GTK_WINDOW (dialog_window), "dialog");
+      gtk_container_border_width (GTK_CONTAINER (dialog_window), 0);
+
+      button = gtk_button_new_with_label ("OK");
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->action_area), 
+                         button, TRUE, TRUE, 0);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+
+      button = gtk_button_new_with_label ("Toggle");
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         (GtkSignalFunc) label_toggle,
+                         &label);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_window)->action_area),
+                         button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+      label = NULL;
+    }
+
+  if (!GTK_WIDGET_VISIBLE (dialog_window))
+    gtk_widget_show (dialog_window);
+  else
+    gtk_widget_destroy (dialog_window);
+}
+
+
+/*
+ * GtkRange
+ */
+void
+create_range_controls ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *box1;
+  GtkWidget *box2;
+  GtkWidget *button;
+  GtkWidget *scrollbar;
+  GtkWidget *scale;
+  GtkWidget *separator;
+  GtkObject *adjustment;
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "range controls");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+
+      box1 = gtk_vbox_new (FALSE, 0);
+      gtk_container_add (GTK_CONTAINER (window), box1);
+      gtk_widget_show (box1);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      adjustment = gtk_adjustment_new (0.0, 0.0, 101.0, 0.1, 1.0, 1.0);
+
+      scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment));
+      gtk_widget_set_usize (GTK_WIDGET (scale), 150, 30);
+      gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
+      gtk_scale_set_digits (GTK_SCALE (scale), 1);
+      gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
+      gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0);
+      gtk_widget_show (scale);
+
+      scrollbar = gtk_hscrollbar_new (GTK_ADJUSTMENT (adjustment));
+      gtk_range_set_update_policy (GTK_RANGE (scrollbar), 
+                                  GTK_UPDATE_CONTINUOUS);
+      gtk_box_pack_start (GTK_BOX (box2), scrollbar, TRUE, TRUE, 0);
+      gtk_widget_show (scrollbar);
+
+
+      separator = gtk_hseparator_new ();
+      gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
+      gtk_widget_show (separator);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+
+/*
+ * GtkRulers
+ */
+void
+create_rulers ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *table;
+  GtkWidget *ruler;
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "rulers");
+      gtk_widget_set_usize (window, 300, 300);
+      gtk_widget_set_events (window, 
+                            GDK_POINTER_MOTION_MASK 
+                            | GDK_POINTER_MOTION_HINT_MASK);
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+      table = gtk_table_new (2, 2, FALSE);
+      gtk_container_add (GTK_CONTAINER (window), table);
+      gtk_widget_show (table);
+
+      ruler = gtk_hruler_new ();
+      gtk_ruler_set_range (GTK_RULER (ruler), 5, 15, 0, 20);
+
+      gtk_signal_connect_object (
+        GTK_OBJECT (window), 
+       "motion_notify_event",
+       (GtkSignalFunc) 
+          GTK_WIDGET_CLASS (GTK_OBJECT (ruler)->klass)->motion_notify_event,
+       GTK_OBJECT (ruler));
+
+      gtk_table_attach (GTK_TABLE (table), ruler, 1, 2, 0, 1,
+                       GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
+      gtk_widget_show (ruler);
+
+
+      ruler = gtk_vruler_new ();
+      gtk_ruler_set_range (GTK_RULER (ruler), 5, 15, 0, 20);
+
+      gtk_signal_connect_object (
+        GTK_OBJECT (window), 
+       "motion_notify_event",
+       (GtkSignalFunc) 
+          GTK_WIDGET_CLASS (GTK_OBJECT (ruler)->klass)->motion_notify_event,
+       GTK_OBJECT (ruler));
+
+      gtk_table_attach (GTK_TABLE (table), ruler, 0, 1, 1, 2,
+                       GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+      gtk_widget_show (ruler);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+
+/*
+ * GtkText
+ */
+void
+create_text ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *box1;
+  GtkWidget *box2;
+  GtkWidget *button;
+  GtkWidget *separator;
+  GtkWidget *table;
+  GtkWidget *hscrollbar;
+  GtkWidget *vscrollbar;
+  GtkWidget *text;
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+      gtk_widget_set_name (window, "text window");
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "test");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+
+      box1 = gtk_vbox_new (FALSE, 0);
+      gtk_container_add (GTK_CONTAINER (window), box1);
+      gtk_widget_show (box1);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      table = gtk_table_new (2, 2, FALSE);
+      gtk_table_set_row_spacing (GTK_TABLE (table), 0, 2);
+      gtk_table_set_col_spacing (GTK_TABLE (table), 0, 2);
+      gtk_box_pack_start (GTK_BOX (box2), table, TRUE, TRUE, 0);
+      gtk_widget_show (table);
+
+      text = gtk_text_new (NULL, NULL);
+      gtk_table_attach_defaults (GTK_TABLE (table), text, 0, 1, 0, 1);
+      gtk_widget_show (text);
+
+      hscrollbar = gtk_hscrollbar_new (GTK_TEXT (text)->hadj);
+      gtk_table_attach (GTK_TABLE (table), hscrollbar, 0, 1, 1, 2,
+                       GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
+      gtk_widget_show (hscrollbar);
+
+      vscrollbar = gtk_vscrollbar_new (GTK_TEXT (text)->vadj);
+      gtk_table_attach (GTK_TABLE (table), vscrollbar, 1, 2, 0, 1,
+                       GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+      gtk_widget_show (vscrollbar);
+
+      gtk_text_freeze (GTK_TEXT (text));
+
+      gtk_widget_realize (text);
+
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "spencer blah blah blah\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "kimball\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "is\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "a\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "wuss.\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "but\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL,
+                      "josephine\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "(his\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "girlfriend\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "is\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "not).\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "why?\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "because\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "spencer\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "puked\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "last\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "night\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "but\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "josephine\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "did\n", -1);
+      gtk_text_insert (GTK_TEXT (text), NULL, &text->style->white, NULL, 
+                      "not", -1);
+
+      gtk_text_thaw (GTK_TEXT (text));
+
+      separator = gtk_hseparator_new ();
+      gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
+      gtk_widget_show (separator);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+
+/*
+ * GtkNotebook
+ */
+void
+rotate_notebook (GtkButton   *button,
+                GtkNotebook *notebook)
+{
+  gtk_notebook_set_tab_pos (notebook, (notebook->tab_pos + 1) % 4);
+}
+
+void
+create_notebook ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *box1;
+  GtkWidget *box2;
+  GtkWidget *button;
+  GtkWidget *separator;
+  GtkWidget *notebook;
+  GtkWidget *frame;
+  GtkWidget *label;
+  char buffer[32];
+  int i;
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "notebook");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+
+      box1 = gtk_vbox_new (FALSE, 0);
+      gtk_container_add (GTK_CONTAINER (window), box1);
+      gtk_widget_show (box1);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      notebook = gtk_notebook_new ();
+      gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP);
+      gtk_box_pack_start (GTK_BOX (box2), notebook, TRUE, TRUE, 0);
+      gtk_widget_show (notebook);
+
+
+      for (i = 0; i < 5; i++)
+       {
+         sprintf (buffer, "Page %d", i+1);
+
+         frame = gtk_frame_new (buffer);
+         gtk_container_border_width (GTK_CONTAINER (frame), 10);
+         gtk_widget_set_usize (frame, 200, 150);
+         gtk_widget_show (frame);
+
+         label = gtk_label_new (buffer);
+         gtk_container_add (GTK_CONTAINER (frame), label);
+         gtk_widget_show (label);
+
+         label = gtk_label_new (buffer);
+         gtk_notebook_append_page (GTK_NOTEBOOK (notebook), frame, label);
+       }
+
+
+      separator = gtk_hseparator_new ();
+      gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
+      gtk_widget_show (separator);
+
+
+      box2 = gtk_hbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+
+      button = gtk_button_new_with_label ("next");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_notebook_next_page,
+                                GTK_OBJECT (notebook));
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+      button = gtk_button_new_with_label ("prev");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_notebook_prev_page,
+                                GTK_OBJECT (notebook));
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+      button = gtk_button_new_with_label ("rotate");
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         (GtkSignalFunc) rotate_notebook,
+                         notebook);
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+
+/*
+ * GtkPanes
+ */
+void
+create_panes ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *frame;
+  GtkWidget *hpaned;
+  GtkWidget *vpaned;
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "Panes");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+      vpaned = gtk_vpaned_new ();
+      gtk_container_add (GTK_CONTAINER (window), vpaned);
+      gtk_container_border_width (GTK_CONTAINER(vpaned), 5);
+      gtk_widget_show (vpaned);
+
+      hpaned = gtk_hpaned_new ();
+      gtk_paned_add1 (GTK_PANED (vpaned), hpaned);
+
+      frame = gtk_frame_new (NULL);
+      gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
+      gtk_widget_set_usize (frame, 60, 60);
+      gtk_paned_add1 (GTK_PANED (hpaned), frame);
+      gtk_widget_show (frame);
+
+      frame = gtk_frame_new (NULL);
+      gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
+      gtk_widget_set_usize (frame, 80, 60);
+      gtk_paned_add2 (GTK_PANED (hpaned), frame);
+      gtk_widget_show (frame);
+
+      gtk_widget_show (hpaned);
+
+      frame = gtk_frame_new (NULL);
+      gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
+      gtk_widget_set_usize (frame, 60, 80);
+      gtk_paned_add2 (GTK_PANED (vpaned), frame);
+      gtk_widget_show (frame);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+
+/*
+ * Drag -N- Drop
+ */
+void
+dnd_drop (GtkWidget *button, GdkEvent *event)
+{
+  g_print ("Got drop of type |%s| with data of:\n%s\n",
+          event->dropdataavailable.data_type,
+          event->dropdataavailable.data);
+  g_free (event->dropdataavailable.data);
+  g_free (event->dropdataavailable.data_type);
+}
+
+void
+dnd_drag_request (GtkWidget *button, GdkEvent *event)
+{
+  g_print ("Button |%s| got drag request %d\n",
+          gtk_widget_get_name (button), event->type);
+
+  gtk_widget_dnd_data_set (button, event, "Hello world!!!", 
+                          strlen("Hello world!!!") + 1);
+}
+
+void
+create_dnd ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *box1;
+  GtkWidget *box2;
+  GtkWidget *box3;
+  GtkWidget *entry;
+  GtkWidget *frame;
+  GtkWidget *button;
+  GtkWidget *separator;
+  char *foo = "testing";
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "Drag -N- Drop");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+      box1 = gtk_vbox_new (FALSE, 0);
+      gtk_container_add (GTK_CONTAINER (window), box1);
+      gtk_widget_show (box1);
+
+      box2 = gtk_hbox_new (FALSE, 5);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
+      gtk_widget_show (box2);
+
+      frame = gtk_frame_new ("Drag");
+      gtk_box_pack_start (GTK_BOX (box2), frame, TRUE, TRUE, 0);
+      gtk_widget_show (frame);
+
+      box3 = gtk_vbox_new (FALSE, 5);
+      gtk_container_border_width (GTK_CONTAINER (box3), 5);
+      gtk_container_add (GTK_CONTAINER (frame), box3);
+      gtk_widget_show (box3);
+
+      /*
+       * FROM Button
+       */
+      button = gtk_button_new_with_label ("From");
+      gtk_box_pack_start (GTK_BOX (box3), button, FALSE, TRUE, 0);
+      gtk_widget_show (button);
+
+      /*
+       * currently, the widget has to be realized to
+       * set dnd on it, this needs to change
+       */
+      gtk_widget_realize (button);
+      gtk_signal_connect (GTK_OBJECT (button), 
+                         "drag_request_event",
+                         (GtkSignalFunc) dnd_drag_request,
+                         button);
+      
+      gtk_widget_dnd_drag_set (button, TRUE, &foo, 1);
+
+
+      frame = gtk_frame_new ("Drop");
+      gtk_box_pack_start (GTK_BOX (box2), frame, TRUE, TRUE, 0);
+      gtk_widget_show (frame);
+
+      box3 = gtk_vbox_new (FALSE, 5);
+      gtk_container_border_width (GTK_CONTAINER (box3), 5);
+      gtk_container_add (GTK_CONTAINER (frame), box3);
+      gtk_widget_show (box3);
+
+
+      /*
+       * TO Button
+       */
+      button = gtk_button_new_with_label ("To");
+      gtk_box_pack_start (GTK_BOX (box3), button, FALSE, TRUE, 0);
+      gtk_widget_show (button);
+
+      gtk_widget_realize (button);
+      gtk_signal_connect (GTK_OBJECT (button), 
+                         "drop_data_available_event",
+                         (GtkSignalFunc) dnd_drop,
+                         button);
+
+      gtk_widget_dnd_drop_set (button, TRUE, &foo, 1, FALSE);
+
+
+      separator = gtk_hseparator_new ();
+      gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
+      gtk_widget_show (separator);
+
+
+      box2 = gtk_vbox_new (FALSE, 10);
+      gtk_container_border_width (GTK_CONTAINER (box2), 10);
+      gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
+      gtk_widget_show (box2);
+
+
+      button = gtk_button_new_with_label ("close");
+
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+/*
+ * Shaped Windows
+ */
+static GdkWindow *root_win = NULL;
+static GtkWidget *modeller = NULL;
+static GtkWidget *sheets = NULL;
+static GtkWidget *rings = NULL;
+
+typedef struct _cursoroffset {gint x,y;} CursorOffset;
+
+static void
+shape_pressed (GtkWidget *widget)
+{
+  CursorOffset *p;
+
+  p = gtk_object_get_user_data (GTK_OBJECT(widget));
+  gtk_widget_get_pointer (widget, &(p->x), &(p->y));
+
+  gtk_grab_add (widget);
+  gdk_pointer_grab (widget->window, TRUE,
+                   GDK_BUTTON_RELEASE_MASK |
+                   GDK_BUTTON_MOTION_MASK,
+                   NULL, NULL, 0);
+}
+
+
+static void
+shape_released (GtkWidget *widget)
+{
+  gtk_grab_remove (widget);
+  gdk_pointer_ungrab (0);
+}
+
+static void
+shape_motion (GtkWidget      *widget, 
+             GdkEventMotion *event)
+{
+  gint xp, yp;
+  CursorOffset * p;
+  GdkModifierType mask;
+
+  p = gtk_object_get_user_data (GTK_OBJECT (widget));
+
+  gdk_window_get_pointer (root_win, &xp, &yp, &mask);
+  gtk_widget_set_uposition (widget, xp  - p->x, yp  - p->y);
+}
+
+GtkWidget *
+shape_create_icon (char     *xpm_file,
+                  gint      x,
+                  gint      y,
+                  gint      px,
+                  gint      py,
+                  gint      window_type)
+{
+  GtkWidget *window;
+  GtkWidget *pixmap;
+  GtkWidget *fixed;
+  CursorOffset* icon_pos;
+  GdkGC* gc;
+  GdkBitmap *gdk_pixmap_mask;
+  GdkPixmap *gdk_pixmap;
+  GtkStyle *style;
+
+  style = gtk_widget_get_default_style ();
+  gc = style->black_gc;        
+
+  /*
+   * GDK_WINDOW_TOPLEVEL works also, giving you a title border
+   */
+  window = gtk_window_new (window_type);
+  
+  fixed = gtk_fixed_new ();
+  gtk_widget_set_usize (fixed, 100,100);
+  gtk_container_add (GTK_CONTAINER (window), fixed);
+  gtk_widget_show (fixed);
+  
+  gdk_pixmap = gdk_pixmap_create_from_xpm (window->window, &gdk_pixmap_mask, 
+                                          &style->bg[GTK_STATE_NORMAL],
+                                          xpm_file);
+
+  pixmap = gtk_pixmap_new (gdk_pixmap, gdk_pixmap_mask);
+  gtk_fixed_put (GTK_FIXED (fixed), pixmap, px,py);
+  gtk_widget_show (pixmap);
+  
+  gtk_widget_shape_combine_mask (window, gdk_pixmap_mask, px,py);
+
+  gtk_widget_set_events (window, 
+                        gtk_widget_get_events (window) |
+                        GDK_BUTTON_MOTION_MASK |
+                        GDK_BUTTON_PRESS_MASK);
+
+  gtk_signal_connect (GTK_OBJECT (window), "button_press_event",
+                     GTK_SIGNAL_FUNC (shape_pressed),NULL);
+  gtk_signal_connect (GTK_OBJECT (window), "button_release_event",
+                     GTK_SIGNAL_FUNC (shape_released),NULL);
+  gtk_signal_connect (GTK_OBJECT (window), "motion_notify_event",
+                     GTK_SIGNAL_FUNC (shape_motion),NULL);
+
+  icon_pos = g_new (CursorOffset, 1);
+  gtk_object_set_user_data(GTK_OBJECT(window), icon_pos);
+
+  gtk_widget_set_uposition (window, x, y);
+  gtk_widget_show (window);
+
+  return window;
+}
+
+void 
+create_shapes ()
+{
+  root_win = gdk_window_foreign_new (GDK_ROOT_WINDOW ());
+
+  if (!modeller)
+    {
+      modeller = shape_create_icon ("Modeller.xpm",
+                                   440, 140, 0,0, GTK_WINDOW_POPUP);
+
+      gtk_signal_connect (GTK_OBJECT (modeller), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &modeller);
+      gtk_signal_connect (GTK_OBJECT (modeller), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &modeller);
+    }
+  else
+    gtk_widget_destroy (modeller);
+
+  if (!sheets)
+    {
+      sheets = shape_create_icon ("FilesQueue.xpm",
+                                 580, 170, 0,0, GTK_WINDOW_POPUP);
+
+      gtk_signal_connect (GTK_OBJECT (sheets), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &sheets);
+      gtk_signal_connect (GTK_OBJECT (sheets), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &sheets);
+
+    }
+  else
+    gtk_widget_destroy (sheets);
+
+  if (!rings)
+    {
+      rings = shape_create_icon ("3DRings.xpm",
+                                460, 270, 25,25, GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (rings), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &rings);
+      gtk_signal_connect (GTK_OBJECT (rings), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &rings);
+    }
+  else
+    gtk_widget_destroy (rings);
+}
+
+
+/*
+ * Progress Bar
+ */
+static int progress_timer = 0;
+
+gint
+progress_timeout (gpointer data)
+{
+  gfloat new_val;
+
+  new_val = GTK_PROGRESS_BAR (data)->percentage;
+  if (new_val >= 1.0)
+    new_val = 0.0;
+  new_val += 0.02;
+
+  gtk_progress_bar_update (GTK_PROGRESS_BAR (data), new_val);
+
+  return TRUE;
+}
+
+void
+destroy_progress (GtkWidget  *widget,
+                 GtkWidget **window)
+{
+  destroy_window (widget, window);
+  gtk_timeout_remove (progress_timer);
+  progress_timer = 0;
+}
+
+void
+create_progress_bar ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *button;
+  GtkWidget *vbox;
+  GtkWidget *pbar;
+  GtkWidget *label;
+
+  if (!window)
+    {
+      window = gtk_dialog_new ();
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_progress,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_progress,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "dialog");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+
+      vbox = gtk_vbox_new (FALSE, 5);
+      gtk_container_border_width (GTK_CONTAINER (vbox), 10);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
+                         vbox, TRUE, TRUE, 0);
+      gtk_widget_show (vbox);
+
+      label = gtk_label_new ("progress...");
+      gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+      gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0);
+      gtk_widget_show (label);
+
+      pbar = gtk_progress_bar_new ();
+      gtk_widget_set_usize (pbar, 200, 20);
+      gtk_box_pack_start (GTK_BOX (vbox), pbar, TRUE, TRUE, 0);
+      gtk_widget_show (pbar);
+
+      progress_timer = gtk_timeout_add (100, progress_timeout, pbar);
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
+                         button, TRUE, TRUE, 0);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+
+/*
+ * Color Preview
+ */
+static int color_idle = 0;
+
+gint
+color_idle_func (GtkWidget *preview)
+{
+  static int count = 1;
+  guchar buf[768];
+  int i, j, k;
+
+  for (i = 0; i < 256; i++)
+    {
+      for (j = 0, k = 0; j < 256; j++)
+       {
+         buf[k+0] = i + count;
+         buf[k+1] = 0;
+         buf[k+2] = j + count;
+         k += 3;
+       }
+
+      gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
+    }
+
+  count += 1;
+
+  gtk_widget_draw (preview, NULL);
+
+  return TRUE;
+}
+
+void
+color_preview_destroy (GtkWidget  *widget,
+                      GtkWidget **window)
+{
+  gtk_idle_remove (color_idle);
+  color_idle = 0;
+
+  destroy_window (widget, window);
+}
+
+void
+create_color_preview ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *preview;
+  guchar buf[768];
+  int i, j, k;
+
+  if (!window)
+    {
+      gtk_widget_push_visual (gtk_preview_get_visual ());
+      gtk_widget_push_colormap (gtk_preview_get_cmap ());
+
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) color_preview_destroy,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) color_preview_destroy,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "test");
+      gtk_container_border_width (GTK_CONTAINER (window), 10);
+
+      preview = gtk_preview_new (GTK_PREVIEW_COLOR);
+      gtk_preview_size (GTK_PREVIEW (preview), 256, 256);
+      gtk_container_add (GTK_CONTAINER (window), preview);
+      gtk_widget_show (preview);
+
+      for (i = 0; i < 256; i++)
+       {
+         for (j = 0, k = 0; j < 256; j++)
+           {
+             buf[k+0] = i;
+             buf[k+1] = 0;
+             buf[k+2] = j;
+             k += 3;
+           }
+
+         gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
+       }
+
+      color_idle = gtk_idle_add ((GtkFunction) color_idle_func, preview);
+
+      gtk_widget_pop_colormap ();
+      gtk_widget_pop_visual ();
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+
+/*
+ * Gray Preview
+ */
+static int gray_idle = 0;
+
+gint
+gray_idle_func (GtkWidget *preview)
+{
+  static int count = 1;
+  guchar buf[256];
+  int i, j;
+
+  for (i = 0; i < 256; i++)
+    {
+      for (j = 0; j < 256; j++)
+       buf[j] = i + j + count;
+
+      gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
+    }
+
+  count += 1;
+
+  gtk_widget_draw (preview, NULL);
+
+  return TRUE;
+}
+
+void
+gray_preview_destroy (GtkWidget  *widget,
+                     GtkWidget **window)
+{
+  gtk_idle_remove (gray_idle);
+  gray_idle = 0;
+
+  destroy_window (widget, window);
+}
+
+void
+create_gray_preview ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *preview;
+  guchar buf[256];
+  int i, j;
+
+  if (!window)
+    {
+      gtk_widget_push_visual (gtk_preview_get_visual ());
+      gtk_widget_push_colormap (gtk_preview_get_cmap ());
+
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) gray_preview_destroy,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) gray_preview_destroy,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "test");
+      gtk_container_border_width (GTK_CONTAINER (window), 10);
+
+      preview = gtk_preview_new (GTK_PREVIEW_GRAYSCALE);
+      gtk_preview_size (GTK_PREVIEW (preview), 256, 256);
+      gtk_container_add (GTK_CONTAINER (window), preview);
+      gtk_widget_show (preview);
+
+      for (i = 0; i < 256; i++)
+       {
+         for (j = 0; j < 256; j++)
+           buf[j] = i + j;
+
+         gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, 256);
+       }
+
+      gray_idle = gtk_idle_add ((GtkFunction) gray_idle_func, preview);
+
+      gtk_widget_pop_colormap ();
+      gtk_widget_pop_visual ();
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+
+/*
+ * Selection Test
+ */
+void
+selection_test_received (GtkWidget *list, GtkSelectionData *data)
+{
+  GdkAtom *atoms;
+  GtkWidget *list_item;
+  GList *item_list;
+  int i, l;
+
+  if (data->length < 0)
+    {
+      g_print ("Selection retrieval failed\n");
+      return;
+    }
+  if (data->type != GDK_SELECTION_TYPE_ATOM)
+    {
+      g_print ("Selection \"TARGETS\" was not returned as atoms!\n");
+      return;
+    }
+
+  /* Clear out any current list items */
+
+  gtk_list_clear_items (GTK_LIST(list), 0, -1);
+
+  /* Add new items to list */
+
+  atoms = (GdkAtom *)data->data;
+
+  item_list = NULL;
+  l = data->length / sizeof (GdkAtom);
+  for (i = 0; i < l; i++)
+    {
+      char *name;
+      name = gdk_atom_name (atoms[i]);
+      if (name != NULL)
+       {
+         list_item = gtk_list_item_new_with_label (name);
+         g_free (name);
+       }
+      else
+       list_item = gtk_list_item_new_with_label ("(bad atom)");
+
+      gtk_widget_show (list_item);
+      item_list = g_list_append (item_list, list_item);
+    }
+
+  gtk_list_append_items (GTK_LIST (list), item_list);
+
+  return;
+}
+
+void
+selection_test_get_targets (GtkWidget *widget, GtkWidget *list)
+{
+  static GdkAtom targets_atom = GDK_NONE;
+
+  if (targets_atom == GDK_NONE)
+    targets_atom = gdk_atom_intern ("TARGETS", FALSE);
+
+  gtk_selection_convert (list, GDK_SELECTION_PRIMARY, targets_atom,
+                        GDK_CURRENT_TIME);
+}
+
+void
+create_selection_test ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *button;
+  GtkWidget *vbox;
+  GtkWidget *scrolled_win;
+  GtkWidget *list;
+  GtkWidget *label;
+
+  if (!window)
+    {
+      window = gtk_dialog_new ();
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "Selection Test");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+      /* Create the list */
+
+      vbox = gtk_vbox_new (FALSE, 5);
+      gtk_container_border_width (GTK_CONTAINER (vbox), 10);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), vbox,
+                         TRUE, TRUE, 0);
+      gtk_widget_show (vbox);
+
+      label = gtk_label_new ("Gets available targets for current selection");
+      gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+      gtk_widget_show (label);
+
+      scrolled_win = gtk_scrolled_window_new (NULL, NULL);
+      gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
+                                     GTK_POLICY_AUTOMATIC, 
+                                     GTK_POLICY_AUTOMATIC);
+      gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
+      gtk_widget_set_usize (scrolled_win, 100, 200);
+      gtk_widget_show (scrolled_win);
+
+      list = gtk_list_new ();
+      gtk_container_add (GTK_CONTAINER (scrolled_win), list);
+
+      gtk_signal_connect (GTK_OBJECT(list), "selection_received",
+                         GTK_SIGNAL_FUNC (selection_test_received), NULL);
+      gtk_widget_show (list);
+
+      /* .. And create some buttons */
+      button = gtk_button_new_with_label ("Get Targets");
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
+                         button, TRUE, TRUE, 0);
+
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         GTK_SIGNAL_FUNC (selection_test_get_targets), list);
+      gtk_widget_show (button);
+
+      button = gtk_button_new_with_label ("Quit");
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
+                         button, TRUE, TRUE, 0);
+
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                GTK_SIGNAL_FUNC (gtk_widget_destroy),
+                                GTK_OBJECT (window));
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+
+/*
+ * Gamma Curve
+ */
+void
+create_gamma_curve ()
+{
+  static GtkWidget *window = NULL, *curve;
+  static int count = 0;
+  gfloat vec[256];
+  gint max;
+  gint i;
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+      gtk_window_set_title (GTK_WINDOW (window), "test");
+      gtk_container_border_width (GTK_CONTAINER (window), 10);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_window,
+                         &window);
+
+      curve = gtk_gamma_curve_new ();
+      gtk_container_add (GTK_CONTAINER (window), curve);
+      gtk_widget_show (curve);
+    }
+
+  max = 127 + (count % 2)*128;
+  gtk_curve_set_range (GTK_CURVE (GTK_GAMMA_CURVE (curve)->curve),
+                      0, max, 0, max);
+  for (i = 0; i < max; ++i)
+    vec[i] = (127 / sqrt (max)) * sqrt (i);
+  gtk_curve_set_vector (GTK_CURVE (GTK_GAMMA_CURVE (curve)->curve),
+                       max, vec);
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else if (count % 4 == 3)
+    {
+      gtk_widget_destroy (window);
+      window = NULL;
+    }
+
+  ++count;
+}
+
+
+/*
+ * Timeout Test
+ */
+static int timer = 0;
+
+void
+timeout_test (GtkWidget *label)
+{
+  static int count = 0;
+  static char buffer[32];
+
+  sprintf (buffer, "count: %d", ++count);
+  gtk_label_set (GTK_LABEL (label), buffer);
+}
+
+void
+start_timeout_test (GtkWidget *widget,
+                   GtkWidget *label)
+{
+  if (!timer)
+    {
+      timer = gtk_timeout_add (100, (GtkFunction) timeout_test, label);
+    }
+}
+
+void
+stop_timeout_test (GtkWidget *widget,
+                  gpointer   data)
+{
+  if (timer)
+    {
+      gtk_timeout_remove (timer);
+      timer = 0;
+    }
+}
+
+void
+destroy_timeout_test (GtkWidget  *widget,
+                     GtkWidget **window)
+{
+  destroy_window (widget, window);
+  stop_timeout_test (NULL, NULL);
+}
+
+void
+create_timeout_test ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *button;
+  GtkWidget *label;
+
+  if (!window)
+    {
+      window = gtk_dialog_new ();
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_timeout_test,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_timeout_test,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "Timeout Test");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+      label = gtk_label_new ("count: 0");
+      gtk_misc_set_padding (GTK_MISC (label), 10, 10);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
+                         label, TRUE, TRUE, 0);
+      gtk_widget_show (label);
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
+                         button, TRUE, TRUE, 0);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+
+      button = gtk_button_new_with_label ("start");
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         (GtkSignalFunc) start_timeout_test,
+                         label);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
+                         button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+      button = gtk_button_new_with_label ("stop");
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         (GtkSignalFunc) stop_timeout_test,
+                         NULL);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
+                         button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+
+/*
+ * Idle Test
+ */
+static int idle = 0;
+
+gint
+idle_test (GtkWidget *label)
+{
+  static int count = 0;
+  static char buffer[32];
+
+  sprintf (buffer, "count: %d", ++count);
+  gtk_label_set (GTK_LABEL (label), buffer);
+
+  return TRUE;
+}
+
+void
+start_idle_test (GtkWidget *widget,
+                GtkWidget *label)
+{
+  if (!idle)
+    {
+      idle = gtk_idle_add ((GtkFunction) idle_test, label);
+    }
+}
+
+void
+stop_idle_test (GtkWidget *widget,
+               gpointer   data)
+{
+  if (idle)
+    {
+      gtk_idle_remove (idle);
+      idle = 0;
+    }
+}
+
+void
+destroy_idle_test (GtkWidget  *widget,
+                  GtkWidget **window)
+{
+  destroy_window (widget, window);
+  stop_idle_test (NULL, NULL);
+}
+
+void
+create_idle_test ()
+{
+  static GtkWidget *window = NULL;
+  GtkWidget *button;
+  GtkWidget *label;
+
+  if (!window)
+    {
+      window = gtk_dialog_new ();
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) destroy_idle_test,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) destroy_idle_test,
+                         &window);
+
+      gtk_window_set_title (GTK_WINDOW (window), "Idle Test");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+
+      label = gtk_label_new ("count: 0");
+      gtk_misc_set_padding (GTK_MISC (label), 10, 10);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
+                         label, TRUE, TRUE, 0);
+      gtk_widget_show (label);
+
+      button = gtk_button_new_with_label ("close");
+      gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                                (GtkSignalFunc) gtk_widget_destroy,
+                                GTK_OBJECT (window));
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
+                         button, TRUE, TRUE, 0);
+      gtk_widget_grab_default (button);
+      gtk_widget_show (button);
+
+      button = gtk_button_new_with_label ("start");
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         (GtkSignalFunc) start_idle_test,
+                         label);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
+                         button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+
+      button = gtk_button_new_with_label ("stop");
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                         (GtkSignalFunc) stop_idle_test,
+                         NULL);
+      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
+                         button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+}
+
+void
+test_destroy (GtkWidget  *widget,
+             GtkWidget **window)
+{
+  destroy_window (widget, window);
+  gtk_main_quit ();
+}
+
+/*
+ * Basic Test
+ */
+void
+create_test ()
+{
+  static GtkWidget *window = NULL;
+
+  if (!window)
+    {
+      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+      gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                         (GtkSignalFunc) test_destroy,
+                         &window);
+      gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                         (GtkSignalFunc) test_destroy,
+                         &window);
+
+
+      gtk_window_set_title (GTK_WINDOW (window), "test");
+      gtk_container_border_width (GTK_CONTAINER (window), 0);
+    }
+
+  if (!GTK_WIDGET_VISIBLE (window))
+    {
+      gtk_widget_show (window);
+
+      g_print ("create_test: start\n");
+      gtk_main ();
+      g_print ("create_test: done\n");
+    }
+  else
+    gtk_widget_destroy (window);
+}
+
+
+/*
+ * Main Window and Exit
+ */
+void
+do_exit ()
+{
+  gtk_exit (0);
+}
+
+void
+create_main_window ()
+{
+  struct {
+    char *label;
+    void (*func) ();
+  } buttons[] =
+    {
+      { "buttons", create_buttons },
+      { "toggle buttons", create_toggle_buttons },
+      { "check buttons", create_check_buttons },
+      { "radio buttons", create_radio_buttons },
+      { "button box", create_button_box },
+      { "reparent", create_reparent },
+      { "pixmap", create_pixmap },
+      { "tooltips", create_tooltips },
+      { "menus", create_menus },
+      { "scrolled windows", create_scrolled_windows },
+      { "drawing areas", NULL },
+      { "entry", create_entry },
+      { "list", create_list },
+      { "color selection", create_color_selection },
+      { "file selection", create_file_selection },
+      { "dialog", create_dialog },
+      { "miscellaneous", NULL },
+      { "range controls", create_range_controls },
+      { "rulers", create_rulers },
+      { "text", create_text },
+      { "notebook", create_notebook },
+      { "panes", create_panes },
+      { "shapes", create_shapes },
+      { "dnd", create_dnd },
+      { "progress bar", create_progress_bar },
+      { "preview color", create_color_preview },
+      { "preview gray", create_gray_preview },
+      { "gamma curve", create_gamma_curve },
+      { "test selection", create_selection_test },
+      { "test timeout", create_timeout_test },
+      { "test idle", create_idle_test },
+      { "test", create_test },
+    };
+  int nbuttons = sizeof (buttons) / sizeof (buttons[0]);
+  GtkWidget *window;
+  GtkWidget *box1;
+  GtkWidget *box2;
+  GtkWidget *scrolled_window;
+  GtkWidget *button;
+  GtkWidget *separator;
+  int i;
+
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_widget_set_name (window, "main window");
+  gtk_widget_set_usize (window, 200, 400);
+  gtk_widget_set_uposition (window, 20, 20);
+
+  gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                     (GtkSignalFunc) gtk_exit,
+                     NULL);
+  gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                     (GtkSignalFunc) gtk_exit,
+                     NULL);
+
+  box1 = gtk_vbox_new (FALSE, 0);
+  gtk_container_add (GTK_CONTAINER (window), box1);
+  gtk_widget_show (box1);
+
+  scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+  gtk_container_border_width (GTK_CONTAINER (scrolled_window), 10);
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
+                                 GTK_POLICY_AUTOMATIC, 
+                                  GTK_POLICY_AUTOMATIC);
+  gtk_box_pack_start (GTK_BOX (box1), scrolled_window, TRUE, TRUE, 0);
+  gtk_widget_show (scrolled_window);
+
+  box2 = gtk_vbox_new (FALSE, 0);
+  gtk_container_border_width (GTK_CONTAINER (box2), 10);
+  gtk_container_add (GTK_CONTAINER (scrolled_window), box2);
+  gtk_widget_show (box2);
+
+  for (i = 0; i < nbuttons; i++)
+    {
+      button = gtk_button_new_with_label (buttons[i].label);
+      if (buttons[i].func)
+        gtk_signal_connect (GTK_OBJECT (button), 
+                           "clicked", 
+                           (GtkSignalFunc) 
+                           buttons[i].func, NULL);
+      else
+        gtk_widget_set_sensitive (button, FALSE);
+      gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+      gtk_widget_show (button);
+    }
+
+  separator = gtk_hseparator_new ();
+  gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
+  gtk_widget_show (separator);
+
+  box2 = gtk_vbox_new (FALSE, 10);
+  gtk_container_border_width (GTK_CONTAINER (box2), 10);
+  gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
+  gtk_widget_show (box2);
+
+  button = gtk_button_new_with_label ("close");
+  gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                     (GtkSignalFunc) do_exit, NULL);
+  gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
+  GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+  gtk_widget_grab_default (button);
+  gtk_widget_show (button);
+
+  gtk_widget_show (window);
+}
+
+int
+main (int argc, char *argv[])
+{
+  gtk_set_locale ();
+
+  gtk_init (&argc, &argv);
+  gtk_rc_parse ("testgtkrc");
+
+  create_main_window ();
+
+  gtk_main ();
+
+  return 0;
+}
diff --git a/tests/testgtkrc b/tests/testgtkrc
new file mode 100644 (file)
index 0000000..e909e31
--- /dev/null
@@ -0,0 +1,69 @@
+# pixmap_path "<dir 1>:<dir 2>:<dir 3>:..."
+#
+# style <name> [= <name>]
+# {
+#   <option>
+# }
+#
+# widget <widget_set> style <style_name>
+# widget_class <widget_class_set> style <style_name>
+
+pixmap_path "."
+
+style "window"
+{
+#  bg_pixmap[NORMAL] = "warning.xpm"
+}
+
+style "scale"
+{
+  fg[NORMAL] = { 1.0, 0, 0 }
+  bg_pixmap[NORMAL] = "<parent>"
+}
+
+style "button"
+{
+  fg[PRELIGHT] = { 1.0, 1.0, 1.0 }
+  bg[PRELIGHT] = { 0, 0, 0.75 }
+}
+
+style "main_button" = "button"
+{
+  font = "-adobe-helvetica-medium-r-normal--*-100-*-*-*-*-*-*"
+  bg[PRELIGHT] = { 0.75, 0, 0 }
+}
+
+style "toggle_button" = "button"
+{
+  fg[NORMAL] = { 1.0, 0, 0 }
+  fg[ACTIVE] = { 1.0, 0, 0 }
+  bg_pixmap[NORMAL] = "<parent>"
+}
+
+style "text"
+{
+  bg_pixmap[NORMAL] = "marble.xpm"
+  fg[NORMAL] = { 1.0, 1.0, 1.0 }
+}
+
+style "ruler"
+{
+  font = "-adobe-helvetica-medium-r-normal--*-80-*-*-*-*-*-*"
+}
+
+style "curve"
+{
+  fg[NORMAL] = { 58000, 0, 0 }                 # red
+}
+
+widget_class "GtkWindow" style "window"
+widget_class "GtkDialog" style "window"
+widget_class "GtkFileSelection" style "window"
+widget_class "*Gtk*Scale" style "scale"
+widget_class "*GtkCheckButton*" style "toggle_button"
+widget_class "*GtkRadioButton*" style "toggle_button"
+widget_class "*GtkButton*" style "button"
+widget_class "*Ruler" style "ruler"
+widget_class "*GtkText" style "text"
+widget "main window.*GtkButton*" style "main_button"
+widget "*GtkCurve" style "curve"
diff --git a/tests/testinput.c b/tests/testinput.c
new file mode 100644 (file)
index 0000000..1c6dae0
--- /dev/null
@@ -0,0 +1,379 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "gtk.h"
+
+/* Backing pixmap for drawing area */
+
+static GdkPixmap *pixmap = NULL;
+
+/* Information about cursor */
+
+static gint need_cursor = FALSE;
+static gint cursor_proximity = TRUE;
+static gdouble cursor_x;
+static gdouble cursor_y;
+
+/* Unique ID of current device */
+static guint32 current_device = GDK_CORE_POINTER;
+
+/* Check to see if we need to draw a cursor for current device */
+static void
+check_cursor ()
+{
+  GList *tmp_list;
+
+  /* gdk_input_list_devices returns an internal list, so we shouldn't
+     free it afterwards */
+  tmp_list = gdk_input_list_devices();
+
+  while (tmp_list)
+    {
+      GdkDeviceInfo *info = (GdkDeviceInfo *)tmp_list->data;
+
+      if (info->deviceid == current_device)
+       {
+         need_cursor = !info->has_cursor;
+         break;
+       }
+
+      tmp_list = tmp_list->next;
+    }
+}
+
+/* Erase the old cursor, and/or draw a new one, if necessary */
+static void
+update_cursor (GtkWidget *widget,  gdouble x, gdouble y)
+{
+  static gint cursor_present = 0;
+  gint state = need_cursor && cursor_proximity;
+
+  if (pixmap != NULL)
+    {
+      if (cursor_present && (cursor_present != state ||
+                            x != cursor_x || y != cursor_y))
+       {
+         gdk_draw_pixmap(widget->window,
+                         widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+                         pixmap,
+                         cursor_x - 5, cursor_y - 5,
+                         cursor_x - 5, cursor_y - 5,
+                         10, 10);
+       }
+
+      cursor_present = state;
+      cursor_x = x;
+      cursor_y = y;
+
+      if (cursor_present)
+       {
+         gdk_draw_rectangle (widget->window,
+                             widget->style->black_gc,
+                             TRUE,
+                             cursor_x - 5, cursor_y -5,
+                             10, 10);
+       }
+    }
+}
+
+/* Create a new backing pixmap of the appropriate size */
+static gint
+configure_event (GtkWidget *widget, GdkEventConfigure *event)
+{
+  if (pixmap)
+    {
+      gdk_pixmap_destroy(pixmap);
+    }
+  pixmap = gdk_pixmap_new(widget->window,
+                         widget->allocation.width,
+                         widget->allocation.height,
+                         -1);
+  gdk_draw_rectangle (pixmap,
+                     widget->style->white_gc,
+                     TRUE,
+                     0, 0,
+                     widget->allocation.width,
+                     widget->allocation.height);
+
+  return TRUE;
+}
+
+/* Refill the screen from the backing pixmap */
+static gint
+expose_event (GtkWidget *widget, GdkEventExpose *event)
+{
+  gdk_draw_pixmap(widget->window,
+                 widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+                 pixmap,
+                 event->area.x, event->area.y,
+                 event->area.x, event->area.y,
+                 event->area.width, event->area.height);
+
+  return FALSE;
+}
+
+/* Draw a rectangle on the screen, size depending on pressure,
+   and color on the type of device */
+static void
+draw_brush (GtkWidget *widget, GdkInputSource source,
+           gdouble x, gdouble y, gdouble pressure)
+{
+  GdkGC *gc;
+  GdkRectangle update_rect;
+
+  switch (source)
+    {
+    case GDK_SOURCE_MOUSE:
+      gc = widget->style->dark_gc[GTK_WIDGET_STATE (widget)];
+      break;
+    case GDK_SOURCE_PEN:
+      gc = widget->style->black_gc;
+      break;
+    case GDK_SOURCE_ERASER:
+      gc = widget->style->white_gc;
+      break;
+    default:
+      gc = widget->style->light_gc[GTK_WIDGET_STATE (widget)];
+    }
+
+  update_rect.x = x - 10 * pressure;
+  update_rect.y = y - 10 * pressure;
+  update_rect.width = 20 * pressure;
+  update_rect.height = 20 * pressure;
+  gdk_draw_rectangle (pixmap, gc, TRUE,
+                     update_rect.x, update_rect.y,
+                     update_rect.width, update_rect.height);
+  gtk_widget_draw (widget, &update_rect);
+}
+
+static guint32 motion_time;
+
+static gint
+button_press_event (GtkWidget *widget, GdkEventButton *event)
+{
+  if (event->deviceid != current_device)
+    {
+      current_device = event->deviceid;
+      check_cursor ();
+    }
+
+  cursor_proximity = TRUE;
+
+  if (event->button == 1 && pixmap != NULL)
+    {
+      draw_brush (widget, event->source, event->x, event->y,
+                 event->pressure);
+      motion_time = event->time;
+    }
+
+  update_cursor (widget, event->x, event->y);
+
+  return TRUE;
+}
+
+static gint
+motion_notify_event (GtkWidget *widget, GdkEventMotion *event)
+{
+  GdkTimeCoord *coords;
+  int nevents;
+  int i;
+
+  if (event->deviceid != current_device)
+    {
+      current_device = event->deviceid;
+      check_cursor ();
+    }
+
+  cursor_proximity = TRUE;
+
+  if (event->state & GDK_BUTTON1_MASK && pixmap != NULL)
+    {
+      coords = gdk_input_motion_events (event->window, event->deviceid,
+                                       motion_time, event->time,
+                                       &nevents);
+      motion_time = event->time;
+      if (coords)
+       {
+         for (i=0; i<nevents; i++)
+           draw_brush (widget,  event->source, coords[i].x, coords[i].y,
+                       coords[i].pressure);
+         g_free (coords);
+       }
+      else
+       {
+         if (event->is_hint)
+           gdk_input_window_get_pointer (event->window, event->deviceid,
+                                         NULL, NULL, NULL, NULL, NULL, NULL);
+         draw_brush (widget,  event->source, event->x, event->y,
+                     event->pressure);
+       }
+    }
+  else
+    {
+      gdk_input_window_get_pointer (event->window, event->deviceid,
+                                   &event->x, &event->y,
+                                   NULL, NULL, NULL, NULL);
+    }
+
+  update_cursor (widget, event->x, event->y);
+
+  return TRUE;
+}
+
+/* We track the next two events to know when we need to draw a
+   cursor */
+
+static gint
+proximity_out_event (GtkWidget *widget, GdkEventProximity *event)
+{
+  cursor_proximity = FALSE;
+  update_cursor (widget, cursor_x, cursor_y);
+  return TRUE;
+}
+
+static gint
+leave_notify_event (GtkWidget *widget, GdkEventCrossing *event)
+{
+  cursor_proximity = FALSE;
+  update_cursor (widget, cursor_x, cursor_y);
+  return TRUE;
+}
+
+void
+input_dialog_destroy (GtkWidget *w, gpointer data)
+{
+  *((GtkWidget **)data) = NULL;
+}
+
+void
+create_input_dialog ()
+{
+  static GtkWidget *inputd = NULL;
+
+  if (!inputd)
+    {
+      inputd = gtk_input_dialog_new();
+
+      gtk_signal_connect (GTK_OBJECT(inputd), "destroy",
+                         (GtkSignalFunc)input_dialog_destroy, &inputd);
+      gtk_signal_connect_object (GTK_OBJECT(GTK_INPUT_DIALOG(inputd)->close_button),
+                         "clicked",
+                         (GtkSignalFunc)gtk_widget_hide,
+                         GTK_OBJECT(inputd));
+      gtk_widget_hide ( GTK_INPUT_DIALOG(inputd)->save_button);
+
+      gtk_signal_connect (GTK_OBJECT(inputd), "enable_device",
+                         (GtkSignalFunc)check_cursor, NULL);
+      gtk_widget_show (inputd);
+    }
+  else
+    {
+      if (!GTK_WIDGET_MAPPED(inputd))
+       gtk_widget_show(inputd);
+      else
+       gdk_window_raise(inputd->window);
+    }
+}
+
+void
+quit ()
+{
+  gtk_exit (0);
+}
+
+int
+main (int argc, char *argv[])
+{
+  GtkWidget *window;
+  GtkWidget *drawing_area;
+  GtkWidget *vbox;
+
+  GtkWidget *button;
+
+  gtk_init (&argc, &argv);
+
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_widget_set_name (window, "Test Input");
+
+  vbox = gtk_vbox_new (FALSE, 0);
+  gtk_container_add (GTK_CONTAINER (window), vbox);
+  gtk_widget_show (vbox);
+
+  gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                     GTK_SIGNAL_FUNC (quit), NULL);
+
+  /* Create the drawing area */
+
+  drawing_area = gtk_drawing_area_new ();
+  gtk_drawing_area_size (GTK_DRAWING_AREA (drawing_area), 200, 200);
+  gtk_box_pack_start (GTK_BOX (vbox), drawing_area, TRUE, TRUE, 0);
+
+  gtk_widget_show (drawing_area);
+
+  /* Signals used to handle backing pixmap */
+
+  gtk_signal_connect (GTK_OBJECT (drawing_area), "expose_event",
+                     (GtkSignalFunc) expose_event, NULL);
+  gtk_signal_connect (GTK_OBJECT(drawing_area),"configure_event",
+                     (GtkSignalFunc) configure_event, NULL);
+
+  /* Event signals */
+
+  gtk_signal_connect (GTK_OBJECT (drawing_area), "motion_notify_event",
+                     (GtkSignalFunc) motion_notify_event, NULL);
+  gtk_signal_connect (GTK_OBJECT (drawing_area), "button_press_event",
+                     (GtkSignalFunc) button_press_event, NULL);
+
+  gtk_signal_connect (GTK_OBJECT (drawing_area), "leave_notify_event",
+                     (GtkSignalFunc) leave_notify_event, NULL);
+  gtk_signal_connect (GTK_OBJECT (drawing_area), "proximity_out_event",
+                     (GtkSignalFunc) proximity_out_event, NULL);
+
+  gtk_widget_set_events (drawing_area, GDK_EXPOSURE_MASK
+                        | GDK_LEAVE_NOTIFY_MASK
+                        | GDK_BUTTON_PRESS_MASK
+                        | GDK_POINTER_MOTION_MASK
+                        | GDK_POINTER_MOTION_HINT_MASK
+                        | GDK_PROXIMITY_OUT_MASK);
+
+  /* The following call enables tracking and processing of extension
+     events for the drawing area */
+  gtk_widget_set_extension_events (drawing_area, GDK_EXTENSION_EVENTS_ALL);
+
+  /* .. And create some buttons */
+  button = gtk_button_new_with_label ("Input Dialog");
+  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+
+  gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                     GTK_SIGNAL_FUNC (create_input_dialog), NULL);
+  gtk_widget_show (button);
+
+  button = gtk_button_new_with_label ("Quit");
+  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+
+  gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                            GTK_SIGNAL_FUNC (gtk_widget_destroy),
+                            GTK_OBJECT (window));
+  gtk_widget_show (button);
+
+  gtk_widget_show (window);
+
+  gtk_main ();
+
+  return 0;
+}
diff --git a/tests/testselection.c b/tests/testselection.c
new file mode 100644 (file)
index 0000000..3377cc6
--- /dev/null
@@ -0,0 +1,466 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "gtk.h"
+
+typedef enum {
+  SEL_TYPE_NONE,
+  APPLE_PICT,
+  ATOM,
+  ATOM_PAIR,
+  BITMAP,
+  C_STRING,
+  COLORMAP,
+  COMPOUND_TEXT,
+  DRAWABLE,
+  INTEGER,
+  PIXEL,
+  PIXMAP,
+  SPAN,
+  STRING,
+  TEXT,
+  WINDOW,
+  LAST_SEL_TYPE,
+} SelType;
+
+GdkAtom seltypes[LAST_SEL_TYPE];
+
+typedef struct _Target {
+  gchar *target_name;
+  SelType type;
+  GdkAtom target;
+  gint format;
+  GtkSelectionFunction *handler;
+} Target;
+
+/* The following is a list of all the selection targets defined
+   in the ICCCM */
+
+static Target targets[] = {
+  { "ADOBE_PORTABLE_DOCUMENT_FORMAT",      STRING,        0, 8,  NULL },
+  { "APPLE_PICT",                          APPLE_PICT,    0, 8,  NULL },
+  { "BACKGROUND",                          PIXEL,         0, 32, NULL },
+  { "BITMAP",                              BITMAP,        0, 32, NULL },
+  { "CHARACTER_POSITION",                   SPAN,         0, 32, NULL },
+  { "CLASS",                               TEXT,          0, 8,  NULL },
+  { "CLIENT_WINDOW",                       WINDOW,        0, 32, NULL },
+  { "COLORMAP",                            COLORMAP,      0, 32, NULL },
+  { "COLUMN_NUMBER",                       SPAN,          0, 32, NULL },
+  { "COMPOUND_TEXT",                       COMPOUND_TEXT, 0, 8,  NULL },
+  /*  { "DELETE", "NULL", 0, ?, NULL }, */
+  { "DRAWABLE",                            DRAWABLE,      0, 32, NULL },
+  { "ENCAPSULATED_POSTSCRIPT",                     STRING,        0, 8,  NULL },
+  { "ENCAPSULATED_POSTSCRIPT_INTERCHANGE",  STRING,       0, 8,  NULL },
+  { "FILE_NAME",                           TEXT,          0, 8,  NULL },
+  { "FOREGROUND",                          PIXEL,         0, 32, NULL },
+  { "HOST_NAME",                           TEXT,          0, 8,  NULL },
+  /*  { "INSERT_PROPERTY", "NULL", 0, ? NULL }, */
+  /*  { "INSERT_SELECTION", "NULL", 0, ? NULL }, */
+  { "LENGTH",                              INTEGER,       0, 32, NULL },
+  { "LINE_NUMBER",                         SPAN,          0, 32, NULL },
+  { "LIST_LENGTH",                         INTEGER,       0, 32, NULL },
+  { "MODULE",                              TEXT,          0, 8,  NULL },
+  /*  { "MULTIPLE", "ATOM_PAIR", 0, 32, NULL }, */
+  { "NAME",                                TEXT,          0, 8,  NULL },
+  { "ODIF",                                TEXT,          0, 8,  NULL },
+  { "OWNER_OS",                            TEXT,          0, 8,  NULL },
+  { "PIXMAP",                              PIXMAP,        0, 32, NULL },
+  { "POSTSCRIPT",                          STRING,        0, 8,  NULL },
+  { "PROCEDURE",                           TEXT,          0, 8,  NULL },
+  { "PROCESS",                             INTEGER,       0, 32, NULL },
+  { "STRING",                              STRING,        0, 8,  NULL },
+  { "TARGETS",                                     ATOM,          0, 32, NULL },
+  { "TASK",                                INTEGER,       0, 32, NULL },
+  { "TEXT",                                TEXT,          0, 8 , NULL },
+  { "TIMESTAMP",                           INTEGER,       0, 32, NULL },
+  { "USER",                                TEXT,          0, 8,  NULL },
+};
+
+static int num_targets = sizeof(targets)/sizeof(Target);
+
+static int have_selection = FALSE;
+
+GtkWidget *selection_text;
+GtkWidget *selection_button;
+GString *selection_string = NULL;
+
+static void
+init_atoms ()
+{
+  int i;
+
+  seltypes[SEL_TYPE_NONE] = GDK_NONE;
+  seltypes[APPLE_PICT] = gdk_atom_intern ("APPLE_PICT",FALSE);
+  seltypes[ATOM]       = gdk_atom_intern ("ATOM",FALSE);
+  seltypes[ATOM_PAIR]  = gdk_atom_intern ("ATOM_PAIR",FALSE);
+  seltypes[BITMAP]     = gdk_atom_intern ("BITMAP",FALSE);
+  seltypes[C_STRING]   = gdk_atom_intern ("C_STRING",FALSE);
+  seltypes[COLORMAP]   = gdk_atom_intern ("COLORMAP",FALSE);
+  seltypes[COMPOUND_TEXT] = gdk_atom_intern ("COMPOUND_TEXT",FALSE);
+  seltypes[DRAWABLE]   = gdk_atom_intern ("DRAWABLE",FALSE);
+  seltypes[INTEGER]    = gdk_atom_intern ("INTEGER",FALSE);
+  seltypes[PIXEL]      = gdk_atom_intern ("PIXEL",FALSE);
+  seltypes[PIXMAP]     = gdk_atom_intern ("PIXMAP",FALSE);
+  seltypes[SPAN]       = gdk_atom_intern ("SPAN",FALSE);
+  seltypes[STRING]     = gdk_atom_intern ("STRING",FALSE);
+  seltypes[TEXT]       = gdk_atom_intern ("TEXT",FALSE);
+  seltypes[WINDOW]     = gdk_atom_intern ("WINDOW",FALSE);
+
+  for (i=0; i<num_targets; i++)
+    targets[i].target = gdk_atom_intern (targets[i].target_name, FALSE);
+}
+
+void
+selection_toggled (GtkWidget *widget)
+{
+  if (GTK_TOGGLE_BUTTON(widget)->active)
+    {
+      have_selection = gtk_selection_owner_set (widget,
+                                               GDK_SELECTION_PRIMARY,
+                                               GDK_CURRENT_TIME);
+      if (!have_selection)
+       gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON(widget), FALSE);
+    }
+  else
+    {
+      if (have_selection)
+       {
+         if (gdk_selection_owner_get (GDK_SELECTION_PRIMARY) == widget->window)
+           gtk_selection_owner_set (NULL, GDK_SELECTION_PRIMARY,
+                                    GDK_CURRENT_TIME);
+         have_selection = FALSE;
+       }
+    }
+}
+
+void
+selection_handle (GtkWidget *widget, 
+                 GtkSelectionData *selection_data, gpointer data)
+{
+  guchar *buffer;
+  gint len;
+
+  if (!selection_string)
+    {
+      buffer = NULL;
+      len = 0;
+    }      
+  else
+    {
+      buffer = selection_string->str;
+      len = selection_string->len;
+    }
+  
+  gtk_selection_data_set (selection_data,
+                         selection_data->target == seltypes[COMPOUND_TEXT] ?
+                                 seltypes[COMPOUND_TEXT] : seltypes[STRING],
+                         8, buffer, len);
+}
+
+gint
+selection_clear (GtkWidget *widget, GdkEventSelection *event)
+{
+  have_selection = FALSE;
+  gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON(widget), FALSE);
+
+  return TRUE;
+}
+
+gchar *
+stringify_atom (guchar *data, gint *position)
+{
+  gchar *str = gdk_atom_name (*(GdkAtom *)(data+*position));
+  *position += sizeof(GdkAtom);
+    
+  return str;
+}
+
+gchar *
+stringify_text (guchar *data, gint *position)
+{
+  gchar *str = g_strdup ((gchar *)(data+*position));
+  *position += strlen (str) + 1;
+    
+  return str;
+}
+
+gchar *
+stringify_xid (guchar *data, gint *position)
+{
+  gchar buffer[20];
+  gchar *str;
+
+  sprintf(buffer,"0x%x",*(guint32 *)(data+*position));
+  str = g_strdup (buffer);
+
+  *position += sizeof(guint32);
+    
+  return str;
+}
+
+gchar *
+stringify_integer (guchar *data, gint *position)
+{
+  gchar buffer[20];
+  gchar *str;
+
+  sprintf(buffer,"%d",*(int *)(data+*position));
+  str = g_strdup (buffer);
+
+  *position += sizeof(int);
+    
+  return str;
+}
+
+gchar *
+stringify_span (guchar *data, gint *position)
+{
+  gchar buffer[42];
+  gchar *str;
+
+  sprintf(buffer,"%d - %d",((int *)(data+*position))[0],
+         ((int *)(data+*position))[1]);
+  str = g_strdup (buffer);
+
+  *position += 2*sizeof(int);
+    
+  return str;
+}
+
+void
+selection_received (GtkWidget *widget, GtkSelectionData *data)
+{
+  int position;
+  int i;
+  SelType seltype;
+  char *str;
+  
+  if (data->length < 0)
+    {
+      g_print("Error retrieving selection\n");
+      return;
+    }
+
+  seltype = SEL_TYPE_NONE;
+  for (i=0; i<LAST_SEL_TYPE; i++)
+    {
+      if (seltypes[i] == data->type)
+       {
+         seltype = i;
+         break;
+       }
+    }
+
+  if (seltype == SEL_TYPE_NONE)
+    {
+      char *name = gdk_atom_name (data->type);
+      g_print("Don't know how to handle type: %s (%ld)\n",
+             name?name:"<unknown>",
+             data->type);
+      return;
+    }
+
+  if (selection_string != NULL)
+    g_string_free (selection_string, TRUE);
+
+  selection_string = g_string_new (NULL);
+
+  gtk_text_freeze (GTK_TEXT (selection_text));
+  gtk_text_set_point (GTK_TEXT (selection_text), 0);
+  gtk_text_foreward_delete (GTK_TEXT (selection_text), 
+                           gtk_text_get_length (GTK_TEXT (selection_text)));
+
+  position = 0;
+  while (position < data->length)
+    {
+      switch (seltype)
+       {
+       case ATOM:
+         str = stringify_atom (data->data, &position);
+         break;
+       case COMPOUND_TEXT:
+       case STRING:
+       case TEXT:
+         str = stringify_text (data->data, &position);
+         break;
+       case BITMAP:
+       case DRAWABLE:
+       case PIXMAP:
+       case WINDOW:
+       case COLORMAP:
+         str = stringify_xid (data->data, &position);
+         break;
+       case INTEGER:
+       case PIXEL:
+         str = stringify_integer (data->data, &position);
+         break;
+       case SPAN:
+         str = stringify_span (data->data, &position);
+         break;
+       default:
+         {
+           char *name = gdk_atom_name (data->type);
+           g_print("Can't convert type %s (%ld) to string\n",
+                   name?name:"<unknown>",
+                   data->type);
+           position = data->length;
+         }
+       }
+      gtk_text_insert (GTK_TEXT (selection_text), NULL, 
+                      &selection_text->style->black, 
+                      NULL, str, -1);
+      gtk_text_insert (GTK_TEXT (selection_text), NULL, 
+                      &selection_text->style->black, 
+                      NULL, "\n", -1);
+      g_string_append (selection_string, str);
+      g_free (str);
+    }
+  gtk_text_thaw (GTK_TEXT (selection_text));
+}
+
+void
+paste (GtkWidget *widget, GtkWidget *entry)
+{
+  char *name;
+  GdkAtom atom;
+
+  name = gtk_entry_get_text (GTK_ENTRY(entry));
+  atom = gdk_atom_intern (name, FALSE);
+
+  if (atom == GDK_NONE)
+    {
+      g_print("Could not create atom: \"%s\"\n",name);
+      return;
+    }
+
+  gtk_selection_convert (selection_button, GDK_SELECTION_PRIMARY, atom, 
+                        GDK_CURRENT_TIME);
+}
+
+void
+quit ()
+{
+  gtk_exit (0);
+}
+
+int
+main (int argc, char *argv[])
+{
+  GtkWidget *dialog;
+  GtkWidget *button;
+  GtkWidget *table;
+  GtkWidget *label;
+  GtkWidget *entry;
+  GtkWidget *hscrollbar;
+  GtkWidget *vscrollbar;
+  GtkWidget *hbox;
+  
+  gtk_init (&argc, &argv);
+
+  init_atoms();
+
+  dialog = gtk_dialog_new ();
+  gtk_widget_set_name (dialog, "Test Input");
+  gtk_container_border_width (GTK_CONTAINER(dialog), 0);
+
+  gtk_signal_connect (GTK_OBJECT (dialog), "destroy",
+                     GTK_SIGNAL_FUNC (quit), NULL);
+
+  table = gtk_table_new (4, 2, FALSE);
+  gtk_container_border_width (GTK_CONTAINER(table), 10);
+
+  gtk_table_set_row_spacing (GTK_TABLE (table), 0, 5);
+  gtk_table_set_row_spacing (GTK_TABLE (table), 1, 2);
+  gtk_table_set_row_spacing (GTK_TABLE (table), 2, 2);
+  gtk_table_set_col_spacing (GTK_TABLE (table), 0, 2);
+  gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dialog)->vbox), 
+                     table, TRUE, TRUE, 0);
+  gtk_widget_show (table);
+  
+  selection_button = gtk_toggle_button_new_with_label ("Claim Selection");
+  gtk_table_attach (GTK_TABLE (table), selection_button, 0, 2, 0, 1,
+                   GTK_EXPAND | GTK_FILL, 0, 0, 0);
+  gtk_widget_show (selection_button);
+
+  gtk_signal_connect (GTK_OBJECT(selection_button), "toggled",
+                     GTK_SIGNAL_FUNC (selection_toggled), NULL);
+  gtk_signal_connect (GTK_OBJECT(selection_button), "selection_clear_event",
+                     GTK_SIGNAL_FUNC (selection_clear), NULL);
+  gtk_signal_connect (GTK_OBJECT(selection_button), "selection_received",
+                     GTK_SIGNAL_FUNC (selection_received), NULL);
+
+  gtk_selection_add_handler (selection_button, GDK_SELECTION_PRIMARY,
+                            seltypes[STRING], selection_handle, NULL, NULL);
+
+  gtk_selection_add_handler (selection_button, GDK_SELECTION_PRIMARY,
+                            seltypes[TEXT], selection_handle, NULL, NULL);
+
+  gtk_selection_add_handler (selection_button, GDK_SELECTION_PRIMARY,
+                            seltypes[COMPOUND_TEXT],
+                            selection_handle, NULL, NULL);
+
+  selection_text = gtk_text_new (NULL, NULL);
+  gtk_table_attach_defaults (GTK_TABLE (table), selection_text, 0, 1, 1, 2);
+  gtk_widget_show (selection_text);
+  
+  hscrollbar = gtk_hscrollbar_new (GTK_TEXT (selection_text)->hadj);
+  gtk_table_attach (GTK_TABLE (table), hscrollbar, 0, 1, 2, 3,
+                   GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
+  gtk_widget_show (hscrollbar);
+  
+  vscrollbar = gtk_vscrollbar_new (GTK_TEXT (selection_text)->vadj);
+  gtk_table_attach (GTK_TABLE (table), vscrollbar, 1, 2, 1, 2,
+                   GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+  gtk_widget_show (vscrollbar);
+
+  hbox = gtk_hbox_new (FALSE, 2);
+  gtk_table_attach (GTK_TABLE (table), hbox, 0, 2, 3, 4,
+                   GTK_EXPAND | GTK_FILL, 0, 0, 0);
+  gtk_widget_show (hbox);
+
+  label = gtk_label_new ("Target:");
+  gtk_box_pack_start (GTK_BOX(hbox), label, FALSE, FALSE, 0);
+  gtk_widget_show (label);
+
+  entry = gtk_entry_new ();
+  gtk_box_pack_start (GTK_BOX(hbox), entry, TRUE, TRUE, 0);
+  gtk_widget_show (entry);
+
+  /* .. And create some buttons */
+  button = gtk_button_new_with_label ("Paste");
+  gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dialog)->action_area), 
+                     button, TRUE, TRUE, 0);
+  gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                     GTK_SIGNAL_FUNC (paste), entry);
+  gtk_widget_show (button);
+
+  button = gtk_button_new_with_label ("Quit");
+  gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dialog)->action_area), 
+                     button, TRUE, TRUE, 0);
+
+  gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                            GTK_SIGNAL_FUNC (gtk_widget_destroy), 
+                            GTK_OBJECT (dialog));
+  gtk_widget_show (button);
+
+  gtk_widget_show (dialog);
+
+  gtk_main ();
+
+  return 0;
+}